mm/damon/core: make damon_start() waits until kdamond_fn() starts
Subsystems (3)
SeongJae Park
maintainerPATCH 1/1 mm/damon/core: make damon_start() waits until kdamond_fn() starts
The cleanup tasks of kdamond threads including reset of corresponding DAMON context's ->kdamond field and decrease of global nr_running_ctxs counter is supposed to be executed by kdamond_fn(). However, commit 0f91d13366a4 ("mm/damon: simplify stop mechanism") made neither damon_start() nor damon_stop() ensure the corresponding kdamond has started the execution of kdamond_fn().
As a result, the cleanup can be skipped if damon_stop() is called fast enough after the previous damon_start(). Especially the skipped reset of ->kdamond could cause a use-after-free.
Fix it by waiting for start of kdamond_fn() execution from damon_start().
---
Note that the report has not publicly made, so this patch doesn't have a
Closes: tag.
include/linux/damon.h | 2 ++ mm/damon/core.c | 6 ++++++ 2 files changed, 8 insertions(+)
include/linux/damon.h +2 -0
@@ -579,6 +579,8 @@ struct damon_ctx {* update */ unsigned long next_ops_update_sis; +/* for waiting until the execution of the kdamond_fn is started */ +struct completion kdamond_started;/* public: */ struct task_struct *kdamond;
mm/damon/core.c +6 -0
@@ -445,6 +445,8 @@ struct damon_ctx *damon_new_ctx(void)if (!ctx)return NULL ; +init_completion (&ctx->kdamond_started); + ctx->attrs.sample_interval =5 *1000 ; ctx->attrs.aggr_interval =100 *1000 ; ctx->attrs.ops_update_interval =60 *1000 *1000 ;
@@ -668,11 +670,14 @@ static int __damon_start(struct damon_ctx *ctx)mutex_lock (&ctx->kdamond_lock);if (!ctx->kdamond) { err =0 ; +reinit_completion (&ctx->kdamond_started); ctx->kdamond =kthread_run (kdamond_fn, ctx,"kdamond.%d" , nr_running_ctxs);if (IS_ERR (ctx->kdamond)) { err =PTR_ERR (ctx->kdamond); ctx->kdamond =NULL ; + }else { +wait_for_completion (&ctx->kdamond_started); } }mutex_unlock (&ctx->kdamond_lock);
@@ -1483,6 +1488,7 @@ static int kdamond_fn(void *data)pr_debug ("kdamond (%d) starts\n" , current->pid); +complete (&ctx->kdamond_started);kdamond_init_intervals_sis (ctx);if (ctx->ops.init)
Signature · 1 line
2.34.1