Skip to content

Commit

Permalink
IB/uverbs: Extend create QP to get RWQ indirection table
Browse files Browse the repository at this point in the history
User applications that want to spread incoming traffic between several WQs
should create a QP which contains an indirection table.

When such a QP is created other receive side parameters are not valid
and should not be given. Its send side is optional and assumed active
based on max_send_wr capability value.

Extend create QP to work accordingly.

Signed-off-by: Yishai Hadas <yishaih@mellanox.com>
Signed-off-by: Matan Barak <matanb@mellanox.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Doug Ledford <dledford@redhat.com>
  • Loading branch information
Yishai Hadas authored and Doug Ledford committed Jun 23, 2016
1 parent a9017e2 commit c70285f
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 12 deletions.
75 changes: 63 additions & 12 deletions drivers/infiniband/core/uverbs_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,17 @@ static void put_wq_read(struct ib_wq *wq)
put_uobj_read(wq->uobject);
}

static struct ib_rwq_ind_table *idr_read_rwq_indirection_table(int ind_table_handle,
struct ib_ucontext *context)
{
return idr_read_obj(&ib_uverbs_rwq_ind_tbl_idr, ind_table_handle, context, 0);
}

static void put_rwq_indirection_table_read(struct ib_rwq_ind_table *ind_table)
{
put_uobj_read(ind_table->uobject);
}

static struct ib_qp *idr_write_qp(int qp_handle, struct ib_ucontext *context)
{
struct ib_uobject *uobj;
Expand Down Expand Up @@ -1761,9 +1772,11 @@ static int create_qp(struct ib_uverbs_file *file,
struct ib_srq *srq = NULL;
struct ib_qp *qp;
char *buf;
struct ib_qp_init_attr attr;
struct ib_qp_init_attr attr = {};
struct ib_uverbs_ex_create_qp_resp resp;
int ret;
struct ib_rwq_ind_table *ind_tbl = NULL;
bool has_sq = true;

if (cmd->qp_type == IB_QPT_RAW_PACKET && !capable(CAP_NET_RAW))
return -EPERM;
Expand All @@ -1775,6 +1788,32 @@ static int create_qp(struct ib_uverbs_file *file,
init_uobj(&obj->uevent.uobject, cmd->user_handle, file->ucontext,
&qp_lock_class);
down_write(&obj->uevent.uobject.mutex);
if (cmd_sz >= offsetof(typeof(*cmd), rwq_ind_tbl_handle) +
sizeof(cmd->rwq_ind_tbl_handle) &&
(cmd->comp_mask & IB_UVERBS_CREATE_QP_MASK_IND_TABLE)) {
ind_tbl = idr_read_rwq_indirection_table(cmd->rwq_ind_tbl_handle,
file->ucontext);
if (!ind_tbl) {
ret = -EINVAL;
goto err_put;
}

attr.rwq_ind_tbl = ind_tbl;
}

if ((cmd_sz >= offsetof(typeof(*cmd), reserved1) +
sizeof(cmd->reserved1)) && cmd->reserved1) {
ret = -EOPNOTSUPP;
goto err_put;
}

if (ind_tbl && (cmd->max_recv_wr || cmd->max_recv_sge || cmd->is_srq)) {
ret = -EINVAL;
goto err_put;
}

if (ind_tbl && !cmd->max_send_wr)
has_sq = false;

if (cmd->qp_type == IB_QPT_XRC_TGT) {
xrcd = idr_read_xrcd(cmd->pd_handle, file->ucontext,
Expand All @@ -1798,20 +1837,24 @@ static int create_qp(struct ib_uverbs_file *file,
}
}

if (cmd->recv_cq_handle != cmd->send_cq_handle) {
rcq = idr_read_cq(cmd->recv_cq_handle,
file->ucontext, 0);
if (!rcq) {
ret = -EINVAL;
goto err_put;
if (!ind_tbl) {
if (cmd->recv_cq_handle != cmd->send_cq_handle) {
rcq = idr_read_cq(cmd->recv_cq_handle,
file->ucontext, 0);
if (!rcq) {
ret = -EINVAL;
goto err_put;
}
}
}
}

scq = idr_read_cq(cmd->send_cq_handle, file->ucontext, !!rcq);
rcq = rcq ?: scq;
if (has_sq)
scq = idr_read_cq(cmd->send_cq_handle, file->ucontext, !!rcq);
if (!ind_tbl)
rcq = rcq ?: scq;
pd = idr_read_pd(cmd->pd_handle, file->ucontext);
if (!pd || !scq) {
if (!pd || (!scq && has_sq)) {
ret = -EINVAL;
goto err_put;
}
Expand Down Expand Up @@ -1878,16 +1921,20 @@ static int create_qp(struct ib_uverbs_file *file,
qp->send_cq = attr.send_cq;
qp->recv_cq = attr.recv_cq;
qp->srq = attr.srq;
qp->rwq_ind_tbl = ind_tbl;
qp->event_handler = attr.event_handler;
qp->qp_context = attr.qp_context;
qp->qp_type = attr.qp_type;
atomic_set(&qp->usecnt, 0);
atomic_inc(&pd->usecnt);
atomic_inc(&attr.send_cq->usecnt);
if (attr.send_cq)
atomic_inc(&attr.send_cq->usecnt);
if (attr.recv_cq)
atomic_inc(&attr.recv_cq->usecnt);
if (attr.srq)
atomic_inc(&attr.srq->usecnt);
if (ind_tbl)
atomic_inc(&ind_tbl->usecnt);
}
qp->uobject = &obj->uevent.uobject;

Expand Down Expand Up @@ -1927,6 +1974,8 @@ static int create_qp(struct ib_uverbs_file *file,
put_cq_read(rcq);
if (srq)
put_srq_read(srq);
if (ind_tbl)
put_rwq_indirection_table_read(ind_tbl);

mutex_lock(&file->mutex);
list_add_tail(&obj->uevent.uobject.list, &file->ucontext->qp_list);
Expand Down Expand Up @@ -1954,6 +2003,8 @@ static int create_qp(struct ib_uverbs_file *file,
put_cq_read(rcq);
if (srq)
put_srq_read(srq);
if (ind_tbl)
put_rwq_indirection_table_read(ind_tbl);

put_uobj_write(&obj->uevent.uobject);
return ret;
Expand Down Expand Up @@ -2047,7 +2098,7 @@ int ib_uverbs_ex_create_qp(struct ib_uverbs_file *file,
if (err)
return err;

if (cmd.comp_mask)
if (cmd.comp_mask & ~IB_UVERBS_CREATE_QP_SUP_COMP_MASK)
return -EINVAL;

if (cmd.reserved)
Expand Down
10 changes: 10 additions & 0 deletions include/uapi/rdma/ib_user_verbs.h
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,14 @@ struct ib_uverbs_create_qp {
__u64 driver_data[0];
};

enum ib_uverbs_create_qp_mask {
IB_UVERBS_CREATE_QP_MASK_IND_TABLE = 1UL << 0,
};

enum {
IB_UVERBS_CREATE_QP_SUP_COMP_MASK = IB_UVERBS_CREATE_QP_MASK_IND_TABLE,
};

struct ib_uverbs_ex_create_qp {
__u64 user_handle;
__u32 pd_handle;
Expand All @@ -540,6 +548,8 @@ struct ib_uverbs_ex_create_qp {
__u8 reserved;
__u32 comp_mask;
__u32 create_flags;
__u32 rwq_ind_tbl_handle;
__u32 reserved1;
};

struct ib_uverbs_open_qp {
Expand Down

0 comments on commit c70285f

Please sign in to comment.