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: fix canceling flag handling in batch I/O recovery

Two issues with ubq->canceling flag handling:

1) In ublk_queue_reset_io_flags(), ubq->canceling is set outside
cancel_lock, violating the locking requirement. Move it inside
the spinlock-protected section.

2) In ublk_batch_unprep_io(), when rolling back after a batch prep
failure, if the queue became ready during prep (which cleared
canceling), the flag is not restored when the queue becomes
not-ready again. This allows new requests to be queued to
uninitialized IO slots.

Fix by restoring ubq->canceling = true under cancel_lock when the
queue transitions from ready to not-ready during rollback.

Reported-by: Jens Axboe <axboe@kernel.dk>
Fixes: 3f3850785594 ("ublk: fix batch I/O recovery -ENODEV error")
Signed-off-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Ming Lei and committed by
Jens Axboe
e4c4bfec dbc635c4

+8 -3
+8 -3
drivers/block/ublk_drv.c
··· 2806 2806 spin_lock(&ubq->cancel_lock); 2807 2807 for (j = 0; j < ubq->q_depth; j++) 2808 2808 ubq->ios[j].flags &= ~UBLK_IO_FLAG_CANCELED; 2809 + ubq->canceling = false; 2809 2810 spin_unlock(&ubq->cancel_lock); 2810 2811 ubq->fail_io = false; 2811 - ubq->canceling = false; 2812 2812 } 2813 2813 2814 2814 /* device can only be started after all IOs are ready */ ··· 3435 3435 3436 3436 /* 3437 3437 * If queue was ready before this decrement, it won't be anymore, 3438 - * so we need to decrement the queue ready count too. 3438 + * so we need to decrement the queue ready count and restore the 3439 + * canceling flag to prevent new requests from being queued. 3439 3440 */ 3440 - if (ublk_queue_ready(ubq)) 3441 + if (ublk_queue_ready(ubq)) { 3441 3442 data->ub->nr_queue_ready--; 3443 + spin_lock(&ubq->cancel_lock); 3444 + ubq->canceling = true; 3445 + spin_unlock(&ubq->cancel_lock); 3446 + } 3442 3447 ubq->nr_io_ready--; 3443 3448 3444 3449 ublk_io_lock(io);