* [PATCH] scsi: ufs: core: Quiesce SCSI devices instead of host tagset during error handling
@ 2026-09-02 8:23 Stanley Jhu
2026-09-11 15:52 ` Bart Van Assche
0 siblings, 1 reply; 2+ messages in thread
From: Stanley Jhu @ 2026-09-02 8:23 UTC (permalink / raw)
To: linux-scsi
Cc: Martin K . Petersen, Bart Van Assche, Alim Akhtar, Avri Altman,
Stanley Jhu, stable
Commit 08b12cda6c44 ("scsi: ufs: core: Switch to scsi_get_internal_cmd()")
switched UFS internal commands to allocate requests on
hba->host->pseudo_sdev->request_queue, which shares the host tagset with
regular LUNs.
During error recovery, ufshcd_err_handling_prepare() calls
blk_mq_quiesce_tagset(&hba->host->tag_set), marking all queues in the
tagset as quiesced, including pseudo_sdev->request_queue. When
ufshcd_verify_dev_init() subsequently issues internal commands (e.g. NOP
OUT UPIU) via blk_execute_rq(), blk_mq_run_hw_queue() skips running the
quiesced queue, resulting in an unrecoverable circular wait deadlock.
Resolve this by quiescing only logical units attached to the host via
shost_for_each_device() during error handling. Because
shost_for_each_device() explicitly skips pseudo SCSI devices (via
scsi_device_is_pseudo_dev() in __scsi_iterate_devices()), regular LUNs
are quiesced to prevent retry storms, while pseudo_sdev remains
unquiesced so internal commands can be dispatched and completed during
error recovery.
Clock scaling and command pause (ufshcd_pause_command_processing) paths
continue to use blk_mq_quiesce_tagset() as they require freezing all
queues including internal commands.
Fixes: 08b12cda6c44 ("scsi: ufs: core: Switch to scsi_get_internal_cmd()")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/all/alpine.DEB.2.22.394.2609010729350.218556@hyperv.ins.bvanassche.us/
Signed-off-by: Stanley Jhu <stanleyjhu@google.com>
---
drivers/ufs/core/ufshcd.c | 22 ++++++++++++++++++++--
1 file changed, 20 insertions(+), 2 deletions(-)
diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
index 2ba244cf40ac..11488c5efb47 100644
--- a/drivers/ufs/core/ufshcd.c
+++ b/drivers/ufs/core/ufshcd.c
@@ -6798,6 +6798,23 @@ static void ufshcd_clk_scaling_suspend(struct ufs_hba *hba, bool suspend)
}
}
+static void ufshcd_quiesce_all_sdevs(struct ufs_hba *hba)
+{
+ struct scsi_device *sdev;
+
+ shost_for_each_device(sdev, hba->host)
+ blk_mq_quiesce_queue_nowait(sdev->request_queue);
+ blk_mq_wait_quiesce_done(&hba->host->tag_set);
+}
+
+static void ufshcd_unquiesce_all_sdevs(struct ufs_hba *hba)
+{
+ struct scsi_device *sdev;
+
+ shost_for_each_device(sdev, hba->host)
+ blk_mq_unquiesce_queue(sdev->request_queue);
+}
+
static void ufshcd_err_handling_prepare(struct ufs_hba *hba)
{
/*
@@ -6833,7 +6850,7 @@ static void ufshcd_err_handling_prepare(struct ufs_hba *hba)
ufshcd_clk_scaling_allow(hba, false);
}
/* Wait for ongoing ufshcd_queuecommand() calls to finish. */
- blk_mq_quiesce_tagset(&hba->host->tag_set);
+ ufshcd_quiesce_all_sdevs(hba);
cancel_work_sync(&hba->eeh_work);
}
@@ -6840,7 +6857,7 @@ static void ufshcd_err_handling_prepare(struct ufs_hba *hba)
static void ufshcd_err_handling_unprepare(struct ufs_hba *hba)
{
- blk_mq_unquiesce_tagset(&hba->host->tag_set);
+ ufshcd_unquiesce_all_sdevs(hba);
ufshcd_release(hba);
if (ufshcd_is_clkscaling_supported(hba))
ufshcd_clk_scaling_suspend(hba, false);
--
2.43.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] scsi: ufs: core: Quiesce SCSI devices instead of host tagset during error handling
2026-09-02 8:23 [PATCH] scsi: ufs: core: Quiesce SCSI devices instead of host tagset during error handling Stanley Jhu
@ 2026-09-11 15:52 ` Bart Van Assche
0 siblings, 0 replies; 2+ messages in thread
From: Bart Van Assche @ 2026-09-11 15:52 UTC (permalink / raw)
To: Stanley Jhu, linux-scsi
Cc: Martin K . Petersen, Alim Akhtar, Avri Altman, stable
On 9/2/26 1:23 AM, Stanley Jhu wrote:
> Commit 08b12cda6c44 ("scsi: ufs: core: Switch to scsi_get_internal_cmd()")
> switched UFS internal commands to allocate requests on
> hba->host->pseudo_sdev->request_queue, which shares the host tagset with
> regular LUNs.
>
> During error recovery, ufshcd_err_handling_prepare() calls
> blk_mq_quiesce_tagset(&hba->host->tag_set), marking all queues in the
> tagset as quiesced, including pseudo_sdev->request_queue. When
> ufshcd_verify_dev_init() subsequently issues internal commands (e.g. NOP
> OUT UPIU) via blk_execute_rq(), blk_mq_run_hw_queue() skips running the
> quiesced queue, resulting in an unrecoverable circular wait deadlock.
>
> Resolve this by quiescing only logical units attached to the host via
> shost_for_each_device() during error handling. Because
> shost_for_each_device() explicitly skips pseudo SCSI devices (via
> scsi_device_is_pseudo_dev() in __scsi_iterate_devices()), regular LUNs
> are quiesced to prevent retry storms, while pseudo_sdev remains
> unquiesced so internal commands can be dispatched and completed during
> error recovery.
>
> Clock scaling and command pause (ufshcd_pause_command_processing) paths
> continue to use blk_mq_quiesce_tagset() as they require freezing all
> queues including internal commands.
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-11 15:53 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-02 8:23 [PATCH] scsi: ufs: core: Quiesce SCSI devices instead of host tagset during error handling Stanley Jhu
2026-09-11 15:52 ` Bart Van Assche
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox