New SCSI command timeout handler
Subsystems (5)
v2 cover New SCSI command timeout handler
this is the first step towards a new non-blocking error handler. This patch implements a new command timeout handler which will be sending command aborts inline without engaging SCSI EH.
In addition the commands will be returned directly if the command abort succeeded, cutting down recovery times dramatically.
With the original scsi error recovery I got:
# time dd if=/dev/zero of=/mnt/test.blk bs=512 count=2048 oflag=sync 2048+0 records in 2048+0 records out 1048576 bytes (1.0 MB) copied, 3.72732 s, 281 kB/s
real 2m14.475s
user 0m0.000s
sys 0m0.104s
with this patchset I got:
# time dd if=/dev/zero of=/mnt/test.blk bs=512 count=2048 oflag=sync 2048+0 records in 2048+0 records out 1048576 bytes (1.0 MB) copied, 31.5151 s, 33.3 kB/s
real 0m31.519s
user 0m0.000s
sys 0m0.088s
Test was to disable RSCN on the target port, disable the target port, and then start the 'dd' command as indicated.
As a proof-of-concept I've also enabled the new timeout handler for virtio, so that things can be tested out more easily.
As requested I've also hooked in the new SCSI timeout handler to SAS.
Changes to the original version:
- Use a private list in scsi_eh_abort_handler to avoid list starvation (pointed out by Joern Engel)
- Terminate command aborts when the first abort fails
- Do not attempt command aborts if the host is already in recovery or if the device is removed.
- Flush abort workqueue if the device is removed.
Comments etc are welcome.
Hannes Reinecke (9):
scsi: move initialization of scmd->eh_entry
blk-timeout: add BLK_EH_SCHEDULED return code
scsi: improved eh timeout handler
virtio_scsi: Enable new EH timeout handler
virtio-scsi: Implement TMF timeout
libsas: Enable new EH timeout handler
mptsas: Enable new EH timeout handler
mpt2sas: Enable new EH timeout handler
mpt3sas: Enable new EH timeout handler
drivers/message/fusion/mptsas.c | 1 + drivers/message/fusion/mptscsih.c | 7 ++ drivers/message/fusion/mptscsih.h | 1 + drivers/scsi/libsas/sas_scsi_host.c | 2 +- drivers/scsi/mpt2sas/mpt2sas_scsih.c | 11 +++ drivers/scsi/mpt3sas/mpt3sas_scsih.c | 11 +++ drivers/scsi/scsi_error.c | 126 ++++++++++++++++++++++++++++++++++- drivers/scsi/scsi_lib.c | 4 +- drivers/scsi/scsi_scan.c | 3 + drivers/scsi/scsi_sysfs.c | 5 ++ drivers/scsi/scsi_transport_fc.c | 2 +- drivers/scsi/virtio_scsi.c | 14 +++- include/linux/blkdev.h | 1 + include/scsi/scsi_cmnd.h | 1 + include/scsi/scsi_device.h | 2 + 15 files changed, 184 insertions(+), 7 deletions(-)
Signature · 1 line
1.7.12.4
PATCH v2 1/9 scsi: move initialization of scmd->eh_entry
The 'eh_entry' list might be used even before scsi_softirq_done() is called. Hence we should rather initialize it together with the other eh-related variables.
--- drivers/scsi/scsi_lib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/scsi/scsi_lib.c +2 -2
@@ -317,6 +317,8 @@ static void scsi_init_cmd_errh(struct scsi_cmnd *cmd)memset (cmd->sense_buffer,0 ,SCSI_SENSE_BUFFERSIZE );if (cmd->cmd_len ==0 ) cmd->cmd_len =scsi_command_size (cmd->cmnd); +INIT_LIST_HEAD (&cmd->eh_entry); + cmd->eh_eflags =0 ; }void scsi_device_unbusy (struct scsi_device *sdev)
@@ -1482,8 +1484,6 @@ static void scsi_softirq_done(struct request *rq)unsigned long wait_for = (cmd->allowed +1 ) * rq->timeout;int disposition; -INIT_LIST_HEAD (&cmd->eh_entry); -atomic_inc (&cmd->device->iodone_cnt);if (cmd->result)atomic_inc (&cmd->device->ioerr_cnt);
Signature · 1 line
1.7.12.4
Re: [PATCH 1/9] scsi: move initialization of scmd->eh_entry
Quoted 3 lines · Hannes Reinecke
The '
eh_entry' list might be used even beforescsi_softirq_done()is called. Hence we should rather initialize it together with the other eh-related variables.
As mentioned earlier I don't think moving the initialization from one random point in the middle of the lifetime of the command to another is a good idea. If we initialize it it should be when it is allocated.
But looking at the code I can't see why it needs to be initialized at all. eh_entry is not used as the head of a list but just as the list link, and it's never tested for emptyness either, which shouldn't require it to be initialized at all.
PATCH v2 2/9 blk-timeout: add BLK_EH_SCHEDULED return code
In reply to Hannes ReineckeAdd a 'BLK_EH_SCHEDULED' return code for blk-timeout to indicate that a delayed error recovery has been initiated.
--- drivers/scsi/scsi_error.c | 3 +++ include/linux/blkdev.h | 1 + 2 files changed, 4 insertions(+)
drivers/scsi/scsi_error.c +3 -0
@@ -146,6 +146,9 @@ enum blk_eh_timer_return scsi_times_out(struct request *req) rtn = host->hostt->eh_timed_out (scmd); scmd->result |=DID_TIME_OUT <<16 ; +/* Check for delayed EH scheduling */ +if (rtn ==BLK_EH_SCHEDULED ) +return BLK_EH_NOT_HANDLED ;if (unlikely (rtn ==BLK_EH_NOT_HANDLED && !scsi_eh_scmd_add (scmd,SCSI_EH_CANCEL_CMD )))
include/linux/blkdev.h +1 -0
@@ -238,6 +238,7 @@ enum blk_eh_timer_return {BLK_EH_NOT_HANDLED ,BLK_EH_HANDLED ,BLK_EH_RESET_TIMER , + BLK_EH_SCHEDULED, };typedef enum blk_eh_timer_return (rq_timed_out_fn )(struct request *);
Signature · 1 line
1.7.12.4
PATCH v2 3/9 scsi: improved eh timeout handler
In reply to Hannes ReineckeWhen a command runs into a timeout we need to send an 'ABORT TASK' TMF. This is typically done by the 'eh_abort_handler' LLDD callback.
Conceptually, however, this function is a normal SCSI command, so there is no need to enter the error handler.
This patch implements a new scsi_abort_command() function which invokes an asynchronous function scsi_eh_abort_handler() to abort the commands via 'eh_abort_handler'.
If the 'eh_abort_handler' returns SUCCESS or FAST_IO_FAIL the command will be retried if possible. If no retries are allowed the command will be returned immediately, as we have to assume the TMF succeeded and the command is completed with the LLDD. If the TMF fails the command will be pushed back onto the list of failed commands and the SCSI EH handler will be called immediately for all timed-out commands.
--- drivers/scsi/scsi_error.c | 123 ++++++++++++++++++++++++++++++++++++++- drivers/scsi/scsi_scan.c | 3 + drivers/scsi/scsi_sysfs.c | 5 ++ drivers/scsi/scsi_transport_fc.c | 2 +- include/scsi/scsi_cmnd.h | 1 + include/scsi/scsi_device.h | 2 + 6 files changed, 134 insertions(+), 2 deletions(-)
drivers/scsi/scsi_error.c +122 -1
@@ -55,6 +55,8 @@ static void scsi_eh_done(struct scsi_cmnd *scmd);#define HOST_RESET_SETTLE_TIME (10)static int scsi_eh_try_stu (struct scsi_cmnd *scmd); +static int scsi_try_to_abort_cmd (struct scsi_host_template *hostt, +struct scsi_cmnd *scmd);/* called with shost->host_lock held */ void scsi_eh_wakeup (struct Scsi_Host *shost)
@@ -90,6 +92,125 @@ void scsi_schedule_eh(struct Scsi_Host *shost)EXPORT_SYMBOL_GPL (scsi_schedule_eh);/** +* scsi_eh_abort_handler - Handle command aborts +* @work: sdev on which commands should be aborted. +*/ +void +scsi_eh_abort_handler (struct work_struct *work) +{ +struct scsi_device *sdev = + container_of(work, struct scsi_device, abort_work); +struct scsi_cmnd *scmd, *tmp; +LIST_HEAD (abort_list); +unsigned long flags; +int rtn; + +spin_lock_irqsave (&sdev->list_lock, flags); +list_splice_init (&sdev->eh_abort_list, &abort_list); +spin_unlock_irqrestore (&sdev->list_lock, flags); + +list_for_each_entry_safe (scmd, tmp, &abort_list, eh_entry) { +list_del_init (&scmd->eh_entry); +if (sdev->sdev_state ==SDEV_CANCEL ) { +SCSI_LOG_ERROR_RECOVERY (3 , +scmd_printk (KERN_INFO , scmd, +"terminate, device removed\n" )); + scmd->result |=DID_NO_CONNECT <<16 ; +scsi_finish_command (scmd); +continue ; + } +SCSI_LOG_ERROR_RECOVERY (3 , +scmd_printk (KERN_INFO , scmd, +"aborting command %p\n" , scmd)); + rtn =scsi_try_to_abort_cmd (sdev->host->hostt, scmd); +if (rtn ==FAILED ) { +SCSI_LOG_ERROR_RECOVERY (3 , +scmd_printk (KERN_INFO , scmd, +"abort command failed\n" )); +list_move_tail (&scmd->eh_entry, &abort_list); + goto start_eh; + } +if (!(scmd->request->cmd_flags &REQ_FAILFAST_DEV ) && + (scmd->request->cmd_type !=REQ_TYPE_BLOCK_PC ) && + (++scmd->retries <= scmd->allowed)) { +SCSI_LOG_ERROR_RECOVERY (3 , +scmd_printk (KERN_WARNING , scmd, +"retry aborted command\n" )); + +scsi_queue_insert (scmd,SCSI_MLQUEUE_EH_RETRY ); + }else { +SCSI_LOG_ERROR_RECOVERY (3 , +scmd_printk (KERN_WARNING , scmd, +"fast fail aborted command\n" )); + scmd->result |=DID_TRANSPORT_FAILFAST <<16 ; +scsi_finish_command (scmd); + } + } + +if (list_empty (&abort_list)) +return ; + +start_eh: +list_for_each_entry_safe (scmd, tmp, &abort_list, eh_entry) { + scmd->result |=DID_TIME_OUT <<16 ; +if (!scsi_eh_scmd_add (scmd,0 )) { +SCSI_LOG_ERROR_RECOVERY (3 , +scmd_printk (KERN_WARNING , scmd, +"terminate aborted command\n" )); +scsi_finish_command (scmd); + } + } +} + +/** +* scsi_abort_command - schedule a command abort +* @scmd: scmd to abort. +* +* We only need to abort commands after a command timeout +*/ +enum blk_eh_timer_return +scsi_abort_command (struct scsi_cmnd *scmd) +{ +unsigned long flags; +int kick_worker =0 ; +struct scsi_device *sdev = scmd->device; + +/* +* Do not try a command abort if +* SCSI EH has already started. +*/ +if (scsi_host_in_recovery (sdev->host)) { +SCSI_LOG_ERROR_RECOVERY (3 , +scmd_printk (KERN_INFO , scmd, +"host in recovery, not aborting\n" )); + scmd->result |=DID_TIME_OUT <<16 ; +scsi_eh_scmd_add (scmd,0 ); +return BLK_EH_SCHEDULED ; + } +if (sdev->sdev_state ==SDEV_CANCEL || + sdev->sdev_state ==SDEV_OFFLINE ) { +SCSI_LOG_ERROR_RECOVERY (3 , +scmd_printk (KERN_INFO , scmd, +"device removed, terminating command\n" )); + scmd->result |=DID_NO_CONNECT <<16 ; +scsi_finish_command (scmd); +return BLK_EH_SCHEDULED ; + } + +spin_lock_irqsave (&sdev->list_lock, flags); +if (list_empty (&sdev->eh_abort_list)) + kick_worker =1 ; +list_add (&scmd->eh_entry, &sdev->eh_abort_list); +spin_unlock_irqrestore (&sdev->list_lock, flags); +SCSI_LOG_ERROR_RECOVERY (3 , +scmd_printk (KERN_INFO , scmd,"adding to eh_abort_list\n" )); +if (kick_worker) +schedule_work (&sdev->abort_work); +return BLK_EH_SCHEDULED ; +} +EXPORT_SYMBOL_GPL (scsi_abort_command); + +/** * scsi_eh_scmd_add - add scsi cmd to error handling. * @scmd: scmd to run eh on. * @eh_flag: optional SCSI_EH flag.
@@ -145,11 +266,11 @@ enum blk_eh_timer_return scsi_times_out(struct request *req)else if (host->hostt->eh_timed_out) rtn = host->hostt->eh_timed_out (scmd); - scmd->result |=DID_TIME_OUT <<16 ;/* Check for delayed EH scheduling */ if (rtn ==BLK_EH_SCHEDULED )return BLK_EH_NOT_HANDLED ; + scmd->result |=DID_TIME_OUT <<16 ;if (unlikely (rtn ==BLK_EH_NOT_HANDLED && !scsi_eh_scmd_add (scmd,SCSI_EH_CANCEL_CMD ))) rtn =BLK_EH_HANDLED ;
drivers/scsi/scsi_scan.c +3 -0
@@ -231,6 +231,7 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,struct Scsi_Host *shost =dev_to_shost (starget->dev.parent);extern void scsi_evt_thread (struct work_struct *work);extern void scsi_requeue_run_queue (struct work_struct *work); +extern void scsi_eh_abort_handler (struct work_struct *work); sdev =kzalloc (sizeof (*sdev) + shost->transportt->device_size,GFP_ATOMIC );
@@ -251,9 +252,11 @@ static struct scsi_device *scsi_alloc_sdev(struct scsi_target *starget,INIT_LIST_HEAD (&sdev->cmd_list);INIT_LIST_HEAD (&sdev->starved_entry);INIT_LIST_HEAD (&sdev->event_list); +INIT_LIST_HEAD (&sdev->eh_abort_list);spin_lock_init (&sdev->list_lock);INIT_WORK (&sdev->event_work, scsi_evt_thread);INIT_WORK (&sdev->requeue_work, scsi_requeue_run_queue); +INIT_WORK (&sdev->abort_work, scsi_eh_abort_handler); sdev->sdev_gendev.parent =get_device (&starget->dev); sdev->sdev_target = starget;
drivers/scsi/scsi_sysfs.c +5 -0
@@ -966,6 +966,11 @@ void __scsi_remove_device(struct scsi_device *sdev)put_device (&sdev->sdev_dev);/* +* Terminate timed-out commands +*/ +flush_work (&sdev->abort_work); + +/* * Stop accepting new requests and wait until all queuecommand() and * scsi_run_queue() invocations have finished before tearing down the * device.
drivers/scsi/scsi_transport_fc.c +1 -1
@@ -2079,7 +2079,7 @@ fc_timed_out(struct scsi_cmnd *scmd)if (rport->port_state ==FC_PORTSTATE_BLOCKED )return BLK_EH_RESET_TIMER ; -return BLK_EH_NOT_HANDLED ; +return scsi_abort_command (scmd); }/*
include/scsi/scsi_cmnd.h +1 -0
@@ -144,6 +144,7 @@ extern void scsi_put_command(struct scsi_cmnd *);extern void __scsi_put_command (struct Scsi_Host *,struct scsi_cmnd *,struct device *);extern void scsi_finish_command (struct scsi_cmnd *cmd); +extern enum blk_eh_timer_return scsi_abort_command (struct scsi_cmnd *cmd);extern void *scsi_kmap_atomic_sg (struct scatterlist *sg,int sg_count,size_t *offset,size_t *len);
include/scsi/scsi_device.h +2 -0
@@ -80,6 +80,7 @@ struct scsi_device {spinlock_t list_lock;struct list_head cmd_list;/* queue of in use SCSI Command structures */ struct list_head starved_entry; +struct list_head eh_abort_list;struct scsi_cmnd *current_cmnd;/* currently active command */ unsigned short queue_depth;/* How deep of a queue we want */ unsigned short max_queue_depth;/* max queue depth */
@@ -180,6 +181,7 @@ struct scsi_device {struct execute_work ew;/* used to get process context on put */ struct work_struct requeue_work; +struct work_struct abort_work;struct scsi_dh_data *scsi_dh_data;enum scsi_device_state sdev_state;
Signature · 1 line
1.7.12.4
Re: [PATCH 3/9] scsi: improved eh timeout handler
Quoted 10 lines · Hannes Reinecke
When a command runs into a timeout we need to send an 'ABORT TASK' TMF. This is typically done by the '
eh_abort_handler' LLDD callback.Conceptually, however, this function is a normal SCSI command, so there is no need to enter the error handler.
This patch implements a new
scsi_abort_command()function which invokes an asynchronous functionscsi_eh_abort_handler()to abort the commands via 'eh_abort_handler'.
Quoted 7 lines
If the '
eh_abort_handler' returns SUCCESS orFAST_IO_FAILthe command will be retried if possible. If no retries are allowed the command will be returned immediately, as we have to assume the TMF succeeded and the command is completed with the LLDD. If the TMF fails the command will be pushed back onto the list of failed commands and the SCSI EH handler will be called immediately for all timed-out commands.
Why can't we use a work item per command? Linking things into a list just to queue it up to workqueues missed half of the point of the workqueue infrastructure.
Re: [PATCH 3/9] scsi: improved eh timeout handler
Quoted 19 lines · Christoph Hellwig
Quoted 10 lines · Hannes Reinecke
When a command runs into a timeout we need to send an 'ABORT TASK' TMF. This is typically done by the '
eh_abort_handler' LLDD callback.Conceptually, however, this function is a normal SCSI command, so there is no need to enter the error handler.
This patch implements a new
scsi_abort_command()function which invokes an asynchronous functionscsi_eh_abort_handler()to abort the commands via 'eh_abort_handler'.Quoted 7 lines
If the '
eh_abort_handler' returns SUCCESS orFAST_IO_FAILthe command will be retried if possible. If no retries are allowed the command will be returned immediately, as we have to assume the TMF succeeded and the command is completed with the LLDD. If the TMF fails the command will be pushed back onto the list of failed commands and the SCSI EH handler will be called immediately for all timed-out commands.
Quoted 4 lines
Why can't we use a work item per command? Linking things into a list just to queue it up to workqueues missed half of the point of the workqueue infrastructure.
Hmm. I felt that using a per command workqueue might be a bit excessive. Also the current semantics call for a synchronous command abort. So even using a per command workqueue won't buy us anything as the workqueue item would have to wait for the command abort to complete, which again is quite a waste.
And concurrency would be hell; you'd have to flush the workqueue items for all outstanding if a device reset should attempted. And hope that no completion arrives at the time you're attempting to flush them. etc.
I've been planning for asynchronous command aborts eventually, where using a per-command workqueue item comes in useful. Gut for now using existing callbacks makes life so much easier. And per-command workqueues will just complicate matters.
Cheers,
Hannes
Signature · 8 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/9] scsi: improved eh timeout handler
Quoted 11 lines · Hannes Reinecke
Quoted 5 lines · Christoph Hellwig
Why can't we use a work item per command? Linking things into a list just to queue it up to workqueues missed half of the point of the workqueue infrastructure.
Hmm. I felt that using a per command workqueue might be a bit excessive. Also the current semantics call for a synchronous command abort. So even using a per command workqueue won't buy us anything as the workqueue item would have to wait for the command abort to complete, which again is quite a waste.
Not sure if you confuse workqueue with workitem. Either way, using a single work item to handle a queue of commands does not fly and we either have to use per-command work items or abandon work queues and use a kernel thread. The middle ground is either racy or useless.
I don't care too much whether we use per-command work items or a single system-global thread. This shouldn't ever become a hot path or the system is screwed anyway. The only problem with our current error handling is that even rare errors can effectively break the system.
Jörn
--
Victory in war is not repetitious.
-- Sun Tzu
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/9] scsi: improved eh timeout handler
Quoted 3 lines · Jörn Engel
I don't care too much whether we use per-command work items or a single system-global thread.
Actually, I do care. We have to abort the commands in parallel, as a fairly large number of abort can queue up and individual aborts can take 20s on hardware I care about.
20s for an abort is pretty bad, but given today's reality there is no need to make things worse by serializing.
Jörn
--
A defeated army first battles and then seeks victory.
-- Sun Tzu
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/9] scsi: improved eh timeout handler
Quoted 5 lines · Jörn Engel
Quoted 3 lines · Jörn Engel
I don't care too much whether we use per-command work items or a single system-global thread.
Quoted 7 lines
Actually, I do care. We have to abort the commands in parallel, as a fairly large number of abort can queue up and individual aborts can take 20s on hardware I care about.
20s for an abort is pretty bad, but given today's reality there is no need to make things worse by serializing.
We're only serializing aborts per LUN, so this is a _big_ improvement as the original, where we would be serializing per _host_.
Also, upon the first abort failure EH will be escalating to LUN reset, so we won't have to wait for all aborts to time out.
More importantly, the current synchronous implementation of command aborts does not allow for complete de-serialisation:
- There is no way to abort a running command abort, so we have to wait for it to complete, with the chance of running into a timeout.
- We will have to sent command aborts in parallel, and can only stop sending aborts once the first returns an error.
- After we've received an error we have to wait for the outstanding aborts to complete.
-> So the max wait-time will be 2 times the abort timeout.
Not much of a gain here :-)
The _correct_ way of handling asynchronous aborts would be to mandate that the LLDD has to send a command completion on the original command once an abort has been issued. Then we could just kick off the TMF and rearm the request timer. Everything else would then be handled via normal I/O paths.
However, this would mean to implement new callouts into each and every driver. And the actual gain would be dubious, as the several IHVs indicated that a command abort might be handled lazily, ie the target will return a good status, but abort the command only at a later time. Other vendors treat a command abort as a best bet, and rely on the LUN reset to clear up things.
So overall I doubt we'd be gaining much from a fully asynchronous command abort. I'd rather concentrate on getting the remaining bits like LUN reset working correctly.
Cheers,
Hannes
Signature · 8 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/9] scsi: improved eh timeout handler
Quoted 10 lines · Hannes Reinecke
Quoted 9 lines · Jörn Engel
Quoted 3 lines · Jörn Engel
I don't care too much whether we use per-command work items or a single system-global thread.
Actually, I do care. We have to abort the commands in parallel, as a fairly large number of abort can queue up and individual aborts can take 20s on hardware I care about.
Quoted 6 lines
Quoted 3 lines
20s for an abort is pretty bad, but given today's reality there is no need to make things worse by serializing.
We're only serializing aborts per LUN, so this is a _big_ improvement as the original, where we would be serializing per _host_.
I agree it is a big improvement. But I also have some evidence indicating it may not be enough. So let me change my private patch to do parallel aborts and see how it fares.
Quoted 2 lines
Also, upon the first abort failure EH will be escalating to LUN reset, so we won't have to wait for all aborts to time out.
The case I saw was a successful abort taking 20s.
Quoted 11 lines
More importantly, the current synchronous implementation of command aborts does not allow for complete de-serialisation:
- There is no way to abort a running command abort, so we have to wait for it to complete, with the chance of running into a timeout.
- We will have to sent command aborts in parallel, and can only stop sending aborts once the first returns an error.
- After we've received an error we have to wait for the outstanding aborts to complete.
-> So the max wait-time will be 2 times the abort timeout.
Not much of a gain here :-)
I have seen 10 commands get queued for aborts. Assuming the 20s above are the worst case, it will make the difference between 200s and 40s.
Granted, 40s is still horrible. The command in question has just timed out and the kernel should inform userspace about this asap. If a command with a 10s timeout takes 50s to complete, userspace will have to add another layer of timeouts. That should never be necessary.
Quoted 15 lines
The _correct_ way of handling asynchronous aborts would be to mandate that the LLDD has to send a command completion on the original command once an abort has been issued. Then we could just kick off the TMF and rearm the request timer. Everything else would then be handled via normal I/O paths.
However, this would mean to implement new callouts into each and every driver. And the actual gain would be dubious, as the several IHVs indicated that a command abort might be handled lazily, ie the target will return a good status, but abort the command only at a later time. Other vendors treat a command abort as a best bet, and rely on the LUN reset to clear up things.
Quoted 4 lines
So overall I doubt we'd be gaining much from a fully asynchronous command abort. I'd rather concentrate on getting the remaining bits like LUN reset working correctly.
Fair approach. Again, let me play with it and don't let this stop you from making other improvements.
Jörn
--
There's nothing that will change someone's moral outlook quicker than cash in large sums.
-- Larry Flynt
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/9] scsi: improved eh timeout handler
In reply to Christoph HellwigQuoted 19 lines · Christoph Hellwig
Quoted 10 lines · Hannes Reinecke
When a command runs into a timeout we need to send an 'ABORT TASK' TMF. This is typically done by the '
eh_abort_handler' LLDD callback.Conceptually, however, this function is a normal SCSI command, so there is no need to enter the error handler.
This patch implements a new
scsi_abort_command()function which invokes an asynchronous functionscsi_eh_abort_handler()to abort the commands via 'eh_abort_handler'.Quoted 7 lines
If the '
eh_abort_handler' returns SUCCESS orFAST_IO_FAILthe command will be retried if possible. If no retries are allowed the command will be returned immediately, as we have to assume the TMF succeeded and the command is completed with the LLDD. If the TMF fails the command will be pushed back onto the list of failed commands and the SCSI EH handler will be called immediately for all timed-out commands.
Quoted 3 lines
Why can't we use a work item per command? Linking things into a list just to queue it up to workqueues missed half of the point of the workqueue infrastructure.
Actually, I think we can dump the workqueue altogether. The only reason we need it is because the current abort handlers wait for the command and return the completion state. However, all LLDs are capable of emitting TMFs at interrupt level, so if we separated the emit from the wait, we could simply do this sequence:
on timeout, fire the abort from interrupt and mark the command as having an abort issued (possibly by adding a pointer to the abort task), return BLK_EH_RESET_TIMER.
Now if the timeout fires again, assume the abort was unsucessful and escalate to LUN reset.
This is fully asynchronous, fully tracked and doesn't rely on work queues.
The necessary additions for something like this are the from interrupt issue abort and LUN reset, which could just be additional callbacks in the host template.
James
Re: [PATCH 3/9] scsi: improved eh timeout handler
Quoted 30 lines · James Bottomley
Quoted 19 lines · Christoph Hellwig
Quoted 10 lines · Hannes Reinecke
When a command runs into a timeout we need to send an 'ABORT TASK' TMF. This is typically done by the '
eh_abort_handler' LLDD callback.Conceptually, however, this function is a normal SCSI command, so there is no need to enter the error handler.
This patch implements a new
scsi_abort_command()function which invokes an asynchronous functionscsi_eh_abort_handler()to abort the commands via 'eh_abort_handler'.Quoted 7 lines
If the '
eh_abort_handler' returns SUCCESS orFAST_IO_FAILthe command will be retried if possible. If no retries are allowed the command will be returned immediately, as we have to assume the TMF succeeded and the command is completed with the LLDD. If the TMF fails the command will be pushed back onto the list of failed commands and the SCSI EH handler will be called immediately for all timed-out commands.Quoted 3 lines
Why can't we use a work item per command? Linking things into a list just to queue it up to workqueues missed half of the point of the workqueue infrastructure.
Actually, I think we can dump the workqueue altogether. The only reason we need it is because the current abort handlers wait for the command and return the completion state. However, all LLDs are capable of emitting TMFs at interrupt level, so if we separated the emit from the wait, we could simply do this sequence:
Quoted 3 lines
on timeout, fire the abort from interrupt and mark the command as having an abort issued (possibly by adding a pointer to the abort task), return
BLK_EH_RESET_TIMER.
Doesn't this cause blk_rq_timed_out to reset the timer on the req to the original timeout value again? It seems like this would increase the time before any further attempted error handling. The default timeout is 30 seconds for sd, but it could be much longer (e.g. WRITE SAME, which was 120 seconds last I looked).
Quoted 12 lines
Now if the timeout fires again, assume the abort was unsucessful and escalate to LUN reset.
This is fully asynchronous, fully tracked and doesn't rely on work queues.
The necessary additions for something like this are the from interrupt issue abort and LUN reset, which could just be additional callbacks in the host template.
James
Re: [PATCH 3/9] scsi: improved eh timeout handler
Quoted 35 lines · Ewan Milne
Quoted 30 lines · James Bottomley
Quoted 19 lines · Christoph Hellwig
Quoted 10 lines · Hannes Reinecke
When a command runs into a timeout we need to send an 'ABORT TASK' TMF. This is typically done by the '
eh_abort_handler' LLDD callback.Conceptually, however, this function is a normal SCSI command, so there is no need to enter the error handler.
This patch implements a new
scsi_abort_command()function which invokes an asynchronous functionscsi_eh_abort_handler()to abort the commands via 'eh_abort_handler'.Quoted 7 lines
If the '
eh_abort_handler' returns SUCCESS orFAST_IO_FAILthe command will be retried if possible. If no retries are allowed the command will be returned immediately, as we have to assume the TMF succeeded and the command is completed with the LLDD. If the TMF fails the command will be pushed back onto the list of failed commands and the SCSI EH handler will be called immediately for all timed-out commands.Quoted 3 lines
Why can't we use a work item per command? Linking things into a list just to queue it up to workqueues missed half of the point of the workqueue infrastructure.
Actually, I think we can dump the workqueue altogether. The only reason we need it is because the current abort handlers wait for the command and return the completion state. However, all LLDs are capable of emitting TMFs at interrupt level, so if we separated the emit from the wait, we could simply do this sequence:
Quoted 3 lines
on timeout, fire the abort from interrupt and mark the command as having an abort issued (possibly by adding a pointer to the abort task), return
BLK_EH_RESET_TIMER.
Quoted 5 lines
Doesn't this cause
blk_rq_timed_outto reset the timer on the req to the original timeout value again? It seems like this would increase the time before any further attempted error handling. The default timeout is 30 seconds for sd, but it could be much longer (e.g. WRITE SAME, which was 120 seconds last I looked).
It currently does, but that's fixable via a special return code.
James
Re: [PATCH 3/9] scsi: improved eh timeout handler
In reply to James BottomleyQuoted 34 lines · James Bottomley
Quoted 19 lines · Christoph Hellwig
Quoted 10 lines · Hannes Reinecke
When a command runs into a timeout we need to send an 'ABORT TASK' TMF. This is typically done by the '
eh_abort_handler' LLDD callback.Conceptually, however, this function is a normal SCSI command, so there is no need to enter the error handler.
This patch implements a new
scsi_abort_command()function which invokes an asynchronous functionscsi_eh_abort_handler()to abort the commands via 'eh_abort_handler'.Quoted 7 lines
If the '
eh_abort_handler' returns SUCCESS orFAST_IO_FAILthe command will be retried if possible. If no retries are allowed the command will be returned immediately, as we have to assume the TMF succeeded and the command is completed with the LLDD. If the TMF fails the command will be pushed back onto the list of failed commands and the SCSI EH handler will be called immediately for all timed-out commands.Quoted 3 lines
Why can't we use a work item per command? Linking things into a list just to queue it up to workqueues missed half of the point of the workqueue infrastructure.
Actually, I think we can dump the workqueue altogether. The only reason we need it is because the current abort handlers wait for the command and return the completion state. However, all LLDs are capable of emitting TMFs at interrupt level, so if we separated the emit from the wait, we could simply do this sequence:
on timeout, fire the abort from interrupt and mark the command as having an abort issued (possibly by adding a pointer to the abort task), return
BLK_EH_RESET_TIMER.
Quoted 6 lines
Now if the timeout fires again, assume the abort was unsucessful and escalate to LUN reset.
This is fully asynchronous, fully tracked and doesn't rely on work queues.
Hehe. Been there, done that, doesn't work :-(
That was my original idea, too.
But some LLDDs send TMFs in a non-interrupt-safe way, so the only way to make it work was to use a workqueue.
(Eg qla2xxx has a parameter to send TMFs async, but this doesn't work on older firmware).
Quoted 4 lines
The necessary additions for something like this are the from interrupt issue abort and LUN reset, which could just be additional callbacks in the host template.
However, we could make that optional, so that LLDDs not capable of sending TMFs in an interrupt-safe manner will continue to use the original framework.
Ok, let's see whether this flies.
Cheers,
Hannes
Signature · 8 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/9] scsi: improved eh timeout handler
In reply to James BottomleyQuoted 13 lines · James Bottomley
Actually, I think we can dump the workqueue altogether. The only reason we need it is because the current abort handlers wait for the command and return the completion state. However, all LLDs are capable of emitting TMFs at interrupt level, so if we separated the emit from the wait, we could simply do this sequence:
on timeout, fire the abort from interrupt and mark the command as having an abort issued (possibly by adding a pointer to the abort task), return
BLK_EH_RESET_TIMER.Now if the timeout fires again, assume the abort was unsuccessful and escalate to LUN reset.
Quoted 6 lines
This is fully asynchronous, fully tracked and doesn't rely on work queues.
The necessary additions for something like this are the from interrupt issue abort and LUN reset, which could just be additional callbacks in the host template.
Do we really need a new callback in the host template for a command abort that does not wait ? Several LLDs already have their own internal data structures for keeping track of the request state and can use these data structures to set a flag "command has been aborted". If aborting a command fails and the command completes that flag can then be used to avoid a second invocation of scsi_done(). At least, that's what the SRP initiator already does today in srp_abort().
Bart.
Re: [PATCH 3/9] scsi: improved eh timeout handler
Quoted 27 lines · Bart Van Assche
Quoted 17 lines · James Bottomley
Actually, I think we can dump the workqueue altogether. The only reason
we need it is because the current abort handlers wait for the command and return the completion state. However, all LLDs are capable of emitting TMFs at interrupt level, so if we separated the emit from the
wait, we could simply do this sequence:on timeout, fire the abort from interrupt and mark the command as having
an abort issued (possibly by adding a pointer to the abort task), returnBLK_EH_RESET_TIMER.Now if the timeout fires again, assume the abort was unsuccessful and escalate to LUN reset.
Quoted 8 lines
This is fully asynchronous, fully tracked and doesn't rely on work queues.
The necessary additions for something like this are the from interrupt
issue abort and LUN reset, which could just be additional callbacks in
the host template.
Quoted 9 lines
Do we really need a new callback in the host template for a command abort that does not wait ? Several LLDs already have their own internal data structures for keeping track of the request state and can use these data structures to set a flag "command has been aborted". If aborting a command fails and the command completes that flag can then be used to avoid a second invocation of
scsi_done(). At least, that's what the SRP initiator already does today insrp_abort().
Currently I'm playing around with this:
include/scsi/scsi_host.h +3 -0
@@ -174,6 +174,9 @@ struct scsi_host_template {int (* eh_bus_reset_handler)(struct scsi_cmnd *);int (* eh_host_reset_handler)(struct scsi_cmnd *); +int (* eh_send_abort)(struct scsi_cmnd *); +void (* eh_cancel_abort)(struct scsi_cmnd *); +/*
'eh_send_abort' sends the TMF asynchronously; it is the drivers responsibility to return the command to be aborted to the SCSI midlayer after calling this function.
The return value is 'SUCCESS' if the TMF was sent or 'FAILED' if sending the TMF failed. It does _not_ indicate the status of the TMF itself, as this is done implicitly by returning the command with an appropriate status.
'eh_cancel_abort' is optional, and can be called at any time after 'eh_send_abort' to cancel the TMF. After calling 'eh_cancel_abort' neither the TMF nor the command must be considered valid from the LLDD. 'eh_cancel_abort' is for LLDDs requiring cleanups when aborting TMFs. LLDDs not requiring any cleanup simply can not implement this callback.
Cheers,
Hannes
Signature · 8 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 3/9] scsi: improved eh timeout handler
In reply to Hannes Reineckedrivers/scsi/scsi_error.c void scsi_schedule_eh(struct Scsi_Host *shost) · line 208
Quoted 10 lines · Hannes Reinecke
drivers/scsi/scsi_error.c +10
-0+ +spin_lock_irqsave (&sdev->list_lock, flags); +if (list_empty (&sdev->eh_abort_list)) + kick_worker =1 ; +list_add (&scmd->eh_entry, &sdev->eh_abort_list); +spin_unlock_irqrestore (&sdev->list_lock, flags); +SCSI_LOG_ERROR_RECOVERY (3 , +scmd_printk (KERN_INFO , scmd,"adding to eh_abort_list\n" )); +if (kick_worker) +schedule_work (&sdev->abort_work);
You fixed the case with the non-empty list. But afaics the same workitem can still be called multiple times simultaneously, which will crash the system.
Jörn
--
The only real mistake is the one from which we learn nothing. -- John Powell
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 4/9 virtio_scsi: Enable new EH timeout handler
In reply to Hannes Reinecke--- drivers/scsi/virtio_scsi.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/scsi/virtio_scsi.c +7 -0
@@ -654,6 +654,11 @@ static int virtscsi_abort(struct scsi_cmnd *sc)return virtscsi_tmf (vscsi, cmd); } +static enum blk_eh_timer_return virtscsi_timedout (struct scsi_cmnd *scmd) +{ +return scsi_abort_command (scmd); +} +static int virtscsi_target_alloc (struct scsi_target *starget) { struct virtio_scsi_target_state *tgt =
@@ -683,6 +688,7 @@ static struct scsi_host_template virtscsi_host_template_single = { .queuecommand = virtscsi_queuecommand_single, .eh_abort_handler = virtscsi_abort, .eh_device_reset_handler = virtscsi_device_reset, + .eh_timed_out = virtscsi_timedout, .can_queue = 1024, .dma_boundary = UINT_MAX,
@@ -699,6 +705,7 @@ static struct scsi_host_template virtscsi_host_template_multi = { .queuecommand = virtscsi_queuecommand_multi, .eh_abort_handler = virtscsi_abort, .eh_device_reset_handler = virtscsi_device_reset, + .eh_timed_out = virtscsi_timedout, .can_queue = 1024, .dma_boundary = UINT_MAX,
Signature · 1 line
1.7.12.4
Re: [PATCH 4/9] virtio_scsi: Enable new EH timeout handler
Il 10/06/2013 03:40, Hannes Reinecke ha scritto:
Quoted 31 lines
Signed-off-by Hannes Reinecke <[email protected]>--- drivers/scsi/virtio_scsi.c | 7 +++++++ 1 file changed, 7 insertions(+)drivers/scsi/virtio_scsi.c +6
-0@@ -654,6 +654,11 @@ static int virtscsi_abort(struct scsi_cmnd *sc)return virtscsi_tmf (vscsi, cmd); } +static enum blk_eh_timer_return virtscsi_timedout (struct scsi_cmnd *scmd) +{ +return scsi_abort_command (scmd); +} +static int virtscsi_target_alloc (struct scsi_target *starget) { struct virtio_scsi_target_state *tgt =@@ -683,6 +688,7 @@ static struct scsi_host_template virtscsi_host_template_single = { .queuecommand = virtscsi_queuecommand_single, .eh_abort_handler = virtscsi_abort, .eh_device_reset_handler = virtscsi_device_reset, + .eh_timed_out = virtscsi_timedout, .can_queue = 1024, .dma_boundary = UINT_MAX,
drivers/scsi/virtio_scsi.c static struct scsi_host_template virtscsi_host_template_multi = { · line 711
Quoted 7 lines
drivers/scsi/virtio_scsi.c +1
-0@@ -699,6 +705,7 @@ static struct scsi_host_template virtscsi_host_template_multi = { .queuecommand = virtscsi_queuecommand_multi, .eh_abort_handler = virtscsi_abort, .eh_device_reset_handler = virtscsi_device_reset, + .eh_timed_out = virtscsi_timedout, .can_queue = 1024, .dma_boundary = UINT_MAX,
Re: [PATCH 4/9] virtio_scsi: Enable new EH timeout handler
In reply to Hannes ReineckeQuoted 1 line · Hannes Reinecke
Signed-off-by Hannes Reinecke <[email protected]>
Quoted 43 lines
--- drivers/scsi/virtio_scsi.c | 7 +++++++ 1 file changed, 7 insertions(+)drivers/scsi/virtio_scsi.c +7
-0@@ -654,6 +654,11 @@ static int virtscsi_abort(struct scsi_cmnd *sc)return virtscsi_tmf (vscsi, cmd); } +static enum blk_eh_timer_return virtscsi_timedout (struct scsi_cmnd *scmd) +{ +return scsi_abort_command (scmd); +} +static int virtscsi_target_alloc (struct scsi_target *starget) { struct virtio_scsi_target_state *tgt =@@ -683,6 +688,7 @@ static struct scsi_host_template virtscsi_host_template_single = { .queuecommand = virtscsi_queuecommand_single, .eh_abort_handler = virtscsi_abort, .eh_device_reset_handler = virtscsi_device_reset, + .eh_timed_out = virtscsi_timedout, .can_queue = 1024, .dma_boundary = UINT_MAX,@@ -699,6 +705,7 @@ static struct scsi_host_template virtscsi_host_template_multi = { .queuecommand = virtscsi_queuecommand_multi, .eh_abort_handler = virtscsi_abort, .eh_device_reset_handler = virtscsi_device_reset, + .eh_timed_out = virtscsi_timedout, .can_queue = 1024, .dma_boundary = UINT_MAX,Signature · 6 lines
1.7.12.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 1 line
Asias
PATCH v2 5/9 virtio-scsi: Implement TMF timeout
In reply to Hannes ReineckeAny TMF might be take longer as expected, or not return at all. So we need to use 'wait_for_completion_timeout' when sending a TMF to protect against these cases.
--- drivers/scsi/virtio_scsi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/scsi/virtio_scsi.c +5 -2
@@ -30,6 +30,7 @@#define VIRTIO_SCSI_MEMPOOL_SZ 64#define VIRTIO_SCSI_EVENT_LEN 8#define VIRTIO_SCSI_VQ_BASE 2 +#define VIRTIO_SCSI_TMF_TIMEOUT 30/* Command queue element */ struct virtio_scsi_cmd {
@@ -597,8 +598,10 @@ static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd) GFP_NOIO) < 0) goto out; -wait_for_completion (&comp); -if (cmd->resp.tmf.response ==VIRTIO_SCSI_S_OK || +if (wait_for_completion_timeout (&comp, +VIRTIO_SCSI_TMF_TIMEOUT *HZ ) ==0 ) + ret =FAILED ; +else if (cmd->resp.tmf.response ==VIRTIO_SCSI_S_OK || cmd->resp.tmf.response ==VIRTIO_SCSI_S_FUNCTION_SUCCEEDED ) ret =SUCCESS ;
Signature · 1 line
1.7.12.4
Re: [PATCH 5/9] virtio-scsi: Implement TMF timeout
Il 10/06/2013 03:40, Hannes Reinecke ha scritto:
Quoted 26 lines
Any TMF might be take longer as expected, or not return at all. So we need to use '
wait_for_completion_timeout' when sending a TMF to protect against these cases.Cc Paolo Bonzini <[email protected]>Signed-off-by Hannes Reinecke <[email protected]>--- drivers/scsi/virtio_scsi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)drivers/scsi/virtio_scsi.c +1
-0@@ -30,6 +30,7 @@#define VIRTIO_SCSI_MEMPOOL_SZ 64#define VIRTIO_SCSI_EVENT_LEN 8#define VIRTIO_SCSI_VQ_BASE 2 +#define VIRTIO_SCSI_TMF_TIMEOUT 30/* Command queue element */ struct virtio_scsi_cmd {@@ -597,8 +598,10 @@ static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd) GFP_NOIO) < 0) goto out;
drivers/scsi/virtio_scsi.c static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd) · line 607
Quoted 10 lines
drivers/scsi/virtio_scsi.c +4
-2-wait_for_completion (&comp); -if (cmd->resp.tmf.response ==VIRTIO_SCSI_S_OK || +if (wait_for_completion_timeout (&comp, +VIRTIO_SCSI_TMF_TIMEOUT *HZ ) ==0 ) + ret =FAILED ; +else if (cmd->resp.tmf.response ==VIRTIO_SCSI_S_OK || cmd->resp.tmf.response ==VIRTIO_SCSI_S_FUNCTION_SUCCEEDED ) ret =SUCCESS ;
Re: [PATCH 5/9] virtio-scsi: Implement TMF timeout
In reply to Hannes ReineckeQuoted 6 lines · Hannes Reinecke
Any TMF might be take longer as expected, or not return at all. So we need to use '
wait_for_completion_timeout' when sending a TMF to protect against these cases.Cc Paolo Bonzini <[email protected]>Signed-off-by Hannes Reinecke <[email protected]>
Quoted 36 lines
--- drivers/scsi/virtio_scsi.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)drivers/scsi/virtio_scsi.c +5
-2@@ -30,6 +30,7 @@#define VIRTIO_SCSI_MEMPOOL_SZ 64#define VIRTIO_SCSI_EVENT_LEN 8#define VIRTIO_SCSI_VQ_BASE 2 +#define VIRTIO_SCSI_TMF_TIMEOUT 30/* Command queue element */ struct virtio_scsi_cmd {@@ -597,8 +598,10 @@ static int virtscsi_tmf(struct virtio_scsi *vscsi, struct virtio_scsi_cmd *cmd) GFP_NOIO) < 0) goto out; -wait_for_completion (&comp); -if (cmd->resp.tmf.response ==VIRTIO_SCSI_S_OK || +if (wait_for_completion_timeout (&comp, +VIRTIO_SCSI_TMF_TIMEOUT *HZ ) ==0 ) + ret =FAILED ; +else if (cmd->resp.tmf.response ==VIRTIO_SCSI_S_OK || cmd->resp.tmf.response ==VIRTIO_SCSI_S_FUNCTION_SUCCEEDED ) ret =SUCCESS ;Signature · 6 lines
1.7.12.4 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 1 line
Asias
PATCH v2 6/9 libsas: Enable new EH timeout handler
In reply to Hannes Reinecke--- drivers/scsi/libsas/sas_scsi_host.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/scsi/libsas/sas_scsi_host.c +1 -1
@@ -864,7 +864,7 @@ enum blk_eh_timer_return sas_scsi_timed_out(struct scsi_cmnd *cmd) {scmd_printk (KERN_DEBUG , cmd,"command %p timed out\n" , cmd); -return BLK_EH_NOT_HANDLED ; +return scsi_abort_command (cmd); }int sas_ioctl (struct scsi_device *sdev,int cmd,void __user *arg)
Signature · 1 line
1.7.12.4
PATCH v2 7/9 mptsas: Enable new EH timeout handler
In reply to Hannes Reinecke--- drivers/message/fusion/mptsas.c | 1 + drivers/message/fusion/mptscsih.c | 7 +++++++ drivers/message/fusion/mptscsih.h | 1 + 3 files changed, 9 insertions(+)
drivers/message/fusion/mptsas.c +1 -0
@@ -1987,6 +1987,7 @@ static struct scsi_host_template mptsas_driver_template = { .target_destroy = mptsas_target_destroy, .slave_destroy = mptscsih_slave_destroy, .change_queue_depth = mptscsih_change_queue_depth, + .eh_timed_out = mptscsih_timed_out, .eh_abort_handler = mptscsih_abort, .eh_device_reset_handler = mptscsih_dev_reset, .eh_host_reset_handler = mptscsih_host_reset,
drivers/message/fusion/mptscsih.c +7 -0
@@ -1679,6 +1679,13 @@ mptscsih_get_tm_timeout(MPT_ADAPTER *ioc) } } +enum blk_eh_timer_return +mptscsih_timed_out (struct scsi_cmnd *SCpnt) +{ +return scsi_abort_command (SCpnt); +} +EXPORT_SYMBOL (mptscsih_timed_out); +/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /** * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
drivers/message/fusion/mptscsih.h +1 -0
@@ -118,6 +118,7 @@ extern int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout);extern void mptscsih_slave_destroy (struct scsi_device *device);extern int mptscsih_slave_configure (struct scsi_device *device); +enum blk_eh_timer_return mptscsih_timed_out (struct scsi_cmnd *SCpnt);extern int mptscsih_abort (struct scsi_cmnd * SCpnt);extern int mptscsih_dev_reset (struct scsi_cmnd * SCpnt);extern int mptscsih_bus_reset (struct scsi_cmnd * SCpnt);
Signature · 1 line
1.7.12.4
PATCH v2 8/9 mpt2sas: Enable new EH timeout handler
In reply to Hannes Reinecke--- drivers/scsi/mpt2sas/mpt2sas_scsih.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/scsi/mpt2sas/mpt2sas_scsih.c +11 -0
@@ -2565,6 +2565,16 @@ _scsih_tm_display_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd) }/** +* _scsih_timed_out - eh timeout handler +* @scmd: pointer to scsi command object +*/ +static enum blk_eh_timer_return +_scsih_timed_out (struct scsi_cmnd *scmd) +{ +return scsi_abort_command (scmd); +} + +/** * _scsih_abort - eh threads main abort routine * @scmd: pointer to scsi command object *
@@ -7515,6 +7525,7 @@ static struct scsi_host_template scsih_driver_template = { .scan_start = _scsih_scan_start, .change_queue_depth = _scsih_change_queue_depth, .change_queue_type = _scsih_change_queue_type, + .eh_timed_out = _scsih_timed_out, .eh_abort_handler = _scsih_abort, .eh_device_reset_handler = _scsih_dev_reset, .eh_target_reset_handler = _scsih_target_reset,
Signature · 1 line
1.7.12.4
Re: [PATCH 8/9] mpt2sas: Enable new EH timeout handler
Quoted 12 lines · Hannes Reinecke
Signed-off-by Hannes Reinecke <[email protected]>--- drivers/scsi/mpt2sas/mpt2sas_scsih.c | 11 +++++++++++ 1 file changed, 11 insertions(+)drivers/scsi/mpt2sas/mpt2sas_scsih.c +0
-0@@ -2565,6 +2565,16 @@ _scsih_tm_display_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd) }
drivers/scsi/mpt2sas/mpt2sas_scsih.c _scsih_tm_display_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd) · line 2575
Quoted 10 lines
drivers/scsi/mpt2sas/mpt2sas_scsih.c +8
-0/** +* _scsih_timed_out - eh timeout handler +* @scmd: pointer to scsi command object +*/ +static enum blk_eh_timer_return +_scsih_timed_out (struct scsi_cmnd *scmd) +{ +return scsi_abort_command (scmd); +}
Why did you create this function and not do the following?
+ .eh_timed_out = scsi_abort_command,
Quoted 15 lines
drivers/scsi/mpt2sas/mpt2sas_scsih.c +2
-0+/** * _scsih_abort - eh threads main abort routine * @scmd: pointer to scsi command object * @@ -7515,6 +7525,7 @@ static struct scsi_host_template scsih_driver_template = { .scan_start = _scsih_scan_start, .change_queue_depth = _scsih_change_queue_depth, .change_queue_type = _scsih_change_queue_type, + .eh_timed_out = _scsih_timed_out, .eh_abort_handler = _scsih_abort, .eh_device_reset_handler = _scsih_dev_reset, .eh_target_reset_handler = _scsih_target_reset,Signature · 1 line
1.7.12.4
Jörn
--
The cheapest, fastest and most reliable components of a computer system are those that aren't there.
-- Gordon Bell, DEC labratories
--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 8/9] mpt2sas: Enable new EH timeout handler
Quoted 26 lines · Jörn Engel
Quoted 12 lines · Hannes Reinecke
Signed-off-by Hannes Reinecke <[email protected]>--- drivers/scsi/mpt2sas/mpt2sas_scsih.c | 11 +++++++++++ 1 file changed, 11 insertions(+)drivers/scsi/mpt2sas/mpt2sas_scsih.c +0
-0@@ -2565,6 +2565,16 @@ _scsih_tm_display_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd) }drivers/scsi/mpt2sas/mpt2sas_scsih.c _scsih_tm_display_info(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd) · line 2575
Quoted 10 lines
drivers/scsi/mpt2sas/mpt2sas_scsih.c +8
-0/** +* _scsih_timed_out - eh timeout handler +* @scmd: pointer to scsi command object +*/ +static enum blk_eh_timer_return +_scsih_timed_out (struct scsi_cmnd *scmd) +{ +return scsi_abort_command (scmd); +}Why did you create this function and not do the following?
Review
Quoted 1 line
(quoted diff) +1
-0+ .eh_timed_out = scsi_abort_command,
Good point.
That function was required for an earlier version (where I had 'void scsi_abort_command()').
So yeah, that function isn't required.
Cheers,
Hannes
Signature · 8 lines
Dr. Hannes Reinecke zSeries & Storage [email protected] +49 911 74053 688 SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: J. Hawn, J. Guild, F. Imendörffer, HRB 16746 (AG Nürnberg) -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
PATCH v2 9/9 mpt3sas: Enable new EH timeout handler
In reply to Hannes Reinecke--- drivers/scsi/mpt3sas/mpt3sas_scsih.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
drivers/scsi/mpt3sas/mpt3sas_scsih.c +11 -0
@@ -2228,6 +2228,16 @@ _scsih_tm_display_info(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd) }/** +* _scsih_timed_out - eh timeout handler +* @scmd: pointer to scsi command object +*/ +static enum blk_eh_timer_return +_scsih_timed_out (struct scsi_cmnd *scmd) +{ +return scsi_abort_command (scmd); +} + +/** * _scsih_abort - eh threads main abort routine * @scmd: pointer to scsi command object *
@@ -7230,6 +7240,7 @@ static struct scsi_host_template scsih_driver_template = { .scan_start = _scsih_scan_start, .change_queue_depth = _scsih_change_queue_depth, .change_queue_type = _scsih_change_queue_type, + .eh_timed_out = _scsih_timed_out, .eh_abort_handler = _scsih_abort, .eh_device_reset_handler = _scsih_dev_reset, .eh_target_reset_handler = _scsih_target_reset,
Signature · 1 line
1.7.12.4