]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
mm/damon/ops: have damon_get_folio return folio even for tail pages
authorUsama Arif <usamaarif642@gmail.com>
Fri, 7 Feb 2025 21:20:32 +0000 (13:20 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sun, 20 Apr 2025 08:18:16 +0000 (10:18 +0200)
commit 3a06696305e757f652dd0dcf4dfa2272eda39434 upstream.

Patch series "mm/damon/paddr: fix large folios access and schemes handling".

DAMON operations set for physical address space, namely 'paddr', treats
tail pages as unaccessed always.  It can also apply DAMOS action to a
large folio multiple times within single DAMOS' regions walking.  As a
result, the monitoring output has poor quality and DAMOS works in
unexpected ways when large folios are being used.  Fix those.

The patches were parts of Usama's hugepage_size DAMOS filter patch
series[1].  The first fix has collected from there with a slight commit
message change for the subject prefix.  The second fix is re-written by SJ
and posted as an RFC before this series.  The second one also got a slight
commit message change for the subject prefix.

[1] https://lore.kernel.org/20250203225604.44742-1-usamaarif642@gmail.com
[2] https://lore.kernel.org/20250206231103.38298-1-sj@kernel.org

This patch (of 2):

This effectively adds support for large folios in damon for paddr, as
damon_pa_mkold/young won't get a null folio from this function and won't
ignore it, hence access will be checked and reported.  This also means
that larger folios will be considered for different DAMOS actions like
pageout, prioritization and migration.  As these DAMOS actions will
consider larger folios, iterate through the region at folio_size and not
PAGE_SIZE intervals.  This should not have an affect on vaddr, as
damon_young_pmd_entry considers pmd entries.

Link: https://lkml.kernel.org/r/20250207212033.45269-1-sj@kernel.org
Link: https://lkml.kernel.org/r/20250207212033.45269-2-sj@kernel.org
Fixes: a28397beb55b ("mm/damon: implement primitives for physical address space monitoring")
Signed-off-by: Usama Arif <usamaarif642@gmail.com>
Signed-off-by: SeongJae Park <sj@kernel.org>
Reviewed-by: SeongJae Park <sj@kernel.org>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
mm/damon/ops-common.c
mm/damon/paddr.c

index d25d99cb5f2bb9a1eead9d555a2d42c9d2b4af45..d511be201c4c9e98e51e525afdc4131b026b1213 100644 (file)
@@ -24,7 +24,7 @@ struct folio *damon_get_folio(unsigned long pfn)
        struct page *page = pfn_to_online_page(pfn);
        struct folio *folio;
 
-       if (!page || PageTail(page))
+       if (!page)
                return NULL;
 
        folio = page_folio(page);
index a9ff35341d65d22d89dec521c374ab9bb58a4f64..8813038abc6fb3a3699476761168ad112e30d1aa 100644 (file)
@@ -264,11 +264,14 @@ static unsigned long damon_pa_pageout(struct damon_region *r, struct damos *s)
                damos_add_filter(s, filter);
        }
 
-       for (addr = r->ar.start; addr < r->ar.end; addr += PAGE_SIZE) {
+       addr = r->ar.start;
+       while (addr < r->ar.end) {
                struct folio *folio = damon_get_folio(PHYS_PFN(addr));
 
-               if (!folio)
+               if (!folio) {
+                       addr += PAGE_SIZE;
                        continue;
+               }
 
                if (damos_pa_filter_out(s, folio))
                        goto put_folio;
@@ -282,6 +285,7 @@ static unsigned long damon_pa_pageout(struct damon_region *r, struct damos *s)
                else
                        list_add(&folio->lru, &folio_list);
 put_folio:
+               addr += folio_size(folio);
                folio_put(folio);
        }
        if (install_young_filter)
@@ -296,11 +300,14 @@ static inline unsigned long damon_pa_mark_accessed_or_deactivate(
 {
        unsigned long addr, applied = 0;
 
-       for (addr = r->ar.start; addr < r->ar.end; addr += PAGE_SIZE) {
+       addr = r->ar.start;
+       while (addr < r->ar.end) {
                struct folio *folio = damon_get_folio(PHYS_PFN(addr));
 
-               if (!folio)
+               if (!folio) {
+                       addr += PAGE_SIZE;
                        continue;
+               }
 
                if (damos_pa_filter_out(s, folio))
                        goto put_folio;
@@ -311,6 +318,7 @@ static inline unsigned long damon_pa_mark_accessed_or_deactivate(
                        folio_deactivate(folio);
                applied += folio_nr_pages(folio);
 put_folio:
+               addr += folio_size(folio);
                folio_put(folio);
        }
        return applied * PAGE_SIZE;
@@ -454,11 +462,14 @@ static unsigned long damon_pa_migrate(struct damon_region *r, struct damos *s)
        unsigned long addr, applied;
        LIST_HEAD(folio_list);
 
-       for (addr = r->ar.start; addr < r->ar.end; addr += PAGE_SIZE) {
+       addr = r->ar.start;
+       while (addr < r->ar.end) {
                struct folio *folio = damon_get_folio(PHYS_PFN(addr));
 
-               if (!folio)
+               if (!folio) {
+                       addr += PAGE_SIZE;
                        continue;
+               }
 
                if (damos_pa_filter_out(s, folio))
                        goto put_folio;
@@ -467,6 +478,7 @@ static unsigned long damon_pa_migrate(struct damon_region *r, struct damos *s)
                        goto put_folio;
                list_add(&folio->lru, &folio_list);
 put_folio:
+               addr += folio_size(folio);
                folio_put(folio);
        }
        applied = damon_pa_migrate_pages(&folio_list, s->target_nid);