Commit d1cff222 authored by Mike Marciniszyn's avatar Mike Marciniszyn Committed by Greg Kroah-Hartman

RDMA/qib,hfi1: Fix MR reference count leak on write with immediate

commit 1feb4006 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: default avatarTadeusz Struk <tadeusz.struk@intel.com>
Reviewed-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarMike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: default avatarDennis Dalessandro <dennis.dalessandro@intel.com>
Signed-off-by: default avatarDoug Ledford <dledford@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 292f70cd
...@@ -2366,8 +2366,11 @@ void hfi1_rc_rcv(struct hfi1_packet *packet) ...@@ -2366,8 +2366,11 @@ void hfi1_rc_rcv(struct hfi1_packet *packet)
ret = hfi1_rvt_get_rwqe(qp, 1); ret = hfi1_rvt_get_rwqe(qp, 1);
if (ret < 0) if (ret < 0)
goto nack_op_err; goto nack_op_err;
if (!ret) if (!ret) {
/* peer will send again */
rvt_put_ss(&qp->r_sge);
goto rnr_nak; goto rnr_nak;
}
wc.ex.imm_data = ohdr->u.rc.imm_data; wc.ex.imm_data = ohdr->u.rc.imm_data;
wc.wc_flags = IB_WC_WITH_IMM; wc.wc_flags = IB_WC_WITH_IMM;
goto send_last; goto send_last;
......
...@@ -2067,8 +2067,10 @@ void qib_rc_rcv(struct qib_ctxtdata *rcd, struct ib_header *hdr, ...@@ -2067,8 +2067,10 @@ void qib_rc_rcv(struct qib_ctxtdata *rcd, struct ib_header *hdr,
ret = qib_get_rwqe(qp, 1); ret = qib_get_rwqe(qp, 1);
if (ret < 0) if (ret < 0)
goto nack_op_err; goto nack_op_err;
if (!ret) if (!ret) {
rvt_put_ss(&qp->r_sge);
goto rnr_nak; goto rnr_nak;
}
wc.ex.imm_data = ohdr->u.rc.imm_data; wc.ex.imm_data = ohdr->u.rc.imm_data;
hdrsize += 4; hdrsize += 4;
wc.wc_flags = IB_WC_WITH_IMM; wc.wc_flags = IB_WC_WITH_IMM;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment