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 similar to an RC QP, 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
<[email protected]>

Signed-off-by: Sean Hefty <[email protected]>
---
 drivers/infiniband/core/verbs.c |  149 ++++++++++++++++++++++++++++++++++-----
 include/rdma/ib_verbs.h         |    9 ++
 2 files changed, 137 insertions(+), 21 deletions(-)

diff --git a/drivers/infiniband/core/verbs.c b/drivers/infiniband/core/verbs.c
index 25c1c1e..8ff16e3 100644
--- a/drivers/infiniband/core/verbs.c
+++ b/drivers/infiniband/core/verbs.c
@@ -320,24 +320,43 @@ struct ib_qp *ib_create_qp(struct ib_pd *pd,
                           struct ib_qp_init_attr *qp_init_attr)
 {
        struct ib_qp *qp;
+       struct ib_device *device;
 
-       qp = pd->device->create_qp(pd, qp_init_attr, NULL);
+       device = pd ? pd->device : qp_init_attr->xrcd->device;
+       qp = device->create_qp(pd, qp_init_attr, NULL);
 
        if (!IS_ERR(qp)) {
-               qp->device        = pd->device;
-               qp->pd            = pd;
-               qp->send_cq       = qp_init_attr->send_cq;
-               qp->recv_cq       = qp_init_attr->recv_cq;
-               qp->srq           = qp_init_attr->srq;
+               qp->device = device;
+
+               if (qp_init_attr->qp_type == IB_QPT_XRC_TGT) {
+                       qp->pd = NULL;
+                       qp->send_cq = qp->recv_cq = NULL;
+                       qp->srq = NULL;
+                       qp->xrcd = qp_init_attr->xrcd;
+                       atomic_inc(&qp_init_attr->xrcd->usecnt);
+               } else {
+                       if (qp_init_attr->qp_type == IB_QPT_XRC_INI) {
+                               qp->recv_cq = NULL;
+                               qp->srq = NULL;
+                       } else {
+                               qp->recv_cq = qp_init_attr->recv_cq;
+                               atomic_inc(&qp_init_attr->recv_cq->usecnt);
+                               if ((qp->srq = qp_init_attr->srq))
+                                       atomic_inc(&qp_init_attr->srq->usecnt);
+                       }
+
+                       qp->pd      = pd;
+                       qp->send_cq = qp_init_attr->send_cq;
+                       qp->xrcd    = NULL;
+
+                       atomic_inc(&pd->usecnt);
+                       atomic_inc(&qp_init_attr->send_cq->usecnt);
+               }
+
                qp->uobject       = NULL;
                qp->event_handler = qp_init_attr->event_handler;
                qp->qp_context    = qp_init_attr->qp_context;
                qp->qp_type       = qp_init_attr->qp_type;
-               atomic_inc(&pd->usecnt);
-               atomic_inc(&qp_init_attr->send_cq->usecnt);
-               atomic_inc(&qp_init_attr->recv_cq->usecnt);
-               if (qp_init_attr->srq)
-                       atomic_inc(&qp_init_attr->srq->usecnt);
        }
 
        return qp;
@@ -346,8 +365,8 @@ EXPORT_SYMBOL(ib_create_qp);
 
 static const struct {
        int                     valid;
-       enum ib_qp_attr_mask    req_param[IB_QPT_RAW_ETHERTYPE + 1];
-       enum ib_qp_attr_mask    opt_param[IB_QPT_RAW_ETHERTYPE + 1];
+       enum ib_qp_attr_mask    req_param[IB_QPT_MAX];
+       enum ib_qp_attr_mask    opt_param[IB_QPT_MAX];
 } qp_state_table[IB_QPS_ERR + 1][IB_QPS_ERR + 1] = {
        [IB_QPS_RESET] = {
                [IB_QPS_RESET] = { .valid = 1 },
@@ -363,6 +382,12 @@ static const struct {
                                [IB_QPT_RC]  = (IB_QP_PKEY_INDEX                
|
                                                IB_QP_PORT                      
|
                                                IB_QP_ACCESS_FLAGS),
+                               [IB_QPT_XRC_INI] = (IB_QP_PKEY_INDEX            
|
+                                               IB_QP_PORT                      
|
+                                               IB_QP_ACCESS_FLAGS),
+                               [IB_QPT_XRC_TGT] = (IB_QP_PKEY_INDEX            
|
+                                               IB_QP_PORT                      
|
+                                               IB_QP_ACCESS_FLAGS),
                                [IB_QPT_SMI] = (IB_QP_PKEY_INDEX                
|
                                                IB_QP_QKEY),
                                [IB_QPT_GSI] = (IB_QP_PKEY_INDEX                
|
@@ -385,6 +410,12 @@ static const struct {
                                [IB_QPT_RC]  = (IB_QP_PKEY_INDEX                
|
                                                IB_QP_PORT                      
|
                                                IB_QP_ACCESS_FLAGS),
+                               [IB_QPT_XRC_INI] = (IB_QP_PKEY_INDEX            
|
+                                               IB_QP_PORT                      
|
+                                               IB_QP_ACCESS_FLAGS),
+                               [IB_QPT_XRC_TGT] = (IB_QP_PKEY_INDEX            
|
+                                               IB_QP_PORT                      
|
+                                               IB_QP_ACCESS_FLAGS),
                                [IB_QPT_SMI] = (IB_QP_PKEY_INDEX                
|
                                                IB_QP_QKEY),
                                [IB_QPT_GSI] = (IB_QP_PKEY_INDEX                
|
@@ -404,6 +435,16 @@ static const struct {
                                                IB_QP_RQ_PSN                    
|
                                                IB_QP_MAX_DEST_RD_ATOMIC        
|
                                                IB_QP_MIN_RNR_TIMER),
+                               [IB_QPT_XRC_INI] = (IB_QP_AV                    
|
+                                               IB_QP_PATH_MTU                  
|
+                                               IB_QP_DEST_QPN                  
|
+                                               IB_QP_RQ_PSN),
+                               [IB_QPT_XRC_TGT] = (IB_QP_AV                    
|
+                                               IB_QP_PATH_MTU                  
|
+                                               IB_QP_DEST_QPN                  
|
+                                               IB_QP_RQ_PSN                    
|
+                                               IB_QP_MAX_DEST_RD_ATOMIC        
|
+                                               IB_QP_MIN_RNR_TIMER),
                        },
                        .opt_param = {
                                 [IB_QPT_UD]  = (IB_QP_PKEY_INDEX               
|
@@ -414,6 +455,12 @@ static const struct {
                                 [IB_QPT_RC]  = (IB_QP_ALT_PATH                 
|
                                                 IB_QP_ACCESS_FLAGS             
|
                                                 IB_QP_PKEY_INDEX),
+                                [IB_QPT_XRC_INI] = (IB_QP_ALT_PATH             
|
+                                                IB_QP_ACCESS_FLAGS             
|
+                                                IB_QP_PKEY_INDEX),
+                                [IB_QPT_XRC_TGT] = (IB_QP_ALT_PATH             
|
+                                                IB_QP_ACCESS_FLAGS             
|
+                                                IB_QP_PKEY_INDEX),
                                 [IB_QPT_SMI] = (IB_QP_PKEY_INDEX               
|
                                                 IB_QP_QKEY),
                                 [IB_QPT_GSI] = (IB_QP_PKEY_INDEX               
|
@@ -434,6 +481,13 @@ static const struct {
                                                IB_QP_RNR_RETRY                 
|
                                                IB_QP_SQ_PSN                    
|
                                                IB_QP_MAX_QP_RD_ATOMIC),
+                               [IB_QPT_XRC_INI] = (IB_QP_TIMEOUT               
|
+                                               IB_QP_RETRY_CNT                 
|
+                                               IB_QP_RNR_RETRY                 
|
+                                               IB_QP_SQ_PSN                    
|
+                                               IB_QP_MAX_QP_RD_ATOMIC),
+                               [IB_QPT_XRC_TGT] = (IB_QP_TIMEOUT               
|
+                                               IB_QP_SQ_PSN),
                                [IB_QPT_SMI] = IB_QP_SQ_PSN,
                                [IB_QPT_GSI] = IB_QP_SQ_PSN,
                        },
@@ -449,6 +503,15 @@ static const struct {
                                                 IB_QP_ACCESS_FLAGS             
|
                                                 IB_QP_MIN_RNR_TIMER            
|
                                                 IB_QP_PATH_MIG_STATE),
+                                [IB_QPT_XRC_INI] = (IB_QP_CUR_STATE            
|
+                                                IB_QP_ALT_PATH                 
|
+                                                IB_QP_ACCESS_FLAGS             
|
+                                                IB_QP_PATH_MIG_STATE),
+                                [IB_QPT_XRC_TGT] = (IB_QP_CUR_STATE            
|
+                                                IB_QP_ALT_PATH                 
|
+                                                IB_QP_ACCESS_FLAGS             
|
+                                                IB_QP_MIN_RNR_TIMER            
|
+                                                IB_QP_PATH_MIG_STATE),
                                 [IB_QPT_SMI] = (IB_QP_CUR_STATE                
|
                                                 IB_QP_QKEY),
                                 [IB_QPT_GSI] = (IB_QP_CUR_STATE                
|
@@ -473,6 +536,15 @@ static const struct {
                                                IB_QP_ALT_PATH                  
|
                                                IB_QP_PATH_MIG_STATE            
|
                                                IB_QP_MIN_RNR_TIMER),
+                               [IB_QPT_XRC_INI] = (IB_QP_CUR_STATE             
|
+                                               IB_QP_ACCESS_FLAGS              
|
+                                               IB_QP_ALT_PATH                  
|
+                                               IB_QP_PATH_MIG_STATE),
+                               [IB_QPT_XRC_TGT] = (IB_QP_CUR_STATE             
|
+                                               IB_QP_ACCESS_FLAGS              
|
+                                               IB_QP_ALT_PATH                  
|
+                                               IB_QP_PATH_MIG_STATE            
|
+                                               IB_QP_MIN_RNR_TIMER),
                                [IB_QPT_SMI] = (IB_QP_CUR_STATE                 
|
                                                IB_QP_QKEY),
                                [IB_QPT_GSI] = (IB_QP_CUR_STATE                 
|
@@ -485,6 +557,8 @@ static const struct {
                                [IB_QPT_UD]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
                                [IB_QPT_UC]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
                                [IB_QPT_RC]  = IB_QP_EN_SQD_ASYNC_NOTIFY,
+                               [IB_QPT_XRC_INI] = IB_QP_EN_SQD_ASYNC_NOTIFY,
+                               [IB_QPT_XRC_TGT] = IB_QP_EN_SQD_ASYNC_NOTIFY, 
/* ??? */
                                [IB_QPT_SMI] = IB_QP_EN_SQD_ASYNC_NOTIFY,
                                [IB_QPT_GSI] = IB_QP_EN_SQD_ASYNC_NOTIFY
                        }
@@ -507,6 +581,15 @@ static const struct {
                                                IB_QP_ACCESS_FLAGS              
|
                                                IB_QP_MIN_RNR_TIMER             
|
                                                IB_QP_PATH_MIG_STATE),
+                               [IB_QPT_XRC_INI] = (IB_QP_CUR_STATE             
|
+                                               IB_QP_ALT_PATH                  
|
+                                               IB_QP_ACCESS_FLAGS              
|
+                                               IB_QP_PATH_MIG_STATE),
+                               [IB_QPT_XRC_TGT] = (IB_QP_CUR_STATE             
|
+                                               IB_QP_ALT_PATH                  
|
+                                               IB_QP_ACCESS_FLAGS              
|
+                                               IB_QP_MIN_RNR_TIMER             
|
+                                               IB_QP_PATH_MIG_STATE),
                                [IB_QPT_SMI] = (IB_QP_CUR_STATE                 
|
                                                IB_QP_QKEY),
                                [IB_QPT_GSI] = (IB_QP_CUR_STATE                 
|
@@ -535,6 +618,25 @@ static const struct {
                                                IB_QP_PKEY_INDEX                
|
                                                IB_QP_MIN_RNR_TIMER             
|
                                                IB_QP_PATH_MIG_STATE),
+                               [IB_QPT_XRC_INI] = (IB_QP_PORT                  
|
+                                               IB_QP_AV                        
|
+                                               IB_QP_TIMEOUT                   
|
+                                               IB_QP_RETRY_CNT                 
|
+                                               IB_QP_RNR_RETRY                 
|
+                                               IB_QP_MAX_QP_RD_ATOMIC          
|
+                                               IB_QP_ALT_PATH                  
|
+                                               IB_QP_ACCESS_FLAGS              
|
+                                               IB_QP_PKEY_INDEX                
|
+                                               IB_QP_PATH_MIG_STATE),
+                               [IB_QPT_XRC_TGT] = (IB_QP_PORT                  
|
+                                               IB_QP_AV                        
|
+                                               IB_QP_TIMEOUT                   
|
+                                               IB_QP_MAX_DEST_RD_ATOMIC        
|
+                                               IB_QP_ALT_PATH                  
|
+                                               IB_QP_ACCESS_FLAGS              
|
+                                               IB_QP_PKEY_INDEX                
|
+                                               IB_QP_MIN_RNR_TIMER             
|
+                                               IB_QP_PATH_MIG_STATE),
                                [IB_QPT_SMI] = (IB_QP_PKEY_INDEX                
|
                                                IB_QP_QKEY),
                                [IB_QPT_GSI] = (IB_QP_PKEY_INDEX                
|
@@ -619,20 +721,27 @@ int ib_destroy_qp(struct ib_qp *qp)
        struct ib_pd *pd;
        struct ib_cq *scq, *rcq;
        struct ib_srq *srq;
+       struct ib_xrcd *xrcd;
        int ret;
 
-       pd  = qp->pd;
-       scq = qp->send_cq;
-       rcq = qp->recv_cq;
-       srq = qp->srq;
+       pd   = qp->pd;
+       scq  = qp->send_cq;
+       rcq  = qp->recv_cq;
+       srq  = qp->srq;
+       xrcd = qp->xrcd;
 
        ret = qp->device->destroy_qp(qp);
        if (!ret) {
-               atomic_dec(&pd->usecnt);
-               atomic_dec(&scq->usecnt);
-               atomic_dec(&rcq->usecnt);
+               if (pd)
+                       atomic_dec(&pd->usecnt);
+               if (scq)
+                       atomic_dec(&scq->usecnt);
+               if (rcq)
+                       atomic_dec(&rcq->usecnt);
                if (srq)
                        atomic_dec(&srq->usecnt);
+               if (xrcd)
+                       atomic_dec(&xrcd->usecnt);
        }
 
        return ret;
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 2a85461..16a04ff 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -578,7 +578,11 @@ enum ib_qp_type {
        IB_QPT_UC,
        IB_QPT_UD,
        IB_QPT_RAW_IPV6,
-       IB_QPT_RAW_ETHERTYPE
+       IB_QPT_RAW_ETHERTYPE,
+       /* Save 8 for RAW_PACKET */
+       IB_QPT_XRC_INI = 9,
+       IB_QPT_XRC_TGT,
+       IB_QPT_MAX
 };
 
 enum ib_qp_create_flags {
@@ -592,6 +596,7 @@ struct ib_qp_init_attr {
        struct ib_cq           *send_cq;
        struct ib_cq           *recv_cq;
        struct ib_srq          *srq;
+       struct ib_xrcd         *xrcd;     /* XRC TGT QPs only */
        struct ib_qp_cap        cap;
        enum ib_sig_type        sq_sig_type;
        enum ib_qp_type         qp_type;
@@ -783,6 +788,7 @@ struct ib_send_wr {
                        u32                             rkey;
                } fast_reg;
        } wr;
+       u32                     xrc_remote_srq_num;     /* XRC TGT QPs only */
 };
 
 struct ib_recv_wr {
@@ -918,6 +924,7 @@ struct ib_qp {
        struct ib_cq           *send_cq;
        struct ib_cq           *recv_cq;
        struct ib_srq          *srq;
+       struct ib_xrcd         *xrcd; /* XRC TGT QPs only */
        struct ib_uobject      *uobject;
        void                  (*event_handler)(struct ib_event *, void *);
        void                   *qp_context;


--
To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to