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