]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
ublk: consolidate nr_io_ready and nr_queues_ready
authorCaleb Sander Mateos <csander@purestorage.com>
Mon, 8 Sep 2025 18:45:41 +0000 (12:45 -0600)
committerJens Axboe <axboe@kernel.dk>
Wed, 10 Sep 2025 11:24:53 +0000 (05:24 -0600)
ublk_mark_io_ready() tracks whether all the ublk_device's I/Os have been
fetched by incrementing ublk_queue's nr_io_ready count and incrementing
ublk_device's nr_queues_ready count if the whole queue is ready.
Simplify the logic by just tracking the total number of fetched I/Os on
each ublk_device. When this count reaches nr_hw_queues * queue_depth,
the ublk_device is ready to receive I/O.

Signed-off-by: Caleb Sander Mateos <csander@purestorage.com>
Reviewed-by: Ming Lei <ming.lei@redhat.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
drivers/block/ublk_drv.c

index 3cf6d344d1c0841e1e18bab397a9560b2be2511e..aa64f530d5e9dbd8357d33bcc13184cea8c2babd 100644 (file)
@@ -201,7 +201,6 @@ struct ublk_queue {
        bool force_abort;
        bool canceling;
        bool fail_io; /* copy of dev->state == UBLK_S_DEV_FAIL_IO */
-       unsigned short nr_io_ready;     /* how many ios setup */
        spinlock_t              cancel_lock;
        struct ublk_device *dev;
        struct ublk_io ios[];
@@ -234,7 +233,7 @@ struct ublk_device {
        struct ublk_params      params;
 
        struct completion       completion;
-       unsigned int            nr_queues_ready;
+       u32                     nr_io_ready;
        bool                    unprivileged_daemons;
        struct mutex cancel_mutex;
        bool canceling;
@@ -1499,9 +1498,6 @@ static void ublk_queue_reinit(struct ublk_device *ub, struct ublk_queue *ubq)
 {
        int i;
 
-       /* All old ioucmds have to be completed */
-       ubq->nr_io_ready = 0;
-
        for (i = 0; i < ubq->q_depth; i++) {
                struct ublk_io *io = &ubq->ios[i];
 
@@ -1550,7 +1546,7 @@ static void ublk_reset_ch_dev(struct ublk_device *ub)
 
        /* set to NULL, otherwise new tasks cannot mmap io_cmd_buf */
        ub->mm = NULL;
-       ub->nr_queues_ready = 0;
+       ub->nr_io_ready = 0;
        ub->unprivileged_daemons = false;
        ub->ublksrv_tgid = -1;
 }
@@ -1848,9 +1844,11 @@ static void ublk_uring_cmd_cancel_fn(struct io_uring_cmd *cmd,
        ublk_cancel_cmd(ubq, pdu->tag, issue_flags);
 }
 
-static inline bool ublk_queue_ready(struct ublk_queue *ubq)
+static inline bool ublk_dev_ready(const struct ublk_device *ub)
 {
-       return ubq->nr_io_ready == ubq->q_depth;
+       u32 total = (u32)ub->dev_info.nr_hw_queues * ub->dev_info.queue_depth;
+
+       return ub->nr_io_ready == total;
 }
 
 static void ublk_cancel_queue(struct ublk_queue *ubq)
@@ -1974,16 +1972,14 @@ static void ublk_reset_io_flags(struct ublk_device *ub)
 }
 
 /* device can only be started after all IOs are ready */
-static void ublk_mark_io_ready(struct ublk_device *ub, struct ublk_queue *ubq)
+static void ublk_mark_io_ready(struct ublk_device *ub)
        __must_hold(&ub->mutex)
 {
-       ubq->nr_io_ready++;
-       if (ublk_queue_ready(ubq))
-               ub->nr_queues_ready++;
        if (!ub->unprivileged_daemons && !capable(CAP_SYS_ADMIN))
                ub->unprivileged_daemons = true;
 
-       if (ub->nr_queues_ready == ub->dev_info.nr_hw_queues) {
+       ub->nr_io_ready++;
+       if (ublk_dev_ready(ub)) {
                /* now we are ready for handling ublk io request */
                ublk_reset_io_flags(ub);
                complete_all(&ub->completion);
@@ -2189,8 +2185,8 @@ static int ublk_fetch(struct io_uring_cmd *cmd, struct ublk_queue *ubq,
         * FETCH, so it is fine even for IO_URING_F_NONBLOCK.
         */
        mutex_lock(&ub->mutex);
-       /* UBLK_IO_FETCH_REQ is only allowed before queue is setup */
-       if (ublk_queue_ready(ubq)) {
+       /* UBLK_IO_FETCH_REQ is only allowed before dev is setup */
+       if (ublk_dev_ready(ub)) {
                ret = -EBUSY;
                goto out;
        }
@@ -2209,7 +2205,7 @@ static int ublk_fetch(struct io_uring_cmd *cmd, struct ublk_queue *ubq,
                goto out;
 
        WRITE_ONCE(io->task, get_task_struct(current));
-       ublk_mark_io_ready(ub, ubq);
+       ublk_mark_io_ready(ub);
 out:
        mutex_unlock(&ub->mutex);
        return ret;