summaryrefslogtreecommitdiffstats
path: root/mm/filemap.c
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2007-05-06 23:49:25 +0200
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-07 21:12:52 +0200
commitec0f16372277052a29a6c17527c6cae5e898b3fd (patch)
tree35636edac6ed01baf301f3aca96f090caae82c9d /mm/filemap.c
parentsmaps: add clear_refs file to clear reference (diff)
downloadlinux-ec0f16372277052a29a6c17527c6cae5e898b3fd.tar.xz
linux-ec0f16372277052a29a6c17527c6cae5e898b3fd.zip
readahead: improve heuristic detecting sequential reads
Introduce ra.offset and store in it an offset where the previous read ended. This way we can detect whether reads are really sequential (and thus we should not mark the page as accessed repeatedly) or whether they are random and just happen to be in the same page (and the page should really be marked accessed again). Signed-off-by: Jan Kara <jack@suse.cz> Acked-by: Nick Piggin <nickpiggin@yahoo.com.au> Cc: WU Fengguang <wfg@mail.ustc.edu.cn> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'mm/filemap.c')
-rw-r--r--mm/filemap.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index cbea95a25283..07f5b77114a3 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -868,6 +868,7 @@ void do_generic_mapping_read(struct address_space *mapping,
unsigned long last_index;
unsigned long next_index;
unsigned long prev_index;
+ unsigned int prev_offset;
loff_t isize;
struct page *cached_page;
int error;
@@ -877,6 +878,7 @@ void do_generic_mapping_read(struct address_space *mapping,
index = *ppos >> PAGE_CACHE_SHIFT;
next_index = index;
prev_index = ra.prev_page;
+ prev_offset = ra.offset;
last_index = (*ppos + desc->count + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT;
offset = *ppos & ~PAGE_CACHE_MASK;
@@ -924,10 +926,10 @@ page_ok:
flush_dcache_page(page);
/*
- * When (part of) the same page is read multiple times
- * in succession, only mark it as accessed the first time.
+ * When a sequential read accesses a page several times,
+ * only mark it as accessed the first time.
*/
- if (prev_index != index)
+ if (prev_index != index || offset != prev_offset)
mark_page_accessed(page);
prev_index = index;
@@ -945,6 +947,7 @@ page_ok:
offset += ret;
index += offset >> PAGE_CACHE_SHIFT;
offset &= ~PAGE_CACHE_MASK;
+ prev_offset = ra.offset = offset;
page_cache_release(page);
if (ret == nr && desc->count)