]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
RDMA/qib,hfi1: Fix MR reference count leak on write with immediate
authorMike Marciniszyn <mike.marciniszyn@intel.com>
Fri, 12 May 2017 16:02:00 +0000 (09:02 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 7 Jun 2017 10:10:12 +0000 (12:10 +0200)
commit 1feb40067cf04ae48d65f728d62ca255c9449178 upstream.

The handling of IB_RDMA_WRITE_ONLY_WITH_IMMEDIATE will leak a memory
reference when a buffer cannot be allocated for returning the immediate
data.

The issue is that the rkey validation has already occurred and the RNR
nak fails to release the reference that was fruitlessly gotten.  The
the peer will send the identical single packet request when its RNR
timer pops.

The fix is to release the held reference prior to the rnr nak exit.
This is the only sequence the requires both rkey validation and the
buffer allocation on the same packet.

Tested-by: Tadeusz Struk <tadeusz.struk@intel.com>
Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/infiniband/hw/hfi1/rc.c
drivers/infiniband/hw/qib/qib_rc.c

index 7382be11afcad663424a19e32608c1c1b39c79f7..aa71b73846404f9fbff38b003373994460a34a4d 100644 (file)
@@ -2149,8 +2149,11 @@ send_last:
                ret = hfi1_rvt_get_rwqe(qp, 1);
                if (ret < 0)
                        goto nack_op_err;
-               if (!ret)
+               if (!ret) {
+                       /* peer will send again */
+                       rvt_put_ss(&qp->r_sge);
                        goto rnr_nak;
+               }
                wc.ex.imm_data = ohdr->u.rc.imm_data;
                wc.wc_flags = IB_WC_WITH_IMM;
                goto send_last;
index 12658e3fe154c8a645daedea8f70ba5a1a69cebf..f7dfccf9a1e109dfda794f68cd74f093c5ed7b56 100644 (file)
@@ -1947,8 +1947,10 @@ send_last:
                ret = qib_get_rwqe(qp, 1);
                if (ret < 0)
                        goto nack_op_err;
-               if (!ret)
+               if (!ret) {
+                       rvt_put_ss(&qp->r_sge);
                        goto rnr_nak;
+               }
                wc.ex.imm_data = ohdr->u.rc.imm_data;
                hdrsize += 4;
                wc.wc_flags = IB_WC_WITH_IMM;