DAMON_LRU_SORT calls damon_call() for commit_inputs parameter user input if the DAMON context is initialized. The context could be initialized, but not yet successfully started. In the case, damon_call() could indefinitely hang. Read the comment on damon_call() for more detail. Fix the problem by memorizing if the DAMON context has ever successfully started, and skip damon_call() if it has not. This issue can easily be reproduced by writing Y to the commit_inputs parameter file on a system that DAMON_LRU_SORT has not turned on before. Fixes: de3c60e1c831 ("mm/damon: add synchronous commit for commit_inputs") Cc: # 7.2.x Signed-off-by: SJ Park --- mm/damon/lru_sort.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/mm/damon/lru_sort.c b/mm/damon/lru_sort.c index 3920d5042f109..bd847829a9907 100644 --- a/mm/damon/lru_sort.c +++ b/mm/damon/lru_sort.c @@ -346,6 +346,8 @@ static int damon_lru_sort_commit_inputs_fn(void *arg) return damon_lru_sort_apply_parameters(); } +static bool damon_lru_sort_damon_has_started; + static int damon_lru_sort_commit_inputs_store(const char *val, const struct kernel_param *kp) { @@ -366,11 +368,8 @@ static int damon_lru_sort_commit_inputs_store(const char *val, if (!commit_inputs_request) return 0; - /* - * Skip damon_call() if ctx is not initialized to avoid - * NULL pointer dereference. - */ - if (!ctx) + /* Skip damon_call() if ctx has not successfully started. */ + if (!damon_lru_sort_damon_has_started) return -EINVAL; err = damon_call(ctx, &control); @@ -423,6 +422,8 @@ static int damon_lru_sort_turn(bool on) err = damon_start(&ctx, 1, true); if (err) return err; + if (!damon_lru_sort_damon_has_started) + damon_lru_sort_damon_has_started = true; return damon_call(ctx, &call_control); } -- 2.47.3