aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband
diff options
context:
space:
mode:
authorSean Hefty <sean.hefty@intel.com>2011-05-23 22:59:25 -0400
committerRoland Dreier <roland@purestorage.com>2011-10-13 12:16:19 -0400
commitb42b63cf0dde2af6eec462b2d6cca7d938702a28 (patch)
treeabb1c06c6903bdc816b5a09a25ea3e4b2bda7842 /drivers/infiniband
parent418d51307d102e72e745031adb4f5ba0ddb646e2 (diff)
RDMA/core: Add XRC QPs
XRC ("eXtended reliable connected") is an IB transport that provides better scalability by allowing senders to specify which shared receive queue (SRQ) should be used to receive a message, which essentially allows one transport context (QP connection) to serve multiple destinations (as long as they share an adapter, of course). XRC communication is between an initiator (INI) QP and a target (TGT) QP. Target QPs are associated with SRQs through an XRCD. An XRC TGT QP behaves like a receive-only RD QP. XRC INI QPs behave similarly to RC QPs, except that work requests posted to an XRC INI QP must specify the remote SRQ that is the target of the work request. We define two new QP types for XRC, to distinguish between INI and TGT QPs, and update the core layer to support XRC QPs. This patch is derived from work by Jack Morgenstein <jackm@dev.mellanox.co.il> Signed-off-by: Sean Hefty <sean.hefty@intel.com> Signed-off-by: Roland Dreier <roland@purestorage.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r--drivers/infiniband/core/verbs.c150
1 files changed, 130 insertions, 20 deletions
diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 25c1c1ea4460..89277e5129be 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -320,24 +320,44 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
320 struct ib_qp_init_attr *qp_init_attr) 320 struct ib_qp_init_attr *qp_init_attr)
321{ 321{
322 struct ib_qp *qp; 322 struct ib_qp *qp;
323 struct ib_device *device;
323 324
324 qp = pd->device->create_qp(pd, qp_init_attr, NULL); 325 device = pd ? pd->device : qp_init_attr->xrcd->device;
326 qp = device->create_qp(pd, qp_init_attr, NULL);
325 327
326 if (!IS_ERR(qp)) { 328 if (!IS_ERR(qp)) {
327 qp->device = pd->device; 329 qp->device = device;
328 qp->pd = pd; 330
329 qp->send_cq = qp_init_attr->send_cq; 331 if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) {
330 qp->recv_cq = qp_init_attr->recv_cq; 332 qp->pd = NULL;
331 qp->srq = qp_init_attr->srq; 333 qp->send_cq = qp->recv_cq = NULL;
334 qp->srq = NULL;
335 qp->xrcd = qp_init_attr->xrcd;
336 atomic_inc(&qp_init_attr->xrcd->usecnt);
337 } else {
338 if (qp_init_attr->qp_type == IB_QPT_XRC_INI) {
339 qp->recv_cq = NULL;
340 qp->srq = NULL;
341 } else {
342 qp->recv_cq = qp_init_attr->recv_cq;
343 atomic_inc(&qp_init_attr->recv_cq->usecnt);
344 qp->srq = qp_init_attr->srq;
345 if (qp->srq)
346 atomic_inc(&qp_init_attr->srq->usecnt);
347 }
348
349 qp->pd = pd;
350 qp->send_cq = qp_init_attr->send_cq;
351 qp->xrcd = NULL;
352
353 atomic_inc(&pd->usecnt);
354 atomic_inc(&qp_init_attr->send_cq->usecnt);
355 }
356
332 qp->uobject = NULL; 357 qp->uobject = NULL;
333 qp->event_handler = qp_init_attr->event_handler; 358 qp->event_handler = qp_init_attr->event_handler;
334 qp->qp_context = qp_init_attr->qp_context; 359 qp->qp_context = qp_init_attr->qp_context;
335 qp->qp_type = qp_init_attr->qp_type; 360 qp->qp_type = qp_init_attr->qp_type;
336 atomic_inc(&pd->usecnt);
337 atomic_inc(&qp_init_attr->send_cq->usecnt);
338 atomic_inc(&qp_init_attr->recv_cq->usecnt);
339 if (qp_init_attr->srq)
340 atomic_inc(&qp_init_attr->srq->usecnt);
341 } 361 }
342 362
343 return qp; 363 return qp;
@@ -346,8 +366,8 @@ EXPORT_SYMBOL(ib_create_qp);
346 366
347static const struct { 367static const struct {
348 int valid; 368 int valid;
349 enum ib_qp_attr_mask req_param[IB_QPT_RAW_ETHERTYPE + 1]; 369 enum ib_qp_attr_mask req_param[IB_QPT_MAX];
350 enum ib_qp_attr_mask opt_param[IB_QPT_RAW_ETHERTYPE + 1]; 370 enum ib_qp_attr_mask opt_param[IB_QPT_MAX];
351} qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = { 371} qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = {
352 [IB_QPS_RESET] = { 372 [IB_QPS_RESET] = {
353 [IB_QPS_RESET] = { .valid = 1 }, 373 [IB_QPS_RESET] = { .valid = 1 },
@@ -363,6 +383,12 @@ static const struct {
363 [IB_QPT_RC] = (IB_QP_PKEY_INDEX | 383 [IB_QPT_RC] = (IB_QP_PKEY_INDEX |
364 IB_QP_PORT | 384 IB_QP_PORT |
365 IB_QP_ACCESS_FLAGS), 385 IB_QP_ACCESS_FLAGS),
386 [IB_QPT_XRC_INI] = (IB_QP_PKEY_INDEX |
387 IB_QP_PORT |
388 IB_QP_ACCESS_FLAGS),
389 [IB_QPT_XRC_TGT] = (IB_QP_PKEY_INDEX |
390 IB_QP_PORT |
391 IB_QP_ACCESS_FLAGS),
366 [IB_QPT_SMI] = (IB_QP_PKEY_INDEX | 392 [IB_QPT_SMI] = (IB_QP_PKEY_INDEX |
367 IB_QP_QKEY), 393 IB_QP_QKEY),
368 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX | 394 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX |
@@ -385,6 +411,12 @@ static const struct {
385 [IB_QPT_RC] = (IB_QP_PKEY_INDEX | 411 [IB_QPT_RC] = (IB_QP_PKEY_INDEX |
386 IB_QP_PORT | 412 IB_QP_PORT |
387 IB_QP_ACCESS_FLAGS), 413 IB_QP_ACCESS_FLAGS),
414 [IB_QPT_XRC_INI] = (IB_QP_PKEY_INDEX |
415 IB_QP_PORT |
416 IB_QP_ACCESS_FLAGS),
417 [IB_QPT_XRC_TGT] = (IB_QP_PKEY_INDEX |
418 IB_QP_PORT |
419 IB_QP_ACCESS_FLAGS),
388 [IB_QPT_SMI] = (IB_QP_PKEY_INDEX | 420 [IB_QPT_SMI] = (IB_QP_PKEY_INDEX |
389 IB_QP_QKEY), 421 IB_QP_QKEY),
390 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX | 422 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX |
@@ -404,6 +436,16 @@ static const struct {
404 IB_QP_RQ_PSN | 436 IB_QP_RQ_PSN |
405 IB_QP_MAX_DEST_RD_ATOMIC | 437 IB_QP_MAX_DEST_RD_ATOMIC |
406 IB_QP_MIN_RNR_TIMER), 438 IB_QP_MIN_RNR_TIMER),
439 [IB_QPT_XRC_INI] = (IB_QP_AV |
440 IB_QP_PATH_MTU |
441 IB_QP_DEST_QPN |
442 IB_QP_RQ_PSN),
443 [IB_QPT_XRC_TGT] = (IB_QP_AV |
444 IB_QP_PATH_MTU |
445 IB_QP_DEST_QPN |
446 IB_QP_RQ_PSN |
447 IB_QP_MAX_DEST_RD_ATOMIC |
448 IB_QP_MIN_RNR_TIMER),
407 }, 449 },
408 .opt_param = { 450 .opt_param = {
409 [IB_QPT_UD] = (IB_QP_PKEY_INDEX | 451 [IB_QPT_UD] = (IB_QP_PKEY_INDEX |
@@ -414,6 +456,12 @@ static const struct {
414 [IB_QPT_RC] = (IB_QP_ALT_PATH | 456 [IB_QPT_RC] = (IB_QP_ALT_PATH |
415 IB_QP_ACCESS_FLAGS | 457 IB_QP_ACCESS_FLAGS |
416 IB_QP_PKEY_INDEX), 458 IB_QP_PKEY_INDEX),
459 [IB_QPT_XRC_INI] = (IB_QP_ALT_PATH |
460 IB_QP_ACCESS_FLAGS |
461 IB_QP_PKEY_INDEX),
462 [IB_QPT_XRC_TGT] = (IB_QP_ALT_PATH |
463 IB_QP_ACCESS_FLAGS |
464 IB_QP_PKEY_INDEX),
417 [IB_QPT_SMI] = (IB_QP_PKEY_INDEX | 465 [IB_QPT_SMI] = (IB_QP_PKEY_INDEX |
418 IB_QP_QKEY), 466 IB_QP_QKEY),
419 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX | 467 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX |
@@ -434,6 +482,13 @@ static const struct {
434 IB_QP_RNR_RETRY | 482 IB_QP_RNR_RETRY |
435 IB_QP_SQ_PSN | 483 IB_QP_SQ_PSN |
436 IB_QP_MAX_QP_RD_ATOMIC), 484 IB_QP_MAX_QP_RD_ATOMIC),
485 [IB_QPT_XRC_INI] = (IB_QP_TIMEOUT |
486 IB_QP_RETRY_CNT |
487 IB_QP_RNR_RETRY |
488 IB_QP_SQ_PSN |
489 IB_QP_MAX_QP_RD_ATOMIC),
490 [IB_QPT_XRC_TGT] = (IB_QP_TIMEOUT |
491 IB_QP_SQ_PSN),
437 [IB_QPT_SMI] = IB_QP_SQ_PSN, 492 [IB_QPT_SMI] = IB_QP_SQ_PSN,
438 [IB_QPT_GSI] = IB_QP_SQ_PSN, 493 [IB_QPT_GSI] = IB_QP_SQ_PSN,
439 }, 494 },
@@ -449,6 +504,15 @@ static const struct {
449 IB_QP_ACCESS_FLAGS | 504 IB_QP_ACCESS_FLAGS |
450 IB_QP_MIN_RNR_TIMER | 505 IB_QP_MIN_RNR_TIMER |
451 IB_QP_PATH_MIG_STATE), 506 IB_QP_PATH_MIG_STATE),
507 [IB_QPT_XRC_INI] = (IB_QP_CUR_STATE |
508 IB_QP_ALT_PATH |
509 IB_QP_ACCESS_FLAGS |
510 IB_QP_PATH_MIG_STATE),
511 [IB_QPT_XRC_TGT] = (IB_QP_CUR_STATE |
512 IB_QP_ALT_PATH |
513 IB_QP_ACCESS_FLAGS |
514 IB_QP_MIN_RNR_TIMER |
515 IB_QP_PATH_MIG_STATE),
452 [IB_QPT_SMI] = (IB_QP_CUR_STATE | 516 [IB_QPT_SMI] = (IB_QP_CUR_STATE |
453 IB_QP_QKEY), 517 IB_QP_QKEY),
454 [IB_QPT_GSI] = (IB_QP_CUR_STATE | 518 [IB_QPT_GSI] = (IB_QP_CUR_STATE |
@@ -473,6 +537,15 @@ static const struct {
473 IB_QP_ALT_PATH | 537 IB_QP_ALT_PATH |
474 IB_QP_PATH_MIG_STATE | 538 IB_QP_PATH_MIG_STATE |
475 IB_QP_MIN_RNR_TIMER), 539 IB_QP_MIN_RNR_TIMER),
540 [IB_QPT_XRC_INI] = (IB_QP_CUR_STATE |
541 IB_QP_ACCESS_FLAGS |
542 IB_QP_ALT_PATH |
543 IB_QP_PATH_MIG_STATE),
544 [IB_QPT_XRC_TGT] = (IB_QP_CUR_STATE |
545 IB_QP_ACCESS_FLAGS |
546 IB_QP_ALT_PATH |
547 IB_QP_PATH_MIG_STATE |
548 IB_QP_MIN_RNR_TIMER),
476 [IB_QPT_SMI] = (IB_QP_CUR_STATE | 549 [IB_QPT_SMI] = (IB_QP_CUR_STATE |
477 IB_QP_QKEY), 550 IB_QP_QKEY),
478 [IB_QPT_GSI] = (IB_QP_CUR_STATE | 551 [IB_QPT_GSI] = (IB_QP_CUR_STATE |
@@ -485,6 +558,8 @@ static const struct {
485 [IB_QPT_UD] = IB_QP_EN_SQD_ASYNC_NOTIFY, 558 [IB_QPT_UD] = IB_QP_EN_SQD_ASYNC_NOTIFY,
486 [IB_QPT_UC] = IB_QP_EN_SQD_ASYNC_NOTIFY, 559 [IB_QPT_UC] = IB_QP_EN_SQD_ASYNC_NOTIFY,
487 [IB_QPT_RC] = IB_QP_EN_SQD_ASYNC_NOTIFY, 560 [IB_QPT_RC] = IB_QP_EN_SQD_ASYNC_NOTIFY,
561 [IB_QPT_XRC_INI] = IB_QP_EN_SQD_ASYNC_NOTIFY,
562 [IB_QPT_XRC_TGT] = IB_QP_EN_SQD_ASYNC_NOTIFY, /* ??? */
488 [IB_QPT_SMI] = IB_QP_EN_SQD_ASYNC_NOTIFY, 563 [IB_QPT_SMI] = IB_QP_EN_SQD_ASYNC_NOTIFY,
489 [IB_QPT_GSI] = IB_QP_EN_SQD_ASYNC_NOTIFY 564 [IB_QPT_GSI] = IB_QP_EN_SQD_ASYNC_NOTIFY
490 } 565 }
@@ -507,6 +582,15 @@ static const struct {
507 IB_QP_ACCESS_FLAGS | 582 IB_QP_ACCESS_FLAGS |
508 IB_QP_MIN_RNR_TIMER | 583 IB_QP_MIN_RNR_TIMER |
509 IB_QP_PATH_MIG_STATE), 584 IB_QP_PATH_MIG_STATE),
585 [IB_QPT_XRC_INI] = (IB_QP_CUR_STATE |
586 IB_QP_ALT_PATH |
587 IB_QP_ACCESS_FLAGS |
588 IB_QP_PATH_MIG_STATE),
589 [IB_QPT_XRC_TGT] = (IB_QP_CUR_STATE |
590 IB_QP_ALT_PATH |
591 IB_QP_ACCESS_FLAGS |
592 IB_QP_MIN_RNR_TIMER |
593 IB_QP_PATH_MIG_STATE),
510 [IB_QPT_SMI] = (IB_QP_CUR_STATE | 594 [IB_QPT_SMI] = (IB_QP_CUR_STATE |
511 IB_QP_QKEY), 595 IB_QP_QKEY),
512 [IB_QPT_GSI] = (IB_QP_CUR_STATE | 596 [IB_QPT_GSI] = (IB_QP_CUR_STATE |
@@ -535,6 +619,25 @@ static const struct {
535 IB_QP_PKEY_INDEX | 619 IB_QP_PKEY_INDEX |
536 IB_QP_MIN_RNR_TIMER | 620 IB_QP_MIN_RNR_TIMER |
537 IB_QP_PATH_MIG_STATE), 621 IB_QP_PATH_MIG_STATE),
622 [IB_QPT_XRC_INI] = (IB_QP_PORT |
623 IB_QP_AV |
624 IB_QP_TIMEOUT |
625 IB_QP_RETRY_CNT |
626 IB_QP_RNR_RETRY |
627 IB_QP_MAX_QP_RD_ATOMIC |
628 IB_QP_ALT_PATH |
629 IB_QP_ACCESS_FLAGS |
630 IB_QP_PKEY_INDEX |
631 IB_QP_PATH_MIG_STATE),
632 [IB_QPT_XRC_TGT] = (IB_QP_PORT |
633 IB_QP_AV |
634 IB_QP_TIMEOUT |
635 IB_QP_MAX_DEST_RD_ATOMIC |
636 IB_QP_ALT_PATH |
637 IB_QP_ACCESS_FLAGS |
638 IB_QP_PKEY_INDEX |
639 IB_QP_MIN_RNR_TIMER |
640 IB_QP_PATH_MIG_STATE),
538 [IB_QPT_SMI] = (IB_QP_PKEY_INDEX | 641 [IB_QPT_SMI] = (IB_QP_PKEY_INDEX |
539 IB_QP_QKEY), 642 IB_QP_QKEY),
540 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX | 643 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX |
@@ -619,20 +722,27 @@ int ib_destroy_qp(struct ib_qp *qp)
619 struct ib_pd *pd; 722 struct ib_pd *pd;
620 struct ib_cq *scq, *rcq; 723 struct ib_cq *scq, *rcq;
621 struct ib_srq *srq; 724 struct ib_srq *srq;
725 struct ib_xrcd *xrcd;
622 int ret; 726 int ret;
623 727
624 pd = qp->pd; 728 pd = qp->pd;
625 scq = qp->send_cq; 729 scq = qp->send_cq;
626 rcq = qp->recv_cq; 730 rcq = qp->recv_cq;
627 srq = qp->srq; 731 srq = qp->srq;
732 xrcd = qp->xrcd;
628 733
629 ret = qp->device->destroy_qp(qp); 734 ret = qp->device->destroy_qp(qp);
630 if (!ret) { 735 if (!ret) {
631 atomic_dec(&pd->usecnt); 736 if (pd)
632 atomic_dec(&scq->usecnt); 737 atomic_dec(&pd->usecnt);
633 atomic_dec(&rcq->usecnt); 738 if (scq)
739 atomic_dec(&scq->usecnt);
740 if (rcq)
741 atomic_dec(&rcq->usecnt);
634 if (srq) 742 if (srq)
635 atomic_dec(&srq->usecnt); 743 atomic_dec(&srq->usecnt);
744 if (xrcd)
745 atomic_dec(&xrcd->usecnt);
636 } 746 }
637 747
638 return ret; 748 return ret;