[PATCH for-rc] IB/isert: Fix hang in iscsit_wait_for_tag

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Mustafa Ismail <mustafa.ismail@xxxxxxxxx>

Running fio can occasionally cause a hang when sbitmap_queue_get() fails to
return a tag in iscsit_allocate_cmd() and iscsit_wait_for_tag() is called
and will never return from the schedule(). This is because the polling
thread of the CQ is suspended, and will not poll for a SQ completion which
would free up a tag.
Fix this by creating a separate CQ for the SQ so that send completions are
processed on a separate thread and are not blocked when the RQ CQ is
stalled.

Fixes: 10e9cbb6b531 ("scsi: target: Convert target drivers to use sbitmap")
Reviewed-by: Mike Marciniszyn <mike.marciniszyn@xxxxxxxxx>
Signed-off-by: Mustafa Ismail <mustafa.ismail@xxxxxxxxx>
Signed-off-by: Shiraz Saleem <shiraz.saleem@xxxxxxxxx>
---
 drivers/infiniband/ulp/isert/ib_isert.c | 33 +++++++++++++++++++++++----------
 drivers/infiniband/ulp/isert/ib_isert.h |  3 ++-
 2 files changed, 25 insertions(+), 11 deletions(-)

diff --git a/drivers/infiniband/ulp/isert/ib_isert.c b/drivers/infiniband/ulp/isert/ib_isert.c
index 7540488..f827b91 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.c
+++ b/drivers/infiniband/ulp/isert/ib_isert.c
@@ -109,19 +109,27 @@ static int isert_sg_tablesize_set(const char *val, const struct kernel_param *kp
 	struct ib_qp_init_attr attr;
 	int ret, factor;
 
-	isert_conn->cq = ib_cq_pool_get(ib_dev, cq_size, -1, IB_POLL_WORKQUEUE);
-	if (IS_ERR(isert_conn->cq)) {
-		isert_err("Unable to allocate cq\n");
-		ret = PTR_ERR(isert_conn->cq);
+	isert_conn->snd_cq = ib_cq_pool_get(ib_dev, cq_size, -1,
+					    IB_POLL_WORKQUEUE);
+	if (IS_ERR(isert_conn->snd_cq)) {
+		isert_err("Unable to allocate send cq\n");
+		ret = PTR_ERR(isert_conn->snd_cq);
 		return ERR_PTR(ret);
 	}
+	isert_conn->rcv_cq = ib_cq_pool_get(ib_dev, cq_size, -1,
+					    IB_POLL_WORKQUEUE);
+	if (IS_ERR(isert_conn->rcv_cq)) {
+		isert_err("Unable to allocate receive cq\n");
+		ret = PTR_ERR(isert_conn->rcv_cq);
+		goto create_cq_err;
+	}
 	isert_conn->cq_size = cq_size;
 
 	memset(&attr, 0, sizeof(struct ib_qp_init_attr));
 	attr.event_handler = isert_qp_event_callback;
 	attr.qp_context = isert_conn;
-	attr.send_cq = isert_conn->cq;
-	attr.recv_cq = isert_conn->cq;
+	attr.send_cq = isert_conn->snd_cq;
+	attr.recv_cq = isert_conn->rcv_cq;
 	attr.cap.max_send_wr = ISERT_QP_MAX_REQ_DTOS + 1;
 	attr.cap.max_recv_wr = ISERT_QP_MAX_RECV_DTOS + 1;
 	factor = rdma_rw_mr_factor(device->ib_device, cma_id->port_num,
@@ -137,12 +145,16 @@ static int isert_sg_tablesize_set(const char *val, const struct kernel_param *kp
 	ret = rdma_create_qp(cma_id, device->pd, &attr);
 	if (ret) {
 		isert_err("rdma_create_qp failed for cma_id %d\n", ret);
-		ib_cq_pool_put(isert_conn->cq, isert_conn->cq_size);
-
-		return ERR_PTR(ret);
+		goto create_qp_err;
 	}
 
 	return cma_id->qp;
+create_qp_err:
+	ib_cq_pool_put(isert_conn->rcv_cq, isert_conn->cq_size);
+create_cq_err:
+	ib_cq_pool_put(isert_conn->snd_cq, isert_conn->cq_size);
+
+	return ERR_PTR(ret);
 }
 
 static int
@@ -409,7 +421,8 @@ static int isert_sg_tablesize_set(const char *val, const struct kernel_param *kp
 isert_destroy_qp(struct isert_conn *isert_conn)
 {
 	ib_destroy_qp(isert_conn->qp);
-	ib_cq_pool_put(isert_conn->cq, isert_conn->cq_size);
+	ib_cq_pool_put(isert_conn->snd_cq, isert_conn->cq_size);
+	ib_cq_pool_put(isert_conn->rcv_cq, isert_conn->cq_size);
 }
 
 static int
diff --git a/drivers/infiniband/ulp/isert/ib_isert.h b/drivers/infiniband/ulp/isert/ib_isert.h
index 0b2dfd6..0cd43af 100644
--- a/drivers/infiniband/ulp/isert/ib_isert.h
+++ b/drivers/infiniband/ulp/isert/ib_isert.h
@@ -180,7 +180,8 @@ struct isert_conn {
 	struct iser_tx_desc	login_tx_desc;
 	struct rdma_cm_id	*cm_id;
 	struct ib_qp		*qp;
-	struct ib_cq		*cq;
+	struct ib_cq		*snd_cq;
+	struct ib_cq		*rcv_cq;
 	u32			cq_size;
 	struct isert_device	*device;
 	struct mutex		mutex;
-- 
1.8.3.1




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux