Re: [RFC PATCH v2 01/10] mm/damon/core: introduce damon_ctx->paused
From: SeongJae Park
Date: Fri Mar 20 2026 - 11:17:27 EST
On Wed, 18 Mar 2026 22:21:44 -0700 SeongJae Park <sj@xxxxxxxxxx> wrote:
> DAMON supports only start and stop of the execution. When it is
> stopped, its internal data that it self-trained goes away. It will be
> useful if the execution can be paused and resumed with the previous
> self-trained data.
>
> Introduce per-context API parameter, 'paused', for the purpose. The
> parameter can be set and unset while DAMON is running and paused, using
> the online parameters commit helper functions (damon_commit_ctx() and
> damon_call()). Once 'paused' is set, the kdamond_fn() main loop does
> only limited works with sampling interval sleep during the works. The
> limited works include the handling of the online parameters update, so
> that users can unset the 'pause' and resume the execution when they
> want. It also keep checking DAMON stop conditions and handling of it,
> so that DAMON can be stopped while paused if needed.
>
> Signed-off-by: SeongJae Park <sj@xxxxxxxxxx>
> ---
> include/linux/damon.h | 2 ++
> mm/damon/core.c | 9 +++++++++
> 2 files changed, 11 insertions(+)
>
> diff --git a/include/linux/damon.h b/include/linux/damon.h
> index 3a441fbca170d..421e51eff3bd2 100644
> --- a/include/linux/damon.h
> +++ b/include/linux/damon.h
> @@ -811,6 +811,8 @@ struct damon_ctx {
> * intervals tuning
> */
> unsigned long next_intervals_tune_sis;
> + /* pause kdamond main loop */
> + bool pause;
> /* for waiting until the execution of the kdamond_fn is started */
> struct completion kdamond_started;
> /* for scheme quotas prioritization */
> diff --git a/mm/damon/core.c b/mm/damon/core.c
> index 339325e1096bc..0b6cb63d64d0e 100644
> --- a/mm/damon/core.c
> +++ b/mm/damon/core.c
> @@ -1331,6 +1331,7 @@ int damon_commit_ctx(struct damon_ctx *dst, struct damon_ctx *src)
> if (err)
> return err;
> }
> + dst->pause = src->pause;
> dst->ops = src->ops;
> dst->addr_unit = src->addr_unit;
> dst->min_region_sz = src->min_region_sz;
> @@ -2978,6 +2979,14 @@ static int kdamond_fn(void *data)
> * kdamond_merge_regions() if possible, to reduce overhead
> */
> kdamond_call(ctx, false);
> + while (ctx->pause) {
> + if (kdamond_need_stop(ctx))
> + goto done;
> + kdamond_usleep(ctx->attrs.sample_interval);
> + /* allow caller unset pause via damon_call() */
> + kdamond_call(ctx, false);
> + damos_walk_cancel(ctx);
Sashiko comment
(https://sashiko.dev/#/patchset/20260319052157.99433-2-sj@xxxxxxxxxx) and my
reply below.
: Can this cause spurious cancellations of DAMOS walk requests if the context
: is unpaused?
:
: If kdamond_call() processes a commit that sets ctx->pause = false, and a new
: walk request is queued concurrently or immediately after, this unconditional
: call to damos_walk_cancel() will cancel the newly submitted request before
: the loop condition is evaluated again to exit the loop.
:
: Would it be safer to verify if the context is still paused before cancelling,
: perhaps by checking if (ctx->pause) before calling damos_walk_cancel()?
Yes, it can cause unnecessary cancel of damos_walk() request. But cancelling a
few more damos_walk() request is no big deal. The caller and user can show it
is cancelled, and just ask it again.
So, not a problem.
Thanks,
SJ
[...]