RDMA/restrack: don't use uaccess_kernel()
authorSteve Wise <swise@opengridcomputing.com>
Thu, 15 Feb 2018 02:43:36 +0000 (18:43 -0800)
committerJason Gunthorpe <jgg@mellanox.com>
Fri, 16 Feb 2018 17:18:11 +0000 (10:18 -0700)
uaccess_kernel() isn't sufficient to determine if an rdma resource is
user-mode or not.  For example, resources allocated in the add_one()
function of an ib_client get falsely labeled as user mode, when they
are kernel mode allocations.  EG: mad qps.

The result is that these qps are skipped over during a nldev query
because of an erroneous namespace mismatch.

So now we determine if the resource is user-mode by looking at the object
struct's uobject or similar pointer to know if it was allocated for user
mode applications.

Fixes: 02d8883f520e ("RDMA/restrack: Add general infrastructure to track RDMA resources")
Signed-off-by: Steve Wise <swise@opengridcomputing.com>
Signed-off-by: Jason Gunthorpe <jgg@mellanox.com>
drivers/infiniband/core/core_priv.h
drivers/infiniband/core/restrack.c
drivers/infiniband/core/uverbs_cmd.c
drivers/infiniband/core/verbs.c

index c91f9a80b83134f1cf6e19215bc14afd5968da01..25bb178f60742233c018dc7edb51c0e6520689af 100644 (file)
@@ -305,7 +305,8 @@ void nldev_exit(void);
 static inline struct ib_qp *_ib_create_qp(struct ib_device *dev,
                                          struct ib_pd *pd,
                                          struct ib_qp_init_attr *attr,
-                                         struct ib_udata *udata)
+                                         struct ib_udata *udata,
+                                         struct ib_uobject *uobj)
 {
        struct ib_qp *qp;
 
@@ -318,6 +319,7 @@ static inline struct ib_qp *_ib_create_qp(struct ib_device *dev,
 
        qp->device = dev;
        qp->pd = pd;
+       qp->uobject = uobj;
        /*
         * We don't track XRC QPs for now, because they don't have PD
         * and more importantly they are created internaly by driver,
index d8dc709a37156e917ca6833a5a90e6dd9f524674..3dbc4e4cca415fd94a24443e44d1430a5cbe63d7 100644 (file)
@@ -7,7 +7,6 @@
 #include <rdma/restrack.h>
 #include <linux/mutex.h>
 #include <linux/sched/task.h>
-#include <linux/uaccess.h>
 #include <linux/pid_namespace.h>
 
 void rdma_restrack_init(struct rdma_restrack_root *res)
@@ -88,6 +87,21 @@ static struct ib_device *res_to_dev(struct rdma_restrack_entry *res)
        return dev;
 }
 
+static bool res_is_user(struct rdma_restrack_entry *res)
+{
+       switch (res->type) {
+       case RDMA_RESTRACK_PD:
+               return container_of(res, struct ib_pd, res)->uobject;
+       case RDMA_RESTRACK_CQ:
+               return container_of(res, struct ib_cq, res)->uobject;
+       case RDMA_RESTRACK_QP:
+               return container_of(res, struct ib_qp, res)->uobject;
+       default:
+               WARN_ONCE(true, "Wrong resource tracking type %u\n", res->type);
+               return false;
+       }
+}
+
 void rdma_restrack_add(struct rdma_restrack_entry *res)
 {
        struct ib_device *dev = res_to_dev(res);
@@ -95,7 +109,7 @@ void rdma_restrack_add(struct rdma_restrack_entry *res)
        if (!dev)
                return;
 
-       if (!uaccess_kernel()) {
+       if (res_is_user(res)) {
                get_task_struct(current);
                res->task = current;
                res->kern_name = NULL;
index dbcfb313cee9f7ef785cc3bed64d0c7a2b6b95dc..25a0e0e083b3350dbdbcddf054f9c725671ed056 100644 (file)
@@ -1520,7 +1520,8 @@ static int create_qp(struct ib_uverbs_file *file,
        if (cmd->qp_type == IB_QPT_XRC_TGT)
                qp = ib_create_qp(pd, &attr);
        else
-               qp = _ib_create_qp(device, pd, &attr, uhw);
+               qp = _ib_create_qp(device, pd, &attr, uhw,
+                                  &obj->uevent.uobject);
 
        if (IS_ERR(qp)) {
                ret = PTR_ERR(qp);
@@ -1553,7 +1554,6 @@ static int create_qp(struct ib_uverbs_file *file,
                if (ind_tbl)
                        atomic_inc(&ind_tbl->usecnt);
        }
-       qp->uobject = &obj->uevent.uobject;
 
        obj->uevent.uobject.object = qp;
 
index 16ebc6372c31abe449f4e892d26e2d384cec56fc..93025d2009b89f8679a19001357b53bdc4733184 100644 (file)
@@ -887,7 +887,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
        if (qp_init_attr->cap.max_rdma_ctxs)
                rdma_rw_init_qp(device, qp_init_attr);
 
-       qp = _ib_create_qp(device, pd, qp_init_attr, NULL);
+       qp = _ib_create_qp(device, pd, qp_init_attr, NULL, NULL);
        if (IS_ERR(qp))
                return qp;
 
@@ -898,7 +898,6 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
        }
 
        qp->real_qp    = qp;
-       qp->uobject    = NULL;
        qp->qp_type    = qp_init_attr->qp_type;
        qp->rwq_ind_tbl = qp_init_attr->rwq_ind_tbl;