[PATCH V2 5/5] blk-mq: Replace tags->lock with SRCU for tag iterators - Rockchip UFS regression

Ming Lei ming.lei at redhat.com
Sat Oct 4 07:42:20 PDT 2025


On Sat, Oct 4, 2025 at 1:18 AM Sebastian Reichel
<sebastian.reichel at collabora.com> wrote:
>
> Hi,
>
> On Sat, Aug 30, 2025 at 10:18:23AM +0800, Ming Lei wrote:
> > Replace the spinlock in blk_mq_find_and_get_req() with an SRCU read lock
> > around the tag iterators.
> >
> > This is done by:
> >
> > - Holding the SRCU read lock in blk_mq_queue_tag_busy_iter(),
> > blk_mq_tagset_busy_iter(), and blk_mq_hctx_has_requests().
> >
> > - Removing the now-redundant tags->lock from blk_mq_find_and_get_req().
> >
> > This change fixes lockup issue in scsi_host_busy() in case of shost->host_blocked.
> >
> > Also avoids big tags->lock when reading disk sysfs attribute `inflight`.
> >
> > Reviewed-by: Hannes Reinecke <hare at suse.de>
> > Signed-off-by: Ming Lei <ming.lei at redhat.com>
> > ---
>
> This patch landed in the last few hours and I now see the following
> fatal error on the Radxa ROCK 4D (most likely Rockchip UFS in
> general). After reverting this patch the error is gone and things
> are working as expected:
>
> [    2.713204] CPU: 7 UID: 0 PID: 1 Comm: swapper/0 Not tainted 6.17.0-g472ea195cdf3 #1 PREEMPT
> [    2.713956] Hardware name: Radxa ROCK 4D (DT)
> [    2.714342] pstate: 60000005 (nZCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> [    2.714955] pc : __srcu_read_lock+0x30/0x80

  The problem: scsi_host_busy() tries to use tags_srcu before it's
initialized by init_srcu_struct().

  The warning at __srcu_read_lock+0x30/0x80 indicates that the SRCU
structure (tags_srcu) has not been properly initialized yet. The code
   at line 754 in srcutree.c tries to read ssp->srcu_ctrp, but this
pointer is likely NULL or contains garbage because init_srcu_struct()
   hasn't been called yet.

  Solution

  The scsi_host_busy() call should only happen after the SCSI host has
been added and the tag_set has been initialized. The fix would be
  to check if the tag_set is initialized before calling
scsi_host_busy(), or to defer the printing of host state until after
the host is
  fully initialized.

  One possible fix is to check hba->scsi_host_added before calling
scsi_host_busy():

  dev_err(hba->dev, "%d outstanding reqs, tasks=0x%lx\n",
      hba->scsi_host_added ? scsi_host_busy(hba->host) : 0,
      hba->outstanding_tasks);




More information about the Linux-rockchip mailing list