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 --- 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); + } if (!list_empty(&ctx->schemes)) kdamond_apply_schemes(ctx); else -- 2.47.3