io_uring: track io length in async_list based on bytes
authorZhengyuan Liu <liuzhengyuan@kylinos.cn>
Mon, 22 Jul 2019 02:23:27 +0000 (10:23 +0800)
committerJens Axboe <axboe@kernel.dk>
Mon, 22 Jul 2019 03:46:55 +0000 (21:46 -0600)
We are using PAGE_SIZE as the unit to determine if the total len in
async_list has exceeded max_pages, it's not fair for smaller io sizes.
For example, if we are doing 1k-size io streams, we will never exceed
max_pages since len >>= PAGE_SHIFT always gets zero. So use original
bytes to make it more accurate.

Signed-off-by: Zhengyuan Liu <liuzhengyuan@kylinos.cn>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
fs/io_uring.c

index 0e6bd60cb113f326c2120b692ad1356bd24c2497..2039f888197e3b7253445e89da9e4c6f072a21cc 100644 (file)
@@ -202,7 +202,7 @@ struct async_list {
 
        struct file             *file;
        off_t                   io_end;
-       size_t                  io_pages;
+       size_t                  io_len;
 };
 
 struct io_ring_ctx {
@@ -1158,28 +1158,26 @@ static void io_async_list_note(int rw, struct io_kiocb *req, size_t len)
        off_t io_end = kiocb->ki_pos + len;
 
        if (filp == async_list->file && kiocb->ki_pos == async_list->io_end) {
-               unsigned long max_pages;
+               unsigned long max_bytes;
 
                /* Use 8x RA size as a decent limiter for both reads/writes */
-               max_pages = filp->f_ra.ra_pages;
-               if (!max_pages)
-                       max_pages = VM_READAHEAD_PAGES;
-               max_pages *= 8;
-
-               /* If max pages are exceeded, reset the state */
-               len >>= PAGE_SHIFT;
-               if (async_list->io_pages + len <= max_pages) {
+               max_bytes = filp->f_ra.ra_pages << (PAGE_SHIFT + 3);
+               if (!max_bytes)
+                       max_bytes = VM_READAHEAD_PAGES << (PAGE_SHIFT + 3);
+
+               /* If max len are exceeded, reset the state */
+               if (async_list->io_len + len <= max_bytes) {
                        req->flags |= REQ_F_SEQ_PREV;
-                       async_list->io_pages += len;
+                       async_list->io_len += len;
                } else {
                        io_end = 0;
-                       async_list->io_pages = 0;
+                       async_list->io_len = 0;
                }
        }
 
        /* New file? Reset state. */
        if (async_list->file != filp) {
-               async_list->io_pages = 0;
+               async_list->io_len = 0;
                async_list->file = filp;
        }
        async_list->io_end = io_end;