Commit 2f08ee36 authored by Steve Wise's avatar Steve Wise Committed by Jason Gunthorpe

RDMA/restrack: don't use uaccess_kernel()

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: 02d8883f ("RDMA/restrack: Add general infrastructure to track RDMA resources")
Signed-off-by: default avatarSteve Wise <swise@opengridcomputing.com>
Signed-off-by: default avatarJason Gunthorpe <jgg@mellanox.com>
parent 21885586
...@@ -305,7 +305,8 @@ void nldev_exit(void); ...@@ -305,7 +305,8 @@ void nldev_exit(void);
static inline struct ib_qp *_ib_create_qp(struct ib_device *dev, static inline struct ib_qp *_ib_create_qp(struct ib_device *dev,
struct ib_pd *pd, struct ib_pd *pd,
struct ib_qp_init_attr *attr, struct ib_qp_init_attr *attr,
struct ib_udata *udata) struct ib_udata *udata,
struct ib_uobject *uobj)
{ {
struct ib_qp *qp; struct ib_qp *qp;
...@@ -318,6 +319,7 @@ static inline struct ib_qp *_ib_create_qp(struct ib_device *dev, ...@@ -318,6 +319,7 @@ static inline struct ib_qp *_ib_create_qp(struct ib_device *dev,
qp->device = dev; qp->device = dev;
qp->pd = pd; qp->pd = pd;
qp->uobject = uobj;
/* /*
* We don't track XRC QPs for now, because they don't have PD * We don't track XRC QPs for now, because they don't have PD
* and more importantly they are created internaly by driver, * and more importantly they are created internaly by driver,
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <rdma/restrack.h> #include <rdma/restrack.h>
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/sched/task.h> #include <linux/sched/task.h>
#include <linux/uaccess.h>
#include <linux/pid_namespace.h> #include <linux/pid_namespace.h>
void rdma_restrack_init(struct rdma_restrack_root *res) 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) ...@@ -88,6 +87,21 @@ static struct ib_device *res_to_dev(struct rdma_restrack_entry *res)
return dev; 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) void rdma_restrack_add(struct rdma_restrack_entry *res)
{ {
struct ib_device *dev = res_to_dev(res); struct ib_device *dev = res_to_dev(res);
...@@ -95,7 +109,7 @@ void rdma_restrack_add(struct rdma_restrack_entry *res) ...@@ -95,7 +109,7 @@ void rdma_restrack_add(struct rdma_restrack_entry *res)
if (!dev) if (!dev)
return; return;
if (!uaccess_kernel()) { if (res_is_user(res)) {
get_task_struct(current); get_task_struct(current);
res->task = current; res->task = current;
res->kern_name = NULL; res->kern_name = NULL;
......
...@@ -1520,7 +1520,8 @@ static int create_qp(struct ib_uverbs_file *file, ...@@ -1520,7 +1520,8 @@ static int create_qp(struct ib_uverbs_file *file,
if (cmd->qp_type == IB_QPT_XRC_TGT) if (cmd->qp_type == IB_QPT_XRC_TGT)
qp = ib_create_qp(pd, &attr); qp = ib_create_qp(pd, &attr);
else else
qp = _ib_create_qp(device, pd, &attr, uhw); qp = _ib_create_qp(device, pd, &attr, uhw,
&obj->uevent.uobject);
if (IS_ERR(qp)) { if (IS_ERR(qp)) {
ret = PTR_ERR(qp); ret = PTR_ERR(qp);
...@@ -1553,7 +1554,6 @@ static int create_qp(struct ib_uverbs_file *file, ...@@ -1553,7 +1554,6 @@ static int create_qp(struct ib_uverbs_file *file,
if (ind_tbl) if (ind_tbl)
atomic_inc(&ind_tbl->usecnt); atomic_inc(&ind_tbl->usecnt);
} }
qp->uobject = &obj->uevent.uobject;
obj->uevent.uobject.object = qp; obj->uevent.uobject.object = qp;
......
...@@ -887,7 +887,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, ...@@ -887,7 +887,7 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
if (qp_init_attr->cap.max_rdma_ctxs) if (qp_init_attr->cap.max_rdma_ctxs)
rdma_rw_init_qp(device, qp_init_attr); 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)) if (IS_ERR(qp))
return qp; return qp;
...@@ -898,7 +898,6 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd, ...@@ -898,7 +898,6 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
} }
qp->real_qp = qp; qp->real_qp = qp;
qp->uobject = NULL;
qp->qp_type = qp_init_attr->qp_type; qp->qp_type = qp_init_attr->qp_type;
qp->rwq_ind_tbl = qp_init_attr->rwq_ind_tbl; qp->rwq_ind_tbl = qp_init_attr->rwq_ind_tbl;
......
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