Commit 2a12ed0e authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] readahead: keep file->f_ra sane

When two threads are simultaneously pread()ing from the same fd (which is a
legitimate thing to do), the readahead code thinks that a huge amount of
seeking is happening and shrinks the window, damaging performance a lot.

I don't see a sane way to avoid this within the readahead code, so take a
private copy of the readahead state and restore it prior to returning from the
read.
parent 60967810
...@@ -606,7 +606,7 @@ EXPORT_SYMBOL(grab_cache_page_nowait); ...@@ -606,7 +606,7 @@ EXPORT_SYMBOL(grab_cache_page_nowait);
* - note the struct file * is only passed for the use of readpage * - note the struct file * is only passed for the use of readpage
*/ */
void do_generic_mapping_read(struct address_space *mapping, void do_generic_mapping_read(struct address_space *mapping,
struct file_ra_state *ra, struct file_ra_state *_ra,
struct file * filp, struct file * filp,
loff_t *ppos, loff_t *ppos,
read_descriptor_t * desc, read_descriptor_t * desc,
...@@ -616,6 +616,7 @@ void do_generic_mapping_read(struct address_space *mapping, ...@@ -616,6 +616,7 @@ void do_generic_mapping_read(struct address_space *mapping,
unsigned long index, offset; unsigned long index, offset;
struct page *cached_page; struct page *cached_page;
int error; int error;
struct file_ra_state ra = *_ra;
cached_page = NULL; cached_page = NULL;
index = *ppos >> PAGE_CACHE_SHIFT; index = *ppos >> PAGE_CACHE_SHIFT;
...@@ -638,13 +639,13 @@ void do_generic_mapping_read(struct address_space *mapping, ...@@ -638,13 +639,13 @@ void do_generic_mapping_read(struct address_space *mapping,
} }
cond_resched(); cond_resched();
page_cache_readahead(mapping, ra, filp, index); page_cache_readahead(mapping, &ra, filp, index);
nr = nr - offset; nr = nr - offset;
find_page: find_page:
page = find_get_page(mapping, index); page = find_get_page(mapping, index);
if (unlikely(page == NULL)) { if (unlikely(page == NULL)) {
handle_ra_miss(mapping, ra, index); handle_ra_miss(mapping, &ra, index);
goto no_cached_page; goto no_cached_page;
} }
if (!PageUptodate(page)) if (!PageUptodate(page))
...@@ -746,6 +747,8 @@ void do_generic_mapping_read(struct address_space *mapping, ...@@ -746,6 +747,8 @@ void do_generic_mapping_read(struct address_space *mapping,
goto readpage; goto readpage;
} }
*_ra = ra;
*ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset; *ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
if (cached_page) if (cached_page)
page_cache_release(cached_page); page_cache_release(cached_page);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment