From: Niklas Cassel <cassel@kernel.org>
To: Damien Le Moal <dlemoal@kernel.org>
Cc: linux-ide@vger.kernel.org, linux-scsi@vger.kernel.org,
"Martin K . Petersen" <martin.petersen@oracle.com>,
Igor Pylypiv <ipylypiv@google.com>,
John Garry <john.g.garry@oracle.com>,
Jason Yan <yanaijie@huawei.com>
Subject: Re: [PATCH v2 1/2] ata: libata-scsi: terminate deferred commands on time out
Date: Fri, 10 Jul 2026 09:32:24 +0200 [thread overview]
Message-ID: <alCgCE9PtbEWSqL9@fedora> (raw)
In-Reply-To: <20260710000646.1202200-2-dlemoal@kernel.org>
On Fri, Jul 10, 2026 at 09:06:45AM +0900, Damien Le Moal wrote:
> If a command timeout occurs while we have a deferred non-NCQ command
> waiting to be issued, the SCSI EH task is never woken up as the waiting
> deferred command is never issued nor completed, thus leaving this command
> to always be counted as "busy" for the SCSI host. This results in the
> scsi_error_handler() function test "shost->host_failed !=
> scsi_host_busy(shost))" to always be true, keeping the EH task sleeping.
> Eventuially, when the deferred command also times out, the SCSI EH task
> is woken up and the timeout processing occurs.
>
> Avoid this unnecessary EH trigger additional wait time using the
> eh_timed_out SCSI host template operation. The function
> ata_scsi_eh_timed_out() is introduced to implement this operation using
> the helper function ata_scsi_port_eh_timed_out(). This function calls
> ata_scsi_requeue_deferred_qc() to force a requeue of deferred QCs, except
> for QCs that actually timed out. In this case,
> ata_scsi_cmd_error_handler() processing of timed out deferred QCs still
> applies. Since the timeout itself and eventual re-issuing of deferred
> commands is not handled by this helper, SCSI_EH_NOT_HANDLED is returned
> to have scsi_timeout() continue with the regular timeout handling.
>
> Fixes: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation")
> Cc: stable@vger.kernel.org
> Signed-off-by: Damien Le Moal <dlemoal@kernel.org>
> ---
> drivers/ata/libata-eh.c | 2 +-
> drivers/ata/libata-scsi.c | 51 +++++++++++++++++++++++++++++++++------
> drivers/ata/libata.h | 3 ++-
> include/linux/libata.h | 2 ++
> 4 files changed, 48 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
> index 05df7ea6954a..57d3d2d11dd8 100644
> --- a/drivers/ata/libata-eh.c
> +++ b/drivers/ata/libata-eh.c
> @@ -951,7 +951,7 @@ static void ata_eh_set_pending(struct ata_port *ap, bool fastdrain)
> * If we have a deferred qc, requeue it so that it is retried once EH
> * completes.
> */
> - ata_scsi_requeue_deferred_qc(ap);
> + ata_scsi_requeue_deferred_qc(ap, NULL);
>
> if (!fastdrain)
> return;
> diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
> index 5868526301a2..b6e25aab01d5 100644
> --- a/drivers/ata/libata-scsi.c
> +++ b/drivers/ata/libata-scsi.c
> @@ -1685,7 +1685,8 @@ void ata_scsi_deferred_qc_work(struct work_struct *work)
> spin_unlock_irqrestore(ap->lock, flags);
> }
>
> -void ata_scsi_requeue_deferred_qc(struct ata_port *ap)
> +void ata_scsi_requeue_deferred_qc(struct ata_port *ap,
> + struct scsi_cmnd *timed_out_scmd)
> {
> struct ata_link *link;
>
> @@ -1694,16 +1695,19 @@ void ata_scsi_requeue_deferred_qc(struct ata_port *ap)
> /*
> * If we have a deferred qc when a reset occurs or NCQ commands fail,
> * do not try to be smart about what to do with this deferred command
> - * and simply requeue it by completing it with DID_REQUEUE.
> + * and simply requeue it by completing it with DID_REQUEUE. The
> + * exception here is if the deferred qc timed out, in which case, we
> + * leave it as is as ata_scsi_cmd_error_handler() will take care of it.
> */
> ata_for_each_link(link, ap, PMP_FIRST) {
> struct ata_queued_cmd *qc = link->deferred_qc;
I like this patch much more than V1, as it does not duplicate the code which
specifically handles the case where the deferred QC timed out.
>
> - if (qc) {
Personally I would write this as:
if (qc && qc->scsicmd != timed_out_scmd)
to make the patch about 7 lines smaller.
> - link->deferred_qc = NULL;
> - cancel_work(&link->deferred_qc_work);
> - ata_scsi_qc_done(qc, true, DID_REQUEUE << 16);
> - }
> + if (!qc || qc->scsicmd == timed_out_scmd)
> + continue;
> +
> + link->deferred_qc = NULL;
> + cancel_work(&link->deferred_qc_work);
> + ata_scsi_qc_done(qc, true, DID_REQUEUE << 16);
> }
> }
>
next prev parent reply other threads:[~2026-07-10 7:32 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-10 0:06 [PATCH v2 0/2] fixup handling of timeouts with deferred QCs Damien Le Moal
2026-07-10 0:06 ` [PATCH v2 1/2] ata: libata-scsi: terminate deferred commands on time out Damien Le Moal
2026-07-10 0:24 ` sashiko-bot
2026-07-10 7:25 ` Damien Le Moal
2026-07-10 8:06 ` Niklas Cassel
2026-07-10 8:29 ` Damien Le Moal
2026-07-10 8:48 ` Niklas Cassel
2026-07-10 8:39 ` Niklas Cassel
2026-07-10 7:32 ` Niklas Cassel [this message]
2026-07-10 0:06 ` [PATCH v2 2/2] scsi: libsas: " Damien Le Moal
2026-07-10 1:53 ` Jason Yan
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=alCgCE9PtbEWSqL9@fedora \
--to=cassel@kernel.org \
--cc=dlemoal@kernel.org \
--cc=ipylypiv@google.com \
--cc=john.g.garry@oracle.com \
--cc=linux-ide@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=martin.petersen@oracle.com \
--cc=yanaijie@huawei.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.