Skip to content

Commit 96ebdb0

Browse files
ioworker0akpm00
authored andcommitted
mm/memory: add any_dirty optional pointer to folio_pte_batch()
This commit adds the any_dirty pointer as an optional parameter to folio_pte_batch() function. By using both the any_young and any_dirty pointers, madvise_free can make smarter decisions about whether to clear the PTEs when marking large folios as lazyfree. Link: https://lkml.kernel.org/r/[email protected] Signed-off-by: Lance Yang <[email protected]> Suggested-by: David Hildenbrand <[email protected]> Acked-by: David Hildenbrand <[email protected]> Cc: Barry Song <[email protected]> Cc: Jeff Xie <[email protected]> Cc: Kefeng Wang <[email protected]> Cc: Michal Hocko <[email protected]> Cc: Minchan Kim <[email protected]> Cc: Muchun Song <[email protected]> Cc: Peter Xu <[email protected]> Cc: Ryan Roberts <[email protected]> Cc: Yang Shi <[email protected]> Cc: Yin Fengwei <[email protected]> Cc: Zach O'Keefe <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 89e8685 commit 96ebdb0

File tree

3 files changed

+26
-9
lines changed

3 files changed

+26
-9
lines changed

mm/internal.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ static inline pte_t __pte_batch_clear_ignored(pte_t pte, fpb_t flags)
134134
* first one is writable.
135135
* @any_young: Optional pointer to indicate whether any entry except the
136136
* first one is young.
137+
* @any_dirty: Optional pointer to indicate whether any entry except the
138+
* first one is dirty.
137139
*
138140
* Detect a PTE batch: consecutive (present) PTEs that map consecutive
139141
* pages of the same large folio.
@@ -149,18 +151,20 @@ static inline pte_t __pte_batch_clear_ignored(pte_t pte, fpb_t flags)
149151
*/
150152
static inline int folio_pte_batch(struct folio *folio, unsigned long addr,
151153
pte_t *start_ptep, pte_t pte, int max_nr, fpb_t flags,
152-
bool *any_writable, bool *any_young)
154+
bool *any_writable, bool *any_young, bool *any_dirty)
153155
{
154156
unsigned long folio_end_pfn = folio_pfn(folio) + folio_nr_pages(folio);
155157
const pte_t *end_ptep = start_ptep + max_nr;
156158
pte_t expected_pte, *ptep;
157-
bool writable, young;
159+
bool writable, young, dirty;
158160
int nr;
159161

160162
if (any_writable)
161163
*any_writable = false;
162164
if (any_young)
163165
*any_young = false;
166+
if (any_dirty)
167+
*any_dirty = false;
164168

165169
VM_WARN_ON_FOLIO(!pte_present(pte), folio);
166170
VM_WARN_ON_FOLIO(!folio_test_large(folio) || max_nr < 1, folio);
@@ -176,6 +180,8 @@ static inline int folio_pte_batch(struct folio *folio, unsigned long addr,
176180
writable = !!pte_write(pte);
177181
if (any_young)
178182
young = !!pte_young(pte);
183+
if (any_dirty)
184+
dirty = !!pte_dirty(pte);
179185
pte = __pte_batch_clear_ignored(pte, flags);
180186

181187
if (!pte_same(pte, expected_pte))
@@ -193,6 +199,8 @@ static inline int folio_pte_batch(struct folio *folio, unsigned long addr,
193199
*any_writable |= writable;
194200
if (any_young)
195201
*any_young |= young;
202+
if (any_dirty)
203+
*any_dirty |= dirty;
196204

197205
nr = pte_batch_hint(ptep, pte);
198206
expected_pte = pte_advance_pfn(expected_pte, nr);

mm/madvise.c

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,18 @@ static inline bool can_do_file_pageout(struct vm_area_struct *vma)
321321
file_permission(vma->vm_file, MAY_WRITE) == 0;
322322
}
323323

324+
static inline int madvise_folio_pte_batch(unsigned long addr, unsigned long end,
325+
struct folio *folio, pte_t *ptep,
326+
pte_t pte, bool *any_young,
327+
bool *any_dirty)
328+
{
329+
const fpb_t fpb_flags = FPB_IGNORE_DIRTY | FPB_IGNORE_SOFT_DIRTY;
330+
int max_nr = (end - addr) / PAGE_SIZE;
331+
332+
return folio_pte_batch(folio, addr, ptep, pte, max_nr, fpb_flags, NULL,
333+
any_young, any_dirty);
334+
}
335+
324336
static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
325337
unsigned long addr, unsigned long end,
326338
struct mm_walk *walk)
@@ -456,13 +468,10 @@ static int madvise_cold_or_pageout_pte_range(pmd_t *pmd,
456468
* next pte in the range.
457469
*/
458470
if (folio_test_large(folio)) {
459-
const fpb_t fpb_flags = FPB_IGNORE_DIRTY |
460-
FPB_IGNORE_SOFT_DIRTY;
461-
int max_nr = (end - addr) / PAGE_SIZE;
462471
bool any_young;
463472

464-
nr = folio_pte_batch(folio, addr, pte, ptent, max_nr,
465-
fpb_flags, NULL, &any_young);
473+
nr = madvise_folio_pte_batch(addr, end, folio, pte,
474+
ptent, &any_young, NULL);
466475
if (any_young)
467476
ptent = pte_mkyoung(ptent);
468477

mm/memory.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -989,7 +989,7 @@ copy_present_ptes(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma
989989
flags |= FPB_IGNORE_SOFT_DIRTY;
990990

991991
nr = folio_pte_batch(folio, addr, src_pte, pte, max_nr, flags,
992-
&any_writable, NULL);
992+
&any_writable, NULL, NULL);
993993
folio_ref_add(folio, nr);
994994
if (folio_test_anon(folio)) {
995995
if (unlikely(folio_try_dup_anon_rmap_ptes(folio, page,
@@ -1558,7 +1558,7 @@ static inline int zap_present_ptes(struct mmu_gather *tlb,
15581558
*/
15591559
if (unlikely(folio_test_large(folio) && max_nr != 1)) {
15601560
nr = folio_pte_batch(folio, addr, pte, ptent, max_nr, fpb_flags,
1561-
NULL, NULL);
1561+
NULL, NULL, NULL);
15621562

15631563
zap_present_folio_ptes(tlb, vma, folio, page, pte, ptent, nr,
15641564
addr, details, rss, force_flush,

0 commit comments

Comments
 (0)