reduce readahead overheads on tmpfs mmap page faults v2
Subsystems (2)
cover reduce readahead overheads on tmpfs mmap page faults v2
Andrew,
I would like to update the changelogs for patches 2 and 3. There are no changes to the code. Sorry for the inconvenience.
The original changelog is not accurate: it's solely the ra->mmap_miss updates that caused cache line bouncing on tmpfs. ra->prev_pos won't be updated at all on tmpfs.
Thanks,
Fengguang
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 1/3 readahead: return early when readahead is disabled
Reduce readahead overheads by returning early in do_sync_mmap_readahead().
tmpfs has ra_pages=0 and it can page fault really fast (not constraint by IO if not swapping).
--- mm/filemap.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
mm/filemap.c +6 -6
@@ -1528,6 +1528,8 @@ static void do_sync_mmap_readahead(struc/* If we don't want any read-ahead, don't bother */ if (VM_RandomReadHint (vma))return ; +if (!ra->ra_pages) +return ;if (VM_SequentialReadHint (vma) || offset -1 == (ra->prev_pos >>PAGE_CACHE_SHIFT )) {
@@ -1550,12 +1552,10 @@ static void do_sync_mmap_readahead(struc* mmap read-around */ ra_pages =max_sane_readahead (ra->ra_pages); -if (ra_pages) { - ra->start =max_t (long,0 , offset - ra_pages/2 ); - ra->size = ra_pages; - ra->async_size =0 ; -ra_submit (ra, mapping, file); - } + ra->start =max_t (long,0 , offset - ra_pages /2 ); + ra->size = ra_pages; + ra->async_size =0 ; +ra_submit (ra, mapping, file); }/*
PATCH 1/3 readahead: return early when readahead is disabled
In reply to Wu FengguangReduce readahead overheads by returning early indo_sync_mmap_readahead().
tmpfs has ra_pages=0 and it can page fault really fast (not constraint by IO if not swapping).
--- mm/filemap.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
mm/filemap.c +6 -6
@@ -1528,6 +1528,8 @@ static void do_sync_mmap_readahead(struc/* If we don't want any read-ahead, don't bother */ if (VM_RandomReadHint (vma))return ; +if (!ra->ra_pages) +return ;if (VM_SequentialReadHint (vma) || offset -1 == (ra->prev_pos >>PAGE_CACHE_SHIFT )) {
@@ -1550,12 +1552,10 @@ static void do_sync_mmap_readahead(struc* mmap read-around */ ra_pages =max_sane_readahead (ra->ra_pages); -if (ra_pages) { - ra->start =max_t (long,0 , offset - ra_pages/2 ); - ra->size = ra_pages; - ra->async_size =0 ; -ra_submit (ra, mapping, file); - } + ra->start =max_t (long,0 , offset - ra_pages /2 ); + ra->size = ra_pages; + ra->async_size =0 ; +ra_submit (ra, mapping, file); }/*
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 2/3 readahead: reduce unnecessary mmap_miss increases
In reply to Wu FengguangFrom: Andi Kleen <[email protected]>
The original INT_MAX is too large, reduce it to
- avoid unnecessarily dirtying/bouncing the cache line
- restore mmap read-around faster on changed access pattern
Background: in the mosbench exim benchmark which does multi-threaded page faults on shared struct file, the ra->mmap_miss updates are found to cause excessive cache line bouncing on tmpfs. The ra state updates are needless for tmpfs because it actually disabled readahead totally (shmem_backing_dev_info.ra_pages == 0).
--- mm/filemap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
mm/filemap.c +2 -1
@@ -1538,7 +1538,8 @@ static void do_sync_mmap_readahead(strucreturn ; } -if (ra->mmap_miss <INT_MAX ) +/* Avoid banging the cache line if not needed */ +if (ra->mmap_miss <MMAP_LOTSAMISS *10 ) ra->mmap_miss++;/*
PATCH 2/3 readahead: reduce unnecessary mmap_miss increases
In reply to Wu FengguangFrom: Andi Kleen <[email protected]>
The original INT_MAX is too large, reduce it to
- avoid unnecessarily dirtying/bouncing the cache line
- restore mmap read-around faster on changed access pattern
Background: in the mosbench exim benchmark which does multi-threaded page faults on shared struct file, the ra->mmap_miss updates are found to cause excessive cache line bouncing on tmpfs. The ra state updates are needless for tmpfs because it actually disabled readahead totally (shmem_backing_dev_info.ra_pages == 0).
--- mm/filemap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
mm/filemap.c +2 -1
@@ -1538,7 +1538,8 @@ static void do_sync_mmap_readahead(strucreturn ; } -if (ra->mmap_miss <INT_MAX ) +/* Avoid banging the cache line if not needed */ +if (ra->mmap_miss <MMAP_LOTSAMISS *10 ) ra->mmap_miss++;/*
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>
PATCH 3/3 readahead: trigger mmap sequential readahead on PG_readahead
In reply to Wu FengguangPreviously 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.
--- mm/filemap.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
mm/filemap.c +2 -4
@@ -1531,8 +1531,7 @@ static void do_sync_mmap_readahead(strucif (!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 ;
PATCH 3/3 readahead: trigger mmap sequential readahead on PG_readahead
In reply to Wu FengguangPreviously 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.
--- mm/filemap.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
mm/filemap.c +2 -4
@@ -1531,8 +1531,7 @@ static void do_sync_mmap_readahead(strucif (!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, send a message with 'unsubscribe linux-mm' in
the body to [email protected]. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Fight unfair telecom internet charges in Canada: sign http://stopthemeter.ca/
Don't email: <a href=mailto:"[email protected]"> [email protected] </a>