[openib-general] [PATCH] IB/SRP identify QP in error state

Ishai Rabinovitz ishai at mellanox.co.il
Tue Sep 26 06:28:50 PDT 2006


There is a bug in mthca low level driver. 
A call to ib_post_send that tries to post to a QP that is in error state does
not return immediately with error. It terminates with errors after a timeout.

This causes SRP to wait a long time to reconnect. (Each abort call and
each reset_device call performs post_send and waits for the timeout).
The following patch solves this problem by identifying the failure 
and returning an immediate error code.

Signed-off-by: Ishai Rabinovitz <ishai at mellanox.co.il>
---
Index: last_stable/drivers/infiniband/ulp/srp/ib_srp.c
===================================================================
--- last_stable.orig/drivers/infiniband/ulp/srp/ib_srp.c	2006-09-25 13:51:47.000000000 +0300
+++ last_stable/drivers/infiniband/ulp/srp/ib_srp.c	2006-09-25 15:40:04.000000000 +0300
@@ -543,6 +543,7 @@ static int srp_reconnect_target(struct s
 	target->tx_head	 = 0;
 	target->tx_tail  = 0;
 
+	target->need_reset = 0;
 	ret = srp_connect_target(target);
 	if (ret)
 		goto err;
@@ -858,6 +859,7 @@ static void srp_completion(struct ib_cq 
 			printk(KERN_ERR PFX "failed %s status %d\n",
 			       wc.wr_id & SRP_OP_RECV ? "receive" : "send",
 			       wc.status);
+			target->need_reset = 1;
 			break;
 		}
 
@@ -1313,6 +1315,8 @@ static int srp_abort(struct scsi_cmnd *s
 
 	printk(KERN_ERR "SRP abort called\n");
 
+	if (target->need_reset)
+		return FAILED;
 	if (srp_find_req(target, scmnd, &req))
 		return FAILED;
 	if (srp_send_tsk_mgmt(target, req, SRP_TSK_ABORT_TASK))
@@ -1341,6 +1345,8 @@ static int srp_reset_device(struct scsi_
 
 	printk(KERN_ERR "SRP reset_device called\n");
 
+	if (target->need_reset)
+		return FAILED;
 	if (srp_find_req(target, scmnd, &req))
 		return FAILED;
 	if (srp_send_tsk_mgmt(target, req, SRP_TSK_LUN_RESET))
@@ -1750,6 +1756,7 @@ static ssize_t srp_create_target(struct 
 		goto err_free;
 	}
 
+	target->need_reset = 0;
 	ret = srp_connect_target(target);
 	if (ret) {
 		printk(KERN_ERR PFX "Connection failed\n");
Index: last_stable/drivers/infiniband/ulp/srp/ib_srp.h
===================================================================
--- last_stable.orig/drivers/infiniband/ulp/srp/ib_srp.h	2006-09-25 13:51:47.000000000 +0300
+++ last_stable/drivers/infiniband/ulp/srp/ib_srp.h	2006-09-25 14:00:36.000000000 +0300
@@ -158,6 +158,7 @@ struct srp_target_port {
 	struct completion	done;
 	int			status;
 	enum srp_target_state	state;
+	int			need_reset;
 };
 
 struct srp_iu {
-- 
Ishai Rabinovitz




More information about the general mailing list