IB/uverbs: Refactor related objects to use their own asynchronous event FD
authorYishai Hadas <yishaih@mellanox.com>
Tue, 19 May 2020 07:27:06 +0000 (10:27 +0300)
committerJason Gunthorpe <jgg@mellanox.com>
Thu, 21 May 2020 23:34:53 +0000 (20:34 -0300)
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>
drivers/infiniband/core/uverbs.h
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/uverbs_main.c
drivers/infiniband/core/uverbs_std_types_cq.c

index 3d189c7ee59e6663dd73c7387b6ef6b33e6b3edd..34c155f8831787f6797c34192d9ba6534205b610 100644 (file)
@@ -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;
index 86c97221872dbac769ea5a98c65a20d34d615150..4859ac0df17c75e7a239a2bb396cc7a8e8ff5ce8 100644 (file)
@@ -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);
index 6948f8cd18856f70dc7a67bacf45f09c4e4cbcd4..47794c85e9af019fe45f8719787db5d91d1442b6 100644 (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)
 {
-       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);
 
index 73fbbeb2586cf0db2fc2dc024d4dfde1325f97d2..be534b0af4f8d85075c498226ed69f6f7516b4ad 100644 (file)
@@ -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;