mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-08 15:04:45 +00:00
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.org Signed-off-by: Yishai Hadas <yishaih@mellanox.com> Signed-off-by: Leon Romanovsky <leonro@mellanox.com> Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
This commit is contained in:
parent
0ac8903cbb
commit
98a8890f73
@ -142,7 +142,7 @@ struct ib_uverbs_file {
|
||||
* ucontext_lock held
|
||||
*/
|
||||
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;
|
||||
|
||||
/*
|
||||
@ -180,6 +180,7 @@ struct ib_uverbs_mcast_entry {
|
||||
|
||||
struct ib_uevent_object {
|
||||
struct ib_uobject uobject;
|
||||
struct ib_uverbs_async_event_file *event_file;
|
||||
/* List member for ib_uverbs_async_event_file list */
|
||||
struct list_head event_list;
|
||||
u32 events_reported;
|
||||
|
@ -1051,6 +1051,10 @@ static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs,
|
||||
goto err_free;
|
||||
|
||||
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);
|
||||
resp.base.cq_handle = obj->uevent.uobject.id;
|
||||
resp.base.cqe = cq->cqe;
|
||||
@ -1067,6 +1071,8 @@ static struct ib_ucq_object *create_cq(struct uverbs_attr_bundle *attrs,
|
||||
return obj;
|
||||
|
||||
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));
|
||||
cq = NULL;
|
||||
err_free:
|
||||
@ -1460,6 +1466,9 @@ static int create_qp(struct uverbs_attr_bundle *attrs,
|
||||
}
|
||||
|
||||
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);
|
||||
resp.base.qpn = qp->qp_num;
|
||||
@ -1473,7 +1482,7 @@ static int create_qp(struct uverbs_attr_bundle *attrs,
|
||||
|
||||
ret = uverbs_response(attrs, &resp, sizeof(resp));
|
||||
if (ret)
|
||||
goto err_cb;
|
||||
goto err_uevent;
|
||||
|
||||
if (xrcd) {
|
||||
obj->uxrcd = container_of(xrcd_uobj, struct ib_uxrcd_object,
|
||||
@ -1498,6 +1507,9 @@ static int create_qp(struct uverbs_attr_bundle *attrs,
|
||||
|
||||
rdma_alloc_commit_uobject(&obj->uevent.uobject, attrs);
|
||||
return 0;
|
||||
err_uevent:
|
||||
if (obj->uevent.event_file)
|
||||
uverbs_uobject_put(&obj->uevent.event_file->uobj);
|
||||
err_cb:
|
||||
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)
|
||||
atomic_set(&wq->usecnt, 0);
|
||||
atomic_inc(&pd->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));
|
||||
resp.wq_handle = obj->uevent.uobject.id;
|
||||
@ -2993,6 +3008,8 @@ static int ib_uverbs_ex_create_wq(struct uverbs_attr_bundle *attrs)
|
||||
return 0;
|
||||
|
||||
err_copy:
|
||||
if (obj->uevent.event_file)
|
||||
uverbs_uobject_put(&obj->uevent.event_file->uobj);
|
||||
ib_destroy_wq(wq, uverbs_get_cleared_udata(attrs));
|
||||
err_put_cq:
|
||||
rdma_lookup_put_uobject(&cq->uobject->uevent.uobject,
|
||||
@ -3453,6 +3470,10 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs,
|
||||
}
|
||||
|
||||
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);
|
||||
resp.srq_handle = obj->uevent.uobject.id;
|
||||
@ -3477,6 +3498,8 @@ static int __uverbs_create_xsrq(struct uverbs_attr_bundle *attrs,
|
||||
return 0;
|
||||
|
||||
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));
|
||||
err_put_pd:
|
||||
uobj_put_obj_read(pd);
|
||||
|
@ -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)
|
||||
{
|
||||
struct ib_uverbs_async_event_file *async_file =
|
||||
READ_ONCE(uobj->uobject.ufile->async_file);
|
||||
struct ib_uverbs_async_event_file *async_file = uobj->event_file;
|
||||
struct ib_uverbs_event *evt, *tmp;
|
||||
|
||||
if (!async_file)
|
||||
@ -159,6 +158,7 @@ void ib_uverbs_release_uevent(struct ib_uevent_object *uobj)
|
||||
kfree(evt);
|
||||
}
|
||||
spin_unlock_irq(&async_file->ev_queue.lock);
|
||||
uverbs_uobject_put(&async_file->uobj);
|
||||
}
|
||||
|
||||
void ib_uverbs_detach_umcast(struct ib_qp *qp,
|
||||
@ -197,8 +197,8 @@ void ib_uverbs_release_file(struct kref *ref)
|
||||
if (atomic_dec_and_test(&file->device->refcount))
|
||||
ib_uverbs_comp_dev(file->device);
|
||||
|
||||
if (file->async_file)
|
||||
uverbs_uobject_put(&file->async_file->uobj);
|
||||
if (file->default_async_file)
|
||||
uverbs_uobject_put(&file->default_async_file->uobj);
|
||||
put_device(&file->device->dev);
|
||||
|
||||
if (file->disassociate_page)
|
||||
@ -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,
|
||||
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->event_list, &eobj->events_reported);
|
||||
}
|
||||
@ -484,10 +484,10 @@ void ib_uverbs_init_async_event_file(
|
||||
|
||||
/* The first async_event_file becomes the default one for the file. */
|
||||
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 */
|
||||
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);
|
||||
|
||||
|
@ -100,6 +100,10 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
|
||||
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) {
|
||||
ret = -EINVAL;
|
||||
goto err_event_file;
|
||||
@ -138,6 +142,8 @@ static int UVERBS_HANDLER(UVERBS_METHOD_CQ_CREATE)(
|
||||
err_free:
|
||||
kfree(cq);
|
||||
err_event_file:
|
||||
if (obj->uevent.event_file)
|
||||
uverbs_uobject_put(&obj->uevent.event_file->uobj);
|
||||
if (ev_file)
|
||||
uverbs_uobject_put(ev_file_uobj);
|
||||
return ret;
|
||||
|
Loading…
Reference in New Issue
Block a user