From: Bijan Tabatabai Any DAMON command that uses damos_walk() internally, such as update_schemes_tried_bytes and update_schemes_tried_regions, waits until each scheme in the DAMON context have finished. This can be useful, for example, if a user wants to know when new scheme parameters they've committed have been applied. Another use case could be if a user wants to record the system state every time a scheme is applied for debug purposes. This patch adds a new command, wait_for_schemes_apply, which calls damos_walk() without a walk function so that all it does is wait until all schemes have been applied. The same functionality can be achieved by using update_schemes_tried_bytes, for example, but having a separate command for this avoid unnecessary work. It also makes user intent clearer when used in scripts. Signed-off-by: Bijan Tabatabai --- mm/damon/core.c | 3 ++- mm/damon/sysfs.c | 27 +++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/mm/damon/core.c b/mm/damon/core.c index 07b4fc5a9790..56a13d16e4d1 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -1731,7 +1731,8 @@ static void damos_walk_call_walk(struct damon_ctx *ctx, struct damon_target *t, if (!control) return; - control->walk_fn(control->data, ctx, t, r, s, sz_filter_passed); + if (control->walk_fn) + control->walk_fn(control->data, ctx, t, r, s, sz_filter_passed); } /* diff --git a/mm/damon/sysfs.c b/mm/damon/sysfs.c index c2b036abb25b..ded3f60e4e22 100644 --- a/mm/damon/sysfs.c +++ b/mm/damon/sysfs.c @@ -1223,6 +1223,11 @@ enum damon_sysfs_cmd { * intevals. */ DAMON_SYSFS_CMD_UPDATE_TUNED_INTERVALS, + /* + * @DAMON_SYSFS_CMD_WAIT_FOR_SCHEMES_APPLY: Wait for all schemes to be + * applied. + */ + DAMON_SYSFS_CMD_WAIT_FOR_SCHEMES_APPLY, /* * @NR_DAMON_SYSFS_CMDS: Total number of DAMON sysfs commands. */ @@ -1242,6 +1247,7 @@ static const char * const damon_sysfs_cmd_strs[] = { "clear_schemes_tried_regions", "update_schemes_effective_quotas", "update_tuned_intervals", + "wait_for_schemes_apply", }; static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, @@ -1643,6 +1649,25 @@ static int damon_sysfs_update_schemes_tried_regions( return damos_walk(ctx, &control); } +static int damon_sysfs_wait_for_schemes_apply( + struct damon_sysfs_kdamond *sysfs_kdamond) +{ + /* + * damos_walk returns after the next time all of the schemes have been + * applied. We don't need to do any actual work, so walk_fn is NULL. + */ + struct damos_walk_control control = { + .walk_fn = NULL, + .data = NULL, + }; + struct damon_ctx *ctx = sysfs_kdamond->damon_ctx; + + if (!ctx) + return -EINVAL; + + return damos_walk(ctx, &control); +} + /* * damon_sysfs_handle_cmd() - Handle a command for a specific kdamond. * @cmd: The command to handle. @@ -1688,6 +1713,8 @@ static int damon_sysfs_handle_cmd(enum damon_sysfs_cmd cmd, case DAMON_SYSFS_CMD_UPDATE_TUNED_INTERVALS: return damon_sysfs_damon_call( damon_sysfs_upd_tuned_intervals, kdamond); + case DAMON_SYSFS_CMD_WAIT_FOR_SCHEMES_APPLY: + return damon_sysfs_wait_for_schemes_apply(kdamond); default: return -EINVAL; } -- 2.43.5