[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