Commit 9310a7ba authored by Zhengyuan Liu's avatar Zhengyuan Liu Committed by Jens Axboe
Browse files

io_uring: track io length in async_list based on bytes



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: default avatarZhengyuan Liu <liuzhengyuan@kylinos.cn>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent bd11b3a3
Loading
Loading
Loading
Loading
+11 −13
Original line number Diff line number Diff line
@@ -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;