* [PATCH 1/3] snic: reserve tag for TMF
2021-08-19 9:12 [PATCH 0/3] snic: Fixes for SCSI EH rework Hannes Reinecke
@ 2021-08-19 9:12 ` Hannes Reinecke
2021-08-20 10:00 ` Christoph Hellwig
2021-08-19 9:12 ` [PATCH 2/3] snic: use dedicated device reset command Hannes Reinecke
2021-08-19 9:12 ` [PATCH 3/3] snic: Use scsi_host_busy_iter() to traverse commands Hannes Reinecke
2 siblings, 1 reply; 6+ messages in thread
From: Hannes Reinecke @ 2021-08-19 9:12 UTC (permalink / raw)
To: Martin K. Petersen
Cc: Christoph Hellwig, James Bottomley, linux-scsi, Hannes Reinecke,
Hannes Reinecke
Rather than re-using the failed command the snic driver should
reserve one command for TMFs.
Signed-off-by: Hannes Reinecke <hare@suse.com>
---
drivers/scsi/snic/snic.h | 3 ++-
drivers/scsi/snic/snic_main.c | 3 +++
drivers/scsi/snic/snic_scsi.c | 51 +++++++++++++++--------------------
3 files changed, 26 insertions(+), 31 deletions(-)
diff --git a/drivers/scsi/snic/snic.h b/drivers/scsi/snic/snic.h
index f4c666285bba..f88ecf73f708 100644
--- a/drivers/scsi/snic/snic.h
+++ b/drivers/scsi/snic/snic.h
@@ -310,6 +310,7 @@ struct snic {
struct list_head spl_cmd_list;
unsigned int max_tag_id;
+ unsigned int tmf_tag_id;
atomic_t ios_inflight; /* io in flight counter */
struct vnic_snic_config config;
@@ -380,7 +381,7 @@ int snic_queuecommand(struct Scsi_Host *, struct scsi_cmnd *);
int snic_abort_cmd(struct scsi_cmnd *);
int snic_device_reset(struct scsi_cmnd *);
int snic_host_reset(struct scsi_cmnd *);
-int snic_reset(struct Scsi_Host *, struct scsi_cmnd *);
+int snic_reset(struct Scsi_Host *);
void snic_shutdown_scsi_cleanup(struct snic *);
diff --git a/drivers/scsi/snic/snic_main.c b/drivers/scsi/snic/snic_main.c
index 14f4ce665e58..65f50057c66e 100644
--- a/drivers/scsi/snic/snic_main.c
+++ b/drivers/scsi/snic/snic_main.c
@@ -512,6 +512,9 @@ snic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
max_t(u32, SNIC_MIN_IO_REQ, max_ios));
snic->max_tag_id = shost->can_queue;
+ /* Reserve one reset command */
+ shost->can_queue--;
+ snic->tmf_tag_id = shost->can_queue;
shost->max_lun = snic->config.luns_per_tgt;
shost->max_id = SNIC_MAX_TARGET;
diff --git a/drivers/scsi/snic/snic_scsi.c b/drivers/scsi/snic/snic_scsi.c
index 6dd0ff188bb4..1e59d59130d6 100644
--- a/drivers/scsi/snic/snic_scsi.c
+++ b/drivers/scsi/snic/snic_scsi.c
@@ -1021,17 +1021,6 @@ snic_hba_reset_cmpl_handler(struct snic *snic, struct snic_fw_req *fwreq)
"reset_cmpl: type = %x, hdr_stat = %x, cmnd_id = %x, hid = %x, ctx = %lx\n",
typ, hdr_stat, cmnd_id, hid, ctx);
- /* spl case, host reset issued through ioctl */
- if (cmnd_id == SCSI_NO_TAG) {
- rqi = (struct snic_req_info *) ctx;
- SNIC_HOST_INFO(snic->shost,
- "reset_cmpl:Tag %d ctx %lx cmpl stat %s\n",
- cmnd_id, ctx, snic_io_status_to_str(hdr_stat));
- sc = rqi->sc;
-
- goto ioctl_hba_rst;
- }
-
if (cmnd_id >= snic->max_tag_id) {
SNIC_HOST_ERR(snic->shost,
"reset_cmpl: Tag 0x%x out of Range,HdrStat %s\n",
@@ -1042,7 +1031,6 @@ snic_hba_reset_cmpl_handler(struct snic *snic, struct snic_fw_req *fwreq)
}
sc = scsi_host_find_tag(snic->shost, cmnd_id);
-ioctl_hba_rst:
if (!sc) {
atomic64_inc(&snic->s_stats.io.sc_null);
SNIC_HOST_ERR(snic->shost,
@@ -1728,7 +1716,7 @@ snic_dr_clean_single_req(struct snic *snic,
{
struct snic_req_info *rqi = NULL;
struct snic_tgt *tgt = NULL;
- struct scsi_cmnd *sc = NULL;
+ struct scsi_cmnd *sc;
spinlock_t *io_lock = NULL;
u32 sv_state = 0, tmf = 0;
DECLARE_COMPLETION_ONSTACK(tm_done);
@@ -2241,13 +2229,6 @@ snic_issue_hba_reset(struct snic *snic, struct scsi_cmnd *sc)
goto hba_rst_end;
}
- if (snic_cmd_tag(sc) == SCSI_NO_TAG) {
- memset(scsi_cmd_priv(sc), 0,
- sizeof(struct snic_internal_io_state));
- SNIC_HOST_INFO(snic->shost, "issu_hr:Host reset thru ioctl.\n");
- rqi->sc = sc;
- }
-
req = rqi_to_req(rqi);
io_lock = snic_io_lock_hash(snic, sc);
@@ -2322,11 +2303,13 @@ snic_issue_hba_reset(struct snic *snic, struct scsi_cmnd *sc)
} /* end of snic_issue_hba_reset */
int
-snic_reset(struct Scsi_Host *shost, struct scsi_cmnd *sc)
+snic_reset(struct Scsi_Host *shost)
{
struct snic *snic = shost_priv(shost);
+ struct scsi_cmnd *sc = NULL;
enum snic_state sv_state;
unsigned long flags;
+ u32 start_time = jiffies;
int ret = FAILED;
/* Set snic state as SNIC_FWRESET*/
@@ -2351,6 +2334,18 @@ snic_reset(struct Scsi_Host *shost, struct scsi_cmnd *sc)
while (atomic_read(&snic->ios_inflight))
schedule_timeout(msecs_to_jiffies(1));
+ sc = scsi_host_find_tag(shost, snic->tmf_tag_id);
+ if (!sc) {
+ SNIC_HOST_ERR(shost,
+ "reset:Host Reset Failed to allocate sc.\n");
+ spin_lock_irqsave(&snic->snic_lock, flags);
+ snic_set_state(snic, sv_state);
+ spin_unlock_irqrestore(&snic->snic_lock, flags);
+ atomic64_inc(&snic->s_stats.reset.hba_reset_fail);
+ ret = FAILED;
+
+ goto reset_end;
+ }
ret = snic_issue_hba_reset(snic, sc);
if (ret) {
SNIC_HOST_ERR(shost,
@@ -2368,6 +2363,10 @@ snic_reset(struct Scsi_Host *shost, struct scsi_cmnd *sc)
ret = SUCCESS;
reset_end:
+ SNIC_TRC(shost->host_no, sc ? snic_cmd_tag(sc) : SCSI_NO_TAG,
+ (ulong) sc, jiffies_to_msecs(jiffies - start_time),
+ 0, 0, 0);
+
return ret;
} /* end of snic_reset */
@@ -2382,21 +2381,13 @@ int
snic_host_reset(struct scsi_cmnd *sc)
{
struct Scsi_Host *shost = sc->device->host;
- u32 start_time = jiffies;
- int ret = FAILED;
SNIC_SCSI_DBG(shost,
"host reset:sc %p sc_cmd 0x%x req %p tag %d flags 0x%llx\n",
sc, sc->cmnd[0], sc->request,
snic_cmd_tag(sc), CMD_FLAGS(sc));
- ret = snic_reset(shost, sc);
-
- SNIC_TRC(shost->host_no, snic_cmd_tag(sc), (ulong) sc,
- jiffies_to_msecs(jiffies - start_time),
- 0, SNIC_TRC_CMD(sc), SNIC_TRC_CMD_STATE_FLAGS(sc));
-
- return ret;
+ return snic_reset(shost);
} /* end of snic_host_reset */
/*
--
2.29.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] snic: reserve tag for TMF
2021-08-19 9:12 ` [PATCH 1/3] snic: reserve tag for TMF Hannes Reinecke
@ 2021-08-20 10:00 ` Christoph Hellwig
2021-08-20 10:12 ` Hannes Reinecke
0 siblings, 1 reply; 6+ messages in thread
From: Christoph Hellwig @ 2021-08-20 10:00 UTC (permalink / raw)
To: Hannes Reinecke
Cc: Martin K. Petersen, Christoph Hellwig, James Bottomley,
linux-scsi, Hannes Reinecke
On Thu, Aug 19, 2021 at 11:12:22AM +0200, Hannes Reinecke wrote:
>
> diff --git a/drivers/scsi/snic/snic_main.c b/drivers/scsi/snic/snic_main.c
> index 14f4ce665e58..65f50057c66e 100644
> --- a/drivers/scsi/snic/snic_main.c
> +++ b/drivers/scsi/snic/snic_main.c
> @@ -512,6 +512,9 @@ snic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> max_t(u32, SNIC_MIN_IO_REQ, max_ios));
>
> snic->max_tag_id = shost->can_queue;
> + /* Reserve one reset command */
> + shost->can_queue--;
> + snic->tmf_tag_id = shost->can_queue;
This is decrementing can_queue before scsi_add_host, which allocates
the requests ..
> + sc = scsi_host_find_tag(shost, snic->tmf_tag_id);
> + if (!sc) {
... but this is expecting a scsi_cmnd / struct request for that tag
value.
How is that supposed to work?
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/3] snic: reserve tag for TMF
2021-08-20 10:00 ` Christoph Hellwig
@ 2021-08-20 10:12 ` Hannes Reinecke
0 siblings, 0 replies; 6+ messages in thread
From: Hannes Reinecke @ 2021-08-20 10:12 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Martin K. Petersen, James Bottomley, linux-scsi, Hannes Reinecke
On 8/20/21 12:00 PM, Christoph Hellwig wrote:
> On Thu, Aug 19, 2021 at 11:12:22AM +0200, Hannes Reinecke wrote:
>>
>> diff --git a/drivers/scsi/snic/snic_main.c b/drivers/scsi/snic/snic_main.c
>> index 14f4ce665e58..65f50057c66e 100644
>> --- a/drivers/scsi/snic/snic_main.c
>> +++ b/drivers/scsi/snic/snic_main.c
>> @@ -512,6 +512,9 @@ snic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
>> max_t(u32, SNIC_MIN_IO_REQ, max_ios));
>>
>> snic->max_tag_id = shost->can_queue;
>> + /* Reserve one reset command */
>> + shost->can_queue--;
>> + snic->tmf_tag_id = shost->can_queue;
>
> This is decrementing can_queue before scsi_add_host, which allocates
> the requests ..
>
>> + sc = scsi_host_find_tag(shost, snic->tmf_tag_id);
>> + if (!sc) {
>
> ... but this is expecting a scsi_cmnd / struct request for that tag
> value.
>
> How is that supposed to work?
>
Ah, right. Will be fixing it.
Cheers,
Hannes
--
Dr. Hannes Reinecke Kernel Storage Architect
hare@suse.de +49 911 74053 688
SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg
HRB 36809 (AG Nürnberg), Geschäftsführer: Felix Imendörffer
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/3] snic: use dedicated device reset command
2021-08-19 9:12 [PATCH 0/3] snic: Fixes for SCSI EH rework Hannes Reinecke
2021-08-19 9:12 ` [PATCH 1/3] snic: reserve tag for TMF Hannes Reinecke
@ 2021-08-19 9:12 ` Hannes Reinecke
2021-08-19 9:12 ` [PATCH 3/3] snic: Use scsi_host_busy_iter() to traverse commands Hannes Reinecke
2 siblings, 0 replies; 6+ messages in thread
From: Hannes Reinecke @ 2021-08-19 9:12 UTC (permalink / raw)
To: Martin K. Petersen
Cc: Christoph Hellwig, James Bottomley, linux-scsi, Hannes Reinecke,
Hannes Reinecke
Use a dedicated command to send a device reset instead of relying
on using the command which triggered the device failure.
Signed-off-by: Hannes Reinecke <hare@suse.com>
---
drivers/scsi/snic/snic_scsi.c | 52 ++++++++++++++++-------------------
1 file changed, 24 insertions(+), 28 deletions(-)
diff --git a/drivers/scsi/snic/snic_scsi.c b/drivers/scsi/snic/snic_scsi.c
index 1e59d59130d6..3cffac9f23c8 100644
--- a/drivers/scsi/snic/snic_scsi.c
+++ b/drivers/scsi/snic/snic_scsi.c
@@ -2131,57 +2131,53 @@ snic_unlink_and_release_req(struct snic *snic, struct scsi_cmnd *sc, int flag)
int
snic_device_reset(struct scsi_cmnd *sc)
{
- struct Scsi_Host *shost = sc->device->host;
+ struct scsi_device *sdev = sc->device;
+ struct Scsi_Host *shost = sdev->host;
struct snic *snic = shost_priv(shost);
struct snic_req_info *rqi = NULL;
- int tag = snic_cmd_tag(sc);
int start_time = jiffies;
int ret = FAILED;
int dr_supp = 0;
- SNIC_SCSI_DBG(shost, "dev_reset:sc %p :0x%x :req = %p :tag = %d\n",
- sc, sc->cmnd[0], sc->request,
- snic_cmd_tag(sc));
- dr_supp = snic_dev_reset_supported(sc->device);
+ SNIC_SCSI_DBG(shost, "dev_reset\n");
+ dr_supp = snic_dev_reset_supported(sdev);
if (!dr_supp) {
/* device reset op is not supported */
SNIC_HOST_INFO(shost, "LUN Reset Op not supported.\n");
- snic_unlink_and_release_req(snic, sc, SNIC_DEV_RST_NOTSUP);
-
goto dev_rst_end;
}
if (unlikely(snic_get_state(snic) != SNIC_ONLINE)) {
- snic_unlink_and_release_req(snic, sc, 0);
SNIC_HOST_ERR(shost, "Devrst: Parent Devs are not online.\n");
goto dev_rst_end;
}
- /* There is no tag when lun reset is issue through ioctl. */
- if (unlikely(tag <= SNIC_NO_TAG)) {
- SNIC_HOST_INFO(snic->shost,
- "Devrst: LUN Reset Recvd thru IOCTL.\n");
-
- rqi = snic_req_init(snic, 0);
- if (!rqi)
- goto dev_rst_end;
-
- memset(scsi_cmd_priv(sc), 0,
- sizeof(struct snic_internal_io_state));
- CMD_SP(sc) = (char *)rqi;
- CMD_FLAGS(sc) = SNIC_NO_FLAGS;
+ rqi = snic_req_init(snic, 0);
+ if (!rqi)
+ goto dev_rst_end;
- /* Add special tag for dr coming from user spc */
- rqi->tm_tag = SNIC_TAG_IOCTL_DEV_RST;
- rqi->sc = sc;
+ /* The last tag is reserved for device reset */
+ sc = scsi_host_find_tag(snic->shost, snic->tmf_tag_id);
+ if (!sc || CMD_SP(sc)) {
+ SNIC_HOST_ERR(snic->shost,
+ "Devrst: TMF busy\n");
+ goto dev_rst_end;
}
+ memset(scsi_cmd_priv(sc), 0,
+ sizeof(struct snic_internal_io_state));
+ CMD_SP(sc) = (char *)rqi;
+ CMD_FLAGS(sc) = SNIC_NO_FLAGS;
+
+ /* Add special tag for dr coming from user spc */
+ rqi->tm_tag = SNIC_TAG_IOCTL_DEV_RST;
+ rqi->sc = sc;
ret = snic_send_dr_and_wait(snic, sc);
if (ret) {
SNIC_HOST_ERR(snic->shost,
"Devrst: IO w/ Tag %x Failed w/ err = %d\n",
- tag, ret);
+ snic_cmd_tag(sc), ret);
snic_unlink_and_release_req(snic, sc, 0);
@@ -2191,7 +2187,7 @@ snic_device_reset(struct scsi_cmnd *sc)
ret = snic_dr_finish(snic, sc);
dev_rst_end:
- SNIC_TRC(snic->shost->host_no, tag, (ulong) sc,
+ SNIC_TRC(snic->shost->host_no, snic_cmd_tag(sc), (ulong) sc,
jiffies_to_msecs(jiffies - start_time),
0, SNIC_TRC_CMD(sc), SNIC_TRC_CMD_STATE_FLAGS(sc));
@@ -2335,7 +2331,7 @@ snic_reset(struct Scsi_Host *shost)
schedule_timeout(msecs_to_jiffies(1));
sc = scsi_host_find_tag(shost, snic->tmf_tag_id);
- if (!sc) {
+ if (!sc || CMD_SP(sc)) {
SNIC_HOST_ERR(shost,
"reset:Host Reset Failed to allocate sc.\n");
spin_lock_irqsave(&snic->snic_lock, flags);
--
2.29.2
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH 3/3] snic: Use scsi_host_busy_iter() to traverse commands
2021-08-19 9:12 [PATCH 0/3] snic: Fixes for SCSI EH rework Hannes Reinecke
2021-08-19 9:12 ` [PATCH 1/3] snic: reserve tag for TMF Hannes Reinecke
2021-08-19 9:12 ` [PATCH 2/3] snic: use dedicated device reset command Hannes Reinecke
@ 2021-08-19 9:12 ` Hannes Reinecke
2 siblings, 0 replies; 6+ messages in thread
From: Hannes Reinecke @ 2021-08-19 9:12 UTC (permalink / raw)
To: Martin K. Petersen
Cc: Christoph Hellwig, James Bottomley, linux-scsi, Hannes Reinecke
Use scsi_host_busy_iter() to traverse commands instead of hand-crafted
routines walking the command list.
Signed-off-by: Hannes Reinecke <hare@suse.de>
---
drivers/scsi/snic/snic_scsi.c | 207 ++++++++++++++++------------------
1 file changed, 100 insertions(+), 107 deletions(-)
diff --git a/drivers/scsi/snic/snic_scsi.c b/drivers/scsi/snic/snic_scsi.c
index 3cffac9f23c8..db99ea103baa 100644
--- a/drivers/scsi/snic/snic_scsi.c
+++ b/drivers/scsi/snic/snic_scsi.c
@@ -77,7 +77,7 @@ static const char * const snic_io_status_str[] = {
[SNIC_STAT_FATAL_ERROR] = "SNIC_STAT_FATAL_ERROR",
};
-static void snic_scsi_cleanup(struct snic *, int);
+static void snic_scsi_cleanup(struct snic *);
const char *
snic_state_to_str(unsigned int state)
@@ -980,7 +980,7 @@ snic_hba_reset_scsi_cleanup(struct snic *snic, struct scsi_cmnd *sc)
long act_ios = 0, act_fwreqs = 0;
SNIC_SCSI_DBG(snic->shost, "HBA Reset scsi cleanup.\n");
- snic_scsi_cleanup(snic, snic_cmd_tag(sc));
+ snic_scsi_cleanup(snic);
/* Update stats on pending IOs */
act_ios = atomic64_read(&st->io.active);
@@ -2415,87 +2415,82 @@ snic_cmpl_pending_tmreq(struct snic *snic, struct scsi_cmnd *sc)
complete(rqi->abts_done);
}
-/*
- * snic_scsi_cleanup: Walks through tag map and releases the reqs
- */
-static void
-snic_scsi_cleanup(struct snic *snic, int ex_tag)
+static bool snic_scsi_cleanup_iter(struct scsi_cmnd *sc, void *data,
+ bool reserved)
{
- struct snic_req_info *rqi = NULL;
- struct scsi_cmnd *sc = NULL;
+ struct snic *snic = data;
+ u32 tag = sc->request->tag;
spinlock_t *io_lock = NULL;
- unsigned long flags;
- int tag;
+ struct snic_req_info *rqi = NULL;
u64 st_time = 0;
+ unsigned long flags;
- SNIC_SCSI_DBG(snic->shost, "sc_clean: scsi cleanup.\n");
-
- for (tag = 0; tag < snic->max_tag_id; tag++) {
- /* Skip ex_tag */
- if (tag == ex_tag)
- continue;
-
- io_lock = snic_io_lock_tag(snic, tag);
- spin_lock_irqsave(io_lock, flags);
- sc = scsi_host_find_tag(snic->shost, tag);
- if (!sc) {
- spin_unlock_irqrestore(io_lock, flags);
-
- continue;
- }
-
- if (unlikely(snic_tmreq_pending(sc))) {
- /*
- * When FW Completes reset w/o sending completions
- * for outstanding ios.
- */
- snic_cmpl_pending_tmreq(snic, sc);
- spin_unlock_irqrestore(io_lock, flags);
+ io_lock = snic_io_lock_tag(snic, tag);
+ spin_lock_irqsave(io_lock, flags);
+ if (unlikely(snic_tmreq_pending(sc))) {
+ /*
+ * When FW Completes reset w/o sending completions
+ * for outstanding ios.
+ */
+ snic_cmpl_pending_tmreq(snic, sc);
+ spin_unlock_irqrestore(io_lock, flags);
- continue;
- }
+ return true;
+ }
- rqi = (struct snic_req_info *) CMD_SP(sc);
- if (!rqi) {
- spin_unlock_irqrestore(io_lock, flags);
+ rqi = (struct snic_req_info *) CMD_SP(sc);
+ if (!rqi) {
+ spin_unlock_irqrestore(io_lock, flags);
- goto cleanup;
- }
+ goto cleanup;
+ }
- SNIC_SCSI_DBG(snic->shost,
- "sc_clean: sc %p, rqi %p, tag %d flags 0x%llx\n",
- sc, rqi, tag, CMD_FLAGS(sc));
+ SNIC_SCSI_DBG(snic->shost,
+ "sc_clean: sc %p, rqi %p, tag %d flags 0x%llx\n",
+ sc, rqi, tag, CMD_FLAGS(sc));
- CMD_SP(sc) = NULL;
- CMD_FLAGS(sc) |= SNIC_SCSI_CLEANUP;
- spin_unlock_irqrestore(io_lock, flags);
- st_time = rqi->start_time;
+ CMD_SP(sc) = NULL;
+ CMD_FLAGS(sc) |= SNIC_SCSI_CLEANUP;
+ spin_unlock_irqrestore(io_lock, flags);
+ st_time = rqi->start_time;
- SNIC_HOST_INFO(snic->shost,
- "sc_clean: Releasing rqi %p : flags 0x%llx\n",
- rqi, CMD_FLAGS(sc));
+ SNIC_HOST_INFO(snic->shost,
+ "sc_clean: Releasing rqi %p : flags 0x%llx\n",
+ rqi, CMD_FLAGS(sc));
- snic_release_req_buf(snic, rqi, sc);
+ snic_release_req_buf(snic, rqi, sc);
cleanup:
- sc->result = DID_TRANSPORT_DISRUPTED << 16;
- SNIC_HOST_INFO(snic->shost,
- "sc_clean: DID_TRANSPORT_DISRUPTED for sc %p, Tag %d flags 0x%llx rqi %p duration %u msecs\n",
- sc, sc->request->tag, CMD_FLAGS(sc), rqi,
- jiffies_to_msecs(jiffies - st_time));
+ sc->result = DID_TRANSPORT_DISRUPTED << 16;
+ SNIC_HOST_INFO(snic->shost,
+ "sc_clean: DID_TRANSPORT_DISRUPTED for sc %p, "
+ "Tag %d flags 0x%llx rqi %p duration %u msecs\n",
+ sc, sc->request->tag, CMD_FLAGS(sc), rqi,
+ jiffies_to_msecs(jiffies - st_time));
- /* Update IO stats */
- snic_stats_update_io_cmpl(&snic->s_stats);
+ /* Update IO stats */
+ snic_stats_update_io_cmpl(&snic->s_stats);
- if (sc->scsi_done) {
- SNIC_TRC(snic->shost->host_no, tag, (ulong) sc,
- jiffies_to_msecs(jiffies - st_time), 0,
- SNIC_TRC_CMD(sc),
- SNIC_TRC_CMD_STATE_FLAGS(sc));
+ if (sc->scsi_done) {
+ SNIC_TRC(snic->shost->host_no, tag, (ulong) sc,
+ jiffies_to_msecs(jiffies - st_time), 0,
+ SNIC_TRC_CMD(sc),
+ SNIC_TRC_CMD_STATE_FLAGS(sc));
- sc->scsi_done(sc);
- }
+ sc->scsi_done(sc);
}
+ return true;
+}
+
+/*
+ * snic_scsi_cleanup: Walks through tag map and releases the reqs
+ */
+static void
+snic_scsi_cleanup(struct snic *snic)
+{
+ SNIC_SCSI_DBG(snic->shost, "sc_clean: scsi cleanup.\n");
+
+ scsi_host_busy_iter(snic->shost, snic_scsi_cleanup_iter, snic);
} /* end of snic_scsi_cleanup */
void
@@ -2503,7 +2498,7 @@ snic_shutdown_scsi_cleanup(struct snic *snic)
{
SNIC_HOST_INFO(snic->shost, "Shutdown time SCSI Cleanup.\n");
- snic_scsi_cleanup(snic, SCSI_NO_TAG);
+ snic_scsi_cleanup(snic);
} /* end of snic_shutdown_scsi_cleanup */
/*
@@ -2517,7 +2512,7 @@ snic_internal_abort_io(struct snic *snic, struct scsi_cmnd *sc, int tmf)
spinlock_t *io_lock = NULL;
unsigned long flags;
u32 sv_state = 0;
- int ret = 0;
+ int ret = FAILED;
io_lock = snic_io_lock_hash(snic, sc);
spin_lock_irqsave(io_lock, flags);
@@ -2592,6 +2587,35 @@ snic_internal_abort_io(struct snic *snic, struct scsi_cmnd *sc, int tmf)
return ret;
} /* end of snic_internal_abort_io */
+struct snic_tgt_scsi_abort_io_data {
+ struct snic *snic;
+ struct snic_tgt *tgt;
+ int tmf;
+ int abt_cnt;
+};
+
+static bool snic_tgt_scsi_abort_io_iter(struct scsi_cmnd *sc, void *data,
+ bool reserved)
+{
+ struct snic_tgt_scsi_abort_io_data *iter_data = data;
+ struct snic *snic = iter_data->snic;
+ struct snic_tgt *sc_tgt;
+ int ret;
+
+ sc_tgt = starget_to_tgt(scsi_target(sc->device));
+ if (sc_tgt != iter_data->tgt)
+ return true;
+
+ ret = snic_internal_abort_io(snic, sc, iter_data->tmf);
+ if (ret == SUCCESS)
+ iter_data->abt_cnt++;
+ else
+ SNIC_HOST_ERR(snic->shost,
+ "tgt_abt_io: Tag %x, Failed w err = %d\n",
+ sc->request->tag, ret);
+ return true;
+}
+
/*
* snic_tgt_scsi_abort_io : called by snic_tgt_del
*/
@@ -2599,11 +2623,9 @@ int
snic_tgt_scsi_abort_io(struct snic_tgt *tgt)
{
struct snic *snic = NULL;
- struct scsi_cmnd *sc = NULL;
- struct snic_tgt *sc_tgt = NULL;
- spinlock_t *io_lock = NULL;
- unsigned long flags;
- int ret = 0, tag, abt_cnt = 0, tmf = 0;
+ struct snic_tgt_scsi_abort_io_data data = {
+ .abt_cnt = 0,
+ };
if (!tgt)
return -1;
@@ -2611,44 +2633,15 @@ snic_tgt_scsi_abort_io(struct snic_tgt *tgt)
snic = shost_priv(snic_tgt_to_shost(tgt));
SNIC_SCSI_DBG(snic->shost, "tgt_abt_io: Cleaning Pending IOs.\n");
+ data.snic = snic;
if (tgt->tdata.typ == SNIC_TGT_DAS)
- tmf = SNIC_ITMF_ABTS_TASK;
+ data.tmf = SNIC_ITMF_ABTS_TASK;
else
- tmf = SNIC_ITMF_ABTS_TASK_TERM;
-
- for (tag = 0; tag < snic->max_tag_id; tag++) {
- io_lock = snic_io_lock_tag(snic, tag);
-
- spin_lock_irqsave(io_lock, flags);
- sc = scsi_host_find_tag(snic->shost, tag);
- if (!sc) {
- spin_unlock_irqrestore(io_lock, flags);
-
- continue;
- }
-
- sc_tgt = starget_to_tgt(scsi_target(sc->device));
- if (sc_tgt != tgt) {
- spin_unlock_irqrestore(io_lock, flags);
+ data.tmf = SNIC_ITMF_ABTS_TASK_TERM;
- continue;
- }
- spin_unlock_irqrestore(io_lock, flags);
-
- ret = snic_internal_abort_io(snic, sc, tmf);
- if (ret < 0) {
- SNIC_HOST_ERR(snic->shost,
- "tgt_abt_io: Tag %x, Failed w err = %d\n",
- tag, ret);
-
- continue;
- }
-
- if (ret == SUCCESS)
- abt_cnt++;
- }
+ scsi_host_busy_iter(snic->shost, snic_tgt_scsi_abort_io_iter, &data);
- SNIC_SCSI_DBG(snic->shost, "tgt_abt_io: abt_cnt = %d\n", abt_cnt);
+ SNIC_SCSI_DBG(snic->shost, "tgt_abt_io: abt_cnt = %d\n", data.abt_cnt);
return 0;
} /* end of snic_tgt_scsi_abort_io */
--
2.29.2
^ permalink raw reply related [flat|nested] 6+ messages in thread