Thread (2 messages) 2 messages, 2 authors, 2018-07-27

[PATCH] readahead: stricter check for bdi io_pages

STALE2988d

From: <hidden>
Date: 2018-07-26 20:54:09
Subsystem: memory management, page cache, the rest · Maintainers: Andrew Morton, Matthew Wilcox, Jan Kara, Linus Torvalds

ondemand_readahead() checks bdi->io_pages to cap the maximum pages
that need to be processed. This works until the readit section. If
we would do an async only readahead (async size = sync size) and
target is at beginning of window we expand the pages by another
get_next_ra_size() pages. Btrace for large reads shows that kernel
always issues a doubled size read at the beginning of processing.
Add an additional check for io_pages in the lower part of the func.
The fix helps devices that hard limit bio pages and rely on proper
handling of max_hw_read_sectors (e.g. older FusionIO cards). For
that reason it could qualify for stable.
    
Fixes: 9491ae4a ("mm: don't cap request size based on read-ahead setting")
Signed-off-by: Markus Stockhausen stockhausen@collogia.de
diff --git a/mm/readahead.c b/mm/readahead.c
index 539bbb6..d4ad4bb 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -380,6 +380,7 @@ static int try_context_readahead(struct address_space *mapping,
 {
 	struct backing_dev_info *bdi = inode_to_bdi(mapping->host);
 	unsigned long max_pages = ra->ra_pages;
+	unsigned long add_pages;
 	pgoff_t prev_offset;
 
 	/*
@@ -469,10 +470,17 @@ static int try_context_readahead(struct address_space *mapping,
 	 * Will this read hit the readahead marker made by itself?
 	 * If so, trigger the readahead marker hit now, and merge
 	 * the resulted next readahead window into the current one.
+	 * Take care of maximum IO pages as above.
 	 */
 	if (offset == ra->start && ra->size == ra->async_size) {
-		ra->async_size = get_next_ra_size(ra, max_pages);
-		ra->size += ra->async_size;
+		add_pages = get_next_ra_size(ra, max_pages);
+		if (ra->size + add_pages <= max_pages) {
+			ra->async_size = add_pages;
+			ra->size += add_pages;
+		} else {
+			ra->size = max_pages;
+			ra->async_size = max_pages >> 1;
+		}
 	}
 
 	return ra_submit(ra, mapping, filp);

Attachments

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help