IB/uverbs: Do not pass struct ib_device to the write based methods
authorJason Gunthorpe <jgg@mellanox.com>
Thu, 26 Jul 2018 03:40:17 +0000 (21:40 -0600)
committerJason Gunthorpe <jgg@mellanox.com>
Wed, 1 Aug 2018 20:55:48 +0000 (14:55 -0600)
This is a step to get rid of the global check for disassociation. In this
model, the ib_dev is not proven to be valid by the core code and cannot be
provided to the method. Instead, every method decides if it is able to
run after disassociation and obtains the ib_dev using one of three
different approaches:

- Call srcu_dereference on the udevice's ib_dev. As before, this means
  the method cannot be called after disassociation begins.
  (eg alloc ucontext)
- Retrieve the ib_dev from the ucontext, via ib_uverbs_get_ucontext()
- Retrieve the ib_dev from the uobject->object after checking
  under SRCU if disassociation has started (eg uobj_get)

Largely, the code is all ready for this, the main work is to provide a
ib_dev after calling uobj_alloc(). The few other places simply use
ib_uverbs_get_ucontext() to get the ib_dev.

This flexibility will let the next patches allow destroy to operate
after disassociation.

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
include/rdma/uverbs_std_types.h

index cf02b43..5e21cc1 100644 (file)
@@ -299,7 +299,6 @@ extern const struct uverbs_object_def UVERBS_OBJECT(UVERBS_OBJECT_COUNTERS);
 
 #define IB_UVERBS_DECLARE_CMD(name)                                    \
        ssize_t ib_uverbs_##name(struct ib_uverbs_file *file,           \
-                                struct ib_device *ib_dev,              \
                                 const char __user *buf, int in_len,    \
                                 int out_len)
 
@@ -341,7 +340,6 @@ IB_UVERBS_DECLARE_CMD(close_xrcd);
 
 #define IB_UVERBS_DECLARE_EX_CMD(name)                         \
        int ib_uverbs_ex_##name(struct ib_uverbs_file *file,    \
-                               struct ib_device *ib_dev,               \
                                struct ib_udata *ucore,         \
                                struct ib_udata *uhw)
 
index fe96ced..465b4d9 100644 (file)
@@ -66,7 +66,6 @@ _ib_uverbs_lookup_comp_file(s32 fd, struct ib_uverbs_file *ufile)
        _ib_uverbs_lookup_comp_file((_fd)*typecheck(s32, _fd), _ufile)
 
 ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
-                             struct ib_device *ib_dev,
                              const char __user *buf,
                              int in_len, int out_len)
 {
@@ -76,6 +75,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
        struct ib_ucontext               *ucontext;
        struct file                      *filp;
        struct ib_rdmacg_object          cg_obj;
+       struct ib_device *ib_dev;
        int ret;
 
        if (out_len < sizeof resp)
@@ -85,6 +85,12 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file,
                return -EFAULT;
 
        mutex_lock(&file->ucontext_lock);
+       ib_dev = srcu_dereference(file->device->ib_dev,
+                                 &file->device->disassociate_srcu);
+       if (!ib_dev) {
+               ret = -EIO;
+               goto err;
+       }
 
        if (file->ucontext) {
                ret = -EINVAL;
@@ -177,11 +183,12 @@ err:
        return ret;
 }
 
-static void copy_query_dev_fields(struct ib_uverbs_file *file,
-                                 struct ib_device *ib_dev,
+static void copy_query_dev_fields(struct ib_ucontext *ucontext,
                                  struct ib_uverbs_query_device_resp *resp,
                                  struct ib_device_attr *attr)
 {
+       struct ib_device *ib_dev = ucontext->device;
+
        resp->fw_ver            = attr->fw_ver;
        resp->node_guid         = ib_dev->node_guid;
        resp->sys_image_guid    = attr->sys_image_guid;
@@ -225,12 +232,16 @@ static void copy_query_dev_fields(struct ib_uverbs_file *file,
 }
 
 ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
-                              struct ib_device *ib_dev,
                               const char __user *buf,
                               int in_len, int out_len)
 {
        struct ib_uverbs_query_device      cmd;
        struct ib_uverbs_query_device_resp resp;
+       struct ib_ucontext *ucontext;
+
+       ucontext = ib_uverbs_get_ucontext(file);
+       if (IS_ERR(ucontext))
+               return PTR_ERR(ucontext);
 
        if (out_len < sizeof resp)
                return -ENOSPC;
@@ -239,7 +250,7 @@ ssize_t ib_uverbs_query_device(struct ib_uverbs_file *file,
                return -EFAULT;
 
        memset(&resp, 0, sizeof resp);
-       copy_query_dev_fields(file, ib_dev, &resp, &ib_dev->attrs);
+       copy_query_dev_fields(ucontext, &resp, &ucontext->device->attrs);
 
        if (copy_to_user(u64_to_user_ptr(cmd.response), &resp, sizeof resp))
                return -EFAULT;
@@ -269,7 +280,6 @@ static u32 make_port_cap_flags(const struct ib_port_attr *attr)
 }
 
 ssize_t ib_uverbs_query_port(struct ib_uverbs_file *file,
-                            struct ib_device *ib_dev,
                             const char __user *buf,
                             int in_len, int out_len)
 {
@@ -277,6 +287,13 @@ ssize_t ib_uverbs_query_port(struct ib_uverbs_file *file,
        struct ib_uverbs_query_port_resp resp;
        struct ib_port_attr              attr;
        int                              ret;
+       struct ib_ucontext *ucontext;
+       struct ib_device *ib_dev;
+
+       ucontext = ib_uverbs_get_ucontext(file);
+       if (IS_ERR(ucontext))
+               return PTR_ERR(ucontext);
+       ib_dev = ucontext->device;
 
        if (out_len < sizeof resp)
                return -ENOSPC;
@@ -328,7 +345,6 @@ ssize_t ib_uverbs_query_port(struct ib_uverbs_file *file,
 }
 
 ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
-                          struct ib_device *ib_dev,
                           const char __user *buf,
                           int in_len, int out_len)
 {
@@ -338,6 +354,7 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
        struct ib_uobject             *uobj;
        struct ib_pd                  *pd;
        int                            ret;
+       struct ib_device *ib_dev;
 
        if (out_len < sizeof resp)
                return -ENOSPC;
@@ -350,7 +367,7 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file,
                    in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
                    out_len - sizeof(resp));
 
-       uobj = uobj_alloc(UVERBS_OBJECT_PD, file);
+       uobj = uobj_alloc(UVERBS_OBJECT_PD, file, &ib_dev);
        if (IS_ERR(uobj))
                return PTR_ERR(uobj);
 
@@ -387,7 +404,6 @@ err:
 }
 
 ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file,
-                            struct ib_device *ib_dev,
                             const char __user *buf,
                             int in_len, int out_len)
 {
@@ -486,7 +502,6 @@ static void xrcd_table_delete(struct ib_uverbs_device *dev,
 }
 
 ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
-                           struct ib_device *ib_dev,
                            const char __user *buf, int in_len,
                            int out_len)
 {
@@ -499,6 +514,7 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
        struct inode                   *inode = NULL;
        int                             ret = 0;
        int                             new_xrcd = 0;
+       struct ib_device *ib_dev;
 
        if (out_len < sizeof resp)
                return -ENOSPC;
@@ -535,7 +551,8 @@ ssize_t ib_uverbs_open_xrcd(struct ib_uverbs_file *file,
                }
        }
 
-       obj = (struct ib_uxrcd_object *)uobj_alloc(UVERBS_OBJECT_XRCD, file);
+       obj = (struct ib_uxrcd_object *)uobj_alloc(UVERBS_OBJECT_XRCD, file,
+                                                  &ib_dev);
        if (IS_ERR(obj)) {
                ret = PTR_ERR(obj);
                goto err_tree_mutex_unlock;
@@ -606,7 +623,6 @@ err_tree_mutex_unlock:
 }
 
 ssize_t ib_uverbs_close_xrcd(struct ib_uverbs_file *file,
-                            struct ib_device *ib_dev,
                             const char __user *buf, int in_len,
                             int out_len)
 {
@@ -645,7 +661,6 @@ int ib_uverbs_dealloc_xrcd(struct ib_uobject *uobject,
 }
 
 ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
-                        struct ib_device *ib_dev,
                         const char __user *buf, int in_len,
                         int out_len)
 {
@@ -656,6 +671,7 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
        struct ib_pd                *pd;
        struct ib_mr                *mr;
        int                          ret;
+       struct ib_device *ib_dev;
 
        if (out_len < sizeof resp)
                return -ENOSPC;
@@ -675,7 +691,7 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file,
        if (ret)
                return ret;
 
-       uobj = uobj_alloc(UVERBS_OBJECT_MR, file);
+       uobj = uobj_alloc(UVERBS_OBJECT_MR, file, &ib_dev);
        if (IS_ERR(uobj))
                return PTR_ERR(uobj);
 
@@ -737,7 +753,6 @@ err_free:
 }
 
 ssize_t ib_uverbs_rereg_mr(struct ib_uverbs_file *file,
-                          struct ib_device *ib_dev,
                           const char __user *buf, int in_len,
                           int out_len)
 {
@@ -829,7 +844,6 @@ put_uobjs:
 }
 
 ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file,
-                          struct ib_device *ib_dev,
                           const char __user *buf, int in_len,
                           int out_len)
 {
@@ -843,7 +857,6 @@ ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file,
 }
 
 ssize_t ib_uverbs_alloc_mw(struct ib_uverbs_file *file,
-                          struct ib_device *ib_dev,
                           const char __user *buf, int in_len,
                           int out_len)
 {
@@ -854,6 +867,7 @@ ssize_t ib_uverbs_alloc_mw(struct ib_uverbs_file *file,
        struct ib_mw                  *mw;
        struct ib_udata                udata;
        int                            ret;
+       struct ib_device *ib_dev;
 
        if (out_len < sizeof(resp))
                return -ENOSPC;
@@ -861,7 +875,7 @@ ssize_t ib_uverbs_alloc_mw(struct ib_uverbs_file *file,
        if (copy_from_user(&cmd, buf, sizeof(cmd)))
                return -EFAULT;
 
-       uobj = uobj_alloc(UVERBS_OBJECT_MW, file);
+       uobj = uobj_alloc(UVERBS_OBJECT_MW, file, &ib_dev);
        if (IS_ERR(uobj))
                return PTR_ERR(uobj);
 
@@ -911,7 +925,6 @@ err_free:
 }
 
 ssize_t ib_uverbs_dealloc_mw(struct ib_uverbs_file *file,
-                            struct ib_device *ib_dev,
                             const char __user *buf, int in_len,
                             int out_len)
 {
@@ -925,7 +938,6 @@ ssize_t ib_uverbs_dealloc_mw(struct ib_uverbs_file *file,
 }
 
 ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,
-                                     struct ib_device *ib_dev,
                                      const char __user *buf, int in_len,
                                      int out_len)
 {
@@ -933,6 +945,7 @@ ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,
        struct ib_uverbs_create_comp_channel_resp  resp;
        struct ib_uobject                         *uobj;
        struct ib_uverbs_completion_event_file    *ev_file;
+       struct ib_device *ib_dev;
 
        if (out_len < sizeof resp)
                return -ENOSPC;
@@ -940,7 +953,7 @@ ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,
        if (copy_from_user(&cmd, buf, sizeof cmd))
                return -EFAULT;
 
-       uobj = uobj_alloc(UVERBS_OBJECT_COMP_CHANNEL, file);
+       uobj = uobj_alloc(UVERBS_OBJECT_COMP_CHANNEL, file, &ib_dev);
        if (IS_ERR(uobj))
                return PTR_ERR(uobj);
 
@@ -959,7 +972,6 @@ ssize_t ib_uverbs_create_comp_channel(struct ib_uverbs_file *file,
 }
 
 static struct ib_ucq_object *create_cq(struct ib_uverbs_file *file,
-                                       struct ib_device *ib_dev,
                                       struct ib_udata *ucore,
                                       struct ib_udata *uhw,
                                       struct ib_uverbs_ex_create_cq *cmd,
@@ -977,17 +989,21 @@ static struct ib_ucq_object *create_cq(struct ib_uverbs_file *file,
        int                             ret;
        struct ib_uverbs_ex_create_cq_resp resp;
        struct ib_cq_init_attr attr = {};
-
-       if (!ib_dev->create_cq)
-               return ERR_PTR(-EOPNOTSUPP);
+       struct ib_device *ib_dev;
 
        if (cmd->comp_vector >= file->device->num_comp_vectors)
                return ERR_PTR(-EINVAL);
 
-       obj = (struct ib_ucq_object *)uobj_alloc(UVERBS_OBJECT_CQ, file);
+       obj = (struct ib_ucq_object *)uobj_alloc(UVERBS_OBJECT_CQ, file,
+                                                &ib_dev);
        if (IS_ERR(obj))
                return obj;
 
+       if (!ib_dev->create_cq) {
+               ret = -EOPNOTSUPP;
+               goto err;
+       }
+
        if (cmd->comp_channel >= 0) {
                ev_file = ib_uverbs_lookup_comp_file(cmd->comp_channel, file);
                if (IS_ERR(ev_file)) {
@@ -1066,7 +1082,6 @@ static int ib_uverbs_create_cq_cb(struct ib_uverbs_file *file,
 }
 
 ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
-                           struct ib_device *ib_dev,
                            const char __user *buf, int in_len,
                            int out_len)
 {
@@ -1097,7 +1112,7 @@ ssize_t ib_uverbs_create_cq(struct ib_uverbs_file *file,
        cmd_ex.comp_vector = cmd.comp_vector;
        cmd_ex.comp_channel = cmd.comp_channel;
 
-       obj = create_cq(file, ib_dev, &ucore, &uhw, &cmd_ex,
+       obj = create_cq(file, &ucore, &uhw, &cmd_ex,
                        offsetof(typeof(cmd_ex), comp_channel) +
                        sizeof(cmd.comp_channel), ib_uverbs_create_cq_cb,
                        NULL);
@@ -1120,7 +1135,6 @@ static int ib_uverbs_ex_create_cq_cb(struct ib_uverbs_file *file,
 }
 
 int ib_uverbs_ex_create_cq(struct ib_uverbs_file *file,
-                        struct ib_device *ib_dev,
                           struct ib_udata *ucore,
                           struct ib_udata *uhw)
 {
@@ -1146,7 +1160,7 @@ int ib_uverbs_ex_create_cq(struct ib_uverbs_file *file,
                             sizeof(resp.response_length)))
                return -ENOSPC;
 
-       obj = create_cq(file, ib_dev, ucore, uhw, &cmd,
+       obj = create_cq(file, ucore, uhw, &cmd,
                        min(ucore->inlen, sizeof(cmd)),
                        ib_uverbs_ex_create_cq_cb, NULL);
 
@@ -1154,7 +1168,6 @@ int ib_uverbs_ex_create_cq(struct ib_uverbs_file *file,
 }
 
 ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file,
-                           struct ib_device *ib_dev,
                            const char __user *buf, int in_len,
                            int out_len)
 {
@@ -1222,7 +1235,6 @@ static int copy_wc_to_user(struct ib_device *ib_dev, void __user *dest,
 }
 
 ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
-                         struct ib_device *ib_dev,
                          const char __user *buf, int in_len,
                          int out_len)
 {
@@ -1253,7 +1265,7 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
                if (!ret)
                        break;
 
-               ret = copy_wc_to_user(ib_dev, data_ptr, &wc);
+               ret = copy_wc_to_user(cq->device, data_ptr, &wc);
                if (ret)
                        goto out_put;
 
@@ -1274,7 +1286,6 @@ out_put:
 }
 
 ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file,
-                               struct ib_device *ib_dev,
                                const char __user *buf, int in_len,
                                int out_len)
 {
@@ -1297,7 +1308,6 @@ ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file,
 }
 
 ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file,
-                            struct ib_device *ib_dev,
                             const char __user *buf, int in_len,
                             int out_len)
 {
@@ -1350,11 +1360,13 @@ static int create_qp(struct ib_uverbs_file *file,
        int                             ret;
        struct ib_rwq_ind_table *ind_tbl = NULL;
        bool has_sq = true;
+       struct ib_device *ib_dev;
 
        if (cmd->qp_type == IB_QPT_RAW_PACKET && !capable(CAP_NET_RAW))
                return -EPERM;
 
-       obj = (struct ib_uqp_object *)uobj_alloc(UVERBS_OBJECT_QP, file);
+       obj = (struct ib_uqp_object *)uobj_alloc(UVERBS_OBJECT_QP, file,
+                                                &ib_dev);
        if (IS_ERR(obj))
                return PTR_ERR(obj);
        obj->uxrcd = NULL;
@@ -1611,7 +1623,6 @@ static int ib_uverbs_create_qp_cb(struct ib_uverbs_file *file,
 }
 
 ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
-                           struct ib_device *ib_dev,
                            const char __user *buf, int in_len,
                            int out_len)
 {
@@ -1672,7 +1683,6 @@ static int ib_uverbs_ex_create_qp_cb(struct ib_uverbs_file *file,
 }
 
 int ib_uverbs_ex_create_qp(struct ib_uverbs_file *file,
-                          struct ib_device *ib_dev,
                           struct ib_udata *ucore,
                           struct ib_udata *uhw)
 {
@@ -1709,7 +1719,6 @@ int ib_uverbs_ex_create_qp(struct ib_uverbs_file *file,
 }
 
 ssize_t ib_uverbs_open_qp(struct ib_uverbs_file *file,
-                         struct ib_device *ib_dev,
                          const char __user *buf, int in_len, int out_len)
 {
        struct ib_uverbs_open_qp        cmd;
@@ -1721,6 +1730,7 @@ ssize_t ib_uverbs_open_qp(struct ib_uverbs_file *file,
        struct ib_qp                   *qp;
        struct ib_qp_open_attr          attr;
        int ret;
+       struct ib_device *ib_dev;
 
        if (out_len < sizeof resp)
                return -ENOSPC;
@@ -1733,7 +1743,8 @@ ssize_t ib_uverbs_open_qp(struct ib_uverbs_file *file,
                   in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
                   out_len - sizeof(resp));
 
-       obj = (struct ib_uqp_object *)uobj_alloc(UVERBS_OBJECT_QP, file);
+       obj = (struct ib_uqp_object *)uobj_alloc(UVERBS_OBJECT_QP, file,
+                                                &ib_dev);
        if (IS_ERR(obj))
                return PTR_ERR(obj);
 
@@ -1815,7 +1826,6 @@ static void copy_ah_attr_to_uverbs(struct ib_uverbs_qp_dest *uverb_attr,
 }
 
 ssize_t ib_uverbs_query_qp(struct ib_uverbs_file *file,
-                          struct ib_device *ib_dev,
                           const char __user *buf, int in_len,
                           int out_len)
 {
@@ -2018,7 +2028,6 @@ out:
 }
 
 ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
-                           struct ib_device *ib_dev,
                            const char __user *buf, int in_len,
                            int out_len)
 {
@@ -2045,7 +2054,6 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
 }
 
 int ib_uverbs_ex_modify_qp(struct ib_uverbs_file *file,
-                          struct ib_device *ib_dev,
                           struct ib_udata *ucore,
                           struct ib_udata *uhw)
 {
@@ -2081,7 +2089,6 @@ int ib_uverbs_ex_modify_qp(struct ib_uverbs_file *file,
 }
 
 ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file,
-                            struct ib_device *ib_dev,
                             const char __user *buf, int in_len,
                             int out_len)
 {
@@ -2120,7 +2127,6 @@ static void *alloc_wr(size_t wr_size, __u32 num_sge)
 }
 
 ssize_t ib_uverbs_post_send(struct ib_uverbs_file *file,
-                           struct ib_device *ib_dev,
                            const char __user *buf, int in_len,
                            int out_len)
 {
@@ -2401,7 +2407,6 @@ err:
 }
 
 ssize_t ib_uverbs_post_recv(struct ib_uverbs_file *file,
-                           struct ib_device *ib_dev,
                            const char __user *buf, int in_len,
                            int out_len)
 {
@@ -2451,7 +2456,6 @@ out:
 }
 
 ssize_t ib_uverbs_post_srq_recv(struct ib_uverbs_file *file,
-                               struct ib_device *ib_dev,
                                const char __user *buf, int in_len,
                                int out_len)
 {
@@ -2502,7 +2506,6 @@ out:
 }
 
 ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
-                           struct ib_device *ib_dev,
                            const char __user *buf, int in_len,
                            int out_len)
 {
@@ -2514,6 +2517,7 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
        struct rdma_ah_attr             attr = {};
        int ret;
        struct ib_udata                   udata;
+       struct ib_device *ib_dev;
 
        if (out_len < sizeof resp)
                return -ENOSPC;
@@ -2521,18 +2525,20 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file,
        if (copy_from_user(&cmd, buf, sizeof cmd))
                return -EFAULT;
 
-       if (!rdma_is_port_valid(ib_dev, cmd.attr.port_num))
-               return -EINVAL;
-
        ib_uverbs_init_udata(&udata, buf + sizeof(cmd),
                   u64_to_user_ptr(cmd.response) + sizeof(resp),
                   in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
                   out_len - sizeof(resp));
 
-       uobj = uobj_alloc(UVERBS_OBJECT_AH, file);
+       uobj = uobj_alloc(UVERBS_OBJECT_AH, file, &ib_dev);
        if (IS_ERR(uobj))
                return PTR_ERR(uobj);
 
+       if (!rdma_is_port_valid(ib_dev, cmd.attr.port_num)) {
+               ret = -EINVAL;
+               goto err;
+       }
+
        pd = uobj_get_obj_read(pd, UVERBS_OBJECT_PD, cmd.pd_handle, file);
        if (!pd) {
                ret = -EINVAL;
@@ -2589,7 +2595,6 @@ err:
 }
 
 ssize_t ib_uverbs_destroy_ah(struct ib_uverbs_file *file,
-                            struct ib_device *ib_dev,
                             const char __user *buf, int in_len, int out_len)
 {
        struct ib_uverbs_destroy_ah cmd;
@@ -2602,7 +2607,6 @@ ssize_t ib_uverbs_destroy_ah(struct ib_uverbs_file *file,
 }
 
 ssize_t ib_uverbs_attach_mcast(struct ib_uverbs_file *file,
-                              struct ib_device *ib_dev,
                               const char __user *buf, int in_len,
                               int out_len)
 {
@@ -2652,7 +2656,6 @@ out_put:
 }
 
 ssize_t ib_uverbs_detach_mcast(struct ib_uverbs_file *file,
-                              struct ib_device *ib_dev,
                               const char __user *buf, int in_len,
                               int out_len)
 {
@@ -3021,7 +3024,6 @@ static int kern_spec_to_ib_spec(struct ib_uverbs_file *ufile,
 }
 
 int ib_uverbs_ex_create_wq(struct ib_uverbs_file *file,
-                          struct ib_device *ib_dev,
                           struct ib_udata *ucore,
                           struct ib_udata *uhw)
 {
@@ -3035,6 +3037,7 @@ int ib_uverbs_ex_create_wq(struct ib_uverbs_file *file,
        struct ib_wq_init_attr wq_init_attr = {};
        size_t required_cmd_sz;
        size_t required_resp_len;
+       struct ib_device *ib_dev;
 
        required_cmd_sz = offsetof(typeof(cmd), max_sge) + sizeof(cmd.max_sge);
        required_resp_len = offsetof(typeof(resp), wqn) + sizeof(resp.wqn);
@@ -3057,7 +3060,8 @@ int ib_uverbs_ex_create_wq(struct ib_uverbs_file *file,
        if (cmd.comp_mask)
                return -EOPNOTSUPP;
 
-       obj = (struct ib_uwq_object *)uobj_alloc(UVERBS_OBJECT_WQ, file);
+       obj = (struct ib_uwq_object *)uobj_alloc(UVERBS_OBJECT_WQ, file,
+                                                &ib_dev);
        if (IS_ERR(obj))
                return PTR_ERR(obj);
 
@@ -3136,7 +3140,6 @@ err_uobj:
 }
 
 int ib_uverbs_ex_destroy_wq(struct ib_uverbs_file *file,
-                           struct ib_device *ib_dev,
                            struct ib_udata *ucore,
                            struct ib_udata *uhw)
 {
@@ -3183,7 +3186,6 @@ int ib_uverbs_ex_destroy_wq(struct ib_uverbs_file *file,
 }
 
 int ib_uverbs_ex_modify_wq(struct ib_uverbs_file *file,
-                          struct ib_device *ib_dev,
                           struct ib_udata *ucore,
                           struct ib_udata *uhw)
 {
@@ -3233,7 +3235,6 @@ out:
 }
 
 int ib_uverbs_ex_create_rwq_ind_table(struct ib_uverbs_file *file,
-                                     struct ib_device *ib_dev,
                                      struct ib_udata *ucore,
                                      struct ib_udata *uhw)
 {
@@ -3251,6 +3252,7 @@ int ib_uverbs_ex_create_rwq_ind_table(struct ib_uverbs_file *file,
        u32 expected_in_size;
        size_t required_cmd_sz_header;
        size_t required_resp_len;
+       struct ib_device *ib_dev;
 
        required_cmd_sz_header = offsetof(typeof(cmd), log_ind_tbl_size) + sizeof(cmd.log_ind_tbl_size);
        required_resp_len = offsetof(typeof(resp), ind_tbl_num) + sizeof(resp.ind_tbl_num);
@@ -3316,7 +3318,7 @@ int ib_uverbs_ex_create_rwq_ind_table(struct ib_uverbs_file *file,
                wqs[num_read_wqs] = wq;
        }
 
-       uobj = uobj_alloc(UVERBS_OBJECT_RWQ_IND_TBL, file);
+       uobj = uobj_alloc(UVERBS_OBJECT_RWQ_IND_TBL, file, &ib_dev);
        if (IS_ERR(uobj)) {
                err = PTR_ERR(uobj);
                goto put_wqs;
@@ -3376,7 +3378,6 @@ err_free:
 }
 
 int ib_uverbs_ex_destroy_rwq_ind_table(struct ib_uverbs_file *file,
-                                      struct ib_device *ib_dev,
                                       struct ib_udata *ucore,
                                       struct ib_udata *uhw)
 {
@@ -3406,7 +3407,6 @@ int ib_uverbs_ex_destroy_rwq_ind_table(struct ib_uverbs_file *file,
 }
 
 int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
-                            struct ib_device *ib_dev,
                             struct ib_udata *ucore,
                             struct ib_udata *uhw)
 {
@@ -3423,6 +3423,7 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
        void *kern_spec;
        void *ib_spec;
        int i;
+       struct ib_device *ib_dev;
 
        if (ucore->inlen < sizeof(cmd))
                return -EINVAL;
@@ -3478,7 +3479,7 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file,
                kern_flow_attr = &cmd.flow_attr;
        }
 
-       uobj = uobj_alloc(UVERBS_OBJECT_FLOW, file);
+       uobj = uobj_alloc(UVERBS_OBJECT_FLOW, file, &ib_dev);
        if (IS_ERR(uobj)) {
                err = PTR_ERR(uobj);
                goto err_free_attr;
@@ -3583,7 +3584,6 @@ err_free_attr:
 }
 
 int ib_uverbs_ex_destroy_flow(struct ib_uverbs_file *file,
-                             struct ib_device *ib_dev,
                              struct ib_udata *ucore,
                              struct ib_udata *uhw)
 {
@@ -3605,7 +3605,6 @@ int ib_uverbs_ex_destroy_flow(struct ib_uverbs_file *file,
 }
 
 static int __uverbs_create_xsrq(struct ib_uverbs_file *file,
-                               struct ib_device *ib_dev,
                                struct ib_uverbs_create_xsrq *cmd,
                                struct ib_udata *udata)
 {
@@ -3616,8 +3615,10 @@ static int __uverbs_create_xsrq(struct ib_uverbs_file *file,
        struct ib_uobject               *uninitialized_var(xrcd_uobj);
        struct ib_srq_init_attr          attr;
        int ret;
+       struct ib_device *ib_dev;
 
-       obj = (struct ib_usrq_object *)uobj_alloc(UVERBS_OBJECT_SRQ, file);
+       obj = (struct ib_usrq_object *)uobj_alloc(UVERBS_OBJECT_SRQ, file,
+                                                 &ib_dev);
        if (IS_ERR(obj))
                return PTR_ERR(obj);
 
@@ -3740,7 +3741,6 @@ err:
 }
 
 ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
-                            struct ib_device *ib_dev,
                             const char __user *buf, int in_len,
                             int out_len)
 {
@@ -3770,7 +3770,7 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
                   in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
                   out_len - sizeof(resp));
 
-       ret = __uverbs_create_xsrq(file, ib_dev, &xcmd, &udata);
+       ret = __uverbs_create_xsrq(file, &xcmd, &udata);
        if (ret)
                return ret;
 
@@ -3778,7 +3778,6 @@ ssize_t ib_uverbs_create_srq(struct ib_uverbs_file *file,
 }
 
 ssize_t ib_uverbs_create_xsrq(struct ib_uverbs_file *file,
-                             struct ib_device *ib_dev,
                              const char __user *buf, int in_len, int out_len)
 {
        struct ib_uverbs_create_xsrq     cmd;
@@ -3797,7 +3796,7 @@ ssize_t ib_uverbs_create_xsrq(struct ib_uverbs_file *file,
                   in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr),
                   out_len - sizeof(resp));
 
-       ret = __uverbs_create_xsrq(file, ib_dev, &cmd, &udata);
+       ret = __uverbs_create_xsrq(file, &cmd, &udata);
        if (ret)
                return ret;
 
@@ -3805,7 +3804,6 @@ ssize_t ib_uverbs_create_xsrq(struct ib_uverbs_file *file,
 }
 
 ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
-                            struct ib_device *ib_dev,
                             const char __user *buf, int in_len,
                             int out_len)
 {
@@ -3836,7 +3834,6 @@ ssize_t ib_uverbs_modify_srq(struct ib_uverbs_file *file,
 }
 
 ssize_t ib_uverbs_query_srq(struct ib_uverbs_file *file,
-                           struct ib_device *ib_dev,
                            const char __user *buf,
                            int in_len, int out_len)
 {
@@ -3876,7 +3873,6 @@ ssize_t ib_uverbs_query_srq(struct ib_uverbs_file *file,
 }
 
 ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
-                             struct ib_device *ib_dev,
                              const char __user *buf, int in_len,
                              int out_len)
 {
@@ -3905,15 +3901,21 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file,
 }
 
 int ib_uverbs_ex_query_device(struct ib_uverbs_file *file,
-                             struct ib_device *ib_dev,
                              struct ib_udata *ucore,
                              struct ib_udata *uhw)
 {
        struct ib_uverbs_ex_query_device_resp resp = { {0} };
        struct ib_uverbs_ex_query_device  cmd;
        struct ib_device_attr attr = {0};
+       struct ib_ucontext *ucontext;
+       struct ib_device *ib_dev;
        int err;
 
+       ucontext = ib_uverbs_get_ucontext(file);
+       if (IS_ERR(ucontext))
+               return PTR_ERR(ucontext);
+       ib_dev = ucontext->device;
+
        if (!ib_dev->query_device)
                return -EOPNOTSUPP;
 
@@ -3939,7 +3941,7 @@ int ib_uverbs_ex_query_device(struct ib_uverbs_file *file,
        if (err)
                return err;
 
-       copy_query_dev_fields(file, ib_dev, &resp.base, &attr);
+       copy_query_dev_fields(ucontext, &resp.base, &attr);
 
        if (ucore->outlen < resp.response_length + sizeof(resp.odp_caps))
                goto end;
@@ -4026,7 +4028,6 @@ end:
 }
 
 int ib_uverbs_ex_modify_cq(struct ib_uverbs_file *file,
-                          struct ib_device *ib_dev,
                           struct ib_udata *ucore,
                           struct ib_udata *uhw)
 {
index 34df04e..a1e427b 100644 (file)
@@ -75,7 +75,6 @@ static struct class *uverbs_class;
 static DECLARE_BITMAP(dev_map, IB_UVERBS_MAX_DEVICES);
 
 static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file,
-                                    struct ib_device *ib_dev,
                                     const char __user *buf, int in_len,
                                     int out_len) = {
        [IB_USER_VERBS_CMD_GET_CONTEXT]         = ib_uverbs_get_context,
@@ -116,7 +115,6 @@ static ssize_t (*uverbs_cmd_table[])(struct ib_uverbs_file *file,
 };
 
 static int (*uverbs_ex_cmd_table[])(struct ib_uverbs_file *file,
-                                   struct ib_device *ib_dev,
                                    struct ib_udata *ucore,
                                    struct ib_udata *uhw) = {
        [IB_USER_VERBS_EX_CMD_CREATE_FLOW]      = ib_uverbs_ex_create_flow,
@@ -774,7 +772,7 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
        buf += sizeof(hdr);
 
        if (!extended) {
-               ret = uverbs_cmd_table[command](file, ib_dev, buf,
+               ret = uverbs_cmd_table[command](file, buf,
                                                hdr.in_words * 4,
                                                hdr.out_words * 4);
        } else {
@@ -793,7 +791,7 @@ static ssize_t ib_uverbs_write(struct file *filp, const char __user *buf,
                                        ex_hdr.provider_in_words * 8,
                                        ex_hdr.provider_out_words * 8);
 
-               ret = uverbs_ex_cmd_table[command](file, ib_dev, &ucore, &uhw);
+               ret = uverbs_ex_cmd_table[command](file, &ucore, &uhw);
                ret = (ret) ? : count;
        }
 
index 8c54e14..64ee254 100644 (file)
@@ -125,12 +125,18 @@ static inline void uobj_alloc_abort(struct ib_uobject *uobj)
 }
 
 static inline struct ib_uobject *__uobj_alloc(const struct uverbs_obj_type *type,
-                                             struct ib_uverbs_file *ufile)
+                                             struct ib_uverbs_file *ufile,
+                                             struct ib_device **ib_dev)
 {
-       return rdma_alloc_begin_uobject(type, ufile);
+       struct ib_uobject *uobj = rdma_alloc_begin_uobject(type, ufile);
+
+       if (!IS_ERR(uobj))
+               *ib_dev = uobj->context->device;
+       return uobj;
 }
 
-#define uobj_alloc(_type, _ufile) __uobj_alloc(uobj_get_type(_type), _ufile)
+#define uobj_alloc(_type, _ufile, _ib_dev)                                     \
+       __uobj_alloc(uobj_get_type(_type), _ufile, _ib_dev)
 
 #endif