[PATCH 3/3] readahead: trigger mmap sequential readahead on PG_readahead

From: Wu Fengguang
Date: Fri Apr 29 2011 - 23:31:52 EST


Previously the mmap sequential readahead is triggered by updating
ra->prev_pos on each page fault and compare it with current page offset.

It costs dirtying the cache line on each _minor_ page fault. So remove
the ra->prev_pos recording, and instead tag PG_readahead to trigger the
possible sequential readahead. It's not only more simple, but also will
work more reliably and reduce cache line bouncing on concurrent page
faults on shared struct file.

Tested-by: Tim Chen <tim.c.chen@xxxxxxxxx>
Reported-by: Andi Kleen <ak@xxxxxxxxxxxxxxx>
Signed-off-by: Wu Fengguang <fengguang.wu@xxxxxxxxx>
---
mm/filemap.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)

--- linux-next.orig/mm/filemap.c 2011-04-23 16:52:21.000000000 +0800
+++ linux-next/mm/filemap.c 2011-04-24 09:59:08.000000000 +0800
@@ -1531,8 +1531,7 @@ static void do_sync_mmap_readahead(struc
if (!ra->ra_pages)
return;

- if (VM_SequentialReadHint(vma) ||
- offset - 1 == (ra->prev_pos >> PAGE_CACHE_SHIFT)) {
+ if (VM_SequentialReadHint(vma)) {
page_cache_sync_readahead(mapping, ra, file, offset,
ra->ra_pages);
return;
@@ -1555,7 +1554,7 @@ static void do_sync_mmap_readahead(struc
ra_pages = max_sane_readahead(ra->ra_pages);
ra->start = max_t(long, 0, offset - ra_pages / 2);
ra->size = ra_pages;
- ra->async_size = 0;
+ ra->async_size = ra_pages / 4;
ra_submit(ra, mapping, file);
}

@@ -1661,7 +1660,6 @@ retry_find:
return VM_FAULT_SIGBUS;
}

- ra->prev_pos = (loff_t)offset << PAGE_CACHE_SHIFT;
vmf->page = page;
return ret | VM_FAULT_LOCKED;



--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/