From a24b3d4c873c76a12684bee1c7f62ac21cc36509 Mon Sep 17 00:00:00 2001 From: Hao Xu Date: Wed, 9 Dec 2020 16:15:21 +0800 Subject: [PATCH 2443/2944] alinux: io_uring: revert io_file_supports_async() to #31243040 Io_uring has a optimization(see Fixes:) to punt nowait IO requests for devices which has bio-based queue to async iowq thread directly, since bio-based devices doesn't suooprt nowait IO. For these devices, if we do nowait IO to them, the IO will fail in block layer and punt to iowq thread. So this optimization makes this process faster by punt this kind of IO to iowq thread directly in io_uring layer. So theoretically, it should be: (1) before the optimization: nowait IO(1st) normal IO(2nd) io_uring layer: pass --- punt --> iowq thread | block layer: fail ------ (2) after the optimization: nowait IO(1st) normal IO(2nd) io_uring layer: fail ----- punt --> iowq thread block layer: But we found in the nowait IO process, IOCB_NOWAIT is not delivered to block layer(REQ_NOWAIT), which makes this kind of IO passes the check in block layer. So actually, it is: (1) before the optimization: nowait IO(1st) io_uring layer: pass (IOCB_NOWAIT ignored) block layer: pass (2) after the optimization: nowait IO(1st) normal IO(2nd) io_uring layer: fail ----- punt --> iowq thread block layer: We can see the code path is shorter before the optimization. Especially for brd device(it is a bio-based device), it just involves memcpy and I believe there is no block points. So before the optimizationm it is faster, this causes a big slow down. Here we revert the optimization in io_uring. Fixes: 1d658dc411bd ("io_uring: catch -EIO from buffered issue request failure") Signed-off-by: Hao Xu Acked-by: Joseph Qi --- fs/io_uring.c | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/fs/io_uring.c b/fs/io_uring.c index 7dd75b6..3f8e3b3 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -2269,15 +2269,6 @@ static struct file *__io_file_get(struct io_submit_state *state, int fd) return state->file; } -static bool io_bdev_nowait(struct block_device *bdev) -{ -#ifdef CONFIG_BLOCK - return !bdev || blk_queue_nowait(bdev_get_queue(bdev)); -#else - return true; -#endif -} - /* * If we tracked the file through the SCM inflight mechanism, we could support * any file. For now, just ensure that anything potentially problematic is done @@ -2286,20 +2277,10 @@ static bool io_bdev_nowait(struct block_device *bdev) static bool io_file_supports_async(struct file *file, int rw) { umode_t mode = file_inode(file)->i_mode; - - if (S_ISBLK(mode)) { - if (io_bdev_nowait(file->f_inode->i_bdev)) - return true; - return false; - } - if (S_ISCHR(mode) || S_ISSOCK(mode)) + if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISSOCK(mode)) + return true; + if (S_ISREG(mode) && file->f_op != &io_uring_fops) return true; - if (S_ISREG(mode)) { - if (io_bdev_nowait(file->f_inode->i_sb->s_bdev) && - file->f_op != &io_uring_fops) - return true; - return false; - } /* any ->read/write should understand O_NONBLOCK */ if (file->f_flags & O_NONBLOCK) -- 1.8.3.1