Commit 98a8890f authored by Yishai Hadas's avatar Yishai Hadas Committed by Jason Gunthorpe

IB/uverbs: Refactor related objects to use their own asynchronous event FD

Refactor related objects to use their own asynchronous event FD.
The ufile event FD will be the default in case an object won't have its own
event FD.

Link: https://lore.kernel.org/r/20200519072711.257271-3-leon@kernel.orgSigned-off-by: default avatarYishai Hadas <yishaih@mellanox.com>
Signed-off-by: default avatarLeon Romanovsky <leonro@mellanox.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 0ac8903c
...@@ -142,7 +142,7 @@ struct ib_uverbs_file { ...@@ -142,7 +142,7 @@ struct ib_uverbs_file {
* ucontext_lock held * ucontext_lock held
*/ */
struct ib_ucontext *ucontext; struct ib_ucontext *ucontext;
struct ib_uverbs_async_event_file *async_file; struct ib_uverbs_async_event_file *default_async_file;
struct list_head list; struct list_head list;
/* /*
...@@ -180,6 +180,7 @@ struct ib_uverbs_mcast_entry { ...@@ -180,6 +180,7 @@ struct ib_uverbs_mcast_entry {
struct ib_uevent_object { struct ib_uevent_object {
struct ib_uobject uobject; struct ib_uobject uobject;
struct ib_uverbs_async_event_file *event_file;
/* List member for ib_uverbs_async_event_file list */ /* List member for ib_uverbs_async_event_file list */
struct list_head event_list; struct list_head event_list;
u32 events_reported; u32 events_reported;
......
...@@ -1051,6 +1051,10 @@ static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs, ...@@ -1051,6 +1051,10 @@ static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs,
goto err_free; goto err_free;
obj->uevent.uobject.object = cq; obj->uevent.uobject.object = cq;
obj->uevent.event_file = READ_ONCE(attrs->ufile->default_async_file);
if (obj->uevent.event_file)
uverbs_uobject_get(&obj->uevent.event_file->uobj);
memset(&resp, 0, sizeof resp); memset(&resp, 0, sizeof resp);
resp.base.cq_handle = obj->uevent.uobject.id; resp.base.cq_handle = obj->uevent.uobject.id;
resp.base.cqe = cq->cqe; resp.base.cqe = cq->cqe;
...@@ -1067,6 +1071,8 @@ static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs, ...@@ -1067,6 +1071,8 @@ static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs,
return obj; return obj;
err_cb: err_cb:
if (obj->uevent.event_file)
uverbs_uobject_put(&obj->uevent.event_file->uobj);
ib_destroy_cq_user(cq, uverbs_get_cleared_udata(attrs)); ib_destroy_cq_user(cq, uverbs_get_cleared_udata(attrs));
cq = NULL; cq = NULL;
err_free: err_free:
...@@ -1460,6 +1466,9 @@ static int create_qp(struct uverbs_attr_bundle *attrs, ...@@ -1460,6 +1466,9 @@ static int create_qp(struct uverbs_attr_bundle *attrs,
} }
obj->uevent.uobject.object = qp; obj->uevent.uobject.object = qp;
obj->uevent.event_file = READ_ONCE(attrs->ufile->default_async_file);
if (obj->uevent.event_file)
uverbs_uobject_get(&obj->uevent.event_file->uobj);
memset(&resp, 0, sizeof resp); memset(&resp, 0, sizeof resp);
resp.base.qpn = qp->qp_num; resp.base.qpn = qp->qp_num;
...@@ -1473,7 +1482,7 @@ static int create_qp(struct uverbs_attr_bundle *attrs, ...@@ -1473,7 +1482,7 @@ static int create_qp(struct uverbs_attr_bundle *attrs,
ret = uverbs_response(attrs, &resp, sizeof(resp)); ret = uverbs_response(attrs, &resp, sizeof(resp));
if (ret) if (ret)
goto err_cb; goto err_uevent;
if (xrcd) { if (xrcd) {
obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object, obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object,
...@@ -1498,6 +1507,9 @@ static int create_qp(struct uverbs_attr_bundle *attrs, ...@@ -1498,6 +1507,9 @@ static int create_qp(struct uverbs_attr_bundle *attrs,
rdma_alloc_commit_uobject(&obj->uevent.uobject, attrs); rdma_alloc_commit_uobject(&obj->uevent.uobject, attrs);
return 0; return 0;
err_uevent:
if (obj->uevent.event_file)
uverbs_uobject_put(&obj->uevent.event_file->uobj);
err_cb: err_cb:
ib_destroy_qp_user(qp, uverbs_get_cleared_udata(attrs)); ib_destroy_qp_user(qp, uverbs_get_cleared_udata(attrs));
...@@ -2975,6 +2987,9 @@ static int ib_uverbs_ex_create_wq(struct uverbs_attr_bundle *attrs) ...@@ -2975,6 +2987,9 @@ static int ib_uverbs_ex_create_wq(struct uverbs_attr_bundle *attrs)
atomic_set(&wq->usecnt, 0); atomic_set(&wq->usecnt, 0);
atomic_inc(&pd->usecnt); atomic_inc(&pd->usecnt);
atomic_inc(&cq->usecnt); atomic_inc(&cq->usecnt);
obj->uevent.event_file = READ_ONCE(attrs->ufile->default_async_file);
if (obj->uevent.event_file)
uverbs_uobject_get(&obj->uevent.event_file->uobj);
memset(&resp, 0, sizeof(resp)); memset(&resp, 0, sizeof(resp));
resp.wq_handle = obj->uevent.uobject.id; resp.wq_handle = obj->uevent.uobject.id;
...@@ -2993,6 +3008,8 @@ static int ib_uverbs_ex_create_wq(struct uverbs_attr_bundle *attrs) ...@@ -2993,6 +3008,8 @@ static int ib_uverbs_ex_create_wq(struct uverbs_attr_bundle *attrs)
return 0; return 0;
err_copy: err_copy:
if (obj->uevent.event_file)
uverbs_uobject_put(&obj->uevent.event_file->uobj);
ib_destroy_wq(wq, uverbs_get_cleared_udata(attrs)); ib_destroy_wq(wq, uverbs_get_cleared_udata(attrs));
err_put_cq: err_put_cq:
rdma_lookup_put_uobject(&cq->uobject->uevent.uobject, rdma_lookup_put_uobject(&cq->uobject->uevent.uobject,
...@@ -3453,6 +3470,10 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs, ...@@ -3453,6 +3470,10 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs,
} }
obj->uevent.uobject.object = srq; obj->uevent.uobject.object = srq;
obj->uevent.uobject.user_handle = cmd->user_handle;
obj->uevent.event_file = READ_ONCE(attrs->ufile->default_async_file);
if (obj->uevent.event_file)
uverbs_uobject_get(&obj->uevent.event_file->uobj);
memset(&resp, 0, sizeof resp); memset(&resp, 0, sizeof resp);
resp.srq_handle = obj->uevent.uobject.id; resp.srq_handle = obj->uevent.uobject.id;
...@@ -3477,6 +3498,8 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs, ...@@ -3477,6 +3498,8 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs,
return 0; return 0;
err_copy: err_copy:
if (obj->uevent.event_file)
uverbs_uobject_put(&obj->uevent.event_file->uobj);
ib_destroy_srq_user(srq, uverbs_get_cleared_udata(attrs)); ib_destroy_srq_user(srq, uverbs_get_cleared_udata(attrs));
err_put_pd: err_put_pd:
uobj_put_obj_read(pd); uobj_put_obj_read(pd);
......
...@@ -146,8 +146,7 @@ void ib_uverbs_release_ucq(struct ib_uverbs_completion_event_file *ev_file, ...@@ -146,8 +146,7 @@ void ib_uverbs_release_ucq(struct ib_uverbs_completion_event_file *ev_file,
void ib_uverbs_release_uevent(struct ib_uevent_object *uobj) void ib_uverbs_release_uevent(struct ib_uevent_object *uobj)
{ {
struct ib_uverbs_async_event_file *async_file = struct ib_uverbs_async_event_file *async_file = uobj->event_file;
READ_ONCE(uobj->uobject.ufile->async_file);
struct ib_uverbs_event *evt, *tmp; struct ib_uverbs_event *evt, *tmp;
if (!async_file) if (!async_file)
...@@ -159,6 +158,7 @@ void ib_uverbs_release_uevent(struct ib_uevent_object *uobj) ...@@ -159,6 +158,7 @@ void ib_uverbs_release_uevent(struct ib_uevent_object *uobj)
kfree(evt); kfree(evt);
} }
spin_unlock_irq(&async_file->ev_queue.lock); spin_unlock_irq(&async_file->ev_queue.lock);
uverbs_uobject_put(&async_file->uobj);
} }
void ib_uverbs_detach_umcast(struct ib_qp *qp, void ib_uverbs_detach_umcast(struct ib_qp *qp,
...@@ -197,8 +197,8 @@ void ib_uverbs_release_file(struct kref *ref) ...@@ -197,8 +197,8 @@ void ib_uverbs_release_file(struct kref *ref)
if (atomic_dec_and_test(&file->device->refcount)) if (atomic_dec_and_test(&file->device->refcount))
ib_uverbs_comp_dev(file->device); ib_uverbs_comp_dev(file->device);
if (file->async_file) if (file->default_async_file)
uverbs_uobject_put(&file->async_file->uobj); uverbs_uobject_put(&file->default_async_file->uobj);
put_device(&file->device->dev); put_device(&file->device->dev);
if (file->disassociate_page) if (file->disassociate_page)
...@@ -427,7 +427,7 @@ void ib_uverbs_async_handler(struct ib_uverbs_async_event_file *async_file, ...@@ -427,7 +427,7 @@ void ib_uverbs_async_handler(struct ib_uverbs_async_event_file *async_file,
static void uverbs_uobj_event(struct ib_uevent_object *eobj, static void uverbs_uobj_event(struct ib_uevent_object *eobj,
struct ib_event *event) struct ib_event *event)
{ {
ib_uverbs_async_handler(READ_ONCE(eobj->uobject.ufile->async_file), ib_uverbs_async_handler(eobj->event_file,
eobj->uobject.user_handle, event->event, eobj->uobject.user_handle, event->event,
&eobj->event_list, &eobj->events_reported); &eobj->event_list, &eobj->events_reported);
} }
...@@ -484,10 +484,10 @@ void ib_uverbs_init_async_event_file( ...@@ -484,10 +484,10 @@ void ib_uverbs_init_async_event_file(
/* The first async_event_file becomes the default one for the file. */ /* The first async_event_file becomes the default one for the file. */
mutex_lock(&uverbs_file->ucontext_lock); mutex_lock(&uverbs_file->ucontext_lock);
if (!uverbs_file->async_file) { if (!uverbs_file->default_async_file) {
/* Pairs with the put in ib_uverbs_release_file */ /* Pairs with the put in ib_uverbs_release_file */
uverbs_uobject_get(&async_file->uobj); uverbs_uobject_get(&async_file->uobj);
smp_store_release(&uverbs_file->async_file, async_file); smp_store_release(&uverbs_file->default_async_file, async_file);
} }
mutex_unlock(&uverbs_file->ucontext_lock); mutex_unlock(&uverbs_file->ucontext_lock);
......
...@@ -100,6 +100,10 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)( ...@@ -100,6 +100,10 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
uverbs_uobject_get(ev_file_uobj); uverbs_uobject_get(ev_file_uobj);
} }
obj->uevent.event_file = READ_ONCE(attrs->ufile->default_async_file);
if (obj->uevent.event_file)
uverbs_uobject_get(&obj->uevent.event_file->uobj);
if (attr.comp_vector >= attrs->ufile->device->num_comp_vectors) { if (attr.comp_vector >= attrs->ufile->device->num_comp_vectors) {
ret = -EINVAL; ret = -EINVAL;
goto err_event_file; goto err_event_file;
...@@ -138,6 +142,8 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)( ...@@ -138,6 +142,8 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
err_free: err_free:
kfree(cq); kfree(cq);
err_event_file: err_event_file:
if (obj->uevent.event_file)
uverbs_uobject_put(&obj->uevent.event_file->uobj);
if (ev_file) if (ev_file)
uverbs_uobject_put(ev_file_uobj); uverbs_uobject_put(ev_file_uobj);
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment