summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWu Fengguang <fengguang.wu@intel.com>2011-05-24 17:12:30 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-25 08:39:27 -0700
commit2cbea1d3ab11946885d37a2461072ee4d687cb4e (patch)
treeaab301cb3da1e633bbd7df2acc4b4c2e4f777b35
parent207d04baa3591a354711e863dd90087fc75873b3 (diff)
downloadlinux-3.10-2cbea1d3ab11946885d37a2461072ee4d687cb4e.tar.gz
linux-3.10-2cbea1d3ab11946885d37a2461072ee4d687cb4e.tar.bz2
linux-3.10-2cbea1d3ab11946885d37a2461072ee4d687cb4e.zip
readahead: trigger mmap sequential readahead on PG_readahead
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. In the mosbench exim benchmark which does multi-threaded page faults on shared struct file, the ra->mmap_miss and ra->prev_pos updates are found to cause excessive cache line bouncing on tmpfs, which actually disabled readahead totally (shmem_backing_dev_info.ra_pages == 0). 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 on concurrent reads on shared struct file. Signed-off-by: Wu Fengguang <fengguang.wu@intel.com> Tested-by: Tim Chen <tim.c.chen@intel.com> Reported-by: Andi Kleen <ak@linux.intel.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--mm/filemap.c6
1 files changed, 2 insertions, 4 deletions
diff --git a/mm/filemap.c b/mm/filemap.c
index e5131392d32..68e782b3d3d 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1559,8 +1559,7 @@ static void do_sync_mmap_readahead(struct vm_area_struct *vma,
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;
@@ -1583,7 +1582,7 @@ static void do_sync_mmap_readahead(struct vm_area_struct *vma,
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);
}
@@ -1689,7 +1688,6 @@ retry_find:
return VM_FAULT_SIGBUS;
}
- ra->prev_pos = (loff_t)offset << PAGE_CACHE_SHIFT;
vmf->page = page;
return ret | VM_FAULT_LOCKED;