From: sashiko-bot@kernel.org
To: "Shawn Lin" <shawn.lin@rock-chips.com>
Cc: linux-scsi@vger.kernel.org
Subject: Re: [PATCH v2 2/2] scsi: ufs: core: Retry the full device init on fatal link loss
Date: Thu, 29 Oct 2026 02:06:39 +0000 [thread overview]
Message-ID: <sashiko-outbox-188630@kernel.org> (raw)
In-Reply-To: <20261029014839.3390579-3-shawn.lin@rock-chips.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] scsi: ufs: core: broken MCQ reconfiguration order in ufshcd_init() retry
- [High] scsi: ufs: error state cleared before ufshcd_hba_stop() in ufshcd_init()
- [High] scsi: ufs: core: missing ufs_hwmon_remove() and EE mask reset on init retry
- [Low] scsi: ufs: core: pass host_lock pointer to spin_lock_irqsave()
--
commit 23f03ec7ec12e66a1c4114bfb0fbd0cd5e4ff5c9
Author: Shawn Lin <shawn.lin@rock-chips.com>
scsi: ufs: core: Retry the full device init on fatal link loss
This commit retries ufshcd_full_device_init() up to three times in
ufshcd_init() when device initialization fails, resetting the device and
host controller and clearing latched error state between attempts.
> diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c
> index f1e54d7195370..bd82d6755739c 100644
> --- a/drivers/ufs/core/ufshcd.c
> +++ b/drivers/ufs/core/ufshcd.c
> @@ -11468,8 +11468,52 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
>
> /* Initialize hba, detect and initialize UFS device */
> ktime_t probe_start = ktime_get();
> + int retries = 3;
>
> - err = ufshcd_full_device_init(hba);
> + while (retries--) {
> + unsigned long flags;
> +
> + err = ufshcd_full_device_init(hba);
> + if (!err)
> + break;
> +
> + if (!retries)
> + break;
> +
> + dev_warn(hba->dev, "UFS init failed %d, full retry (%d left)\n",
> + err, retries);
> +
> + /*
> + * The failed attempt may have latched fatal errors and
> + * scheduled the error handler. Stop it and start the retry
> + * from a clean state, mirroring ufshcd_reset_and_restore().
> + */
> + cancel_work_sync(&hba->eh_work);
> + spin_lock_irqsave(hba->host->host_lock, flags);
> + hba->saved_err = 0;
> + hba->saved_uic_err = 0;
> + hba->force_reset = false;
> + hba->ufshcd_state = UFSHCD_STATE_RESET;
> + spin_unlock_irqrestore(hba->host->host_lock, flags);
[Severity: Low]
In include/scsi/scsi_host.h, host_lock in struct Scsi_Host is defined by
value rather than as a pointer:
spinlock_t host_lock;
Should spin_lock_irqsave() and spin_unlock_irqrestore() in ufshcd_init()
take &hba->host->host_lock instead of hba->host->host_lock so that
drivers/ufs/core/ufshcd.c compiles?
> +
> + ufshcd_device_reset(hba);
> + ufs_put_device_desc(hba);
> + ufshcd_hba_stop(hba);
[Severity: High]
What happens if an error or link-loss interrupt fires while the host
controller is still active during ufshcd_device_reset(), before
ufshcd_hba_stop() disables the controller?
Because cancel_work_sync(&hba->eh_work) and the clearing of hba->saved_err,
hba->saved_uic_err, and hba->ufshcd_state happen before ufshcd_hba_stop(),
resetting the attached device while controller interrupts are enabled can
trigger ufshcd_intr() -> ufshcd_check_errors():
hba->saved_err |= hba->errors;
hba->saved_uic_err |= hba->uic_error;
...
ufshcd_schedule_eh_work(hba);
Since hba->ufs_device_wlun is not set yet and hba->host_sem is not held
during ufshcd_init(), ufshcd_err_handler() can then run concurrently on
hba->eh_wq:
down(&hba->host_sem);
spin_lock_irqsave(&hba->host->host_lock, flags);
if (ufshcd_err_handling_should_stop(hba)) {
if (hba->ufshcd_state != UFSHCD_STATE_ERROR)
hba->ufshcd_state = UFSHCD_STATE_OPERATIONAL;
spin_unlock_irqrestore(&hba->host->host_lock, flags);
up(&hba->host_sem);
return;
}
Could this overwrite hba->ufshcd_state and leave hba->saved_err and
hba->saved_uic_err latched during the retry? Should ufshcd_hba_stop(hba) be
called before cancelling hba->eh_work, clearing the error state, and
resetting the device?
[Severity: High]
Can this retry path also leak the hwmon device and struct ufs_hwmon_data if
ufshcd_full_device_init() fails in ufshcd_post_device_init() after
ufshcd_device_params_init() has already succeeded?
During ufshcd_full_device_init(), the call chain is:
ufshcd_device_params_init()
ufs_get_device_desc()
ufshcd_temp_notif_probe()
ufshcd_enable_ee(hba, mask);
ufs_hwmon_probe(hba, mask);
ufshcd_post_device_init()
ufshcd_config_pwr_mode()
If ufshcd_post_device_init() fails, ufs_put_device_desc() only frees
dev_info->model and dev_info->device_id. On the next iteration,
ufs_hwmon_probe() in drivers/ufs/core/ufs-hwmon.c allocates a new
struct ufs_hwmon_data, registers a second hwmon device, and overwrites
hba->hwmon_device:
data = kzalloc_obj(*data);
if (!data)
return;
...
hwmon = hwmon_device_register_with_info(dev, "ufs", data, &ufs_hwmon_hba_info, NULL);
...
hba->hwmon_device = hwmon;
In addition, hba->ee_ctrl_mask and hba->ee_drv_mask retain the bits set by
ufshcd_enable_ee() before ufshcd_device_reset() reset the device, which
causes ufshcd_update_ee_control() on the next attempt to see an unchanged
mask and skip writing the exception event control attribute to the device.
Should the retry cleanup call ufs_hwmon_remove(hba) and clear the exception
event masks?
> + if (ufshcd_hba_enable(hba)) {
> + dev_err(hba->dev, "Host controller enable failed\n");
> + ufshcd_print_evt_hist(hba);
> + ufshcd_print_host_state(hba);
> + goto out_release;
> + }
> +
> + /* Reconfigure MCQ upon controller re-enable */
> + if (hba->mcq_enabled) {
> + ufshcd_config_mcq(hba);
> + ufshcd_mcq_enable(hba);
> + }
[Severity: High]
Is the ordering of ufshcd_config_mcq(hba) and ufshcd_mcq_enable(hba) here
intended?
On the initial probe path, ufshcd_add_scsi_host() calls ufshcd_mcq_enable()
first, and ufshcd_full_device_init() calls ufshcd_config_mcq() only after
ufshcd_link_startup() completes:
err = ufshcd_link_startup(hba);
if (err)
return err;
if (hba->mcq_enabled)
ufshcd_config_mcq(hba);
In the retry path of ufshcd_init(), calling ufshcd_config_mcq(hba) before
ufshcd_mcq_enable(hba) configures the queues and enables them in
ufshcd_mcq_make_queues_operational() before ufshcd_mcq_enable() selects
multi-circular queue mode in REG_UFS_MEM_CFG and before the next attempt's
ufshcd_link_startup(hba). Then, when ufshcd_full_device_init() runs on the
next iteration, it calls ufshcd_config_mcq(hba) a second time while the
hardware queues are already enabled.
Furthermore, if ufshcd_link_startup() encounters an error on its own retry
and calls ufshcd_hba_enable(hba), the controller reset will clear
REG_UFS_MEM_CFG again without ufshcd_mcq_enable(hba) being re-applied before
ufshcd_config_mcq(hba). Should the retry path only call
ufshcd_mcq_enable(hba) (or should ufshcd_mcq_enable(hba) be called right
before ufshcd_config_mcq(hba) inside ufshcd_full_device_init())?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261029014839.3390579-1-shawn.lin@rock-chips.com?part=2
next prev parent reply other threads:[~2026-10-29 2:06 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-29 1:48 [PATCH v2 0/2] Retry the full device init on fatal link loss Shawn Lin
2026-10-29 1:48 ` Shawn Lin
2026-10-29 1:48 ` [PATCH v2 1/2] scsi: ufs: core: Move the device initialization sequence into a new function Shawn Lin
2026-10-29 1:48 ` Shawn Lin
2026-10-29 1:48 ` [PATCH v2 2/2] scsi: ufs: core: Retry the full device init on fatal link loss Shawn Lin
2026-10-29 1:48 ` Shawn Lin
2026-10-29 2:06 ` sashiko-bot [this message]
2026-10-29 2:17 ` Shawn Lin
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=sashiko-outbox-188630@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
--cc=shawn.lin@rock-chips.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.