Message ID | 20190721155408.14009-1-liuzhengyuan@kylinos.cn (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | io_uring: use bytes instead of pages to decide len exceeding | expand |
On 7/21/19 9:54 AM, Zhengyuan Liu wrote: > 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 things fair. Thanks, we do need this for sub page sized reads to be accurate. One minor nit: > @@ -1121,28 +1121,27 @@ 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_pages, 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; > + max_bytes = (max_pages * 8) << PAGE_SHIFT; Let's get rid of max_pages, and just do: /* Use 8x RA size as a decent limiter for both reads/writes */ max_bytes = filp->f_ra.ra_pages << (PAGE_SHIFT + 3); if (!max_bytes) max_bytes = VM_READAHEAD_PAGES << (PAGE_SHIFT + 3); There's really no need to have both a max_pages and max_bytes variable if we're tracking and limiting based on bytes.
diff --git a/fs/io_uring.c b/fs/io_uring.c index 7e932c572f26..79272cf1ab83 100644 --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -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 { @@ -1121,28 +1121,27 @@ 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_pages, 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; + max_bytes = (max_pages * 8) << PAGE_SHIFT; - /* If max pages are exceeded, reset the state */ - len >>= PAGE_SHIFT; - if (async_list->io_pages + len <= max_pages) { + /* 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;
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 things fair. Signed-off-by: Zhengyuan Liu <liuzhengyuan@kylinos.cn> --- fs/io_uring.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)