Re: [PATCH] nvme: bound the freeze drain in passthrough commands
Chao S <[email protected]>
| Newsgroups | org.infradead.lists.linux-nvme,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <CACd_6n2N=r+-dBdKxbQbVi0+FVgKqSPR-EmqSdt=aTO2hAQyhw@mail.gmail.com> |
Get it now, thanks for the detailed suggestions. On Thu, Jul 9, 2026 at 2:17 PM Keith Busch <[email protected]> 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 > > ([email protected]) 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.