diff options
-rw-r--r-- | drivers/infiniband/core/uverbs_cmd.c | 105 | ||||
-rw-r--r-- | drivers/infiniband/core/uverbs_main.c | 8 |
2 files changed, 73 insertions, 40 deletions
diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index 3eba64c51b0b..9058e38ca4cd 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c | |||
@@ -1370,8 +1370,11 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, | |||
1370 | struct ib_uverbs_create_qp_resp resp; | 1370 | struct ib_uverbs_create_qp_resp resp; |
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_device *device; |
1374 | struct ib_cq *scq, *rcq = NULL; | 1374 | struct ib_pd *pd = NULL; |
1375 | struct ib_xrcd *xrcd = NULL; | ||
1376 | struct ib_uobject *uninitialized_var(xrcd_uobj); | ||
1377 | struct ib_cq *scq = NULL, *rcq = NULL; | ||
1375 | struct ib_srq *srq = NULL; | 1378 | struct ib_srq *srq = NULL; |
1376 | struct ib_qp *qp; | 1379 | struct ib_qp *qp; |
1377 | struct ib_qp_init_attr attr; | 1380 | struct ib_qp_init_attr attr; |
@@ -1394,29 +1397,39 @@ 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); | 1397 | init_uobj(&obj->uevent.uobject, cmd.user_handle, file->ucontext, &qp_lock_key); |
1395 | down_write(&obj->uevent.uobject.mutex); | 1398 | down_write(&obj->uevent.uobject.mutex); |
1396 | 1399 | ||
1397 | pd = idr_read_pd(cmd.pd_handle, file->ucontext); | 1400 | if (cmd.qp_type == IB_QPT_XRC_TGT) { |
1398 | scq = idr_read_cq(cmd.send_cq_handle, file->ucontext, 0); | 1401 | xrcd = idr_read_xrcd(cmd.pd_handle, file->ucontext, &xrcd_uobj); |
1399 | if (!pd || !scq) { | 1402 | if (!xrcd) { |
1400 | ret = -EINVAL; | 1403 | ret = -EINVAL; |
1401 | goto err_put; | 1404 | goto err_put; |
1402 | } | 1405 | } |
1403 | 1406 | device = xrcd->device; | |
1404 | if (cmd.qp_type == IB_QPT_XRC_INI) { | ||
1405 | cmd.max_recv_wr = cmd.max_recv_sge = 0; | ||
1406 | } else { | 1407 | } else { |
1407 | if (cmd.is_srq) { | 1408 | pd = idr_read_pd(cmd.pd_handle, file->ucontext); |
1408 | srq = idr_read_srq(cmd.srq_handle, file->ucontext); | 1409 | scq = idr_read_cq(cmd.send_cq_handle, file->ucontext, 0); |
1409 | if (!srq || srq->srq_type != IB_SRQT_BASIC) { | 1410 | if (!pd || !scq) { |
1411 | ret = -EINVAL; | ||
1412 | goto err_put; | ||
1413 | } | ||
1414 | |||
1415 | if (cmd.qp_type == IB_QPT_XRC_INI) { | ||
1416 | cmd.max_recv_wr = cmd.max_recv_sge = 0; | ||
1417 | } else { | ||
1418 | if (cmd.is_srq) { | ||
1419 | srq = idr_read_srq(cmd.srq_handle, file->ucontext); | ||
1420 | if (!srq || srq->srq_type != IB_SRQT_BASIC) { | ||
1421 | ret = -EINVAL; | ||
1422 | goto err_put; | ||
1423 | } | ||
1424 | } | ||
1425 | rcq = (cmd.recv_cq_handle == cmd.send_cq_handle) ? | ||
1426 | scq : idr_read_cq(cmd.recv_cq_handle, file->ucontext, 1); | ||
1427 | if (!rcq) { | ||
1410 | ret = -EINVAL; | 1428 | ret = -EINVAL; |
1411 | goto err_put; | 1429 | goto err_put; |
1412 | } | 1430 | } |
1413 | } | 1431 | } |
1414 | rcq = (cmd.recv_cq_handle == cmd.send_cq_handle) ? | 1432 | device = pd->device; |
1415 | scq : idr_read_cq(cmd.recv_cq_handle, file->ucontext, 1); | ||
1416 | if (!rcq) { | ||
1417 | ret = -EINVAL; | ||
1418 | goto err_put; | ||
1419 | } | ||
1420 | } | 1433 | } |
1421 | 1434 | ||
1422 | attr.event_handler = ib_uverbs_qp_event_handler; | 1435 | attr.event_handler = ib_uverbs_qp_event_handler; |
@@ -1424,6 +1437,7 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, | |||
1424 | attr.send_cq = scq; | 1437 | attr.send_cq = scq; |
1425 | attr.recv_cq = rcq; | 1438 | attr.recv_cq = rcq; |
1426 | attr.srq = srq; | 1439 | attr.srq = srq; |
1440 | attr.xrcd = xrcd; | ||
1427 | attr.sq_sig_type = cmd.sq_sig_all ? IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR; | 1441 | attr.sq_sig_type = cmd.sq_sig_all ? IB_SIGNAL_ALL_WR : IB_SIGNAL_REQ_WR; |
1428 | attr.qp_type = cmd.qp_type; | 1442 | attr.qp_type = cmd.qp_type; |
1429 | attr.create_flags = 0; | 1443 | attr.create_flags = 0; |
@@ -1438,27 +1452,33 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, | |||
1438 | INIT_LIST_HEAD(&obj->uevent.event_list); | 1452 | INIT_LIST_HEAD(&obj->uevent.event_list); |
1439 | INIT_LIST_HEAD(&obj->mcast_list); | 1453 | INIT_LIST_HEAD(&obj->mcast_list); |
1440 | 1454 | ||
1441 | qp = pd->device->create_qp(pd, &attr, &udata); | 1455 | if (cmd.qp_type == IB_QPT_XRC_TGT) |
1456 | qp = ib_create_qp(pd, &attr); | ||
1457 | else | ||
1458 | qp = device->create_qp(pd, &attr, &udata); | ||
1459 | |||
1442 | if (IS_ERR(qp)) { | 1460 | if (IS_ERR(qp)) { |
1443 | ret = PTR_ERR(qp); | 1461 | ret = PTR_ERR(qp); |
1444 | goto err_put; | 1462 | goto err_put; |
1445 | } | 1463 | } |
1446 | 1464 | ||
1447 | qp->device = pd->device; | 1465 | if (cmd.qp_type != IB_QPT_XRC_TGT) { |
1448 | qp->pd = pd; | 1466 | qp->device = device; |
1449 | qp->send_cq = attr.send_cq; | 1467 | qp->pd = pd; |
1450 | qp->recv_cq = attr.recv_cq; | 1468 | qp->send_cq = attr.send_cq; |
1451 | qp->srq = attr.srq; | 1469 | qp->recv_cq = attr.recv_cq; |
1452 | qp->uobject = &obj->uevent.uobject; | 1470 | qp->srq = attr.srq; |
1453 | qp->event_handler = attr.event_handler; | 1471 | qp->event_handler = attr.event_handler; |
1454 | qp->qp_context = attr.qp_context; | 1472 | qp->qp_context = attr.qp_context; |
1455 | qp->qp_type = attr.qp_type; | 1473 | qp->qp_type = attr.qp_type; |
1456 | atomic_inc(&pd->usecnt); | 1474 | atomic_inc(&pd->usecnt); |
1457 | atomic_inc(&attr.send_cq->usecnt); | 1475 | atomic_inc(&attr.send_cq->usecnt); |
1458 | if (attr.recv_cq) | 1476 | if (attr.recv_cq) |
1459 | atomic_inc(&attr.recv_cq->usecnt); | 1477 | atomic_inc(&attr.recv_cq->usecnt); |
1460 | if (attr.srq) | 1478 | if (attr.srq) |
1461 | atomic_inc(&attr.srq->usecnt); | 1479 | atomic_inc(&attr.srq->usecnt); |
1480 | } | ||
1481 | qp->uobject = &obj->uevent.uobject; | ||
1462 | 1482 | ||
1463 | obj->uevent.uobject.object = qp; | 1483 | obj->uevent.uobject.object = qp; |
1464 | ret = idr_add_uobj(&ib_uverbs_qp_idr, &obj->uevent.uobject); | 1484 | ret = idr_add_uobj(&ib_uverbs_qp_idr, &obj->uevent.uobject); |
@@ -1480,8 +1500,12 @@ ssize_t ib_uverbs_create_qp(struct ib_uverbs_file *file, | |||
1480 | goto err_copy; | 1500 | goto err_copy; |
1481 | } | 1501 | } |
1482 | 1502 | ||
1483 | put_pd_read(pd); | 1503 | if (xrcd) |
1484 | put_cq_read(scq); | 1504 | put_xrcd_read(xrcd_uobj); |
1505 | if (pd) | ||
1506 | put_pd_read(pd); | ||
1507 | if (scq) | ||
1508 | put_cq_read(scq); | ||
1485 | if (rcq && rcq != scq) | 1509 | if (rcq && rcq != scq) |
1486 | put_cq_read(rcq); | 1510 | put_cq_read(rcq); |
1487 | if (srq) | 1511 | if (srq) |
@@ -1504,6 +1528,8 @@ err_destroy: | |||
1504 | ib_destroy_qp(qp); | 1528 | ib_destroy_qp(qp); |
1505 | 1529 | ||
1506 | err_put: | 1530 | err_put: |
1531 | if (xrcd) | ||
1532 | put_xrcd_read(xrcd_uobj); | ||
1507 | if (pd) | 1533 | if (pd) |
1508 | put_pd_read(pd); | 1534 | put_pd_read(pd); |
1509 | if (scq) | 1535 | if (scq) |
@@ -1623,6 +1649,9 @@ static int modify_qp_mask(enum ib_qp_type qp_type, int mask) | |||
1623 | switch (qp_type) { | 1649 | switch (qp_type) { |
1624 | case IB_QPT_XRC_INI: | 1650 | case IB_QPT_XRC_INI: |
1625 | return mask & ~(IB_QP_MAX_DEST_RD_ATOMIC | IB_QP_MIN_RNR_TIMER); | 1651 | return mask & ~(IB_QP_MAX_DEST_RD_ATOMIC | IB_QP_MIN_RNR_TIMER); |
1652 | case IB_QPT_XRC_TGT: | ||
1653 | return mask & ~(IB_QP_MAX_QP_RD_ATOMIC | IB_QP_RETRY_CNT | | ||
1654 | IB_QP_RNR_RETRY); | ||
1626 | default: | 1655 | default: |
1627 | return mask; | 1656 | return mask; |
1628 | } | 1657 | } |
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index 6ad221b87158..0cb69e039f75 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c | |||
@@ -206,8 +206,12 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, | |||
206 | container_of(uobj, struct ib_uqp_object, uevent.uobject); | 206 | container_of(uobj, struct ib_uqp_object, uevent.uobject); |
207 | 207 | ||
208 | idr_remove_uobj(&ib_uverbs_qp_idr, uobj); | 208 | idr_remove_uobj(&ib_uverbs_qp_idr, uobj); |
209 | ib_uverbs_detach_umcast(qp, uqp); | 209 | if (qp->qp_type == IB_QPT_XRC_TGT) { |
210 | ib_destroy_qp(qp); | 210 | ib_release_qp(qp); |
211 | } else { | ||
212 | ib_uverbs_detach_umcast(qp, uqp); | ||
213 | ib_destroy_qp(qp); | ||
214 | } | ||
211 | ib_uverbs_release_uevent(file, &uqp->uevent); | 215 | ib_uverbs_release_uevent(file, &uqp->uevent); |
212 | kfree(uqp); | 216 | kfree(uqp); |
213 | } | 217 | } |