IB: ucontext should be set properly for all cmd & ioctl paths
the Attempt to use the below commit to initialize the ucontext for the
uobject destroy path has shown that the below commit is incomplete.
Parts were reverted and the ucontext set up in the uverbs_attr_bundle was
moved to rdma_lookup_get_uobject which is called from the uobj_get_XXX
macros and rdma_alloc_begin_uobject which is called when uobject is
created.
Fixes: 3d9dfd0603
("IB/uverbs: Add ib_ucontext to uverbs_attr_bundle sent from ioctl and cmd flows")
Signed-off-by: Shamir Rabinovitch <shamir.rabinovitch@oracle.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
parent
fae7a699a9
commit
70f06b26f0
|
@ -224,14 +224,13 @@ out_unlock:
|
||||||
* uverbs_put_destroy.
|
* uverbs_put_destroy.
|
||||||
*/
|
*/
|
||||||
struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj,
|
struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj,
|
||||||
u32 id,
|
u32 id, struct uverbs_attr_bundle *attrs)
|
||||||
const struct uverbs_attr_bundle *attrs)
|
|
||||||
{
|
{
|
||||||
struct ib_uobject *uobj;
|
struct ib_uobject *uobj;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
uobj = rdma_lookup_get_uobject(obj, attrs->ufile, id,
|
uobj = rdma_lookup_get_uobject(obj, attrs->ufile, id,
|
||||||
UVERBS_LOOKUP_DESTROY);
|
UVERBS_LOOKUP_DESTROY, attrs);
|
||||||
if (IS_ERR(uobj))
|
if (IS_ERR(uobj))
|
||||||
return uobj;
|
return uobj;
|
||||||
|
|
||||||
|
@ -249,7 +248,7 @@ struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj,
|
||||||
* (negative errno on failure). For use by callers that do not need the uobj.
|
* (negative errno on failure). For use by callers that do not need the uobj.
|
||||||
*/
|
*/
|
||||||
int __uobj_perform_destroy(const struct uverbs_api_object *obj, u32 id,
|
int __uobj_perform_destroy(const struct uverbs_api_object *obj, u32 id,
|
||||||
const struct uverbs_attr_bundle *attrs)
|
struct uverbs_attr_bundle *attrs)
|
||||||
{
|
{
|
||||||
struct ib_uobject *uobj;
|
struct ib_uobject *uobj;
|
||||||
|
|
||||||
|
@ -393,7 +392,8 @@ lookup_get_fd_uobject(const struct uverbs_api_object *obj,
|
||||||
|
|
||||||
struct ib_uobject *rdma_lookup_get_uobject(const struct uverbs_api_object *obj,
|
struct ib_uobject *rdma_lookup_get_uobject(const struct uverbs_api_object *obj,
|
||||||
struct ib_uverbs_file *ufile, s64 id,
|
struct ib_uverbs_file *ufile, s64 id,
|
||||||
enum rdma_lookup_mode mode)
|
enum rdma_lookup_mode mode,
|
||||||
|
struct uverbs_attr_bundle *attrs)
|
||||||
{
|
{
|
||||||
struct ib_uobject *uobj;
|
struct ib_uobject *uobj;
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -431,6 +431,8 @@ struct ib_uobject *rdma_lookup_get_uobject(const struct uverbs_api_object *obj,
|
||||||
ret = uverbs_try_lock_object(uobj, mode);
|
ret = uverbs_try_lock_object(uobj, mode);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto free;
|
goto free;
|
||||||
|
if (attrs)
|
||||||
|
attrs->context = uobj->context;
|
||||||
|
|
||||||
return uobj;
|
return uobj;
|
||||||
free:
|
free:
|
||||||
|
@ -438,38 +440,6 @@ free:
|
||||||
uverbs_uobject_put(uobj);
|
uverbs_uobject_put(uobj);
|
||||||
return ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
struct ib_uobject *_uobj_get_read(enum uverbs_default_objects type,
|
|
||||||
u32 object_id,
|
|
||||||
struct uverbs_attr_bundle *attrs)
|
|
||||||
{
|
|
||||||
struct ib_uobject *uobj;
|
|
||||||
|
|
||||||
uobj = rdma_lookup_get_uobject(uobj_get_type(attrs, type), attrs->ufile,
|
|
||||||
object_id, UVERBS_LOOKUP_READ);
|
|
||||||
if (IS_ERR(uobj))
|
|
||||||
return uobj;
|
|
||||||
|
|
||||||
attrs->context = uobj->context;
|
|
||||||
|
|
||||||
return uobj;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ib_uobject *_uobj_get_write(enum uverbs_default_objects type,
|
|
||||||
u32 object_id,
|
|
||||||
struct uverbs_attr_bundle *attrs)
|
|
||||||
{
|
|
||||||
struct ib_uobject *uobj;
|
|
||||||
|
|
||||||
uobj = rdma_lookup_get_uobject(uobj_get_type(attrs, type), attrs->ufile,
|
|
||||||
object_id, UVERBS_LOOKUP_WRITE);
|
|
||||||
|
|
||||||
if (IS_ERR(uobj))
|
|
||||||
return uobj;
|
|
||||||
|
|
||||||
attrs->context = uobj->context;
|
|
||||||
|
|
||||||
return uobj;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct ib_uobject *
|
static struct ib_uobject *
|
||||||
alloc_begin_idr_uobject(const struct uverbs_api_object *obj,
|
alloc_begin_idr_uobject(const struct uverbs_api_object *obj,
|
||||||
|
@ -526,7 +496,8 @@ alloc_begin_fd_uobject(const struct uverbs_api_object *obj,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_api_object *obj,
|
struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_api_object *obj,
|
||||||
struct ib_uverbs_file *ufile)
|
struct ib_uverbs_file *ufile,
|
||||||
|
struct uverbs_attr_bundle *attrs)
|
||||||
{
|
{
|
||||||
struct ib_uobject *ret;
|
struct ib_uobject *ret;
|
||||||
|
|
||||||
|
@ -546,6 +517,8 @@ struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_api_object *obj,
|
||||||
up_read(&ufile->hw_destroy_rwsem);
|
up_read(&ufile->hw_destroy_rwsem);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
if (attrs)
|
||||||
|
attrs->context = ret->context;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -967,26 +940,25 @@ const struct uverbs_obj_type_class uverbs_fd_class = {
|
||||||
EXPORT_SYMBOL(uverbs_fd_class);
|
EXPORT_SYMBOL(uverbs_fd_class);
|
||||||
|
|
||||||
struct ib_uobject *
|
struct ib_uobject *
|
||||||
uverbs_get_uobject_from_file(u16 object_id,
|
uverbs_get_uobject_from_file(u16 object_id, enum uverbs_obj_access access,
|
||||||
struct ib_uverbs_file *ufile,
|
s64 id, struct uverbs_attr_bundle *attrs)
|
||||||
enum uverbs_obj_access access, s64 id)
|
|
||||||
{
|
{
|
||||||
const struct uverbs_api_object *obj =
|
const struct uverbs_api_object *obj =
|
||||||
uapi_get_object(ufile->device->uapi, object_id);
|
uapi_get_object(attrs->ufile->device->uapi, object_id);
|
||||||
|
|
||||||
switch (access) {
|
switch (access) {
|
||||||
case UVERBS_ACCESS_READ:
|
case UVERBS_ACCESS_READ:
|
||||||
return rdma_lookup_get_uobject(obj, ufile, id,
|
return rdma_lookup_get_uobject(obj, attrs->ufile, id,
|
||||||
UVERBS_LOOKUP_READ);
|
UVERBS_LOOKUP_READ, attrs);
|
||||||
case UVERBS_ACCESS_DESTROY:
|
case UVERBS_ACCESS_DESTROY:
|
||||||
/* Actual destruction is done inside uverbs_handle_method */
|
/* Actual destruction is done inside uverbs_handle_method */
|
||||||
return rdma_lookup_get_uobject(obj, ufile, id,
|
return rdma_lookup_get_uobject(obj, attrs->ufile, id,
|
||||||
UVERBS_LOOKUP_DESTROY);
|
UVERBS_LOOKUP_DESTROY, attrs);
|
||||||
case UVERBS_ACCESS_WRITE:
|
case UVERBS_ACCESS_WRITE:
|
||||||
return rdma_lookup_get_uobject(obj, ufile, id,
|
return rdma_lookup_get_uobject(obj, attrs->ufile, id,
|
||||||
UVERBS_LOOKUP_WRITE);
|
UVERBS_LOOKUP_WRITE, attrs);
|
||||||
case UVERBS_ACCESS_NEW:
|
case UVERBS_ACCESS_NEW:
|
||||||
return rdma_alloc_begin_uobject(obj, ufile);
|
return rdma_alloc_begin_uobject(obj, attrs->ufile, attrs);
|
||||||
default:
|
default:
|
||||||
WARN_ON(true);
|
WARN_ON(true);
|
||||||
return ERR_PTR(-EOPNOTSUPP);
|
return ERR_PTR(-EOPNOTSUPP);
|
||||||
|
|
|
@ -83,9 +83,8 @@ void uverbs_close_fd(struct file *f);
|
||||||
* uverbs_finalize_objects are called.
|
* uverbs_finalize_objects are called.
|
||||||
*/
|
*/
|
||||||
struct ib_uobject *
|
struct ib_uobject *
|
||||||
uverbs_get_uobject_from_file(u16 object_id,
|
uverbs_get_uobject_from_file(u16 object_id, enum uverbs_obj_access access,
|
||||||
struct ib_uverbs_file *ufile,
|
s64 id, struct uverbs_attr_bundle *attrs);
|
||||||
enum uverbs_obj_access access, s64 id);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Note that certain finalize stages could return a status:
|
* Note that certain finalize stages could return a status:
|
||||||
|
|
|
@ -175,7 +175,7 @@ static int uverbs_request_finish(struct uverbs_req_iter *iter)
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct ib_uverbs_completion_event_file *
|
static struct ib_uverbs_completion_event_file *
|
||||||
_ib_uverbs_lookup_comp_file(s32 fd, const struct uverbs_attr_bundle *attrs)
|
_ib_uverbs_lookup_comp_file(s32 fd, struct uverbs_attr_bundle *attrs)
|
||||||
{
|
{
|
||||||
struct ib_uobject *uobj = ufd_get_read(UVERBS_OBJECT_COMP_CHANNEL,
|
struct ib_uobject *uobj = ufd_get_read(UVERBS_OBJECT_COMP_CHANNEL,
|
||||||
fd, attrs);
|
fd, attrs);
|
||||||
|
|
|
@ -207,13 +207,12 @@ static int uverbs_process_idrs_array(struct bundle_priv *pbundle,
|
||||||
|
|
||||||
for (i = 0; i != array_len; i++) {
|
for (i = 0; i != array_len; i++) {
|
||||||
attr->uobjects[i] = uverbs_get_uobject_from_file(
|
attr->uobjects[i] = uverbs_get_uobject_from_file(
|
||||||
spec->u2.objs_arr.obj_type, pbundle->bundle.ufile,
|
spec->u2.objs_arr.obj_type, spec->u2.objs_arr.access,
|
||||||
spec->u2.objs_arr.access, idr_vals[i]);
|
idr_vals[i], &pbundle->bundle);
|
||||||
if (IS_ERR(attr->uobjects[i])) {
|
if (IS_ERR(attr->uobjects[i])) {
|
||||||
ret = PTR_ERR(attr->uobjects[i]);
|
ret = PTR_ERR(attr->uobjects[i]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
pbundle->bundle.context = attr->uobjects[i]->context;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
attr->len = i;
|
attr->len = i;
|
||||||
|
@ -325,13 +324,10 @@ static int uverbs_process_attr(struct bundle_priv *pbundle,
|
||||||
* IDR implementation today rejects negative IDs
|
* IDR implementation today rejects negative IDs
|
||||||
*/
|
*/
|
||||||
o_attr->uobject = uverbs_get_uobject_from_file(
|
o_attr->uobject = uverbs_get_uobject_from_file(
|
||||||
spec->u.obj.obj_type,
|
spec->u.obj.obj_type, spec->u.obj.access,
|
||||||
pbundle->bundle.ufile,
|
uattr->data_s64, &pbundle->bundle);
|
||||||
spec->u.obj.access,
|
|
||||||
uattr->data_s64);
|
|
||||||
if (IS_ERR(o_attr->uobject))
|
if (IS_ERR(o_attr->uobject))
|
||||||
return PTR_ERR(o_attr->uobject);
|
return PTR_ERR(o_attr->uobject);
|
||||||
pbundle->bundle.context = o_attr->uobject->context;
|
|
||||||
__set_bit(attr_bkey, pbundle->uobj_finalize);
|
__set_bit(attr_bkey, pbundle->uobj_finalize);
|
||||||
|
|
||||||
if (spec->u.obj.access == UVERBS_ACCESS_NEW) {
|
if (spec->u.obj.access == UVERBS_ACCESS_NEW) {
|
||||||
|
|
|
@ -48,17 +48,15 @@
|
||||||
#define uobj_get_type(_attrs, _object) \
|
#define uobj_get_type(_attrs, _object) \
|
||||||
uapi_get_object((_attrs)->ufile->device->uapi, _object)
|
uapi_get_object((_attrs)->ufile->device->uapi, _object)
|
||||||
|
|
||||||
struct ib_uobject *_uobj_get_read(enum uverbs_default_objects type,
|
|
||||||
u32 object_id,
|
|
||||||
struct uverbs_attr_bundle *attrs);
|
|
||||||
|
|
||||||
#define uobj_get_read(_type, _id, _attrs) \
|
#define uobj_get_read(_type, _id, _attrs) \
|
||||||
_uobj_get_read(_type, _uobj_check_id(_id), _attrs)
|
rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
|
||||||
|
_uobj_check_id(_id), UVERBS_LOOKUP_READ, \
|
||||||
|
_attrs)
|
||||||
|
|
||||||
#define ufd_get_read(_type, _fdnum, _attrs) \
|
#define ufd_get_read(_type, _fdnum, _attrs) \
|
||||||
rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
|
rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
|
||||||
(_fdnum)*typecheck(s32, _fdnum), \
|
(_fdnum)*typecheck(s32, _fdnum), \
|
||||||
UVERBS_LOOKUP_READ)
|
UVERBS_LOOKUP_READ, _attrs)
|
||||||
|
|
||||||
static inline void *_uobj_get_obj_read(struct ib_uobject *uobj)
|
static inline void *_uobj_get_obj_read(struct ib_uobject *uobj)
|
||||||
{
|
{
|
||||||
|
@ -70,22 +68,19 @@ static inline void *_uobj_get_obj_read(struct ib_uobject *uobj)
|
||||||
((struct ib_##_object *)_uobj_get_obj_read( \
|
((struct ib_##_object *)_uobj_get_obj_read( \
|
||||||
uobj_get_read(_type, _id, _attrs)))
|
uobj_get_read(_type, _id, _attrs)))
|
||||||
|
|
||||||
struct ib_uobject *_uobj_get_write(enum uverbs_default_objects type,
|
|
||||||
u32 object_id,
|
|
||||||
struct uverbs_attr_bundle *attrs);
|
|
||||||
|
|
||||||
#define uobj_get_write(_type, _id, _attrs) \
|
#define uobj_get_write(_type, _id, _attrs) \
|
||||||
_uobj_get_write(_type, _uobj_check_id(_id), _attrs)
|
rdma_lookup_get_uobject(uobj_get_type(_attrs, _type), (_attrs)->ufile, \
|
||||||
|
_uobj_check_id(_id), UVERBS_LOOKUP_WRITE, \
|
||||||
|
_attrs)
|
||||||
|
|
||||||
int __uobj_perform_destroy(const struct uverbs_api_object *obj, u32 id,
|
int __uobj_perform_destroy(const struct uverbs_api_object *obj, u32 id,
|
||||||
const struct uverbs_attr_bundle *attrs);
|
struct uverbs_attr_bundle *attrs);
|
||||||
#define uobj_perform_destroy(_type, _id, _attrs) \
|
#define uobj_perform_destroy(_type, _id, _attrs) \
|
||||||
__uobj_perform_destroy(uobj_get_type(_attrs, _type), \
|
__uobj_perform_destroy(uobj_get_type(_attrs, _type), \
|
||||||
_uobj_check_id(_id), _attrs)
|
_uobj_check_id(_id), _attrs)
|
||||||
|
|
||||||
struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj,
|
struct ib_uobject *__uobj_get_destroy(const struct uverbs_api_object *obj,
|
||||||
u32 id,
|
u32 id, struct uverbs_attr_bundle *attrs);
|
||||||
const struct uverbs_attr_bundle *attrs);
|
|
||||||
|
|
||||||
#define uobj_get_destroy(_type, _id, _attrs) \
|
#define uobj_get_destroy(_type, _id, _attrs) \
|
||||||
__uobj_get_destroy(uobj_get_type(_attrs, _type), _uobj_check_id(_id), \
|
__uobj_get_destroy(uobj_get_type(_attrs, _type), _uobj_check_id(_id), \
|
||||||
|
@ -127,12 +122,11 @@ static inline struct ib_uobject *
|
||||||
__uobj_alloc(const struct uverbs_api_object *obj,
|
__uobj_alloc(const struct uverbs_api_object *obj,
|
||||||
struct uverbs_attr_bundle *attrs, struct ib_device **ib_dev)
|
struct uverbs_attr_bundle *attrs, struct ib_device **ib_dev)
|
||||||
{
|
{
|
||||||
struct ib_uobject *uobj = rdma_alloc_begin_uobject(obj, attrs->ufile);
|
struct ib_uobject *uobj =
|
||||||
|
rdma_alloc_begin_uobject(obj, attrs->ufile, attrs);
|
||||||
|
|
||||||
if (!IS_ERR(uobj)) {
|
if (!IS_ERR(uobj))
|
||||||
*ib_dev = uobj->context->device;
|
*ib_dev = uobj->context->device;
|
||||||
attrs->context = uobj->context;
|
|
||||||
}
|
|
||||||
return uobj;
|
return uobj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,11 +131,13 @@ struct uverbs_obj_idr_type {
|
||||||
|
|
||||||
struct ib_uobject *rdma_lookup_get_uobject(const struct uverbs_api_object *obj,
|
struct ib_uobject *rdma_lookup_get_uobject(const struct uverbs_api_object *obj,
|
||||||
struct ib_uverbs_file *ufile, s64 id,
|
struct ib_uverbs_file *ufile, s64 id,
|
||||||
enum rdma_lookup_mode mode);
|
enum rdma_lookup_mode mode,
|
||||||
|
struct uverbs_attr_bundle *attrs);
|
||||||
void rdma_lookup_put_uobject(struct ib_uobject *uobj,
|
void rdma_lookup_put_uobject(struct ib_uobject *uobj,
|
||||||
enum rdma_lookup_mode mode);
|
enum rdma_lookup_mode mode);
|
||||||
struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_api_object *obj,
|
struct ib_uobject *rdma_alloc_begin_uobject(const struct uverbs_api_object *obj,
|
||||||
struct ib_uverbs_file *ufile);
|
struct ib_uverbs_file *ufile,
|
||||||
|
struct uverbs_attr_bundle *attrs);
|
||||||
void rdma_alloc_abort_uobject(struct ib_uobject *uobj);
|
void rdma_alloc_abort_uobject(struct ib_uobject *uobj);
|
||||||
int __must_check rdma_alloc_commit_uobject(struct ib_uobject *uobj);
|
int __must_check rdma_alloc_commit_uobject(struct ib_uobject *uobj);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue