aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Hefty <sean.hefty@intel.com>2011-05-26 11:17:04 -0400
committerRoland Dreier <roland@purestorage.com>2011-10-13 12:32:27 -0400
commit9977f4f64bfeb5d907a793a6880aab2d43b0bed2 (patch)
tree0cb064c43fcaa8c7289e6d410ed1f63e9e80e4e6
parent8541f8de0583f562c652008a4e7a65e537842a7e (diff)
RDMA/uverbs: Export XRC INI QPs to userspace
XRC INI QPs are similar to send only RC QPs. Allow user space to create INI QPs. Note that INI QPs do not require receive CQs. Signed-off-by: Sean Hefty <sean.hefty@intel.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
-rw-r--r--drivers/infiniband/core/uverbs_cmd.c48
1 files changed, 37 insertions, 11 deletions
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c
index 2e66b14acd43..3eba64c51b0b 100644
--- a/drivers/infiniband/core/uverbs_cmd.c
+++ b/drivers/infiniband/core/uverbs_cmd.c
@@ -1371,8 +1371,8 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
1371 struct ib_udata udata; 1371 struct ib_udata udata;
1372 struct ib_uqp_object *obj; 1372 struct ib_uqp_object *obj;
1373 struct ib_pd *pd; 1373 struct ib_pd *pd;
1374 struct ib_cq *scq, *rcq; 1374 struct ib_cq *scq, *rcq = NULL;
1375 struct ib_srq *srq; 1375 struct ib_srq *srq = NULL;
1376 struct ib_qp *qp; 1376 struct ib_qp *qp;
1377 struct ib_qp_init_attr attr; 1377 struct ib_qp_init_attr attr;
1378 int ret; 1378 int ret;
@@ -1394,18 +1394,31 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
1394 init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext, &qp_lock_key); 1394 init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext, &qp_lock_key);
1395 down_write(&obj->uevent.uobject.mutex); 1395 down_write(&obj->uevent.uobject.mutex);
1396 1396
1397 srq = cmd.is_srq ? idr_read_srq(cmd.srq_handle, file->ucontext) : NULL;
1398 pd = idr_read_pd(cmd.pd_handle, file->ucontext); 1397 pd = idr_read_pd(cmd.pd_handle, file->ucontext);
1399 scq = idr_read_cq(cmd.send_cq_handle, file->ucontext, 0); 1398 scq = idr_read_cq(cmd.send_cq_handle, file->ucontext, 0);
1400 rcq = cmd.recv_cq_handle == cmd.send_cq_handle ? 1399 if (!pd || !scq) {
1401 scq : idr_read_cq(cmd.recv_cq_handle, file->ucontext, 1);
1402
1403 if (!pd || !scq || !rcq ||
1404 (cmd.is_srq && (!srq || srq->srq_type != IB_SRQT_BASIC))) {
1405 ret = -EINVAL; 1400 ret = -EINVAL;
1406 goto err_put; 1401 goto err_put;
1407 } 1402 }
1408 1403
1404 if (cmd.qp_type == IB_QPT_XRC_INI) {
1405 cmd.max_recv_wr = cmd.max_recv_sge = 0;
1406 } else {
1407 if (cmd.is_srq) {
1408 srq = idr_read_srq(cmd.srq_handle, file->ucontext);
1409 if (!srq || srq->srq_type != IB_SRQT_BASIC) {
1410 ret = -EINVAL;
1411 goto err_put;
1412 }
1413 }
1414 rcq = (cmd.recv_cq_handle == cmd.send_cq_handle) ?
1415 scq : idr_read_cq(cmd.recv_cq_handle, file->ucontext, 1);
1416 if (!rcq) {
1417 ret = -EINVAL;
1418 goto err_put;
1419 }
1420 }
1421
1409 attr.event_handler = ib_uverbs_qp_event_handler; 1422 attr.event_handler = ib_uverbs_qp_event_handler;
1410 attr.qp_context = file; 1423 attr.qp_context = file;
1411 attr.send_cq = scq; 1424 attr.send_cq = scq;
@@ -1442,7 +1455,8 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
1442 qp->qp_type = attr.qp_type; 1455 qp->qp_type = attr.qp_type;
1443 atomic_inc(&pd->usecnt); 1456 atomic_inc(&pd->usecnt);
1444 atomic_inc(&attr.send_cq->usecnt); 1457 atomic_inc(&attr.send_cq->usecnt);
1445 atomic_inc(&attr.recv_cq->usecnt); 1458 if (attr.recv_cq)
1459 atomic_inc(&attr.recv_cq->usecnt);
1446 if (attr.srq) 1460 if (attr.srq)
1447 atomic_inc(&attr.srq->usecnt); 1461 atomic_inc(&attr.srq->usecnt);
1448 1462
@@ -1468,7 +1482,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file,
1468 1482
1469 put_pd_read(pd); 1483 put_pd_read(pd);
1470 put_cq_read(scq); 1484 put_cq_read(scq);
1471 if (rcq != scq) 1485 if (rcq && rcq != scq)
1472 put_cq_read(rcq); 1486 put_cq_read(rcq);
1473 if (srq) 1487 if (srq)
1474 put_srq_read(srq); 1488 put_srq_read(srq);
@@ -1603,6 +1617,17 @@ out:
1603 return ret ? ret : in_len; 1617 return ret ? ret : in_len;
1604} 1618}
1605 1619
1620/* Remove ignored fields set in the attribute mask */
1621static int modify_qp_mask(enum ib_qp_type qp_type, int mask)
1622{
1623 switch (qp_type) {
1624 case IB_QPT_XRC_INI:
1625 return mask & ~(IB_QP_MAX_DEST_RD_ATOMIC | IB_QP_MIN_RNR_TIMER);
1626 default:
1627 return mask;
1628 }
1629}
1630
1606ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file, 1631ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
1607 const char __user *buf, int in_len, 1632 const char __user *buf, int in_len,
1608 int out_len) 1633 int out_len)
@@ -1675,7 +1700,8 @@ ssize_t ib_uverbs_modify_qp(struct ib_uverbs_file *file,
1675 attr->alt_ah_attr.ah_flags = cmd.alt_dest.is_global ? IB_AH_GRH : 0; 1700 attr->alt_ah_attr.ah_flags = cmd.alt_dest.is_global ? IB_AH_GRH : 0;
1676 attr->alt_ah_attr.port_num = cmd.alt_dest.port_num; 1701 attr->alt_ah_attr.port_num = cmd.alt_dest.port_num;
1677 1702
1678 ret = qp->device->modify_qp(qp, attr, cmd.attr_mask, &udata); 1703 ret = qp->device->modify_qp(qp, attr,
1704 modify_qp_mask(qp->qp_type, cmd.attr_mask), &udata);
1679 1705
1680 put_qp_read(qp); 1706 put_qp_read(qp);
1681 1707