diff options
author | Jason Gunthorpe <jgg@mellanox.com> | 2018-08-09 20:14:37 -0600 |
---|---|---|
committer | Jason Gunthorpe <jgg@mellanox.com> | 2018-08-10 16:06:24 -0600 |
commit | 6b0d08f4a27134e6fb49aa33ceb53356081bc92e (patch) | |
tree | 7781178fde4ef9aeb01acf736274de2fca581a5a /include/rdma | |
parent | 9ed3e5f447723a41de6bcc29633e9f7e6246d2f7 (diff) | |
download | linux-stable-6b0d08f4a27134e6fb49aa33ceb53356081bc92e.tar.gz linux-stable-6b0d08f4a27134e6fb49aa33ceb53356081bc92e.tar.bz2 linux-stable-6b0d08f4a27134e6fb49aa33ceb53356081bc92e.zip |
IB/uverbs: Use uverbs_api to manage the object type inside the uobject
Currently the struct uverbs_obj_type stored in the ib_uobject is part of
the .rodata segment of the module that defines the object. This is a
problem if drivers define new uapi objects as we will be left with a
dangling pointer after device disassociation.
Switch the uverbs_obj_type for struct uverbs_api_object, which is
allocated memory that is part of the uverbs_api and is guaranteed to
always exist. Further this moves the 'type_class' into this memory which
means access to the IDR/FD function pointers is also guaranteed. Drivers
cannot define new types.
This makes it safe to continue to use all uobjects, including driver
defined ones, after disassociation.
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
Diffstat (limited to 'include/rdma')
-rw-r--r-- | include/rdma/ib_verbs.h | 2 | ||||
-rw-r--r-- | include/rdma/uverbs_std_types.h | 30 | ||||
-rw-r--r-- | include/rdma/uverbs_types.h | 9 |
3 files changed, 22 insertions, 19 deletions
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h index 3b07201b9a80..5d404c20b49f 100644 --- a/include/rdma/ib_verbs.h +++ b/include/rdma/ib_verbs.h @@ -1524,7 +1524,7 @@ struct ib_uobject { atomic_t usecnt; /* protects exclusive access */ struct rcu_head rcu; /* kfree_rcu() overhead */ - const struct uverbs_obj_type *type; + const struct uverbs_api_object *uapi_object; }; struct ib_udata { diff --git a/include/rdma/uverbs_std_types.h b/include/rdma/uverbs_std_types.h index 64ee2545dd3d..3b00231cc084 100644 --- a/include/rdma/uverbs_std_types.h +++ b/include/rdma/uverbs_std_types.h @@ -54,14 +54,15 @@ static inline const struct uverbs_object_tree_def *uverbs_default_get_objects(vo */ #define _uobj_check_id(_id) ((_id) * typecheck(u32, _id)) -#define uobj_get_type(_object) UVERBS_OBJECT(_object).type_attrs +#define uobj_get_type(_ufile, _object) \ + uapi_get_object((_ufile)->device->uapi, _object) #define uobj_get_read(_type, _id, _ufile) \ - rdma_lookup_get_uobject(uobj_get_type(_type), _ufile, \ + rdma_lookup_get_uobject(uobj_get_type(_ufile, _type), _ufile, \ _uobj_check_id(_id), UVERBS_LOOKUP_READ) #define ufd_get_read(_type, _fdnum, _ufile) \ - rdma_lookup_get_uobject(uobj_get_type(_type), _ufile, \ + rdma_lookup_get_uobject(uobj_get_type(_ufile, _type), _ufile, \ (_fdnum)*typecheck(s32, _fdnum), \ UVERBS_LOOKUP_READ) @@ -76,20 +77,21 @@ static inline void *_uobj_get_obj_read(struct ib_uobject *uobj) uobj_get_read(_type, _id, _ufile))) #define uobj_get_write(_type, _id, _ufile) \ - rdma_lookup_get_uobject(uobj_get_type(_type), _ufile, \ + rdma_lookup_get_uobject(uobj_get_type(_ufile, _type), _ufile, \ _uobj_check_id(_id), UVERBS_LOOKUP_WRITE) -int __uobj_perform_destroy(const struct uverbs_obj_type *type, u32 id, +int __uobj_perform_destroy(const struct uverbs_api_object *obj, u32 id, struct ib_uverbs_file *ufile, int success_res); #define uobj_perform_destroy(_type, _id, _ufile, _success_res) \ - __uobj_perform_destroy(uobj_get_type(_type), _uobj_check_id(_id), \ - _ufile, _success_res) + __uobj_perform_destroy(uobj_get_type(_ufile, _type), \ + _uobj_check_id(_id), _ufile, _success_res) -struct ib_uobject *__uobj_get_destroy(const struct uverbs_obj_type *type, +struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj, u32 id, struct ib_uverbs_file *ufile); #define uobj_get_destroy(_type, _id, _ufile) \ - __uobj_get_destroy(uobj_get_type(_type), _uobj_check_id(_id), _ufile) + __uobj_get_destroy(uobj_get_type(_ufile, _type), _uobj_check_id(_id), \ + _ufile) static inline void uobj_put_destroy(struct ib_uobject *uobj) { @@ -124,11 +126,11 @@ static inline void uobj_alloc_abort(struct ib_uobject *uobj) rdma_alloc_abort_uobject(uobj); } -static inline struct ib_uobject *__uobj_alloc(const struct uverbs_obj_type *type, - struct ib_uverbs_file *ufile, - struct ib_device **ib_dev) +static inline struct ib_uobject * +__uobj_alloc(const struct uverbs_api_object *obj, struct ib_uverbs_file *ufile, + struct ib_device **ib_dev) { - struct ib_uobject *uobj = rdma_alloc_begin_uobject(type, ufile); + struct ib_uobject *uobj = rdma_alloc_begin_uobject(obj, ufile); if (!IS_ERR(uobj)) *ib_dev = uobj->context->device; @@ -136,7 +138,7 @@ static inline struct ib_uobject *__uobj_alloc(const struct uverbs_obj_type *type } #define uobj_alloc(_type, _ufile, _ib_dev) \ - __uobj_alloc(uobj_get_type(_type), _ufile, _ib_dev) + __uobj_alloc(uobj_get_type(_ufile, _type), _ufile, _ib_dev) #endif diff --git a/include/rdma/uverbs_types.h b/include/rdma/uverbs_types.h index 1ab9a85eebd9..acb1bfa3cc99 100644 --- a/include/rdma/uverbs_types.h +++ b/include/rdma/uverbs_types.h @@ -37,6 +37,7 @@ #include <rdma/ib_verbs.h> struct uverbs_obj_type; +struct uverbs_api_object; enum rdma_lookup_mode { UVERBS_LOOKUP_READ, @@ -81,14 +82,14 @@ enum rdma_lookup_mode { * alloc_abort returns. */ struct uverbs_obj_type_class { - struct ib_uobject *(*alloc_begin)(const struct uverbs_obj_type *type, + struct ib_uobject *(*alloc_begin)(const struct uverbs_api_object *obj, struct ib_uverbs_file *ufile); /* This consumes the kref on uobj */ int (*alloc_commit)(struct ib_uobject *uobj); /* This does not consume the kref on uobj */ void (*alloc_abort)(struct ib_uobject *uobj); - struct ib_uobject *(*lookup_get)(const struct uverbs_obj_type *type, + struct ib_uobject *(*lookup_get)(const struct uverbs_api_object *obj, struct ib_uverbs_file *ufile, s64 id, enum rdma_lookup_mode mode); void (*lookup_put)(struct ib_uobject *uobj, enum rdma_lookup_mode mode); @@ -128,12 +129,12 @@ struct uverbs_obj_idr_type { enum rdma_remove_reason why); }; -struct ib_uobject *rdma_lookup_get_uobject(const struct uverbs_obj_type *type, +struct ib_uobject *rdma_lookup_get_uobject(const struct uverbs_api_object *obj, struct ib_uverbs_file *ufile, s64 id, enum rdma_lookup_mode mode); void rdma_lookup_put_uobject(struct ib_uobject *uobj, enum rdma_lookup_mode mode); -struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_obj_type *type, +struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_api_object *obj, struct ib_uverbs_file *ufile); void rdma_alloc_abort_uobject(struct ib_uobject *uobj); int __must_check rdma_alloc_commit_uobject(struct ib_uobject *uobj); |