From: Josef Bacik <josef@toxicpanda.com>
To: Ming Lei <tom.leiming@gmail.com>
Cc: linux-block@vger.kernel.org, Jens Axboe <axboe@kernel.dk>,
Caleb Sander Mateos <csander@purestorage.com>
Subject: Re: [PATCH 0/8] ublk: don't dispatch to canceled io commands
Date: Mon, 05 Oct 2026 18:50:35 +0000 [thread overview]
Message-ID: <63d8149c093169706e7478e779116b61.josef@toxicpanda.com> (raw)
In-Reply-To: <20261001125422.1364260-1-tom.leiming@gmail.com>
On Thu, Oct 01, 2026 at 07:54:14AM -0500, Ming Lei wrote:
> Hi,
>
> Josef reported three ways in which ublk dispatches a request to a
> canceled io command, which oopses on the NULL io->cmd.
Thanks Ming. I ran 1-8 on top of for-next (d70609a2f68c) under QEMU with
KASAN and lockdep: my reproducers for the three routes plus the restart,
recovery and QUIESCE_DEV controls, the ublk selftests including your
generic_18, and my ADD vs STOP_DEV/DEL_DEV race script. No oops or
lockdep report anywhere, and generic_18 passes. A few things though.
1. kublk's batch daemon dies when PREP_IO_CMDS hits the new STOPPING
check. With patch 6, __ublk_fetch() returns UBLK_IO_RES_ABORT while
UB_STATE_STOPPING is set, and batch PREP goes through it, so a PREP
racing STOP_DEV completes with -ENODEV. kublk asserts cqe->res == 0
in ublk_batch_compl_commit_cmd(), the daemon aborts before it writes
the start eventfd, and the parent of `kublk add` sits in
eventfd_read() forever. My race script hangs on the first or second
iteration with -b; the per-io servers handle the abort fine. The
kernel side is fine, but kublk needs to fail the queue cleanly there,
and generic_18 has no batch mode, which is why it doesn't see it.
2. Routes 2 and 3 still bring the device up. START_DEV returns 0 and
every request on the new disk fails, and after END_USER_RECOVERY the
device is LIVE with the reads on the dead task's queue parked forever
with plain USER_RECOVERY (generic_18 accepts both, and turns off the
partition scan, which is what parks under disk->open_mutex otherwise).
I'll send a follow-up on top of your series that returns -ENODEV from
START_DEV and END_USER_RECOVERY while ub->canceling is set; with it
generic_18 still passes.
3. The same follow-up has ublk_start_cancel() read ub->ub_disk under
cancel_mutex, with START_DEV publishing it in the same section. Today
it samples the disk before taking the mutex, so a server dying during
its own START_DEV can mark the queues without quiescing a disk that
START_DEV published in between, with first I/O already past the
canceling check. Narrow, and older than this series.
4. Patch 5: the release work decides there is no disk before it takes
ub->mutex and doesn't look again, so a START_DEV that slips in with
the exiting server's pid can go LIVE first and the work then resets
a LIVE device. It needs START_DEV pending while the node is released,
e.g. a separate control process, and nothing oopses (every queue is
still canceling), but the device ends up LIVE with requests failing
or parked until STOP_DEV/DEL_DEV.
5. Patch 6 changes STOP_DEV's contract: a server that still holds
/dev/ublkcN after STOP_DEV gets ABORT on FETCH/PREP and -EBUSY on
START_DEV until it closes the node, even if it had fetched nothing.
That's fine by me, but it should go in Documentation/block/ublk.rst,
since servers that STOP_DEV and restart on the same fd will see it.
For 1-6, with kublk fixed for 1:
Tested-by: Josef Bacik <josef@toxicpanda.com>
Thanks,
Josef
next prev parent reply other threads:[~2026-10-05 18:50 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-01 12:54 [PATCH 0/8] ublk: don't dispatch to canceled io commands Ming Lei
2026-10-01 12:54 ` [PATCH 1/8] ublk: keep a canceled FETCH round canceling until the server is gone Ming Lei
2026-10-01 12:54 ` [PATCH 2/8] ublk: mark the io command cancelable before publishing it Ming Lei
2026-10-01 12:54 ` [PATCH 3/8] ublk: mark the batch fetch command cancelable before linking it Ming Lei
2026-10-01 12:54 ` [PATCH 4/8] ublk: reset the FETCH round in release also without a disk Ming Lei
2026-10-01 12:54 ` [PATCH 5/8] ublk: reset the FETCH round under ub->mutex Ming Lei
2026-10-01 12:54 ` [PATCH 6/8] ublk: let STOP_DEV cancel the server's commands before its release Ming Lei
2026-10-01 12:54 ` [PATCH 7/8] selftests: ublk: move the control command helpers into ctrl.c Ming Lei
2026-10-01 12:54 ` [PATCH 8/8] selftests: ublk: add test for going live over canceled io commands Ming Lei
2026-10-05 16:23 ` [PATCH] ublk: refuse to go live after an io command was canceled Josef Bacik
2026-10-06 14:14 ` Ming Lei
2026-10-05 16:23 ` [PATCH v2] " Josef Bacik
2026-10-05 18:50 ` Josef Bacik [this message]
2026-10-06 16:10 ` [PATCH 0/4] ublk: fix UBLK_CMD_QUIESCE_DEV leaving commands behind Josef Bacik
2026-10-06 13:05 ` [PATCH 1/4] ublk: don't cancel commands in QUIESCE_DEV on a device that isn't live Josef Bacik
2026-10-06 14:49 ` [PATCH 2/4] ublk: drop QUIESCE_DEV's wait for an idle command Josef Bacik
2026-10-06 14:50 ` [PATCH 3/4] ublk: give the command back from COMMIT_AND_FETCH on a canceling queue Josef Bacik
2026-10-06 14:50 ` [PATCH 4/4] ublk: keep canceling in QUIESCE_DEV until the server's commands are taken Josef Bacik
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=63d8149c093169706e7478e779116b61.josef@toxicpanda.com \
--to=josef@toxicpanda.com \
--cc=axboe@kernel.dk \
--cc=csander@purestorage.com \
--cc=linux-block@vger.kernel.org \
--cc=tom.leiming@gmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox