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: 02d8883f52
("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>
This commit is contained in:
parent
2188558621
commit
2f08ee363f
@ -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,
|
|||||||
|
|
||||||
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 @@
|
|||||||
#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)
|
|||||||
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)
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
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,
|
|||||||
}
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user