RDMA/rxe: Fill in wc byte_len with IB_WC_RECV_RDMA_WITH_IMM [Linux 4.9.187]

This Linux kernel change "RDMA/rxe: Fill in wc byte_len with IB_WC_RECV_RDMA_WITH_IMM" is included in the Linux 4.9.187 release. This change is authored by Konstantin Taranov <konstantin.taranov [at] inf.ethz.ch> on Thu Jun 27 16:06:43 2019 +0200. The commit for this change in Linux stable tree is 8baa8d6 (patch) which is from upstream commit bdce129. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream bdce129.

RDMA/rxe: Fill in wc byte_len with IB_WC_RECV_RDMA_WITH_IMM

[ Upstream commit bdce1290493caa3f8119f24b5dacc3fb7ca27389 ]

Calculate the correct byte_len on the receiving side when a work
completion is generated with IB_WC_RECV_RDMA_WITH_IMM opcode.

According to the IBA byte_len must indicate the number of written bytes,
whereas it was always equal to zero for the IB_WC_RECV_RDMA_WITH_IMM
opcode, even though data was transferred.

Fixes: 8700e3e7c485 ("Soft RoCE driver")
Signed-off-by: Konstantin Taranov <[email protected]>
Signed-off-by: Jason Gunthorpe <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>

There are 6 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 drivers/infiniband/sw/rxe/rxe_resp.c  | 5 ++++-
 drivers/infiniband/sw/rxe/rxe_verbs.h | 1 +
 2 files changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/infiniband/sw/rxe/rxe_resp.c b/drivers/infiniband/sw/rxe/rxe_resp.c
index 297653a..5bfea23 100644
--- a/drivers/infiniband/sw/rxe/rxe_resp.c
+++ b/drivers/infiniband/sw/rxe/rxe_resp.c
@@ -432,6 +432,7 @@ static enum resp_states check_rkey(struct rxe_qp *qp,
            qp->resp.va = reth_va(pkt);
            qp->resp.rkey = reth_rkey(pkt);
            qp->resp.resid = reth_len(pkt);
+           qp->resp.length = reth_len(pkt);
        }
        access = (pkt->mask & RXE_READ_MASK) ? IB_ACCESS_REMOTE_READ
                             : IB_ACCESS_REMOTE_WRITE;
@@ -841,7 +842,9 @@ static enum resp_states do_complete(struct rxe_qp *qp,
                pkt->mask & RXE_WRITE_MASK) ?
                    IB_WC_RECV_RDMA_WITH_IMM : IB_WC_RECV;
        wc->vendor_err = 0;
-       wc->byte_len = wqe->dma.length - wqe->dma.resid;
+       wc->byte_len = (pkt->mask & RXE_IMMDT_MASK &&
+               pkt->mask & RXE_WRITE_MASK) ?
+                   qp->resp.length : wqe->dma.length - wqe->dma.resid;

        /* fields after byte_len are different between kernel and user
         * space
diff --git a/drivers/infiniband/sw/rxe/rxe_verbs.h b/drivers/infiniband/sw/rxe/rxe_verbs.h
index cac1d52..47003d2 100644
--- a/drivers/infiniband/sw/rxe/rxe_verbs.h
+++ b/drivers/infiniband/sw/rxe/rxe_verbs.h
@@ -209,6 +209,7 @@ struct rxe_resp_info {
    struct rxe_mem      *mr;
    u32         resid;
    u32         rkey;
+   u32         length;
    u64         atomic_orig;

    /* SRQ only */

Leave a Reply

Your email address will not be published. Required fields are marked *