[PATCH] mm/damon/core: reject empty access pattern intervals on scheme commit

From: Xiaolei Wang (Kaihong)

Date: Tue Nov 03 2026 - 06:47:08 EST


DAMOS schemes accept access pattern bounds with min > max (e.g.
min_sz_region > max_sz_region). No input path validates the bounds:
damon_new_scheme() stores the pattern as is, and the sysfs ul_range
stores are plain kstrtoul().

At runtime __damos_valid_target() evaluates "min <= x <= max" for each
of the three pattern dimensions. A reversed interval is an empty set,
so every region fails the check and the scheme silently never matches
anything: nr_tried stays zero forever while the kdamond keeps running
normally.

With such a reversed interval, damo starts normally (rc=0, kdamond
state=on), but nr_tried and nr_applied stay zero forever and the target
RSS does not drop.

The same holds for the watermarks thresholds, which must be monotonic
(low <= mid <= high).

Validate the access pattern and watermarks at the beginning of
damos_commit(), through which both new schemes (damo start) and online
updates (damo tune) pass.

Fixes: 1f366e421c8f ("mm/damon/core: implement DAMON-based Operation Schemes (DAMOS)")
Cc: stable@xxxxxxxxxxxxxxx
Cc: Liam R. Howlett <liam@xxxxxxxxxxxxx>
Cc: Michal Hocko <mhocko@xxxxxxxx>
Cc: Mike Rapoport <rppt@xxxxxxxxxx>
Cc: Suren Baghdasaryan <surenb@xxxxxxxxxx>
Cc: Vlastimil Babka <vbabka@xxxxxxxxxx>
Signed-off-by: Xiaolei Wang (Kaihong) <xiaoleiwangxiaolei@xxxxxxxxx>
---
mm/damon/core.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

diff --git a/mm/damon/core.c b/mm/damon/core.c
index eb1fcdabc007..865627bda240 100644
--- a/mm/damon/core.c
+++ b/mm/damon/core.c
@@ -1566,10 +1566,29 @@ static struct damos *damon_nth_scheme(int n, struct damon_ctx *ctx)
return NULL;
}

+static int damos_validate_scheme(struct damos *s)
+{
+ struct damos_access_pattern *p = &s->pattern;
+ struct damos_watermarks *wmarks = &s->wmarks;
+
+ if (p->min_sz_region > p->max_sz_region ||
+ p->min_nr_accesses > p->max_nr_accesses ||
+ p->min_age_region > p->max_age_region)
+ return -EINVAL;
+ if (wmarks->metric != DAMOS_WMARK_NONE &&
+ (wmarks->low > wmarks->mid || wmarks->mid > wmarks->high))
+ return -EINVAL;
+ return 0;
+}
+
static int damos_commit(struct damos *dst, struct damos *src)
{
int err;

+ err = damos_validate_scheme(src);
+ if (err)
+ return err;
+
dst->pattern = src->pattern;
dst->action = src->action;
dst->apply_interval_us = src->apply_interval_us;
--
2.53.0