From d079b6b890d128c396ee42320c027b7dd3c0a2a7 Mon Sep 17 00:00:00 2001 From: SJ Park Date: Mon, 6 Jul 2026 07:06:24 -0700 Subject: [PATCH] mm/damon/core: wait ctx stop in damon_call() before reruning an error damon_call() failure means the DAMON context started its termination. The termination is asynchronously done in kdamond thread. The caller's error handling should handle the race, too. It is complicated and easy to make mistakes. Update damon_call() to ensure the context is stopped in the case, by waiting until the completion is confirmed. Link: https://lore.kernel.org/20260706140628.87414-10-sj@kernel.org Signed-off-by: SJ Park Signed-off-by: Andrew Morton --- mm/damon/core.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/mm/damon/core.c b/mm/damon/core.c index 08510bf9b38d..390e00b3685e 100644 --- a/mm/damon/core.c +++ b/mm/damon/core.c @@ -2010,6 +2010,8 @@ int damon_kdamond_pid(struct damon_ctx *ctx) * @ctx has succeeded. Otherwise, this function could fall into an indefinite * wait. * + * When this function is failed, the @ctx is guaranteed to be stopped. + * * Return: 0 on success, negative error code otherwise. */ int damon_call(struct damon_ctx *ctx, struct damon_call_control *control) @@ -2022,7 +2024,7 @@ int damon_call(struct damon_ctx *ctx, struct damon_call_control *control) mutex_lock(&ctx->call_controls_lock); if (ctx->call_controls_obsolete) { mutex_unlock(&ctx->call_controls_lock); - return -ECANCELED; + goto canceled; } list_add_tail(&control->list, &ctx->call_controls); mutex_unlock(&ctx->call_controls_lock); @@ -2030,8 +2032,14 @@ int damon_call(struct damon_ctx *ctx, struct damon_call_control *control) return 0; wait_for_completion(&control->completion); if (control->canceled) - return -ECANCELED; + goto canceled; return 0; + +canceled: + while (damon_is_running(ctx)) + schedule_timeout_idle(msecs_to_jiffies(100)); + return -ECANCELED; + } /**