srp_qp_in_err_timer_reconnect_target.patch - when detecting a post_send/post_receive error, srp set qp_in_error, set a timer to reconnect to target, return SCSI_MLQUEUE_HOST_BUSY to lock the queue, and return DID_NO_CONNECT when target state is DEAD or REMOVED

Signed-off-by: Vu Pham <[EMAIL PROTECTED]>

--- ofa_kernel-1.3.configured/drivers/infiniband/ulp/srp/ib_srp.c	2008-02-05 11:18:16.000000000 -0800
+++ ofa_kernel-1.3/drivers/infiniband/ulp/srp/ib_srp.c	2008-02-05 15:18:33.000000000 -0800
@@ -885,6 +884,26 @@
 				      DMA_FROM_DEVICE);
 }
 
+static void srp_reconnect_work(struct work_struct *work)
+{
+	struct srp_target_port *target =
+		container_of(work, struct srp_target_port, work);
+
+	srp_reconnect_target(target);
+}
+
+static void srp_qp_in_err_timer(unsigned long data)
+{
+	struct srp_target_port *target = (struct srp_target_port *)data;
+
+	spin_lock_irq(target->scsi_host->host_lock);
+	INIT_WORK(&target->work, srp_reconnect_work);
+	schedule_work(&target->work);
+	spin_unlock_irq(target->scsi_host->host_lock);
+
+	del_timer(&target->qp_err_timer);
+}
+
 static void srp_completion(struct ib_cq *cq, void *target_ptr)
 {
 	struct srp_target_port *target = target_ptr;
@@ -896,7 +915,16 @@
 			printk(KERN_ERR PFX "failed %s status %d\n",
 			       wc.wr_id & SRP_OP_RECV ? "receive" : "send",
 			       wc.status);
-			target->qp_in_error = 1;
+			if (!target->qp_in_error) {
+				target->qp_in_error = 1;
+				if (!timer_pending(&target->qp_err_timer)) {
+					setup_timer(&target->qp_err_timer,
+						    srp_qp_in_err_timer,
+						    (unsigned long)target);
+					target->qp_err_timer.expires = 10 * HZ + jiffies;
+					add_timer(&target->qp_err_timer);
+				}
+			}
 			break;
 		}
 
@@ -1004,12 +1032,13 @@
 	struct ib_device *dev;
 	int len;
 
-	if (target->state == SRP_TARGET_CONNECTING)
+	if (target->state == SRP_TARGET_CONNECTING ||
+	    target->qp_in_error)
 		goto err;
 
 	if (target->state == SRP_TARGET_DEAD ||
 	    target->state == SRP_TARGET_REMOVED) {
-		scmnd->result = DID_BAD_TARGET << 16;
+		scmnd->result = DID_NO_CONNECT << 16;
 		done(scmnd);
 		return 0;
 	}
--- ofa_kernel-1.3.configured/drivers/infiniband/ulp/srp/ib_srp.h	2008-02-05 11:18:16.000000000 -0800
+++ ofa_kernel-1.3/drivers/infiniband/ulp/srp/ib_srp.h	2008-02-05 11:20:49.000000000 -0800
@@ -160,6 +160,7 @@
 	int			status;
 	enum srp_target_state	state;
 	int			qp_in_error;
+	struct timer_list	qp_err_timer;
 };
 
 struct srp_iu {
_______________________________________________
ewg mailing list
ewg@lists.openfabrics.org
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/ewg

Reply via email to