RDMA/rxe: Lookup kernel AH from ah index in UD WQEs
authorBob Pearson <rpearsonhpe@gmail.com>
Thu, 7 Oct 2021 20:40:51 +0000 (15:40 -0500)
committerJason Gunthorpe <jgg@nvidia.com>
Tue, 12 Oct 2021 16:25:26 +0000 (13:25 -0300)
Add code to rxe_get_av in rxe_av.c to use the AH index in UD send WQEs to
lookup the kernel AH. For old user providers continue to use the AV passed
in WQEs. Move setting pkt->rxe to before the call to rxe_get_av() to get
access to the AH pool.

Link: https://lore.kernel.org/r/20211007204051.10086-6-rpearsonhpe@gmail.com
Signed-off-by: Bob Pearson <rpearsonhpe@gmail.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
drivers/infiniband/sw/rxe/rxe_av.c
drivers/infiniband/sw/rxe/rxe_req.c

index 85580ea5eed0d0b65e94570edd75d1ef9bb53903..38c7b6fb39d70256826cee71bf0b09c72730a86c 100644 (file)
@@ -101,11 +101,29 @@ void rxe_av_fill_ip_info(struct rxe_av *av, struct rdma_ah_attr *attr)
 
 struct rxe_av *rxe_get_av(struct rxe_pkt_info *pkt)
 {
+       struct rxe_ah *ah;
+       u32 ah_num;
+
        if (!pkt || !pkt->qp)
                return NULL;
 
        if (qp_type(pkt->qp) == IB_QPT_RC || qp_type(pkt->qp) == IB_QPT_UC)
                return &pkt->qp->pri_av;
 
-       return (pkt->wqe) ? &pkt->wqe->wr.wr.ud.av : NULL;
+       if (!pkt->wqe)
+               return NULL;
+
+       ah_num = pkt->wqe->wr.wr.ud.ah_num;
+       if (ah_num) {
+               /* only new user provider or kernel client */
+               ah = rxe_pool_get_index(&pkt->rxe->ah_pool, ah_num);
+               if (!ah || ah->ah_num != ah_num || rxe_ah_pd(ah) != pkt->qp->pd) {
+                       pr_warn("Unable to find AH matching ah_num\n");
+                       return NULL;
+               }
+               return &ah->av;
+       }
+
+       /* only old user provider for UD sends*/
+       return &pkt->wqe->wr.wr.ud.av;
 }
index fe275fcaffbd919ef282d2197497509c6ba01369..0c9d2af15f3d091af2c3a83d9b66606ddf17e783 100644 (file)
@@ -379,9 +379,8 @@ static struct sk_buff *init_req_packet(struct rxe_qp *qp,
        /* length from start of bth to end of icrc */
        paylen = rxe_opcode[opcode].length + payload + pad + RXE_ICRC_SIZE;
 
-       /* pkt->hdr, rxe, port_num and mask are initialized in ifc
-        * layer
-        */
+       /* pkt->hdr, port_num and mask are initialized in ifc layer */
+       pkt->rxe        = rxe;
        pkt->opcode     = opcode;
        pkt->qp         = qp;
        pkt->psn        = qp->req.psn;
@@ -391,6 +390,9 @@ static struct sk_buff *init_req_packet(struct rxe_qp *qp,
 
        /* init skb */
        av = rxe_get_av(pkt);
+       if (!av)
+               return NULL;
+
        skb = rxe_init_packet(rxe, av, paylen, pkt);
        if (unlikely(!skb))
                return NULL;