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);
* - note the struct file * is only passed for the use of readpage
*/
void do_generic_mapping_read(struct address_space *mapping,
struct file_ra_state *ra,
struct file_ra_state *_ra,
struct file * filp,
loff_t *ppos,
read_descriptor_t * desc,
......@@ -616,6 +616,7 @@ void do_generic_mapping_read(struct address_space *mapping,
unsigned long index, offset;
struct page *cached_page;
int error;
struct file_ra_state ra = *_ra;
cached_page = NULL;
index = *ppos >> PAGE_CACHE_SHIFT;
......@@ -638,13 +639,13 @@ void do_generic_mapping_read(struct address_space *mapping,
}
cond_resched();
page_cache_readahead(mapping, ra, filp, index);
page_cache_readahead(mapping, &ra, filp, index);
nr = nr - offset;
find_page:
page = find_get_page(mapping, index);
if (unlikely(page == NULL)) {
handle_ra_miss(mapping, ra, index);
handle_ra_miss(mapping, &ra, index);
goto no_cached_page;
}
if (!PageUptodate(page))
......@@ -746,6 +747,8 @@ void do_generic_mapping_read(struct address_space *mapping,
goto readpage;
}
*_ra = ra;
*ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset;
if (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