]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
mm/damon/paddr: support data attributes monitoring
authorSeongJae Park <sj@kernel.org>
Mon, 18 May 2026 23:40:56 +0000 (16:40 -0700)
committerAndrew Morton <akpm@linux-foundation.org>
Tue, 2 Jun 2026 22:22:26 +0000 (15:22 -0700)
Implement and register damon_operations->apply_probes() callback to
support data attributes monitoring.

Link: https://lore.kernel.org/20260518234119.97569-9-sj@kernel.org
Signed-off-by: SeongJae Park <sj@kernel.org>
Cc: David Hildenbrand <david@kernel.org>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Lorenzo Stoakes <ljs@kernel.org>
Cc: "Masami Hiramatsu (Google)" <mhiramat@kernel.org>
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Shuah Khan <shuah@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Suren Baghdasaryan <surenb@google.com>
Cc: Vlastimil Babka <vbabka@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/damon/paddr.c

index c4738cd5e221eda81f4d5b41f6e43dcc0fea9a6c..9997c5174ef1b91a2464a0218eba5ea0c9758e25 100644 (file)
@@ -120,6 +120,67 @@ static unsigned int damon_pa_check_accesses(struct damon_ctx *ctx)
        return max_nr_accesses;
 }
 
+static bool damon_pa_filter_match(struct damon_filter *filter,
+               struct folio *folio)
+{
+       bool matched = false;
+
+       switch (filter->type) {
+       case DAMON_FILTER_TYPE_ANON:
+               if (!folio) {
+                       matched = false;
+                       break;
+               }
+               matched = folio_test_anon(folio);
+               break;
+       default:
+               break;
+       }
+       return matched == filter->matching;
+}
+
+static bool damon_pa_filter_pass(phys_addr_t pa, struct folio *folio,
+               struct damon_probe *p)
+{
+       struct damon_filter *f;
+       bool pass = true;
+
+       damon_for_each_filter(f, p) {
+               if (damon_pa_filter_match(f, folio)) {
+                       pass = f->allow;
+                       break;
+               }
+               pass = !f->allow;
+       }
+       return pass;
+}
+
+static void damon_pa_apply_probes(struct damon_ctx *ctx)
+{
+       struct damon_target *t;
+       struct damon_region *r;
+       struct damon_probe *p;
+
+       damon_for_each_target(t, ctx) {
+               damon_for_each_region(r, t) {
+                       int i = 0;
+                       phys_addr_t pa;
+                       struct folio *folio;
+
+                       pa = damon_pa_phys_addr(r->sampling_addr,
+                                       ctx->addr_unit);
+                       folio = damon_get_folio(PHYS_PFN(pa));
+                       damon_for_each_probe(p, ctx) {
+                               if (damon_pa_filter_pass(pa, folio, p))
+                                       r->probe_hits[i]++;
+                               i++;
+                       }
+                       if (folio)
+                               folio_put(folio);
+               }
+       }
+}
+
 /*
  * damos_pa_filter_out - Return true if the page should be filtered out.
  */
@@ -371,6 +432,7 @@ static int __init damon_pa_initcall(void)
                .update = NULL,
                .prepare_access_checks = damon_pa_prepare_access_checks,
                .check_accesses = damon_pa_check_accesses,
+               .apply_probes = damon_pa_apply_probes,
                .target_valid = NULL,
                .apply_scheme = damon_pa_apply_scheme,
                .get_scheme_score = damon_pa_scheme_score,