* allow scsi-ml to manage target queueing limits (v3)
@ 2008-08-17 20:24 michaelc
2008-08-17 20:24 ` [PATCH 1/6] scsi: Add helper code so transport classes/driver can control queueing (take 3) michaelc
0 siblings, 1 reply; 9+ messages in thread
From: michaelc @ 2008-08-17 20:24 UTC (permalink / raw)
To: linux-scsi
These next patches, made over scsi-misc, allow classes or drivers
to allow scsi-ml to control target/session/rport level queueing
limitations. This comes in handy for transitioning those structs states,
or if the hardware has a queueing limit at that level.
The only difference between v2 and v3 is that for the first patch,
0001-scsi-Add-helper-code-so-transport-classes-driver-ca.patch,
I rediffed it for scsi-misc which had some conflicting changes with
the old patch. And I readded patches for the fc and software iscsi drivers.
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH 1/6] scsi: Add helper code so transport classes/driver can control queueing (take 3)
2008-08-17 20:24 allow scsi-ml to manage target queueing limits (v3) michaelc
@ 2008-08-17 20:24 ` michaelc
2008-08-17 20:24 ` [PATCH 2/6] qla4xxx: return SCSI_MLQUEUE_TARGET_BUSY when driver has detected session error michaelc
0 siblings, 1 reply; 9+ messages in thread
From: michaelc @ 2008-08-17 20:24 UTC (permalink / raw)
To: linux-scsi; +Cc: Mike Christie
From: Mike Christie <michaelc@cs.wisc.edu>
SCSI-ml manages the queueing limits for the device and host, but
does not do so at the target level. However something something similar
can come in userful when a driver is transitioning a transport object to
the the blocked state, becuase at that time we do not want to queue
io and we do not want the queuecommand to be called again.
The patch adds code similar to the exisiting SCSI_ML_*BUSY handlers.
You can now return SCSI_MLQUEUE_TARGET_BUSY when we hit
a transport level queueing issue like the hw cannot allocate some
resource at the iscsi session/connection level, or the target has temporarily
closed or shrunk the queueing window, or if we are transitioning
to the blocked state.
bnx2i, when they rework their firmware according to netdev
developers requests, will also need to be able to limit queueing at this
level. bnx2i will hook into libiscsi, but will allocate a scsi host per
netdevice/hba, so unlike pure software iscsi/iser which is allocating
a host per session, it cannot set the scsi_host->can_queue and return
SCSI_MLQUEUE_HOST_BUSY to reflect queueing limits on the transport.
The iscsi class/driver can also set a scsi_target->can_queue value which
reflects the max commands the driver/class can support. For iscsi this
reflects the number of commands we can support for each session due to
session/connection hw limits, driver limits, and to also reflect the
session/targets's queueing window.
Changes:
v1 - initial patch.
v2 - Fix scsi_run_queue handling of multiple blocked targets.
Previously we would break from the main loop if a device was added back on
the starved list. We now run over the list and check if any target is
blocked.
v3 - Rediff for scsi-misc.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
---
drivers/scsi/scsi.c | 11 +++-
drivers/scsi/scsi_lib.c | 104 +++++++++++++++++++++++++++++++++++++-------
drivers/scsi/scsi_scan.c | 1 +
include/scsi/scsi.h | 1 +
include/scsi/scsi_device.h | 10 ++++
5 files changed, 108 insertions(+), 19 deletions(-)
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
index ee6be59..b622dba 100644
--- a/drivers/scsi/scsi.c
+++ b/drivers/scsi/scsi.c
@@ -756,9 +756,12 @@ int scsi_dispatch_cmd(struct scsi_cmnd *cmd)
if (rtn) {
if (scsi_delete_timer(cmd)) {
atomic_inc(&cmd->device->iodone_cnt);
- scsi_queue_insert(cmd,
- (rtn == SCSI_MLQUEUE_DEVICE_BUSY) ?
- rtn : SCSI_MLQUEUE_HOST_BUSY);
+
+ if (rtn != SCSI_MLQUEUE_DEVICE_BUSY &&
+ rtn != SCSI_MLQUEUE_TARGET_BUSY)
+ rtn = SCSI_MLQUEUE_HOST_BUSY;
+
+ scsi_queue_insert(cmd, rtn);
}
SCSI_LOG_MLQUEUE(3,
printk("queuecommand : request rejected\n"));
@@ -857,6 +860,7 @@ static struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd)
void scsi_finish_command(struct scsi_cmnd *cmd)
{
struct scsi_device *sdev = cmd->device;
+ struct scsi_target *starget = scsi_target(sdev);
struct Scsi_Host *shost = sdev->host;
struct scsi_driver *drv;
unsigned int good_bytes;
@@ -872,6 +876,7 @@ void scsi_finish_command(struct scsi_cmnd *cmd)
* XXX(hch): What about locking?
*/
shost->host_blocked = 0;
+ starget->target_blocked = 0;
sdev->device_blocked = 0;
/*
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index ff5d56b..dbb5c9e 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -114,6 +114,7 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
{
struct Scsi_Host *host = cmd->device->host;
struct scsi_device *device = cmd->device;
+ struct scsi_target *starget = scsi_target(device);
struct request_queue *q = device->request_queue;
unsigned long flags;
@@ -133,10 +134,17 @@ int scsi_queue_insert(struct scsi_cmnd *cmd, int reason)
* if a command is requeued with no other commands outstanding
* either for the device or for the host.
*/
- if (reason == SCSI_MLQUEUE_HOST_BUSY)
+ switch (reason) {
+ case SCSI_MLQUEUE_HOST_BUSY:
host->host_blocked = host->max_host_blocked;
- else if (reason == SCSI_MLQUEUE_DEVICE_BUSY)
+ break;
+ case SCSI_MLQUEUE_DEVICE_BUSY:
device->device_blocked = device->max_device_blocked;
+ break;
+ case SCSI_MLQUEUE_TARGET_BUSY:
+ starget->target_blocked = starget->max_target_blocked;
+ break;
+ }
/*
* Decrement the counters, since these commands are no longer
@@ -460,10 +468,12 @@ static void scsi_init_cmd_errh(struct scsi_cmnd *cmd)
void scsi_device_unbusy(struct scsi_device *sdev)
{
struct Scsi_Host *shost = sdev->host;
+ struct scsi_target *starget = scsi_target(sdev);
unsigned long flags;
spin_lock_irqsave(shost->host_lock, flags);
shost->host_busy--;
+ starget->target_busy--;
if (unlikely(scsi_host_in_recovery(shost) &&
(shost->host_failed || shost->host_eh_scheduled)))
scsi_eh_wakeup(shost);
@@ -519,6 +529,13 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev)
spin_unlock_irqrestore(shost->host_lock, flags);
}
+static inline int scsi_target_is_busy(struct scsi_target *starget)
+{
+ return ((starget->can_queue > 0 &&
+ starget->target_busy >= starget->can_queue) ||
+ starget->target_blocked);
+}
+
/*
* Function: scsi_run_queue()
*
@@ -533,7 +550,7 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev)
*/
static void scsi_run_queue(struct request_queue *q)
{
- struct scsi_device *sdev = q->queuedata;
+ struct scsi_device *starved_head = NULL, *sdev = q->queuedata;
struct Scsi_Host *shost = sdev->host;
unsigned long flags;
@@ -560,6 +577,21 @@ static void scsi_run_queue(struct request_queue *q)
*/
sdev = list_entry(shost->starved_list.next,
struct scsi_device, starved_entry);
+ /*
+ * The *queue_ready functions can add a device back onto the
+ * starved list's tail, so we must check for a infinite loop.
+ */
+ if (sdev == starved_head)
+ break;
+ if (!starved_head)
+ starved_head = sdev;
+
+ if (scsi_target_is_busy(scsi_target(sdev))) {
+ list_move_tail(&sdev->starved_entry,
+ &shost->starved_list);
+ continue;
+ }
+
list_del_init(&sdev->starved_entry);
spin_unlock(shost->host_lock);
@@ -575,13 +607,6 @@ static void scsi_run_queue(struct request_queue *q)
spin_unlock(sdev->request_queue->queue_lock);
spin_lock(shost->host_lock);
- if (unlikely(!list_empty(&sdev->starved_entry)))
- /*
- * sdev lost a race, and was put back on the
- * starved list. This is unlikely but without this
- * in theory we could loop forever.
- */
- break;
}
spin_unlock_irqrestore(shost->host_lock, flags);
@@ -1343,6 +1368,52 @@ static inline int scsi_dev_queue_ready(struct request_queue *q,
return 1;
}
+
+/*
+ * scsi_target_queue_ready: checks if there we can send commands to target
+ * @sdev: scsi device on starget to check.
+ *
+ * Called with the host lock held.
+ */
+static inline int scsi_target_queue_ready(struct Scsi_Host *shost,
+ struct scsi_device *sdev)
+{
+ struct scsi_target *starget = scsi_target(sdev);
+
+ if (starget->single_lun) {
+ if (starget->starget_sdev_user &&
+ starget->starget_sdev_user != sdev)
+ return 0;
+ starget->starget_sdev_user = sdev;
+ }
+
+ if (starget->target_busy == 0 && starget->target_blocked) {
+ /*
+ * unblock after target_blocked iterates to zero
+ */
+ if (--starget->target_blocked == 0) {
+ SCSI_LOG_MLQUEUE(3, starget_printk(KERN_INFO, starget,
+ "unblocking target at zero depth\n"));
+ } else {
+ blk_plug_device(sdev->request_queue);
+ return 0;
+ }
+ }
+
+ if (scsi_target_is_busy(starget)) {
+ if (list_empty(&sdev->starved_entry)) {
+ list_add_tail(&sdev->starved_entry,
+ &shost->starved_list);
+ return 0;
+ }
+ }
+
+ /* We're OK to process the command, so we can't be starved */
+ if (!list_empty(&sdev->starved_entry))
+ list_del_init(&sdev->starved_entry);
+ return 1;
+}
+
/*
* scsi_host_queue_ready: if we can send requests to shost, return 1 else
* return 0. We must end up running the queue again whenever 0 is
@@ -1389,6 +1460,7 @@ static void scsi_kill_request(struct request *req, struct request_queue *q)
{
struct scsi_cmnd *cmd = req->special;
struct scsi_device *sdev = cmd->device;
+ struct scsi_target *starget = scsi_target(sdev);
struct Scsi_Host *shost = sdev->host;
blkdev_dequeue_request(req);
@@ -1412,6 +1484,7 @@ static void scsi_kill_request(struct request *req, struct request_queue *q)
spin_unlock(sdev->request_queue->queue_lock);
spin_lock(shost->host_lock);
shost->host_busy++;
+ starget->target_busy++;
spin_unlock(shost->host_lock);
spin_lock(sdev->request_queue->queue_lock);
@@ -1540,14 +1613,13 @@ static void scsi_request_fn(struct request_queue *q)
goto not_ready;
}
+ if (!scsi_target_queue_ready(shost, sdev))
+ goto not_ready;
+
if (!scsi_host_queue_ready(q, shost, sdev))
goto not_ready;
- if (scsi_target(sdev)->single_lun) {
- if (scsi_target(sdev)->starget_sdev_user &&
- scsi_target(sdev)->starget_sdev_user != sdev)
- goto not_ready;
- scsi_target(sdev)->starget_sdev_user = sdev;
- }
+
+ scsi_target(sdev)->target_busy++;
shost->host_busy++;
/*
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index 84b4879..a705c3a 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -419,6 +419,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent,
dev->type = &scsi_target_type;
starget->id = id;
starget->channel = channel;
+ starget->can_queue = 0;
INIT_LIST_HEAD(&starget->siblings);
INIT_LIST_HEAD(&starget->devices);
starget->state = STARGET_CREATED;
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index 5c40cc5..a523b28 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -412,6 +412,7 @@ struct scsi_lun {
#define SCSI_MLQUEUE_HOST_BUSY 0x1055
#define SCSI_MLQUEUE_DEVICE_BUSY 0x1056
#define SCSI_MLQUEUE_EH_RETRY 0x1057
+#define SCSI_MLQUEUE_TARGET_BUSY 0x1058
/*
* Use these to separate status msg and our bytes
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index 291d56a..a6a032e 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -235,6 +235,16 @@ struct scsi_target {
* for the device at a time. */
unsigned int pdt_1f_for_no_lun; /* PDT = 0x1f */
/* means no lun present */
+ /* commands actually active on LLD. protected by host lock. */
+ unsigned int target_busy;
+ /*
+ * LLDs should set this in the slave_alloc host template callout.
+ * If set to zero then there is not limit.
+ */
+ unsigned int can_queue;
+ unsigned int target_blocked;
+ unsigned int max_target_blocked;
+#define SCSI_DEFAULT_TARGET_BLOCKED 3
char scsi_level;
struct execute_work ew;
--
1.5.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 2/6] qla4xxx: return SCSI_MLQUEUE_TARGET_BUSY when driver has detected session error
2008-08-17 20:24 ` [PATCH 1/6] scsi: Add helper code so transport classes/driver can control queueing (take 3) michaelc
@ 2008-08-17 20:24 ` michaelc
2008-08-17 20:24 ` [PATCH 3/6] qla2xxx: return SCSI_MLQUEUE_TARGET_BUSY when driver has detected rport error or race michaelc
0 siblings, 1 reply; 9+ messages in thread
From: michaelc @ 2008-08-17 20:24 UTC (permalink / raw)
To: linux-scsi; +Cc: Mike Christie
From: Mike Christie <michaelc@cs.wisc.edu>
When qla4xxx begins recovery and the iscsi class is firing up to handle
it, we need to retrn SCSI_MLQUEUE_TARGET_BUSY from the driver instead
of host busy, because the session recovery only affects the one target.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Acked-by: David C Somayajulu <david.somayajulu@qlogic.com>
---
drivers/scsi/qla4xxx/ql4_os.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index 88bebb1..ddcb297 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -439,7 +439,7 @@ static int qla4xxx_queuecommand(struct scsi_cmnd *cmd,
cmd->result = DID_NO_CONNECT << 16;
goto qc_fail_command;
}
- goto qc_host_busy;
+ return SCSI_MLQUEUE_TARGET_BUSY;
}
if (test_bit(DPC_RESET_HA_INTR, &ha->dpc_flags))
--
1.5.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 3/6] qla2xxx: return SCSI_MLQUEUE_TARGET_BUSY when driver has detected rport error or race
2008-08-17 20:24 ` [PATCH 2/6] qla4xxx: return SCSI_MLQUEUE_TARGET_BUSY when driver has detected session error michaelc
@ 2008-08-17 20:24 ` michaelc
2008-08-17 20:24 ` [PATCH 4/6] lpfc: use SCSI_MLQUEUE_TARGET_BUSY when catching the rport transition race michaelc
2008-08-19 16:16 ` [PATCH 3/6] qla2xxx: return SCSI_MLQUEUE_TARGET_BUSY when driver has detected rport error or race Andrew Vasquez
0 siblings, 2 replies; 9+ messages in thread
From: michaelc @ 2008-08-17 20:24 UTC (permalink / raw)
To: linux-scsi; +Cc: Mike Christie, Andrew Vasquez
From: Mike Christie <michaelc@cs.wisc.edu>
If the fcport is not online then we do not want to block IO to all ports on
the host. We just want to stop IO on port not online, so we should be using
the SCSI_MLQUEUE_TARGET_BUSY return value.
For the case where we race with the rport memset initialization
we do not want the queuecommand to be called again so we can just use
SCSI_MLQUEUE_TARGET_BUSY for this.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Cc: Andrew Vasquez <andrew.vasquez@qlogic.com>
---
drivers/scsi/qla2xxx/qla_os.c | 26 ++++++++++++--------------
1 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index 7c8af7e..a5888f8 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -394,10 +394,8 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
}
/* Close window on fcport/rport state-transitioning. */
- if (fcport->drport) {
- cmd->result = DID_IMM_RETRY << 16;
- goto qc_fail_command;
- }
+ if (fcport->drport)
+ goto qc_target_busy;
if (atomic_read(&fcport->state) != FCS_ONLINE) {
if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
@@ -405,7 +403,7 @@ qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
cmd->result = DID_NO_CONNECT << 16;
goto qc_fail_command;
}
- goto qc_host_busy;
+ goto qc_target_busy;
}
spin_unlock_irq(ha->host->host_lock);
@@ -428,10 +426,11 @@ qc_host_busy_free_sp:
qc_host_busy_lock:
spin_lock_irq(ha->host->host_lock);
-
-qc_host_busy:
return SCSI_MLQUEUE_HOST_BUSY;
+qc_target_busy:
+ return SCSI_MLQUEUE_TARGET_BUSY;
+
qc_fail_command:
done(cmd);
@@ -461,10 +460,8 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
}
/* Close window on fcport/rport state-transitioning. */
- if (fcport->drport) {
- cmd->result = DID_IMM_RETRY << 16;
- goto qc24_fail_command;
- }
+ if (fcport->drport)
+ goto qc24_target_busy;
if (atomic_read(&fcport->state) != FCS_ONLINE) {
if (atomic_read(&fcport->state) == FCS_DEVICE_DEAD ||
@@ -472,7 +469,7 @@ qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
cmd->result = DID_NO_CONNECT << 16;
goto qc24_fail_command;
}
- goto qc24_host_busy;
+ goto qc24_target_busy;
}
spin_unlock_irq(ha->host->host_lock);
@@ -495,10 +492,11 @@ qc24_host_busy_free_sp:
qc24_host_busy_lock:
spin_lock_irq(ha->host->host_lock);
-
-qc24_host_busy:
return SCSI_MLQUEUE_HOST_BUSY;
+qc24_target_busy:
+ return SCSI_MLQUEUE_TARGET_BUSY;
+
qc24_fail_command:
done(cmd);
--
1.5.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 4/6] lpfc: use SCSI_MLQUEUE_TARGET_BUSY when catching the rport transition race
2008-08-17 20:24 ` [PATCH 3/6] qla2xxx: return SCSI_MLQUEUE_TARGET_BUSY when driver has detected rport error or race michaelc
@ 2008-08-17 20:24 ` michaelc
2008-08-17 20:24 ` [PATCH 5/6] mptfc: " michaelc
2008-08-19 15:27 ` [PATCH 4/6] lpfc: use SCSI_MLQUEUE_TARGET_BUSY when catching the rport transition race James Smart
2008-08-19 16:16 ` [PATCH 3/6] qla2xxx: return SCSI_MLQUEUE_TARGET_BUSY when driver has detected rport error or race Andrew Vasquez
1 sibling, 2 replies; 9+ messages in thread
From: michaelc @ 2008-08-17 20:24 UTC (permalink / raw)
To: linux-scsi; +Cc: Mike Christie, James Smart
From: Mike Christie <michaelc@cs.wisc.edu>
We do want to call right back into the queuecommand during the race,
so we can just use SCSI_MLQUEUE_TARGET_BUSY.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Cc: James Smart <James.Smart@Emulex.Com>
---
drivers/scsi/lpfc/lpfc_scsi.c | 9 +++++----
1 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index 1bcebbd..a22bdf9 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -966,10 +966,9 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
* Catch race where our node has transitioned, but the
* transport is still transitioning.
*/
- if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
- cmnd->result = ScsiResult(DID_BUS_BUSY, 0);
- goto out_fail_command;
- }
+ if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
+ goto out_target_busy;
+
lpfc_cmd = lpfc_get_scsi_buf(phba);
if (lpfc_cmd == NULL) {
lpfc_adjust_queue_depth(phba);
@@ -1014,6 +1013,8 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
lpfc_release_scsi_buf(phba, lpfc_cmd);
out_host_busy:
return SCSI_MLQUEUE_HOST_BUSY;
+ out_target_busy:
+ return SCSI_MLQUEUE_TARGET_BUSY;
out_fail_command:
done(cmnd);
--
1.5.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 5/6] mptfc: use SCSI_MLQUEUE_TARGET_BUSY when catching the rport transition race
2008-08-17 20:24 ` [PATCH 4/6] lpfc: use SCSI_MLQUEUE_TARGET_BUSY when catching the rport transition race michaelc
@ 2008-08-17 20:24 ` michaelc
2008-08-17 20:24 ` [PATCH 6/6] libiscsi: Use SCSI_MLQUEUE_TARGET_BUSY michaelc
2008-08-19 15:27 ` [PATCH 4/6] lpfc: use SCSI_MLQUEUE_TARGET_BUSY when catching the rport transition race James Smart
1 sibling, 1 reply; 9+ messages in thread
From: michaelc @ 2008-08-17 20:24 UTC (permalink / raw)
To: linux-scsi; +Cc: Mike Christie, Eric Moore, Michael Reed
From: Mike Christie <michaelc@cs.wisc.edu>
We do want to call right back into the queuecommand during the race,
so we can just use SCSI_MLQUEUE_TARGET_BUSY.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Cc: Eric Moore <Eric.Moore@lsi.com>
Cc: Michael Reed <mdr@sgi.com>
---
drivers/message/fusion/mptfc.c | 7 ++-----
1 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index c3c24fd..e9ab90f 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -665,11 +665,8 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
/* dd_data is null until finished adding target */
ri = *((struct mptfc_rport_info **)rport->dd_data);
- if (unlikely(!ri)) {
- SCpnt->result = DID_IMM_RETRY << 16;
- done(SCpnt);
- return 0;
- }
+ if (unlikely(!ri))
+ return SCSI_MLQUEUE_HOST_BUSY;
return mptscsih_qcmd(SCpnt,done);
}
--
1.5.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH 6/6] libiscsi: Use SCSI_MLQUEUE_TARGET_BUSY
2008-08-17 20:24 ` [PATCH 5/6] mptfc: " michaelc
@ 2008-08-17 20:24 ` michaelc
0 siblings, 0 replies; 9+ messages in thread
From: michaelc @ 2008-08-17 20:24 UTC (permalink / raw)
To: linux-scsi; +Cc: Mike Christie
From: Mike Christie <michaelc@cs.wisc.edu>
For the conditions below we do not want the queuecommand
function to call us right back, so return SCSI_MLQUEUE_TARGET_BUSY.
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
---
drivers/scsi/libiscsi.c | 8 +++-----
1 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 299e075..fcb0de9 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -1194,12 +1194,10 @@ int iscsi_queuecommand(struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
switch (session->state) {
case ISCSI_STATE_IN_RECOVERY:
reason = FAILURE_SESSION_IN_RECOVERY;
- sc->result = DID_IMM_RETRY << 16;
- break;
+ goto reject;
case ISCSI_STATE_LOGGING_OUT:
reason = FAILURE_SESSION_LOGGING_OUT;
- sc->result = DID_IMM_RETRY << 16;
- break;
+ goto reject;
case ISCSI_STATE_RECOVERY_FAILED:
reason = FAILURE_SESSION_RECOVERY_TIMEOUT;
sc->result = DID_NO_CONNECT << 16;
@@ -1267,7 +1265,7 @@ reject:
spin_unlock(&session->lock);
debug_scsi("cmd 0x%x rejected (%d)\n", sc->cmnd[0], reason);
spin_lock(host->host_lock);
- return SCSI_MLQUEUE_HOST_BUSY;
+ return SCSI_MLQUEUE_TARGET_BUSY;
fault:
spin_unlock(&session->lock);
--
1.5.4.1
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH 4/6] lpfc: use SCSI_MLQUEUE_TARGET_BUSY when catching the rport transition race
2008-08-17 20:24 ` [PATCH 4/6] lpfc: use SCSI_MLQUEUE_TARGET_BUSY when catching the rport transition race michaelc
2008-08-17 20:24 ` [PATCH 5/6] mptfc: " michaelc
@ 2008-08-19 15:27 ` James Smart
1 sibling, 0 replies; 9+ messages in thread
From: James Smart @ 2008-08-19 15:27 UTC (permalink / raw)
To: michaelc@cs.wisc.edu; +Cc: linux-scsi@vger.kernel.org
Ack
-- james s
michaelc@cs.wisc.edu wrote:
> From: Mike Christie <michaelc@cs.wisc.edu>
>
> We do want to call right back into the queuecommand during the race,
> so we can just use SCSI_MLQUEUE_TARGET_BUSY.
>
> Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
> Cc: James Smart <James.Smart@Emulex.Com>
>
> ---
> drivers/scsi/lpfc/lpfc_scsi.c | 9 +++++----
> 1 files changed, 5 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH 3/6] qla2xxx: return SCSI_MLQUEUE_TARGET_BUSY when driver has detected rport error or race
2008-08-17 20:24 ` [PATCH 3/6] qla2xxx: return SCSI_MLQUEUE_TARGET_BUSY when driver has detected rport error or race michaelc
2008-08-17 20:24 ` [PATCH 4/6] lpfc: use SCSI_MLQUEUE_TARGET_BUSY when catching the rport transition race michaelc
@ 2008-08-19 16:16 ` Andrew Vasquez
1 sibling, 0 replies; 9+ messages in thread
From: Andrew Vasquez @ 2008-08-19 16:16 UTC (permalink / raw)
To: michaelc; +Cc: linux-scsi
On Sun, 17 Aug 2008, michaelc@cs.wisc.edu wrote:
> From: Mike Christie <michaelc@cs.wisc.edu>
>
> If the fcport is not online then we do not want to block IO to all ports on
> the host. We just want to stop IO on port not online, so we should be using
> the SCSI_MLQUEUE_TARGET_BUSY return value.
>
> For the case where we race with the rport memset initialization
> we do not want the queuecommand to be called again so we can just use
> SCSI_MLQUEUE_TARGET_BUSY for this.
>
> Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
> Cc: Andrew Vasquez <andrew.vasquez@qlogic.com>
Acked-by: Andrew Vasquez <andrew.vasquez@qlogic.com>
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2008-08-19 16:16 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-08-17 20:24 allow scsi-ml to manage target queueing limits (v3) michaelc
2008-08-17 20:24 ` [PATCH 1/6] scsi: Add helper code so transport classes/driver can control queueing (take 3) michaelc
2008-08-17 20:24 ` [PATCH 2/6] qla4xxx: return SCSI_MLQUEUE_TARGET_BUSY when driver has detected session error michaelc
2008-08-17 20:24 ` [PATCH 3/6] qla2xxx: return SCSI_MLQUEUE_TARGET_BUSY when driver has detected rport error or race michaelc
2008-08-17 20:24 ` [PATCH 4/6] lpfc: use SCSI_MLQUEUE_TARGET_BUSY when catching the rport transition race michaelc
2008-08-17 20:24 ` [PATCH 5/6] mptfc: " michaelc
2008-08-17 20:24 ` [PATCH 6/6] libiscsi: Use SCSI_MLQUEUE_TARGET_BUSY michaelc
2008-08-19 15:27 ` [PATCH 4/6] lpfc: use SCSI_MLQUEUE_TARGET_BUSY when catching the rport transition race James Smart
2008-08-19 16:16 ` [PATCH 3/6] qla2xxx: return SCSI_MLQUEUE_TARGET_BUSY when driver has detected rport error or race Andrew Vasquez
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).