From: Hannes Reinecke <hare@suse.de>
To: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: Christoph Hellwig <hch@lst.de>,
James Bottomley <james.bottomley@hansenpartnership.com>,
linux-scsi@vger.kernel.org, Hannes Reinecke <hare@suse.de>,
Bart Van Assche <bvanassche@acm.org>,
Johannes Thumshirn <johannes.thumshirn@wdc.com>
Subject: [PATCH 07/10] scsi: Do not allocate scsi command in scsi_ioctl_reset()
Date: Mon, 23 Oct 2023 11:28:34 +0200 [thread overview]
Message-ID: <20231023092837.33786-8-hare@suse.de> (raw)
In-Reply-To: <20231023092837.33786-1-hare@suse.de>
As we now have moved the error handler functions to not rely on
a scsi command we can drop the out-of-band scsi command allocation
from scsi_ioctl_reset().
Signed-off-by: Hannes Reinecke <hare@suse.de>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
---
drivers/scsi/scsi_error.c | 95 ++++++++++++++++-----------------------
1 file changed, 39 insertions(+), 56 deletions(-)
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 7c9c376affda..63b762d5d66f 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -866,13 +866,12 @@ void scsi_eh_done(struct scsi_cmnd *scmd)
/**
* scsi_try_host_reset - ask host adapter to reset itself
- * @scmd: SCSI cmd to send host reset.
+ * @host: SCSI host to be reset.
*/
-static enum scsi_disposition scsi_try_host_reset(struct scsi_cmnd *scmd)
+static enum scsi_disposition scsi_try_host_reset(struct Scsi_Host *host)
{
unsigned long flags;
enum scsi_disposition rtn;
- struct Scsi_Host *host = scmd->device->host;
const struct scsi_host_template *hostt = host->hostt;
SCSI_LOG_ERROR_RECOVERY(3,
@@ -887,7 +886,7 @@ static enum scsi_disposition scsi_try_host_reset(struct scsi_cmnd *scmd)
if (!hostt->skip_settle_delay)
ssleep(HOST_RESET_SETTLE_TIME);
spin_lock_irqsave(host->host_lock, flags);
- scsi_report_bus_reset(host, scmd_channel(scmd));
+ scsi_report_bus_reset(host, -1);
spin_unlock_irqrestore(host->host_lock, flags);
}
@@ -896,28 +895,29 @@ static enum scsi_disposition scsi_try_host_reset(struct scsi_cmnd *scmd)
/**
* scsi_try_bus_reset - ask host to perform a bus reset
- * @scmd: SCSI cmd to send bus reset.
+ * @host: SCSI host to send bus reset.
+ * @channel: Number of the bus to be reset
*/
-static enum scsi_disposition scsi_try_bus_reset(struct scsi_cmnd *scmd)
+static enum scsi_disposition scsi_try_bus_reset(struct Scsi_Host *host,
+ int channel)
{
unsigned long flags;
enum scsi_disposition rtn;
- struct Scsi_Host *host = scmd->device->host;
const struct scsi_host_template *hostt = host->hostt;
- SCSI_LOG_ERROR_RECOVERY(3, scmd_printk(KERN_INFO, scmd,
- "%s: Snd Bus RST\n", __func__));
+ SCSI_LOG_ERROR_RECOVERY(3, shost_printk(KERN_INFO, host,
+ "%s: Snd Bus RST to bus %d\n", __func__, channel));
if (!hostt->eh_bus_reset_handler)
return FAILED;
- rtn = hostt->eh_bus_reset_handler(host, scmd_channel(scmd));
+ rtn = hostt->eh_bus_reset_handler(host, channel);
if (rtn == SUCCESS) {
if (!hostt->skip_settle_delay)
ssleep(BUS_RESET_SETTLE_TIME);
spin_lock_irqsave(host->host_lock, flags);
- scsi_report_bus_reset(host, scmd_channel(scmd));
+ scsi_report_bus_reset(host, channel);
spin_unlock_irqrestore(host->host_lock, flags);
}
@@ -932,7 +932,8 @@ static void __scsi_report_device_reset(struct scsi_device *sdev, void *data)
/**
* scsi_try_target_reset - Ask host to perform a target reset
- * @scmd: SCSI cmd used to send a target reset
+ * @host: SCSI Host
+ * @starget: SCSI target to be reset
*
* Notes:
* There is no timeout for this operation. if this operation is
@@ -940,13 +941,12 @@ static void __scsi_report_device_reset(struct scsi_device *sdev, void *data)
* timer on it, and set the host back to a consistent state prior to
* returning.
*/
-static enum scsi_disposition scsi_try_target_reset(struct scsi_cmnd *scmd)
+static enum scsi_disposition scsi_try_target_reset(struct Scsi_Host *host,
+ struct scsi_target *starget)
{
unsigned long flags;
enum scsi_disposition rtn;
- struct Scsi_Host *host = scmd->device->host;
const struct scsi_host_template *hostt = host->hostt;
- struct scsi_target *starget = scsi_target(scmd->device);
if (!hostt->eh_target_reset_handler)
return FAILED;
@@ -964,7 +964,7 @@ static enum scsi_disposition scsi_try_target_reset(struct scsi_cmnd *scmd)
/**
* scsi_try_bus_device_reset - Ask host to perform a BDR on a dev
- * @scmd: SCSI cmd used to send BDR
+ * @sdev: SCSI device to perform the BDR on
*
* Notes:
* There is no timeout for this operation. if this operation is
@@ -972,17 +972,17 @@ static enum scsi_disposition scsi_try_target_reset(struct scsi_cmnd *scmd)
* timer on it, and set the host back to a consistent state prior to
* returning.
*/
-static enum scsi_disposition scsi_try_bus_device_reset(struct scsi_cmnd *scmd)
+static enum scsi_disposition scsi_try_bus_device_reset(struct scsi_device *sdev)
{
enum scsi_disposition rtn;
- const struct scsi_host_template *hostt = scmd->device->host->hostt;
+ const struct scsi_host_template *hostt = sdev->host->hostt;
if (!hostt->eh_device_reset_handler)
return FAILED;
- rtn = hostt->eh_device_reset_handler(scmd->device);
+ rtn = hostt->eh_device_reset_handler(sdev);
if (rtn == SUCCESS)
- __scsi_report_device_reset(scmd->device, NULL);
+ __scsi_report_device_reset(sdev, NULL);
return rtn;
}
@@ -1014,11 +1014,15 @@ scsi_try_to_abort_cmd(const struct scsi_host_template *hostt, struct scsi_cmnd *
static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd)
{
- if (scsi_try_to_abort_cmd(scmd->device->host->hostt, scmd) != SUCCESS)
- if (scsi_try_bus_device_reset(scmd) != SUCCESS)
- if (scsi_try_target_reset(scmd) != SUCCESS)
- if (scsi_try_bus_reset(scmd) != SUCCESS)
- scsi_try_host_reset(scmd);
+ struct Scsi_Host *host = scmd->device->host;
+ struct scsi_target *starget = scsi_target(scmd->device);
+ int channel = scmd->device->channel;
+
+ if (scsi_try_to_abort_cmd(host->hostt, scmd) != SUCCESS)
+ if (scsi_try_bus_device_reset(scmd->device) != SUCCESS)
+ if (scsi_try_target_reset(host, starget) != SUCCESS)
+ if (scsi_try_bus_reset(host, channel) != SUCCESS)
+ scsi_try_host_reset(host);
}
/**
@@ -1592,7 +1596,7 @@ static int scsi_eh_bus_device_reset(struct Scsi_Host *shost,
SCSI_LOG_ERROR_RECOVERY(3,
sdev_printk(KERN_INFO, sdev,
"%s: Sending BDR\n", current->comm));
- rtn = scsi_try_bus_device_reset(bdr_scmd);
+ rtn = scsi_try_bus_device_reset(sdev);
if (rtn == SUCCESS || rtn == FAST_IO_FAIL) {
if (!scsi_device_online(sdev) ||
rtn == FAST_IO_FAIL ||
@@ -1658,7 +1662,7 @@ static int scsi_eh_target_reset(struct Scsi_Host *shost,
shost_printk(KERN_INFO, shost,
"%s: Sending target reset to target %d\n",
current->comm, id));
- rtn = scsi_try_target_reset(scmd);
+ rtn = scsi_try_target_reset(shost, scsi_target(scmd->device));
if (rtn != SUCCESS && rtn != FAST_IO_FAIL)
SCSI_LOG_ERROR_RECOVERY(3,
shost_printk(KERN_INFO, shost,
@@ -1722,7 +1726,7 @@ static int scsi_eh_bus_reset(struct Scsi_Host *shost,
shost_printk(KERN_INFO, shost,
"%s: Sending BRST chan: %d\n",
current->comm, channel));
- rtn = scsi_try_bus_reset(scmd);
+ rtn = scsi_try_bus_reset(shost, channel);
if (rtn != SUCCESS && rtn != FAST_IO_FAIL) {
SCSI_LOG_ERROR_RECOVERY(3,
shost_printk(KERN_INFO, shost,
@@ -1768,7 +1772,7 @@ static int scsi_eh_host_reset(struct Scsi_Host *shost,
"%s: Sending HRST\n",
current->comm));
- rtn = scsi_try_host_reset(scmd);
+ rtn = scsi_try_host_reset(shost);
if (rtn == SUCCESS) {
list_splice_init(work_q, &check_list);
} else if (rtn == FAST_IO_FAIL) {
@@ -2379,7 +2383,7 @@ void scsi_report_bus_reset(struct Scsi_Host *shost, unsigned int channel)
struct scsi_device *sdev;
__shost_for_each_device(sdev, shost) {
- if (channel == sdev_channel(sdev))
+ if (channel == -1 || channel == sdev_channel(sdev))
__scsi_report_device_reset(sdev, NULL);
}
}
@@ -2427,9 +2431,8 @@ EXPORT_SYMBOL(scsi_report_device_reset);
int
scsi_ioctl_reset(struct scsi_device *dev, int __user *arg)
{
- struct scsi_cmnd *scmd;
struct Scsi_Host *shost = dev->host;
- struct request *rq;
+ struct scsi_target *starget = scsi_target(dev);
unsigned long flags;
int error = 0, val;
enum scsi_disposition rtn;
@@ -2444,23 +2447,6 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg)
if (scsi_autopm_get_host(shost) < 0)
return -EIO;
- error = -EIO;
- rq = kzalloc(sizeof(struct request) + sizeof(struct scsi_cmnd) +
- shost->hostt->cmd_size, GFP_KERNEL);
- if (!rq)
- goto out_put_autopm_host;
- blk_rq_init(NULL, rq);
-
- scmd = (struct scsi_cmnd *)(rq + 1);
- scsi_init_command(dev, scmd);
-
- scmd->submitter = SUBMITTED_BY_SCSI_RESET_IOCTL;
- memset(&scmd->sdb, 0, sizeof(scmd->sdb));
-
- scmd->cmd_len = 0;
-
- scmd->sc_data_direction = DMA_BIDIRECTIONAL;
-
spin_lock_irqsave(shost->host_lock, flags);
shost->tmf_in_progress = 1;
spin_unlock_irqrestore(shost->host_lock, flags);
@@ -2470,22 +2456,22 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg)
rtn = SUCCESS;
break;
case SG_SCSI_RESET_DEVICE:
- rtn = scsi_try_bus_device_reset(scmd);
+ rtn = scsi_try_bus_device_reset(dev);
if (rtn == SUCCESS || (val & SG_SCSI_RESET_NO_ESCALATE))
break;
fallthrough;
case SG_SCSI_RESET_TARGET:
- rtn = scsi_try_target_reset(scmd);
+ rtn = scsi_try_target_reset(shost, starget);
if (rtn == SUCCESS || (val & SG_SCSI_RESET_NO_ESCALATE))
break;
fallthrough;
case SG_SCSI_RESET_BUS:
- rtn = scsi_try_bus_reset(scmd);
+ rtn = scsi_try_bus_reset(shost, dev->channel);
if (rtn == SUCCESS || (val & SG_SCSI_RESET_NO_ESCALATE))
break;
fallthrough;
case SG_SCSI_RESET_HOST:
- rtn = scsi_try_host_reset(scmd);
+ rtn = scsi_try_host_reset(shost);
if (rtn == SUCCESS)
break;
fallthrough;
@@ -2511,9 +2497,6 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg)
wake_up(&shost->host_wait);
scsi_run_host_queues(shost);
- kfree(rq);
-
-out_put_autopm_host:
scsi_autopm_put_host(shost);
return error;
}
--
2.35.3
next prev parent reply other threads:[~2023-10-23 9:29 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-10-23 9:28 [PATCHv8 00/10] scsi: EH rework, main part Hannes Reinecke
2023-10-23 9:28 ` [PATCH 01/10] scsi: Use Scsi_Host as argument for eh_host_reset_handler Hannes Reinecke
2023-10-25 11:40 ` Benjamin Block
2023-10-23 9:28 ` [PATCH 02/10] scsi: Use Scsi_Host and channel number as argument for eh_bus_reset_handler() Hannes Reinecke
2023-10-25 13:33 ` Benjamin Block
2023-10-25 13:36 ` Hannes Reinecke
2023-10-25 15:15 ` Benjamin Block
2023-10-23 9:28 ` [PATCH 03/10] scsi: Use scsi_target as argument for eh_target_reset_handler() Hannes Reinecke
2023-10-25 15:11 ` Benjamin Block
2023-10-25 15:35 ` Hannes Reinecke
2023-10-25 15:49 ` Benjamin Block
2023-10-23 9:28 ` [PATCH 04/10] scsi: Use scsi_device as argument to eh_device_reset_handler() Hannes Reinecke
2023-10-26 12:24 ` Benjamin Block
2023-10-26 12:39 ` Hannes Reinecke
2023-10-26 12:44 ` Benjamin Block
2023-10-23 9:28 ` [PATCH 05/10] scsi: set host byte after EH completed Hannes Reinecke
2023-10-26 12:58 ` Benjamin Block
2023-10-23 9:28 ` [PATCH 06/10] scsi_error: iterate over list of failed commands in scsi_eh_bus_reset() Hannes Reinecke
2023-10-26 13:19 ` Benjamin Block
2023-10-23 9:28 ` Hannes Reinecke [this message]
2023-10-26 13:47 ` [PATCH 07/10] scsi: Do not allocate scsi command in scsi_ioctl_reset() Benjamin Block
2023-10-23 9:28 ` [PATCH 08/10] scsi_error: iterate over list of failed commands in scsi_eh_bus_device_reset() Hannes Reinecke
2023-10-26 13:54 ` Benjamin Block
2023-10-23 9:28 ` [PATCH 09/10] scsi_error: map FAST_IO_FAIL to -EAGAIN in SCSI EH Hannes Reinecke
2023-10-26 14:08 ` Benjamin Block
2023-10-26 16:50 ` Mike Christie
2023-10-27 5:05 ` Hannes Reinecke
2023-10-23 9:28 ` [PATCH 10/10] scsi: remove SUBMITTED_BY_SCSI_RESET_IOCTL Hannes Reinecke
2023-10-26 14:12 ` Benjamin Block
2023-10-24 17:30 ` [PATCHv8 00/10] scsi: EH rework, main part Benjamin Block
2023-10-24 17:40 ` Hannes Reinecke
2023-10-24 17:57 ` Benjamin Block
2024-03-06 13:40 ` Wenchao Hao
2024-11-05 9:10 ` Niklas Cassel
2024-11-05 15:22 ` Hannes Reinecke
2024-11-05 15:47 ` Niklas Cassel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20231023092837.33786-8-hare@suse.de \
--to=hare@suse.de \
--cc=bvanassche@acm.org \
--cc=hch@lst.de \
--cc=james.bottomley@hansenpartnership.com \
--cc=johannes.thumshirn@wdc.com \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.