Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ublk: reset per-IO canceled flag on each fetch

If a ublk server starts recovering devices but dies before issuing fetch
commands for all IOs, cancellation of the fetch commands that were
successfully issued may never complete. This is because the per-IO
canceled flag can remain set even after the fetch for that IO has been
submitted - the per-IO canceled flags for all IOs in a queue are reset
together only once all IOs for that queue have been fetched. So if a
nonempty proper subset of the IOs for a queue are fetched when the ublk
server dies, the IOs in that subset will never successfully be canceled,
as their canceled flags remain set, and this prevents ublk_cancel_cmd
from actually calling io_uring_cmd_done on the commands, despite the
fact that they are outstanding.

Fix this by resetting the per-IO cancel flags immediately when each IO
is fetched instead of waiting for all IOs for the queue (which may never
happen).

Signed-off-by: Uday Shankar <ushankar@purestorage.com>
Fixes: 728cbac5fe21 ("ublk: move device reset into ublk_ch_release()")
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Reviewed-by: zhang, the-essence-of-life <zhangweize9@gmail.com>
Link: https://patch.msgid.link/20260405-cancel-v2-1-02d711e643c2@purestorage.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Uday Shankar and committed by
Jens Axboe
0842186d 8b155f2e

+13 -8
+13 -8
drivers/block/ublk_drv.c
··· 2916 2916 ublk_cancel_dev(ub); 2917 2917 } 2918 2918 2919 + static void ublk_reset_io_flags(struct ublk_queue *ubq, struct ublk_io *io) 2920 + { 2921 + /* UBLK_IO_FLAG_CANCELED can be cleared now */ 2922 + spin_lock(&ubq->cancel_lock); 2923 + io->flags &= ~UBLK_IO_FLAG_CANCELED; 2924 + spin_unlock(&ubq->cancel_lock); 2925 + } 2926 + 2919 2927 /* reset per-queue io flags */ 2920 2928 static void ublk_queue_reset_io_flags(struct ublk_queue *ubq) 2921 2929 { 2922 - int j; 2923 - 2924 - /* UBLK_IO_FLAG_CANCELED can be cleared now */ 2925 2930 spin_lock(&ubq->cancel_lock); 2926 - for (j = 0; j < ubq->q_depth; j++) 2927 - ubq->ios[j].flags &= ~UBLK_IO_FLAG_CANCELED; 2928 2931 ubq->canceling = false; 2929 2932 spin_unlock(&ubq->cancel_lock); 2930 2933 ubq->fail_io = false; 2931 2934 } 2932 2935 2933 2936 /* device can only be started after all IOs are ready */ 2934 - static void ublk_mark_io_ready(struct ublk_device *ub, u16 q_id) 2937 + static void ublk_mark_io_ready(struct ublk_device *ub, u16 q_id, 2938 + struct ublk_io *io) 2935 2939 __must_hold(&ub->mutex) 2936 2940 { 2937 2941 struct ublk_queue *ubq = ublk_get_queue(ub, q_id); ··· 2944 2940 ub->unprivileged_daemons = true; 2945 2941 2946 2942 ubq->nr_io_ready++; 2943 + ublk_reset_io_flags(ubq, io); 2947 2944 2948 2945 /* Check if this specific queue is now fully ready */ 2949 2946 if (ublk_queue_ready(ubq)) { ··· 3207 3202 if (!ret) 3208 3203 ret = ublk_config_io_buf(ub, io, cmd, buf_addr, NULL); 3209 3204 if (!ret) 3210 - ublk_mark_io_ready(ub, q_id); 3205 + ublk_mark_io_ready(ub, q_id, io); 3211 3206 mutex_unlock(&ub->mutex); 3212 3207 return ret; 3213 3208 } ··· 3615 3610 ublk_io_unlock(io); 3616 3611 3617 3612 if (!ret) 3618 - ublk_mark_io_ready(data->ub, ubq->q_id); 3613 + ublk_mark_io_ready(data->ub, ubq->q_id, io); 3619 3614 3620 3615 return ret; 3621 3616 }