]> git.proxmox.com Git - mirror_ubuntu-kernels.git/commitdiff
block: don't try to poll multi-bio I/Os in __blkdev_direct_IO
authorChristoph Hellwig <hch@lst.de>
Tue, 12 Oct 2021 11:12:12 +0000 (13:12 +0200)
committerJens Axboe <axboe@kernel.dk>
Mon, 18 Oct 2021 12:17:35 +0000 (06:17 -0600)
If an iocb is split into multiple bios we can't poll for both.  So don't
even bother to try to poll in that case.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Link: https://lore.kernel.org/r/20211012111226.760968-3-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
block/fops.c

index 7bb9581a146cff0b184c009ba5b1c7c2915925e0..15324f2e5a914bc3f9f2ff4a8027b25ef4f82224 100644 (file)
@@ -197,7 +197,7 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
        struct blk_plug plug;
        struct blkdev_dio *dio;
        struct bio *bio;
-       bool is_poll = (iocb->ki_flags & IOCB_HIPRI) != 0;
+       bool do_poll = (iocb->ki_flags & IOCB_HIPRI);
        bool is_read = (iov_iter_rw(iter) == READ), is_sync;
        loff_t pos = iocb->ki_pos;
        blk_qc_t qc = BLK_QC_T_NONE;
@@ -226,7 +226,7 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
         * Don't plug for HIPRI/polled IO, as those should go straight
         * to issue
         */
-       if (!is_poll)
+       if (!(iocb->ki_flags & IOCB_HIPRI))
                blk_start_plug(&plug);
 
        for (;;) {
@@ -260,20 +260,13 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
 
                nr_pages = bio_iov_vecs_to_alloc(iter, BIO_MAX_VECS);
                if (!nr_pages) {
-                       bool polled = false;
-
-                       if (iocb->ki_flags & IOCB_HIPRI) {
+                       if (do_poll)
                                bio_set_polled(bio, iocb);
-                               polled = true;
-                       }
-
                        qc = submit_bio(bio);
-
-                       if (polled)
+                       if (do_poll)
                                WRITE_ONCE(iocb->ki_cookie, qc);
                        break;
                }
-
                if (!dio->multi_bio) {
                        /*
                         * AIO needs an extra reference to ensure the dio
@@ -284,6 +277,7 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
                                bio_get(bio);
                        dio->multi_bio = true;
                        atomic_set(&dio->ref, 2);
+                       do_poll = false;
                } else {
                        atomic_inc(&dio->ref);
                }
@@ -292,7 +286,7 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
                bio = bio_alloc(GFP_KERNEL, nr_pages);
        }
 
-       if (!is_poll)
+       if (!(iocb->ki_flags & IOCB_HIPRI))
                blk_finish_plug(&plug);
 
        if (!is_sync)
@@ -303,8 +297,7 @@ static ssize_t __blkdev_direct_IO(struct kiocb *iocb, struct iov_iter *iter,
                if (!READ_ONCE(dio->waiter))
                        break;
 
-               if (!(iocb->ki_flags & IOCB_HIPRI) ||
-                   !blk_poll(bdev_get_queue(bdev), qc, true))
+               if (!do_poll || !blk_poll(bdev_get_queue(bdev), qc, true))
                        blk_io_schedule();
        }
        __set_current_state(TASK_RUNNING);