The VM_FAULT_RETRY case introduced a performance bug that leads to excessive/unconditional mmap readarounds for wild random mmap reads. A retried page fault means a mmap readahead miss(mmap_miss++) followed by a hit(mmap_miss--) on the same page. This sticks mmap_miss, and thus stops mmap readaround from being turned off for wild random reads. Fix it by an extra mmap_miss increament in order to counteract the followed mmap hit. Also make mmap_miss a more robust 'unsigned int', so that if ever mmap_miss goes out of range, it only create _temporary_ performance impacts. Signed-off-by: Wu Fengguang --- include/linux/fs.h | 2 +- mm/filemap.c | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) --- mm.orig/mm/filemap.c +++ mm/mm/filemap.c @@ -1574,8 +1574,10 @@ retry_find: vmf->pgoff, 1); retry_ret = find_lock_page_retry(mapping, vmf->pgoff, vma, &page, retry_flag); - if (retry_ret == VM_FAULT_RETRY) + if (retry_ret == VM_FAULT_RETRY) { + ra->mmap_miss++; /* counteract the followed retry hit */ return retry_ret; + } if (!page) goto no_cached_page; } @@ -1617,8 +1619,10 @@ retry_find: retry_find_retry: retry_ret = find_lock_page_retry(mapping, vmf->pgoff, vma, &page, retry_flag); - if (retry_ret == VM_FAULT_RETRY) + if (retry_ret == VM_FAULT_RETRY) { + ra->mmap_miss++; /* counteract the followed retry hit */ return retry_ret; + } if (!page) goto no_cached_page; } --- mm.orig/include/linux/fs.h +++ mm/include/linux/fs.h @@ -824,7 +824,7 @@ struct file_ra_state { there are only # of pages ahead */ unsigned int ra_pages; /* Maximum readahead window */ - int mmap_miss; /* Cache miss stat for mmap accesses */ + unsigned int mmap_miss; /* Cache miss stat for mmap accesses */ loff_t prev_pos; /* Cache last read() position */ }; -- -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/