[RFC PATCH v4 9/9] mm/damon/core: apply probe_hits_wsum filters to node_eligible_mem_bp
From: Ravi Jonnalagadda
Date: Mon Oct 05 2026 - 04:48:15 EST
node_eligible_mem_bp is the share of a scheme's eligible memory that is
on a given node, and memory is eligible when its region matches the
scheme's access pattern. In data attributes-only monitoring nr_accesses
is not updated, so the access pattern cannot tell which regions the
scheme is for; its probe_hits_wsum filters do.
Count a region as eligible only if it also passes the scheme's
probe_hits_wsum filters, decided as the scheme's core filters are: the
first matching one decides, and if none matches, the region passes
unless the last of them is an allow filter and the scheme has no ops
filters. The address and target filters stay out of the metric, as
before, since they scope where the scheme acts rather than which memory
it is for.
Signed-off-by: Ravi Jonnalagadda <ravis.opensrc@xxxxxxxxx>
---
mm/damon/core.c | 34 +++++++++++++++++++++++++++++++---
1 file changed, 31 insertions(+), 3 deletions(-)
diff --git a/mm/damon/core.c b/mm/damon/core.c
index 7c0df07f0a90..bae4569f0ab3 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -3609,6 +3609,31 @@ static unsigned long damos_get_node_memcg_used_bp(
}
#ifdef CONFIG_DAMON_PADDR
+/*
+ * Whether @r passes the probe_hits_wsum filters of @s, decided as the core
+ * filters of a scheme are, with the other filter types left out: the first
+ * matching filter decides, and if none matches, @r passes unless the last of
+ * them is an allow filter and @s has no ops filters. These filters select
+ * regions by their data attributes, so they are part of what makes memory
+ * eligible for the scheme, unlike its address and target filters.
+ */
+static bool damos_probe_filters_pass(struct damon_ctx *c,
+ struct damon_target *t, struct damon_region *r, struct damos *s)
+{
+ struct damos_filter *filter;
+ bool pass = true;
+
+ damos_for_each_core_filter(filter, s) {
+ if (filter->type != DAMOS_FILTER_TYPE_PROBE_HITS_WSUM)
+ continue;
+ if (damos_filter_match(c, t, r, filter, c->min_region_sz))
+ return filter->allow;
+ pass = !filter->allow;
+ }
+ /* as damos_set_filters_default_reject(): ops filters decide the rest */
+ return pass || !list_empty(&s->ops_filters);
+}
+
/*
* damos_calc_eligible_bytes() - Calculate raw eligible bytes per node.
* @c: The DAMON context.
@@ -3616,9 +3641,10 @@ static unsigned long damos_get_node_memcg_used_bp(
* @nid: The target NUMA node id.
* @total: Output for total eligible bytes across all nodes.
*
- * Iterates through each folio in eligible regions to accurately determine
- * which node the memory resides on. Returns eligible bytes on the specified
- * node and sets *total to the sum across all nodes.
+ * A region is eligible if it matches the access pattern of @s and passes its
+ * probe_hits_wsum filters. Iterates through each folio in eligible regions to
+ * accurately determine which node the memory resides on. Returns eligible bytes
+ * on the specified node and sets *total to the sum across all nodes.
*
* Note: This function requires damon_get_folio() from ops-common.c, which is
* only available when CONFIG_DAMON_PADDR is enabled. It also requires the
@@ -3638,6 +3664,8 @@ static phys_addr_t damos_calc_eligible_bytes(struct damon_ctx *c,
if (!__damos_valid_target(r, s, c))
continue;
+ if (!damos_probe_filters_pass(c, t, r, s))
+ continue;
/* Convert from core address units to physical bytes */
addr = (phys_addr_t)r->ar.start * c->addr_unit;
--
Git-157)