]> www.infradead.org Git - users/hch/misc.git/commitdiff
mm/damon: respect core layer filters' allowance decision on ops layer
authorSeongJae Park <sj@kernel.org>
Fri, 28 Feb 2025 17:53:36 +0000 (09:53 -0800)
committerAndrew Morton <akpm@linux-foundation.org>
Mon, 17 Mar 2025 00:40:23 +0000 (17:40 -0700)
Filtering decisions are made in filters evaluation order.  Once a decision
is made by a filter, filters that scheduled to be evaluated after the
decision-made filter should just respect it.  This is the intended and
documented behavior.  Since core layer-handled filters are evaluated
before operations layer-handled filters, decisions made on core layer
should respected by ops layer.

In case of reject filters, the decision is respected, since core
layer-rejected regions are not passed to ops layer.  But in case of allow
filters, ops layer filters don't know if the region has passed to them
because it was allowed by core filters or just because it didn't match to
any core layer.  The current wrong implementation assumes it was due to
not matched by any core filters.  As a reuslt, the decision is not
respected.  Pass the missing information to ops layer using a new filed in
'struct damos', and make the ops layer filters respect it.

Link: https://lkml.kernel.org/r/20250228175336.42781-1-sj@kernel.org
Fixes: 491fee286e56 ("mm/damon/core: support damos_filter->allow")
Signed-off-by: SeongJae Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
include/linux/damon.h
mm/damon/core.c
mm/damon/paddr.c

index af525252b853a1e7661098a8d41ad1f921b10989..c9074d569596a667bfce342e2affe82041df35e9 100644 (file)
@@ -470,6 +470,11 @@ struct damos {
        unsigned long next_apply_sis;
        /* informs if ongoing DAMOS walk for this scheme is finished */
        bool walk_completed;
+       /*
+        * If the current region in the filtering stage is allowed by core
+        * layer-handled filters.  If true, operations layer allows it, too.
+        */
+       bool core_filters_allowed;
 /* public: */
        struct damos_quota quota;
        struct damos_watermarks wmarks;
index c7b9813088626530fc37a4d2494d24bfc261fca9..de4396519b83b4cc69a702c805475ae2c33f92d0 100644 (file)
@@ -1429,9 +1429,13 @@ static bool damos_filter_out(struct damon_ctx *ctx, struct damon_target *t,
 {
        struct damos_filter *filter;
 
+       s->core_filters_allowed = false;
        damos_for_each_filter(filter, s) {
-               if (damos_filter_match(ctx, t, r, filter))
+               if (damos_filter_match(ctx, t, r, filter)) {
+                       if (filter->allow)
+                               s->core_filters_allowed = true;
                        return !filter->allow;
+               }
        }
        return false;
 }
index 0f9ae14f884dd8c7b9e4261f28448cc0db47605b..c834aa2178352d507205fb33017c0e98c52aa61c 100644 (file)
@@ -236,6 +236,9 @@ static bool damos_pa_filter_out(struct damos *scheme, struct folio *folio)
 {
        struct damos_filter *filter;
 
+       if (scheme->core_filters_allowed)
+               return false;
+
        damos_for_each_filter(filter, scheme) {
                if (damos_pa_filter_match(filter, folio))
                        return !filter->allow;