Skip to content

Commit e6a0deb

Browse files
sjp38akpm00
authored andcommitted
mm/damon/core: introduce damon_call_control->dealloc_on_cancel
Patch series "mm/damon/sysfs: fix refresh_ms control overwriting on multi-kdamonds usages". Automatic esssential DAMON/DAMOS status update feature of DAMON sysfs interface (refresh_ms) is broken [1] for multiple DAMON contexts (kdamonds) use case, since it uses a global single damon_call_control object for all created DAMON contexts. The fields of the object, particularly the list field is over-written for the contexts and it makes unexpected results including user-space hangup and kernel crashes [2]. Fix it by extending damon_call_control for the use case and updating the usage on DAMON sysfs interface to use per-context dynamically allocated damon_call_control object. This patch (of 2): When damon_call_control->repeat is set, damon_call() is executed asynchronously, and is eventually canceled when kdamond finishes. If the damon_call_control object is dynamically allocated, finding the place to deallocate the object is difficult. Introduce a new damon_call_control field, namely dealloc_on_cancel, to ask the kdamond deallocates those dynamically allocated objects when those are canceled. Link: https://lkml.kernel.org/r/[email protected] Link: https://lkml.kernel.org/r/[email protected] Fixes: d809a7c ("mm/damon/sysfs: implement refresh_ms file internal work") Signed-off-by: SeongJae Park <[email protected]> Cc: Yunjeong Mun <[email protected]> Signed-off-by: Andrew Morton <[email protected]>
1 parent 2da6de3 commit e6a0deb

File tree

2 files changed

+8
-2
lines changed

2 files changed

+8
-2
lines changed

include/linux/damon.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -636,6 +636,7 @@ struct damon_operations {
636636
* @data: Data that will be passed to @fn.
637637
* @repeat: Repeat invocations.
638638
* @return_code: Return code from @fn invocation.
639+
* @dealloc_on_cancel: De-allocate when canceled.
639640
*
640641
* Control damon_call(), which requests specific kdamond to invoke a given
641642
* function. Refer to damon_call() for more details.
@@ -645,6 +646,7 @@ struct damon_call_control {
645646
void *data;
646647
bool repeat;
647648
int return_code;
649+
bool dealloc_on_cancel;
648650
/* private: internal use only */
649651
/* informs if the kdamond finished handling of the request */
650652
struct completion completion;

mm/damon/core.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2479,10 +2479,14 @@ static void kdamond_call(struct damon_ctx *ctx, bool cancel)
24792479
mutex_lock(&ctx->call_controls_lock);
24802480
list_del(&control->list);
24812481
mutex_unlock(&ctx->call_controls_lock);
2482-
if (!control->repeat)
2482+
if (!control->repeat) {
24832483
complete(&control->completion);
2484-
else
2484+
} else if (control->canceled && control->dealloc_on_cancel) {
2485+
kfree(control);
2486+
continue;
2487+
} else {
24852488
list_add(&control->list, &repeat_controls);
2489+
}
24862490
}
24872491
control = list_first_entry_or_null(&repeat_controls,
24882492
struct damon_call_control, list);

0 commit comments

Comments
 (0)