[PATCH] nvme: bound the freeze drain in passthrough commands

Chao S coshi036 at gmail.com
Thu Jul 9 12:01:20 PDT 2026


Get it now, thanks for the detailed suggestions.

On Thu, Jul 9, 2026 at 2:17 PM Keith Busch <kbusch at kernel.org> wrote:
>
> On Tue, Jun 23, 2026 at 06:28:49PM -0400, Chao S wrote:
> > Timeout fires, abort is accepted, reset starts, reset reaches the
> > "IO queues lost" branch (drivers/nvme/host/pci.c).  Then nvme_reset_work
> > itself blocks at
> >
> >   nvme_mark_namespaces_dead -> blk_mark_disk_dead -> blk_report_disk_dead
> >     -> bdev_mark_dead(bdev, true) -> sync_blockdev -> folio_wait_writeback
> >
> > i.e. the unconditional sync_blockdev in bdev_mark_dead's bare-bdev
> > else-branch (block/bdev.c) is itself waiting on the writeback that the
> > reset was supposed to drain.
>
> But sync_blockdev is *not* unconditional. It's conditional on this not
> being a surprise removal, and blk_mark_disk_dead() is considered a
> surprise, so I am not sure you've identified the right sequence.
>
> > So in this report, the IO timeout did its job, but the reset that the
> > timeout kicks off cannot complete, and nvme_passthru_start (which is
> > already in nvme_wait_freeze at this point) has no way to back out.
>
> I guess what may have happened is that the timeout handler requeued the
> IO  on a quiesced queue so it does reach frozen state. Just move the
> unquiesce to before the call to nvme_mark_namespaces_dead(). But I still
> don't think it should be needed because nvme_mark_namespaces_dead()
> shouldn't block.
>
> > 1. The reset path has several ways to fail to drain in
> >    nvme_io_timeout: abort can be rejected, the admin tag for abort
> >    can be unavailable, the controller can be wedged before abort
> >    lands, an in-progress reset can outlast nvme_io_timeout, or (as
> >    here) reset itself can block.  Each leaves nvme_passthru_start
> >    waiting forever, holding ctrl->scan_lock + subsys->lock + every
> >    namespace's freeze ref, which then fans out on bd_disk->open_mutex
> >    via any concurrent bdev_open/release or BLKRRPART.
>
> No, that's not what happens.
>
> If abort fails, then the command times out a 2nd time, then we escalate
> to reset.
>
> If we can't get an abort tag, then that means an abort is in progress.
> If it doesn't completely timely, then we escalate to reset.
>
> > 2. The same pattern is already established in the tree.  pci shutdown
> >    (drivers/nvme/host/pci.c), nvme-tcp reset, nvme-rdma reset,
> >    nvme-apple, and Daniel Wagner's 2021 nvme-fc series
> >    (20210818120530.130501-1-dwagner at suse.de) all use
> >    nvme_wait_freeze_timeout(NVME_IO_TIMEOUT) for exactly this reason.
> >    nvme_passthru_start is the only userspace-reachable caller still
> >    on the unbounded variant.
>
> Those are for entirely different cases where we're in the last line of
> recovery and have to guarantee forward progress.



More information about the Linux-nvme mailing list