Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mm/damon/sysfs: use dynamically allocated repeat mode damon_call_control

DAMON sysfs interface is using a single global repeat mode
damon_call_control variable for refresh_ms handling, for all DAMON
contexts. As a result, when there are more than one context, the single
global damon_call_control is unexpectedly over-written (corrupted).
Particularly the ->link field is overwritten by the multiple contexts and
this can cause a user hangup, and/or a kernel crash. Fix it by using
dynamically allocated damon_call_control object per DAMON context.

Link: https://lkml.kernel.org/r/20250908201513.60802-3-sj@kernel.org
Link: https://lore.kernel.org/20250904011738.930-1-yunjeong.mun@sk.com [1]
Link: https://lore.kernel.org/20250905035411.39501-1-sj@kernel.org [2]
Fixes: d809a7c64ba8 ("mm/damon/sysfs: implement refresh_ms file internal work")
Signed-off-by: SeongJae Park <sj@kernel.org>
Reported-by: Yunjeong Mun <yunjeong.mun@sk.com>
Closes: https://lore.kernel.org/20250904011738.930-1-yunjeong.mun@sk.com
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

SeongJae Park and committed by
Andrew Morton
04a06b13 e6a0deb6

+15 -8
+15 -8
mm/damon/sysfs.c
··· 1534 1534 return 0; 1535 1535 } 1536 1536 1537 - static struct damon_call_control damon_sysfs_repeat_call_control = { 1538 - .fn = damon_sysfs_repeat_call_fn, 1539 - .repeat = true, 1540 - }; 1541 - 1542 1537 static int damon_sysfs_turn_damon_on(struct damon_sysfs_kdamond *kdamond) 1543 1538 { 1544 1539 struct damon_ctx *ctx; 1540 + struct damon_call_control *repeat_call_control; 1545 1541 int err; 1546 1542 1547 1543 if (damon_sysfs_kdamond_running(kdamond)) ··· 1550 1554 damon_destroy_ctx(kdamond->damon_ctx); 1551 1555 kdamond->damon_ctx = NULL; 1552 1556 1557 + repeat_call_control = kmalloc(sizeof(*repeat_call_control), 1558 + GFP_KERNEL); 1559 + if (!repeat_call_control) 1560 + return -ENOMEM; 1561 + 1553 1562 ctx = damon_sysfs_build_ctx(kdamond->contexts->contexts_arr[0]); 1554 - if (IS_ERR(ctx)) 1563 + if (IS_ERR(ctx)) { 1564 + kfree(repeat_call_control); 1555 1565 return PTR_ERR(ctx); 1566 + } 1556 1567 err = damon_start(&ctx, 1, false); 1557 1568 if (err) { 1569 + kfree(repeat_call_control); 1558 1570 damon_destroy_ctx(ctx); 1559 1571 return err; 1560 1572 } 1561 1573 kdamond->damon_ctx = ctx; 1562 1574 1563 - damon_sysfs_repeat_call_control.data = kdamond; 1564 - damon_call(ctx, &damon_sysfs_repeat_call_control); 1575 + repeat_call_control->fn = damon_sysfs_repeat_call_fn; 1576 + repeat_call_control->data = kdamond; 1577 + repeat_call_control->repeat = true; 1578 + repeat_call_control->dealloc_on_cancel = true; 1579 + damon_call(ctx, repeat_call_control); 1565 1580 return err; 1566 1581 } 1567 1582