summaryrefslogtreecommitdiff
path: root/scripts/Makefile.thinlto
diff options
context:
space:
mode:
authorBrian Bunker <brian@purestorage.com>2026-10-30 10:57:20 -0700
committerMartin K. Petersen (Oracle) <mkp@kernel.org>2026-11-08 22:15:13 -0500
commitdc7ba60d45b105b91d4e2e9567b355fb4a043def (patch)
tree829b83e3020eaa43985da73b65903e64381cf199 /scripts/Makefile.thinlto
parent0ba0ffc7748d83c6f8792fea31b569042a12f1b2 (diff)
downloadlinux-next-dc7ba60d45b105b91d4e2e9567b355fb4a043def.tar.gz
linux-next-dc7ba60d45b105b91d4e2e9567b355fb4a043def.zip
scsi: core: Restart the queue when unblocking a device set running
A device that its transport blocks has its queue stopped. If the SCSI error handler then gives up on the device, it moves it from SDEV_BLOCK to SDEV_OFFLINE and leaves the queue stopped. When userspace later writes "running" to the device's state attribute, store_state_field() moves it to SDEV_RUNNING, still with the queue stopped, and rescans it. The rescan takes the device lock and waits for I/O that can never be dispatched. When the transport then unblocks the device, scsi_internal_device_unblock_nowait() rejects a device in SDEV_RUNNING with -EINVAL before it reaches scsi_start_queue(), so nothing ever restarts the queue. The task that wrote "running" hangs forever holding the device lock, and anything else that takes it hangs behind it. The -EINVAL also makes scsi_host_unblock() stop at this device and leave the rest of the host blocked, and keeps the device in SDEV_RUNNING when the transport asked for SDEV_TRANSPORT_OFFLINE. This shows up with iSCSI when a session drops again just after recovering. iscsid onlines the session's devices after a relogin by writing "running" to every device it finds offline: 1. The session is blocked, which blocks the device and stops its queue. 2. The error handler cannot recover the device and moves it from SDEV_BLOCK to SDEV_OFFLINE. The queue stays stopped. 3. iscsid writes "running": SDEV_OFFLINE -> SDEV_RUNNING with the queue still stopped, then the rescan sends an INQUIRY that sits unsent while holding the device lock. 4. The session recovery timeout calls scsi_target_unblock(). The other devices go from SDEV_BLOCK to SDEV_TRANSPORT_OFFLINE and get their queues restarted, but this one is skipped because it is already running. A vmcore from such a hang shows the device in SDEV_RUNNING with queue_stopped set and the queue's quiesce_depth at 1, the rescan's INQUIRY never started (MQ_RQ_IDLE, no start time or deadline), and iscsid owning the device lock while other tasks wait for it. Handle this in scsi_internal_device_unblock_nowait(), which already restarts the queue of an SDEV_OFFLINE device: accept an SDEV_RUNNING device whose queue is still stopped, move it to the requested state and restart the queue. A running device whose queue is not stopped was never blocked and is still rejected. Do not restart the queue from store_state_field() instead. The device is still blocked by its transport at that point, and some transports and drivers rely on the stopped queue to keep commands away while they reconnect or reset the adapter. Fixes: f0f82e2476f6 ("scsi: core: Fix capacity set to zero after offlinining device") Signed-off-by: Brian Bunker <brian@purestorage.com> Link: https://patch.msgid.link/20261030175721.24379-2-brian@purestorage.com Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Diffstat (limited to 'scripts/Makefile.thinlto')
0 files changed, 0 insertions, 0 deletions