From: Ming Lei <ming.lei@redhat.com>
To: Uday Shankar <ushankar@purestorage.com>
Cc: Shuah Khan <shuah@kernel.org>, Jens Axboe <axboe@kernel.dk>,
linux-block@vger.kernel.org, linux-kselftest@vger.kernel.org,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 4/4] ublk: improve handling of saturated queues when ublk server exits
Date: Thu, 27 Mar 2025 10:06:15 +0800 [thread overview]
Message-ID: <Z-Syl52pFLllilmu@fedora> (raw)
In-Reply-To: <20250325-ublk_timeout-v1-4-262f0121a7bd@purestorage.com>
On Tue, Mar 25, 2025 at 04:19:34PM -0600, Uday Shankar wrote:
> There are currently two ways in which ublk server exit is detected by
> ublk_drv:
>
> 1. uring_cmd cancellation. If there are any outstanding uring_cmds which
> have not been completed to the ublk server when it exits, io_uring
> calls the uring_cmd callback with a special cancellation flag as the
> issuing task is exiting.
> 2. I/O timeout. This is needed in addition to the above to handle the
> "saturated queue" case, when all I/Os for a given queue are in the
> ublk server, and therefore there are no outstanding uring_cmds to
> cancel when the ublk server exits.
>
> The second method detects ublk server exit only after a long delay
> (~30s, the default timeout assigned by the block layer). Any
> applications using the ublk device will be left hanging for these 30s
> before seeing an error/knowing anything went wrong. This problem is
> illustrated by running the new test_generic_02 against a ublk_drv which
> doesn't have the fix:
>
> selftests: ublk: test_generic_02.sh
> dev id is 0
> dd: error writing '/dev/ublkb0': Input/output error
> 1+0 records in
> 0+0 records out
> 0 bytes copied, 30.0611 s, 0.0 kB/s
> DEAD
> dd took 31 seconds to exit (>= 5s tolerance)!
> generic_02 : [FAIL]
>
> Fix this by instead handling the saturated queue case in the ublk
> character file release callback. This happens during ublk server exit
> and handles the issue much more quickly than an I/O timeout:
>
> selftests: ublk: test_generic_02.sh
> dev id is 0
> dd: error writing '/dev/ublkb0': Input/output error
> 1+0 records in
> 0+0 records out
> 0 bytes copied, 0.0376731 s, 0.0 kB/s
> DEAD
> generic_02 : [PASS]
>
> Signed-off-by: Uday Shankar <ushankar@purestorage.com>
> ---
> drivers/block/ublk_drv.c | 40 +++++++++++------------
> tools/testing/selftests/ublk/Makefile | 1 +
> tools/testing/selftests/ublk/kublk.c | 3 ++
> tools/testing/selftests/ublk/kublk.h | 3 ++
> tools/testing/selftests/ublk/null.c | 4 +++
> tools/testing/selftests/ublk/test_generic_02.sh | 43 +++++++++++++++++++++++++
> 6 files changed, 72 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
> index c060da409ed8a888b7e414c9065efd2cbd6d57d7..1816b2cac01056dc9d01455759594af43c5f78d6 100644
> --- a/drivers/block/ublk_drv.c
> +++ b/drivers/block/ublk_drv.c
> @@ -1247,8 +1247,6 @@ static void ublk_queue_cmd(struct ublk_queue *ubq, struct request *rq)
> static enum blk_eh_timer_return ublk_timeout(struct request *rq)
> {
> struct ublk_queue *ubq = rq->mq_hctx->driver_data;
> - unsigned int nr_inflight = 0;
> - int i;
>
> if (ubq->flags & UBLK_F_UNPRIVILEGED_DEV) {
> if (!ubq->timeout) {
> @@ -1259,26 +1257,6 @@ static enum blk_eh_timer_return ublk_timeout(struct request *rq)
> return BLK_EH_DONE;
> }
>
> - if (!ubq_daemon_is_dying(ubq))
> - return BLK_EH_RESET_TIMER;
> -
> - for (i = 0; i < ubq->q_depth; i++) {
> - struct ublk_io *io = &ubq->ios[i];
> -
> - if (!(io->flags & UBLK_IO_FLAG_ACTIVE))
> - nr_inflight++;
> - }
> -
> - /* cancelable uring_cmd can't help us if all commands are in-flight */
> - if (nr_inflight == ubq->q_depth) {
> - struct ublk_device *ub = ubq->dev;
> -
> - if (ublk_abort_requests(ub, ubq)) {
> - schedule_work(&ub->nosrv_work);
> - }
> - return BLK_EH_DONE;
> - }
> -
> return BLK_EH_RESET_TIMER;
> }
>
> @@ -1351,6 +1329,24 @@ static int ublk_ch_open(struct inode *inode, struct file *filp)
> static int ublk_ch_release(struct inode *inode, struct file *filp)
> {
> struct ublk_device *ub = filp->private_data;
> + bool need_schedule = false;
> + int i;
> +
> + /*
> + * Error out any requests outstanding to the ublk server. This
> + * may have happened already (via uring_cmd cancellation), in
> + * which case it is not harmful to repeat. But uring_cmd
> + * cancellation does not handle queues which are fully saturated
> + * (all requests in ublk server), because from the kernel's POV,
> + * there are no outstanding uring_cmds to cancel. This code
> + * handles such queues.
> + */
> +
> + for (i = 0; i < ub->dev_info.nr_hw_queues; i++)
> + need_schedule |= ublk_abort_requests(ub, ublk_get_queue(ub, i));
> +
> + if (need_schedule)
> + schedule_work(&ub->nosrv_work);
Thinking of it further, you needn't to call ublk_abort_requests() and schedule
stop work to remove disk here.
It can be the following way:
1) do nothing if 'ubq->canceling' is set, and it is safe to check this flag
because all uring commands are done now
2) otherwise, abort any in-flight request only by calling
ublk_abort_requests() and skipping the get & set ->canceling part.
which should avoid the 30sec delay, right?
Thanks,
Ming
prev parent reply other threads:[~2025-03-27 2:06 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-03-25 22:19 [PATCH 0/4] ublk: improve handling of saturated queues when ublk server exits Uday Shankar
2025-03-25 22:19 ` [PATCH 1/4] selftests: ublk: kublk: use ioctl-encoded opcodes Uday Shankar
2025-03-25 22:26 ` Uday Shankar
2025-03-26 3:07 ` Ming Lei
2025-03-25 22:19 ` [PATCH 2/4] selftests: ublk: kublk: fix an error log line Uday Shankar
2025-03-26 3:08 ` Ming Lei
2025-03-25 22:19 ` [PATCH 3/4] selftests: ublk: kublk: ignore SIGCHLD Uday Shankar
2025-03-26 3:23 ` Ming Lei
2025-03-26 17:17 ` Uday Shankar
2025-03-25 22:19 ` [PATCH 4/4] ublk: improve handling of saturated queues when ublk server exits Uday Shankar
2025-03-26 5:38 ` Ming Lei
2025-03-26 17:54 ` Uday Shankar
2025-03-26 18:56 ` Uday Shankar
2025-03-26 23:08 ` Uday Shankar
2025-03-27 1:38 ` Ming Lei
2025-03-27 1:23 ` Ming Lei
2025-03-31 23:17 ` Uday Shankar
2025-04-02 3:59 ` Ming Lei
2025-04-02 19:41 ` Uday Shankar
2025-03-27 2:06 ` Ming Lei [this message]
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=Z-Syl52pFLllilmu@fedora \
--to=ming.lei@redhat.com \
--cc=axboe@kernel.dk \
--cc=linux-block@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=shuah@kernel.org \
--cc=ushankar@purestorage.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.