Re: [PATCH v1 1/2] ata: libata-scsi: terminate deferred commands on time out
Niklas Cassel <[email protected]> Thu, 9 Jul 2026 19:27:09 +0200
| Newsgroups | gmane.linux.scsi,gmane.linux.ide |
|---|---|
| Message-ID | <ak_Z7Y1j7yoS_R-J@fedora> |
On Thu, Jul 09, 2026 at 06:14:08PM +0900, Damien Le Moal wrote:
> > It seems this causes the handler to fall into the 'raced completion' branch:
> >
> > drivers/ata/libata-eh.c:ata_scsi_cmd_error_handler() {
> > ...
> > } else {
> > /* Normal completion occurred after
> > * SCSI timeout but before this point.
> > * Successfully complete it.
> > */
> > scmd->retries = scmd->allowed;
> > scsi_eh_finish_cmd(scmd, &ap->eh_done_q);
> > }
> > ...
> > }
>
> And after this, scsi_eh_flush_done_q() will retry the command.
> Tested and I do not see failure of the deferred QC :)
I don't see how scsi_eh_flush_done_q() will retry the command.
Since ata_scsi_eh_timed_out() calls ata_scsi_qc_done(), which
calls scsi_done(), which calls scsi_done_internal(cmd, false),
which sets SCMD_STATE_COMPLETE, scsi_timeout() will never add
the scmd to the list of failed scmds using scsi_eh_scmd_add().
Thus, when ata_scsi_cmd_error_handler() loops though the list
of failed scmds, the scmd in question will never have been added
in the first place.
Most likely the command is retried via:
ata_scsi_qc_done() -> scsi_done() -> scsi_done_internal()
softirq -> scsi_complete() -> scsi_decide_disposition()
scsi_decide_disposition() returns ADD_TO_MLQUEUE for DID_REQUEUE,
scsi_complete() calls scsi_queue_insert(cmd, SCSI_MLQUEUE_DEVICE_BUSY);
when scsi_decide_disposition() returns ADD_DO_MLQUEUE.
Kind regards,
Niklas