diff mbox series

[2/2] mm: filemap: batch mm counter updating in filemap_map_pages()

Message ID 20240412025704.53245-3-wangkefeng.wang@huawei.com (mailing list archive)
State New
Headers show
Series mm: batch mm counter updating in filemap_map_pages() | expand

Commit Message

Kefeng Wang April 12, 2024, 2:57 a.m. UTC
Like copy_pte_range()/zap_pte_range(), make mm counter batch updating
in filemap_map_pages(), the 'lat_pagefault -P 1 file' test from lmbench
shows 12% improvement, and the percpu_counter_add_batch() is gone from
perf flame graph.

Signed-off-by: Kefeng Wang <wangkefeng.wang@huawei.com>
---
 mm/filemap.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

Comments

Matthew Wilcox April 12, 2024, 3:17 a.m. UTC | #1
On Fri, Apr 12, 2024 at 10:57:04AM +0800, Kefeng Wang wrote:
>  	} while ((folio = next_uptodate_folio(&xas, mapping, end_pgoff)) != NULL);
> +
> +	add_mm_counter(vma->vm_mm, mm_counter_file(folio), rss);

Can't folio be NULL here?
Kefeng Wang April 12, 2024, 3:49 a.m. UTC | #2
On 2024/4/12 11:17, Matthew Wilcox wrote:
> On Fri, Apr 12, 2024 at 10:57:04AM +0800, Kefeng Wang wrote:
>>   	} while ((folio = next_uptodate_folio(&xas, mapping, end_pgoff)) != NULL);
>> +
>> +	add_mm_counter(vma->vm_mm, mm_counter_file(folio), rss);
> 
> Can't folio be NULL here?
indeed, I need get mm counter type before while
>
diff mbox series

Patch

diff --git a/mm/filemap.c b/mm/filemap.c
index 04b813f0146c..c8d41ab5034b 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -3506,7 +3506,7 @@  static struct folio *next_uptodate_folio(struct xa_state *xas,
 static vm_fault_t filemap_map_folio_range(struct vm_fault *vmf,
 			struct folio *folio, unsigned long start,
 			unsigned long addr, unsigned int nr_pages,
-			unsigned int *mmap_miss)
+			unsigned long *rss, unsigned int *mmap_miss)
 {
 	vm_fault_t ret = 0;
 	struct page *page = folio_page(folio, start);
@@ -3540,8 +3540,7 @@  static vm_fault_t filemap_map_folio_range(struct vm_fault *vmf,
 skip:
 		if (count) {
 			set_pte_range(vmf, folio, page, count, addr);
-			add_mm_counter(vmf->vma->vm_mm, mm_counter_file(folio),
-				       count);
+			*rss += count;
 			folio_ref_add(folio, count);
 			if (in_range(vmf->address, addr, count * PAGE_SIZE))
 				ret = VM_FAULT_NOPAGE;
@@ -3556,7 +3555,7 @@  static vm_fault_t filemap_map_folio_range(struct vm_fault *vmf,
 
 	if (count) {
 		set_pte_range(vmf, folio, page, count, addr);
-		add_mm_counter(vmf->vma->vm_mm, mm_counter_file(folio), count);
+		*rss += count;
 		folio_ref_add(folio, count);
 		if (in_range(vmf->address, addr, count * PAGE_SIZE))
 			ret = VM_FAULT_NOPAGE;
@@ -3569,7 +3568,7 @@  static vm_fault_t filemap_map_folio_range(struct vm_fault *vmf,
 
 static vm_fault_t filemap_map_order0_folio(struct vm_fault *vmf,
 		struct folio *folio, unsigned long addr,
-		unsigned int *mmap_miss)
+		unsigned long *rss, unsigned int *mmap_miss)
 {
 	vm_fault_t ret = 0;
 	struct page *page = &folio->page;
@@ -3593,7 +3592,7 @@  static vm_fault_t filemap_map_order0_folio(struct vm_fault *vmf,
 		ret = VM_FAULT_NOPAGE;
 
 	set_pte_range(vmf, folio, page, 1, addr);
-	add_mm_counter(vmf->vma->vm_mm, mm_counter_file(folio), 1);
+	(*rss)++;
 	folio_ref_inc(folio);
 
 	return ret;
@@ -3610,6 +3609,7 @@  vm_fault_t filemap_map_pages(struct vm_fault *vmf,
 	XA_STATE(xas, &mapping->i_pages, start_pgoff);
 	struct folio *folio;
 	vm_fault_t ret = 0;
+	unsigned long rss = 0;
 	unsigned int nr_pages = 0, mmap_miss = 0, mmap_miss_saved;
 
 	rcu_read_lock();
@@ -3640,15 +3640,17 @@  vm_fault_t filemap_map_pages(struct vm_fault *vmf,
 
 		if (!folio_test_large(folio))
 			ret |= filemap_map_order0_folio(vmf,
-					folio, addr, &mmap_miss);
+					folio, addr, &rss, &mmap_miss);
 		else
 			ret |= filemap_map_folio_range(vmf, folio,
 					xas.xa_index - folio->index, addr,
-					nr_pages, &mmap_miss);
+					nr_pages, &rss, &mmap_miss);
 
 		folio_unlock(folio);
 		folio_put(folio);
 	} while ((folio = next_uptodate_folio(&xas, mapping, end_pgoff)) != NULL);
+
+	add_mm_counter(vma->vm_mm, mm_counter_file(folio), rss);
 	pte_unmap_unlock(vmf->pte, vmf->ptl);
 out:
 	rcu_read_unlock();