diff mbox series

io_uring: use bytes instead of pages to decide len exceeding

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

Commit Message

Zhengyuan Liu July 21, 2019, 3:54 p.m. UTC
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(-)

Comments

Jens Axboe July 21, 2019, 4:56 p.m. UTC | #1
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 mbox series

Patch

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;