Commit 1ccf6aa1 authored by Roland Dreier's avatar Roland Dreier

IB/uverbs: Fix lockdep warning when QP is created with 2 CQs

Lockdep warns when userspace creates a QP that uses different CQs for
send completions and receive completions, because both CQs are locked
and their mutexes belong to the same lock class.  However, we know
that the mutexes are distinct and the nesting is safe (there is no
possibility of AB-BA deadlock because the mutexes are locked with
down_read()), so annotate the situation with SINGLE_DEPTH_NESTING to
get rid of the lockdep warning.
Signed-off-by: default avatarRoland Dreier <rolandd@cisco.com>
parent ab108676
...@@ -155,7 +155,7 @@ static struct ib_uobject *__idr_get_uobj(struct idr *idr, int id, ...@@ -155,7 +155,7 @@ static struct ib_uobject *__idr_get_uobj(struct idr *idr, int id,
} }
static struct ib_uobject *idr_read_uobj(struct idr *idr, int id, static struct ib_uobject *idr_read_uobj(struct idr *idr, int id,
struct ib_ucontext *context) struct ib_ucontext *context, int nested)
{ {
struct ib_uobject *uobj; struct ib_uobject *uobj;
...@@ -163,6 +163,9 @@ static struct ib_uobject *idr_read_uobj(struct idr *idr, int id, ...@@ -163,6 +163,9 @@ static struct ib_uobject *idr_read_uobj(struct idr *idr, int id,
if (!uobj) if (!uobj)
return NULL; return NULL;
if (nested)
down_read_nested(&uobj->mutex, SINGLE_DEPTH_NESTING);
else
down_read(&uobj->mutex); down_read(&uobj->mutex);
if (!uobj->live) { if (!uobj->live) {
put_uobj_read(uobj); put_uobj_read(uobj);
...@@ -190,17 +193,18 @@ static struct ib_uobject *idr_write_uobj(struct idr *idr, int id, ...@@ -190,17 +193,18 @@ static struct ib_uobject *idr_write_uobj(struct idr *idr, int id,
return uobj; return uobj;
} }
static void *idr_read_obj(struct idr *idr, int id, struct ib_ucontext *context) static void *idr_read_obj(struct idr *idr, int id, struct ib_ucontext *context,
int nested)
{ {
struct ib_uobject *uobj; struct ib_uobject *uobj;
uobj = idr_read_uobj(idr, id, context); uobj = idr_read_uobj(idr, id, context, nested);
return uobj ? uobj->object : NULL; return uobj ? uobj->object : NULL;
} }
static struct ib_pd *idr_read_pd(int pd_handle, struct ib_ucontext *context) static struct ib_pd *idr_read_pd(int pd_handle, struct ib_ucontext *context)
{ {
return idr_read_obj(&ib_uverbs_pd_idr, pd_handle, context); return idr_read_obj(&ib_uverbs_pd_idr, pd_handle, context, 0);
} }
static void put_pd_read(struct ib_pd *pd) static void put_pd_read(struct ib_pd *pd)
...@@ -208,9 +212,9 @@ static void put_pd_read(struct ib_pd *pd) ...@@ -208,9 +212,9 @@ static void put_pd_read(struct ib_pd *pd)
put_uobj_read(pd->uobject); put_uobj_read(pd->uobject);
} }
static struct ib_cq *idr_read_cq(int cq_handle, struct ib_ucontext *context) static struct ib_cq *idr_read_cq(int cq_handle, struct ib_ucontext *context, int nested)
{ {
return idr_read_obj(&ib_uverbs_cq_idr, cq_handle, context); return idr_read_obj(&ib_uverbs_cq_idr, cq_handle, context, nested);
} }
static void put_cq_read(struct ib_cq *cq) static void put_cq_read(struct ib_cq *cq)
...@@ -220,7 +224,7 @@ static void put_cq_read(struct ib_cq *cq) ...@@ -220,7 +224,7 @@ static void put_cq_read(struct ib_cq *cq)
static struct ib_ah *idr_read_ah(int ah_handle, struct ib_ucontext *context) static struct ib_ah *idr_read_ah(int ah_handle, struct ib_ucontext *context)
{ {
return idr_read_obj(&ib_uverbs_ah_idr, ah_handle, context); return idr_read_obj(&ib_uverbs_ah_idr, ah_handle, context, 0);
} }
static void put_ah_read(struct ib_ah *ah) static void put_ah_read(struct ib_ah *ah)
...@@ -230,7 +234,7 @@ static void put_ah_read(struct ib_ah *ah) ...@@ -230,7 +234,7 @@ static void put_ah_read(struct ib_ah *ah)
static struct ib_qp *idr_read_qp(int qp_handle, struct ib_ucontext *context) static struct ib_qp *idr_read_qp(int qp_handle, struct ib_ucontext *context)
{ {
return idr_read_obj(&ib_uverbs_qp_idr, qp_handle, context); return idr_read_obj(&ib_uverbs_qp_idr, qp_handle, context, 0);
} }
static void put_qp_read(struct ib_qp *qp) static void put_qp_read(struct ib_qp *qp)
...@@ -240,7 +244,7 @@ static void put_qp_read(struct ib_qp *qp) ...@@ -240,7 +244,7 @@ static void put_qp_read(struct ib_qp *qp)
static struct ib_srq *idr_read_srq(int srq_handle, struct ib_ucontext *context) static struct ib_srq *idr_read_srq(int srq_handle, struct ib_ucontext *context)
{ {
return idr_read_obj(&ib_uverbs_srq_idr, srq_handle, context); return idr_read_obj(&ib_uverbs_srq_idr, srq_handle, context, 0);
} }
static void put_srq_read(struct ib_srq *srq) static void put_srq_read(struct ib_srq *srq)
...@@ -867,7 +871,7 @@ ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file, ...@@ -867,7 +871,7 @@ ssize_t ib_uverbs_resize_cq(struct ib_uverbs_file *file,
(unsigned long) cmd.response + sizeof resp, (unsigned long) cmd.response + sizeof resp,
in_len - sizeof cmd, out_len - sizeof resp); in_len - sizeof cmd, out_len - sizeof resp);
cq = idr_read_cq(cmd.cq_handle, file->ucontext); cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0);
if (!cq) if (!cq)
return -EINVAL; return -EINVAL;
...@@ -914,7 +918,7 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file, ...@@ -914,7 +918,7 @@ ssize_t ib_uverbs_poll_cq(struct ib_uverbs_file *file,
goto out_wc; goto out_wc;
} }
cq = idr_read_cq(cmd.cq_handle, file->ucontext); cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0);
if (!cq) { if (!cq) {
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
...@@ -962,7 +966,7 @@ ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file, ...@@ -962,7 +966,7 @@ ssize_t ib_uverbs_req_notify_cq(struct ib_uverbs_file *file,
if (copy_from_user(&cmd, buf, sizeof cmd)) if (copy_from_user(&cmd, buf, sizeof cmd))
return -EFAULT; return -EFAULT;
cq = idr_read_cq(cmd.cq_handle, file->ucontext); cq = idr_read_cq(cmd.cq_handle, file->ucontext, 0);
if (!cq) if (!cq)
return -EINVAL; return -EINVAL;
...@@ -1060,9 +1064,9 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, ...@@ -1060,9 +1064,9 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
srq = cmd.is_srq ? idr_read_srq(cmd.srq_handle, file->ucontext) : NULL; srq = cmd.is_srq ? idr_read_srq(cmd.srq_handle, file->ucontext) : NULL;
pd = idr_read_pd(cmd.pd_handle, file->ucontext); pd = idr_read_pd(cmd.pd_handle, file->ucontext);
scq = idr_read_cq(cmd.send_cq_handle, file->ucontext); scq = idr_read_cq(cmd.send_cq_handle, file->ucontext, 0);
rcq = cmd.recv_cq_handle == cmd.send_cq_handle ? rcq = cmd.recv_cq_handle == cmd.send_cq_handle ?
scq : idr_read_cq(cmd.recv_cq_handle, file->ucontext); scq : idr_read_cq(cmd.recv_cq_handle, file->ucontext, 1);
if (!pd || !scq || !rcq || (cmd.is_srq && !srq)) { if (!pd || !scq || !rcq || (cmd.is_srq && !srq)) {
ret = -EINVAL; ret = -EINVAL;
......
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