浏览代码

IB/qib: Fix UC MR refs for immediate operations

An MR reference leak exists when handling UC RDMA writes with
immediate data because we manipulate the reference counts as if the
operation had been a send.

This patch moves the last_imm label so that the RDMA write operations
with immediate data converge at the cq building code.  The copy/mr
deref code is now done correctly prior to the branch to last_imm.

Reviewed-by: Edward Mascarenhas <edward.mascarenhas@intel.com>
Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com>
Signed-off-by: Roland Dreier <roland@purestorage.com>
Mike Marciniszyn 13 年之前
父节点
当前提交
354dff1bd8
共有 1 个文件被更改,包括 7 次插入1 次删除
  1. 7 1
      drivers/infiniband/hw/qib/qib_uc.c

+ 7 - 1
drivers/infiniband/hw/qib/qib_uc.c

@@ -403,7 +403,6 @@ send_last:
 		if (unlikely(wc.byte_len > qp->r_len))
 		if (unlikely(wc.byte_len > qp->r_len))
 			goto rewind;
 			goto rewind;
 		wc.opcode = IB_WC_RECV;
 		wc.opcode = IB_WC_RECV;
-last_imm:
 		qib_copy_sge(&qp->r_sge, data, tlen, 0);
 		qib_copy_sge(&qp->r_sge, data, tlen, 0);
 		while (qp->s_rdma_read_sge.num_sge) {
 		while (qp->s_rdma_read_sge.num_sge) {
 			atomic_dec(&qp->s_rdma_read_sge.sge.mr->refcount);
 			atomic_dec(&qp->s_rdma_read_sge.sge.mr->refcount);
@@ -411,6 +410,7 @@ last_imm:
 				qp->s_rdma_read_sge.sge =
 				qp->s_rdma_read_sge.sge =
 					*qp->s_rdma_read_sge.sg_list++;
 					*qp->s_rdma_read_sge.sg_list++;
 		}
 		}
+last_imm:
 		wc.wr_id = qp->r_wr_id;
 		wc.wr_id = qp->r_wr_id;
 		wc.status = IB_WC_SUCCESS;
 		wc.status = IB_WC_SUCCESS;
 		wc.qp = &qp->ibqp;
 		wc.qp = &qp->ibqp;
@@ -509,6 +509,12 @@ rdma_last_imm:
 		}
 		}
 		wc.byte_len = qp->r_len;
 		wc.byte_len = qp->r_len;
 		wc.opcode = IB_WC_RECV_RDMA_WITH_IMM;
 		wc.opcode = IB_WC_RECV_RDMA_WITH_IMM;
+		qib_copy_sge(&qp->r_sge, data, tlen, 1);
+		while (qp->r_sge.num_sge) {
+			atomic_dec(&qp->r_sge.sge.mr->refcount);
+			if (--qp->r_sge.num_sge)
+				qp->r_sge.sge = *qp->r_sge.sg_list++;
+		}
 		goto last_imm;
 		goto last_imm;
 
 
 	case OP(RDMA_WRITE_LAST):
 	case OP(RDMA_WRITE_LAST):