diff options
| author | SJ Park <sj@kernel.org> | 2026-07-05 08:55:52 -0700 |
|---|---|---|
| committer | Andrew Morton <akpm@linux-foundation.org> | 2026-07-09 20:15:27 -0700 |
| commit | 68f2958c4f3f693f2fe4b4fee4a4dbadb835c5c5 (patch) | |
| tree | e21ca817ce0100110f310600bc7044e07ef6cdf5 /mm | |
| parent | b4deda5a46d09d07aae5725874d04c1c51497b18 (diff) | |
| download | linux-next-68f2958c4f3f693f2fe4b4fee4a4dbadb835c5c5.tar.gz linux-next-68f2958c4f3f693f2fe4b4fee4a4dbadb835c5c5.zip | |
mm/damon/core: safely validate src on damon_commit_ctx()
Patch series "mm/damon: validate all parameters in the core".
DAMON has a number of parameters. Some of the parameters are validated by
DAMON, while some are validated by DAMON API callers. Each caller has
their own set of parameters that are exposed to users. Hence each caller
has their own ways to do the validation. There is no clear lines for the
responsibilities. It is confusing and easy to make mistakes at
validations. Actually we found a few bugs in the class.
Define DAMON core as the place to do all the validations and implement
those. damon_set_regions(), damon_start() and damon_commit_ctx() are the
three main DAMON core API functions for setup of DAMON parameters. Make
the three functions to do safe and holistic parameter checks. The first
one is already providing the validation, so changes are only for the last
two functions.
This might add unnecessary validations for some use cases. The overhead
should be negligible as parameters update is expected to only rarely
happen. It reduces the number of places to check and fix for bugs of the
class from all callers to the single component. The maintenance
efficiency gain is obvious.
Further cleanup documents and caller code. Make the lines of validation
duties clearer. Remove validations that are no more needed owing to the
core validations.
Patches Sequence
================
Patch 1 implements the core holistic parameters validation for
damon_commit_ctx(). Patch 2 extends the validation to damon_start().
Patch 3 removes the duplicated holistic parameters validation in DAMON
sysfs interface, which is now embedded into the core layer. Patches 4 and
5 remove duplicated min_region_sz validation in DAMON modules. Patches 6
updates kernel doc to clarify damon_set_regions() is doing the range
validation. Patches 7 and 8 remove monitoring target range validations
that doesn't necessary thanks to the validation in damon_set_regions().
This patch (of 8):
damon_commit_ctx() does its holistic parameter set validation while
applying the new parameter in the set one by one. If it finds a parameter
is invalid, because some invalid parameters may already be committed (it
is called "commit" but not atomic and irreversable), it stops the running
DAMON context.
The callers of the function therefore have to validate the parameters
before calling it. Because the function already embeds holistic
validation, DAMON_SYSFS reuses it in a safe way. It creates a
test-purpose context that is not running but mimics the running one, and
calls damon_commit_ctx() against the test purpose context. If it
succeeds, the parameters are considered valid, and a real
damon_commit_ctx() call against the running context is made with those.
Other callers such as DAMON_RECLAIM and DAMON_LRU_SORT do not expose full
parameters to users. For efficiency, they validate only the known set of
parameters. The efficiency gain is arguably small and doubtful, though.
Meanwhile the maintenance overhead of the multiple different validations
is clearly high. We actually found and fixed a few bugs in the class.
Update damon_commit_ctx() to embed DAMON_SYSFS' safe and holistic
validation approach. Callers can simply call damon_commit_ctx() without
worrying if their parameters are invalid.
Note that damon_commit_ctx() can still cause an unexpected stop of the
running context, if internal memory allocation fails. It is arguably
unlikely since those internal allocations are too small to fail, but
theoretically possible. It should also be better addressed, but not
necessarily a blocker of this small and incremental improvement effort.
Link: https://lore.kernel.org/20260705155600.96555-1-sj@kernel.org
Link: https://lore.kernel.org/20260705155600.96555-2-sj@kernel.org
Signed-off-by: SJ Park <sj@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'mm')
| -rw-r--r-- | mm/damon/core.c | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/mm/damon/core.c b/mm/damon/core.c index 871c6f5257c9..018dd5ff8032 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -1664,20 +1664,7 @@ static int damon_commit_probes(struct damon_ctx *dst, struct damon_ctx *src) return 0; } -/** - * damon_commit_ctx() - Commit parameters of a DAMON context to another. - * @dst: The commit destination DAMON context. - * @src: The commit source DAMON context. - * - * This function copies user-specified parameters from @src to @dst and update - * the internal status and results accordingly. Users should use this function - * for context-level parameters update of running context, instead of manual - * in-place updates. - * - * This function should be called from parameters-update safe context, like - * damon_call(). - */ -int damon_commit_ctx(struct damon_ctx *dst, struct damon_ctx *src) +static int __damon_commit_ctx(struct damon_ctx *dst, struct damon_ctx *src) { int err; struct damos *scheme; @@ -1732,6 +1719,52 @@ int damon_commit_ctx(struct damon_ctx *dst, struct damon_ctx *src) return 0; } +static struct damon_ctx *damon_new_test_ctx(struct damon_ctx *dst) +{ + struct damon_ctx *test_ctx; + int err; + + test_ctx = damon_new_ctx(); + if (!test_ctx) + return NULL; + err = __damon_commit_ctx(test_ctx, dst); + if (err) { + damon_destroy_ctx(test_ctx); + return NULL; + } + return test_ctx; +} + +/** + * damon_commit_ctx() - Commit parameters of a DAMON context to another. + * @dst: The commit destination DAMON context. + * @src: The commit source DAMON context. + * + * This function copies user-specified parameters from @src to @dst and update + * the internal status and results accordingly. Users should use this function + * for context-level parameters update of running context, instead of manual + * in-place updates. + * + * This function should be called from parameters-update safe context, like + * damon_call(). + */ +int damon_commit_ctx(struct damon_ctx *dst, struct damon_ctx *src) +{ + struct damon_ctx *test_ctx; + int err; + + test_ctx = damon_new_test_ctx(dst); + if (!test_ctx) + return -ENOMEM; + err = __damon_commit_ctx(test_ctx, src); + if (err) + goto out; + err = __damon_commit_ctx(dst, src); +out: + damon_destroy_ctx(test_ctx); + return err; +} + /** * damon_nr_running_ctxs() - Return number of currently running contexts. */ |
