<feed xmlns='http://www.w3.org/2005/Atom'>
<title>kernel/git/stable/linux.git/drivers/ata/libata-eh.c, branch linux-7.2.y</title>
<subtitle>Linux kernel stable tree</subtitle>
<id>https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/atom?h=linux-7.2.y</id>
<link rel='self' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/atom?h=linux-7.2.y'/>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/'/>
<updated>2026-07-29T01:51:57+00:00</updated>
<entry>
<title>ata: libata-scsi: terminate deferred commands on time out</title>
<updated>2026-07-29T01:51:57+00:00</updated>
<author>
<name>Damien Le Moal</name>
<email>dlemoal@kernel.org</email>
</author>
<published>2026-07-09T01:01:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=2e1d2e65e773d67dab163127f11a47dab0fbca9f'/>
<id>urn:sha1:2e1d2e65e773d67dab163127f11a47dab0fbca9f</id>
<content type='text'>
If a command times out while we have deferred non-NCQ commands waiting to
be issued, the SCSI EH task is not immediately woken up as the waiting
deferred commands are never issued nor completed, thus leaving the SCSI
host in a busy state (shost-&gt;host_failed != scsi_host_busy(shost)) which
prevents the SCSI EH task from being woken up. Eventually, when the
deferred commands also time out, the SCSI EH task is woken up and the
timeout processing occurs.

Avoid this unnecessary SCSI EH task wake-up additional time by scheduling
a retry of all waiting deferred QCs, using the eh_timed_out SCSI host
template operation. The function ata_scsi_eh_timed_out() is introduced to
implement this operation.

However, terminating deferred commands with DID_REQUEUE to force a retry
by calling the function ata_scsi_requeue_deferred_qc() may still keep the
SCSI host in a busy state because the block layer may immediately re-issue
these commands. The solution to this is to schedule libata EH for the
port which suffered the command timeout to prevent accepting any new
command. ata_scsi_requeue_deferred_qc() is modified to add a call to
ata_port_schedule_eh() for this purpose.

In addition to this change, ata_scsi_requeue_deferred_qc() is also
modified to take a new timedout_scmd scsi command argument which indicates
the SCSI command that timed out. With this additional argument,
ata_scsi_requeue_deferred_qc() can now also terminate with DID_TIME_OUT
any timed out deferred qc, which simplifies ata_scsi_cmd_error_handler().
In this case, ata_scsi_requeue_deferred_qc() returns SCSI_EH_DONE, with
this return value propagated back to the ata_scsi_eh_timed_out() operation
to indicate to scsi_timeout() that the timed out command was handled and
no further processing is needed.

For non-timed out deferred qc that need to be retried,
ata_scsi_requeue_deferred_qc() returns SCSI_EH_NOT_HANDLED, thus
indicating to scsi_timeout() that the timed out command needs to go
through the SCSI EH (and libata EH) processing by adding it to the EH work
queue with scsi_eh_scmd_add().

One side effect of these changes is that the function atapi_qc_complete()
needs to be modified to ensure that a deferred ATAPI command that needs
to be retried is completed with DID_REQUEUE instead of the default
SAM_STAT_GOOD status, and a command that timed out is completed with
DID_TIME_OUT instead of SAM_STAT_CHECK_CONDITION.

Fixes: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation")
Cc: stable@vger.kernel.org
Signed-off-by: Damien Le Moal &lt;dlemoal@kernel.org&gt;
Reviewed-by: Igor Pylypiv &lt;ipylypiv@google.com&gt;
Tested-by: Igor Pylypiv &lt;ipylypiv@google.com&gt;
Reviewed-by: Niklas Cassel &lt;cassel@kernel.org&gt;
Reviewed-by: Martin K. Petersen &lt;martin.petersen@oracle.com&gt;
</content>
</entry>
<entry>
<title>ata: libata-eh: Increase STANDBY IMMEDIATE timeout</title>
<updated>2026-07-28T03:04:17+00:00</updated>
<author>
<name>Matt Vollrath</name>
<email>tactii@gmail.com</email>
</author>
<published>2026-07-24T07:39:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=1e024d2b41ee32bc06818f7f09a3562c58842cf9'/>
<id>urn:sha1:1e024d2b41ee32bc06818f7f09a3562c58842cf9</id>
<content type='text'>
Correct a previous change (see Fixes) which reduced the standby timeout
from 30 to 5 seconds. Increase it to 15 seconds.

I was troubleshooting an error spotted during system suspend:

    [ 1217.152867] ata1.00: Entering standby power mode
    [ 1222.322948] ata1.00: qc timeout after 5000 msecs (cmd 0xe0)
    [ 1222.324010] ata1.00: STANDBY IMMEDIATE failed (err_mask=0x4)

This drive is a Samsung 870 EVO SSD in good SMART standing, and I wasn't
aware of any reason it should be taking so long to standby. The issue is
intermittent, but I observed it sometimes taking 7 seconds to manually
standby. I assume this was interruption of background maintenance after
a power outage.

As a desktop user, I would prefer to wait the extra 2 seconds at suspend
to let the drive finish its business rather than drop the rails from
under it.

The change from 30 to 5 seconds was implicit when switching suspend
from START STOP UNIT to an internal command with no timeout table entry.
No reason was stated for the change.

Fixes: aa3998dbeb3a ("ata: libata-scsi: Disable scsi device manage_system_start_stop")
Cc: stable@vger.kernel.org
Signed-off-by: Matt Vollrath &lt;tactii@gmail.com&gt;
Assisted-by: Claude:claude-5-fable
Signed-off-by: Damien Le Moal &lt;dlemoal@kernel.org&gt;
</content>
</entry>
<entry>
<title>ata: libata: Document when host-&gt;eh_mutex should be held</title>
<updated>2026-06-01T17:09:08+00:00</updated>
<author>
<name>Bart Van Assche</name>
<email>bvanassche@acm.org</email>
</author>
<published>2026-05-29T18:03:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=7725c45682abd7a6590676c33c35a7bdfdec6db5'/>
<id>urn:sha1:7725c45682abd7a6590676c33c35a7bdfdec6db5</id>
<content type='text'>
Annotate the following functions with __must_hold(&amp;host-&gt;eh_mutex):
 * All ata_port_operations.error_handler() implementations.
 * ata_eh_reset() and ata_eh_recover() because these functions call
   ata_eh_release() and ata_eh_acquire().
 * All callers of ata_eh_reset() and ata_eh_recover().

Enable Clang's context analysis. This will cause the build to fail if
e.g. a locking bug would be introduced in an error path. This patch
should not affect the generated assembler code.

Signed-off-by: Bart Van Assche &lt;bvanassche@acm.org&gt;
[cassel: drop note about clang 23 from commit log]
Signed-off-by: Niklas Cassel &lt;cassel@kernel.org&gt;
</content>
</entry>
<entry>
<title>ata: libata: Add an argument to ata_eh_reset()</title>
<updated>2026-06-01T17:09:07+00:00</updated>
<author>
<name>Bart Van Assche</name>
<email>bvanassche@acm.org</email>
</author>
<published>2026-05-29T18:03:09+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=4b3c2ca268b0a66093793466e02d8566d642f19c'/>
<id>urn:sha1:4b3c2ca268b0a66093793466e02d8566d642f19c</id>
<content type='text'>
Pass the ATA port pointer as first argument to ata_eh_reset(). No
functionality has been changed. This patch prepares for enabling lock
context analysis. Without this patch, lockdep_assert_held() statements
would have to be added before each ata_eh_reset() call because the
compiler doesn't know that ap-&gt;link.p == ap. See also ata_link_init().

Signed-off-by: Bart Van Assche &lt;bvanassche@acm.org&gt;
Signed-off-by: Niklas Cassel &lt;cassel@kernel.org&gt;
</content>
</entry>
<entry>
<title>ata: libata-eh: queue hotplug work on the system_dfl_long_wq workqueue</title>
<updated>2026-06-01T17:07:37+00:00</updated>
<author>
<name>Niklas Cassel</name>
<email>cassel@kernel.org</email>
</author>
<published>2026-05-13T08:10:01+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=28afe01eb75cf8e858b9eecebb0e2e7ee0ceb236'/>
<id>urn:sha1:28afe01eb75cf8e858b9eecebb0e2e7ee0ceb236</id>
<content type='text'>
ata_scsi_port_error_handler() uses schedule_delayed_work() to queue
the ap-&gt;hotplug_task work.

schedule_delayed_work() always uses the system_percpu_wq per-cpu
workqueue.

ata_scsi_scan_host() queues the ap-&gt;hotplug_task work on the unbound
system_dfl_long_wq workqueue.

It seems counter-intuitive to queue the same work on two different
workqueues. Thus, change ata_scsi_port_error_handler() to also queue
the ap-&gt;hotplug_task work on the system_dfl_long_wq workqueue, such
that the work is always queued on the same workqueue.

Reviewed-by: Damien Le Moal &lt;dlemoal@kernel.org&gt;
Signed-off-by: Niklas Cassel &lt;cassel@kernel.org&gt;
</content>
</entry>
<entry>
<title>ata: libata-scsi: do not needlessly defer commands when using PMP with FBS</title>
<updated>2026-05-18T10:26:51+00:00</updated>
<author>
<name>Niklas Cassel</name>
<email>cassel@kernel.org</email>
</author>
<published>2026-05-14T07:39:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=759e8756da00aa115d504a18155b1d1ee1cc12e8'/>
<id>urn:sha1:759e8756da00aa115d504a18155b1d1ee1cc12e8</id>
<content type='text'>
The ACS specification does not allow a non-NCQ command to be issued while
an NCQ command is outstanding.

Commit 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation")
introduced a feature where a deferred non-NCQ command gets issued from a
workqueue. The design stores a single non-NCQ command per port.

However, when using Port Multipliers (PMPs), specifically PMPs that
support FIS-Based Switching (FBS), non-NCQ and NCQ commands can be mixed
on the same port, just not for the same link, see e.g. ata_std_qc_defer()
which is, and always has operated on a per-link basis.

Therefore, move the deferred_qc from struct ata_port to struct ata_link.
This way, when using a PMP with FBS, we will not needlessly defer commands
to all other links, just because one link issued a non-NCQ command while
having an NCQ command outstanding. Only commands for that specific link
will be deferred. This is in line with how PMPs with FBS worked before
commit 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation").

Fixes: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation")
Tested-by: Tommy Kelly &lt;linux@tkel.ly&gt;
Reviewed-by: Damien Le Moal &lt;dlemoal@kernel.org&gt;
Signed-off-by: Niklas Cassel &lt;cassel@kernel.org&gt;
</content>
</entry>
<entry>
<title>ata: libata-eh: Do not retry reset if the device is gone</title>
<updated>2026-04-02T18:18:29+00:00</updated>
<author>
<name>Igor Pylypiv</name>
<email>ipylypiv@google.com</email>
</author>
<published>2026-04-02T16:07:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=182caa17360dd48e6df08e18f00ebda0be87ab24'/>
<id>urn:sha1:182caa17360dd48e6df08e18f00ebda0be87ab24</id>
<content type='text'>
If a device is hot-unplugged or otherwise disappears during error handling,
ata_eh_reset() may fail with -ENODEV. Currently, the error handler will
continue to retry the reset operation up to max_tries times.

Prevent unnecessary reset retries by exiting the loop early when
ata_do_reset() returns -ENODEV.

Reviewed-by: Damien Le Moal &lt;dlemoal@kernel.org&gt;
Signed-off-by: Igor Pylypiv &lt;ipylypiv@google.com&gt;
Signed-off-by: Niklas Cassel &lt;cassel@kernel.org&gt;
</content>
</entry>
<entry>
<title>Merge branch 'for-7.0-fixes' into for-7.1</title>
<updated>2026-03-20T10:13:32+00:00</updated>
<author>
<name>Niklas Cassel</name>
<email>cassel@kernel.org</email>
</author>
<published>2026-03-20T10:13:32+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=d78c5bbf098fd93884a5dc05aec045f32cce7525'/>
<id>urn:sha1:d78c5bbf098fd93884a5dc05aec045f32cce7525</id>
<content type='text'>
</content>
</entry>
<entry>
<title>ata: libata-eh: Fix detection of deferred qc timeouts</title>
<updated>2026-03-06T08:58:47+00:00</updated>
<author>
<name>Guenter Roeck</name>
<email>linux@roeck-us.net</email>
</author>
<published>2026-03-06T02:48:05+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=ee0e6e69a772d601e152e5368a1da25d656122a8'/>
<id>urn:sha1:ee0e6e69a772d601e152e5368a1da25d656122a8</id>
<content type='text'>
If the ata_qc_for_each_raw() loop finishes without finding a matching SCSI
command for any QC, the variable qc will hold a pointer to the last element
examined, which has the tag i == ATA_MAX_QUEUE - 1. This qc can match the
port deferred QC (ap-&gt;deferred_qc).

If that happens, the condition qc == ap-&gt;deferred_qc evaluates to true
despite the loop not breaking with a match on the SCSI command for this QC.
In that case, the error handler mistakenly intercepts a command that has
not been issued yet and that has not timed out, and thus erroneously
returning a timeout error.

Fix the problem by checking for i &lt; ATA_MAX_QUEUE in addition to
qc == ap-&gt;deferred_qc.

The problem was found by an experimental code review agent based on
gemini-3.1-pro while reviewing backports into v6.18.y.

Assisted-by: Gemini:gemini-3.1-pro
Fixes: eddb98ad9364 ("ata: libata-eh: correctly handle deferred qc timeouts")
Signed-off-by: Guenter Roeck &lt;linux@roeck-us.net&gt;
[cassel: modified commit log as suggested by Damien]
Reviewed-by: Damien Le Moal &lt;dlemoal@kernel.org&gt;
Signed-off-by: Niklas Cassel &lt;cassel@kernel.org&gt;
</content>
</entry>
<entry>
<title>ata: libata: cancel pending work after clearing deferred_qc</title>
<updated>2026-03-04T09:42:12+00:00</updated>
<author>
<name>Niklas Cassel</name>
<email>cassel@kernel.org</email>
</author>
<published>2026-03-03T10:03:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.rulkc.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=aac9b27f7c1f2b2cf7f50a9ca633ecbbcaf22af9'/>
<id>urn:sha1:aac9b27f7c1f2b2cf7f50a9ca633ecbbcaf22af9</id>
<content type='text'>
Syzbot reported a WARN_ON() in ata_scsi_deferred_qc_work(), caused by
ap-&gt;ops-&gt;qc_defer() returning non-zero before issuing the deferred qc.

ata_scsi_schedule_deferred_qc() is called during each command completion.
This function will check if there is a deferred QC, and if
ap-&gt;ops-&gt;qc_defer() returns zero, meaning that it is possible to queue the
deferred qc at this time (without being deferred), then it will queue the
work which will issue the deferred qc.

Once the work get to run, which can potentially be a very long time after
the work was scheduled, there is a WARN_ON() if ap-&gt;ops-&gt;qc_defer() returns
non-zero.

While we hold the ap-&gt;lock both when assigning and clearing deferred_qc,
and the work itself holds the ap-&gt;lock, the code currently does not cancel
the work after clearing the deferred qc.

This means that the following scenario can happen:
1) One or several NCQ commands are queued.
2) A non-NCQ command is queued, gets stored in ap-&gt;deferred_qc.
3) Last NCQ command gets completed, work is queued to issue the deferred
   qc.
4) Timeout or error happens, ap-&gt;deferred_qc is cleared. The queued work is
   currently NOT canceled.
5) Port is reset.
6) One or several NCQ commands are queued.
7) A non-NCQ command is queued, gets stored in ap-&gt;deferred_qc.
8) Work is finally run. Yet at this time, there is still NCQ commands in
   flight.

The work in 8) really belongs to the non-NCQ command in 2), not to the
non-NCQ command in 7). The reason why the work is executed when it is not
supposed to, is because it was never canceled when ap-&gt;deferred_qc was
cleared in 4). Thus, ensure that we always cancel the work after clearing
ap-&gt;deferred_qc.

Another potential fix would have been to let ata_scsi_deferred_qc_work() do
nothing if ap-&gt;ops-&gt;qc_defer() returns non-zero. However, canceling the
work when clearing ap-&gt;deferred_qc seems slightly more logical, as we hold
the ap-&gt;lock when clearing ap-&gt;deferred_qc, so we know that the work cannot
be holding the lock. (The function could be waiting for the lock, but that
is okay since it will do nothing if ap-&gt;deferred_qc is not set.)

Reported-by: syzbot+bcaf842a1e8ead8dfb89@syzkaller.appspotmail.com
Fixes: 0ea84089dbf6 ("ata: libata-scsi: avoid Non-NCQ command starvation")
Fixes: eddb98ad9364 ("ata: libata-eh: correctly handle deferred qc timeouts")
Reviewed-by: Igor Pylypiv &lt;ipylypiv@google.com&gt;
Reviewed-by: Damien Le Moal &lt;dlemoal@kernel.org&gt;
Signed-off-by: Niklas Cassel &lt;cassel@kernel.org&gt;
</content>
</entry>
</feed>
