reduce readahead overheads on tmpfs mmap page faults
Subsystems (2)
cover reduce readahead overheads on tmpfs mmap page faults
Andrew,
This kills unnessesary ra->mmap_miss and ra->prev_pos updates on every page fault when the readahead is disabled.
They fix the cache line bouncing problem in the mosbench exim benchmark, which does multi-threaded page faults on shared struct file 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
--- 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
--- 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.
In the mosbench exim benchmark which does multi-threaded page faults on shared struct file, this is found to cause excessive cache line bouncing on tmpfs, which does not need readahead at all.
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.
--- 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.
In the mosbench exim benchmark which does multi-threaded page faults on shared struct file, this is found to cause excessive cache line bouncing on tmpfs, which does not need readahead at all.
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.
--- 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>
PATCH 3/3 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.
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.
--- 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>