[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251030020746.967174-2-yanquanmin1@huawei.com>
Date: Thu, 30 Oct 2025 10:07:45 +0800
From: Quanmin Yan <yanquanmin1@...wei.com>
To: <sj@...nel.org>
CC: <akpm@...ux-foundation.org>, <damon@...ts.linux.dev>,
	<linux-kernel@...r.kernel.org>, <linux-mm@...ck.org>,
	<yanquanmin1@...wei.com>, <wangkefeng.wang@...wei.com>, <zuoze1@...wei.com>
Subject: [PATCH v2 1/2] mm/damon/stat: change last_refresh_jiffies to a global variable
In DAMON_STAT's damon_stat_damon_call_fn(), time_before_eq() is used to
avoid unnecessarily frequent stat update.
On 32-bit systems, the kernel initializes jiffies to "-5 minutes" to make
jiffies wrap bugs appear earlier. However, this causes time_before_eq()
in DAMON_STAT to unexpectedly return true during the first 5 minutes
after boot on 32-bit systems (see [1] for more explanation, which fixes
another jiffies-related issue before). As a result, DAMON_STAT does not
update any monitoring results during that period, which becomes more
confusing when DAMON_STAT_ENABLED_DEFAULT is enabled.
There is also an issue unrelated to the system’s word size[2]: if the
user stops DAMON_STAT just after last_refresh_jiffies is updated and
restarts it after 5 seconds or a longer delay, last_refresh_jiffies will
retain an older value, causing time_before_eq() to return false and the
update to happen earlier than expected.
Fix these issues by making last_refresh_jiffies a global variable and
initializing it each time DAMON_STAT is started.
[1] https://lkml.kernel.org/r/20250822025057.1740854-1-ekffu200098@gmail.com
[2] https://lore.kernel.org/all/20251028143250.50144-1-sj@kernel.org/
Fixes: fabdd1e911da ("mm/damon/stat: calculate and expose estimated memory bandwidth")
Suggested-by: SeongJae Park <sj@...nel.org>
Signed-off-by: Quanmin Yan <yanquanmin1@...wei.com>
---
 mm/damon/stat.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/mm/damon/stat.c b/mm/damon/stat.c
index 6c4503d2aee3..ed8e3629d31a 100644
--- a/mm/damon/stat.c
+++ b/mm/damon/stat.c
@@ -46,6 +46,8 @@ MODULE_PARM_DESC(aggr_interval_us,
 
 static struct damon_ctx *damon_stat_context;
 
+static unsigned long damon_stat_last_refresh_jiffies;
+
 static void damon_stat_set_estimated_memory_bandwidth(struct damon_ctx *c)
 {
 	struct damon_target *t;
@@ -130,13 +132,12 @@ static void damon_stat_set_idletime_percentiles(struct damon_ctx *c)
 static int damon_stat_damon_call_fn(void *data)
 {
 	struct damon_ctx *c = data;
-	static unsigned long last_refresh_jiffies;
 
 	/* avoid unnecessarily frequent stat update */
-	if (time_before_eq(jiffies, last_refresh_jiffies +
+	if (time_before_eq(jiffies, damon_stat_last_refresh_jiffies +
 				msecs_to_jiffies(5 * MSEC_PER_SEC)))
 		return 0;
-	last_refresh_jiffies = jiffies;
+	damon_stat_last_refresh_jiffies = jiffies;
 
 	aggr_interval_us = c->attrs.aggr_interval;
 	damon_stat_set_estimated_memory_bandwidth(c);
@@ -211,6 +212,8 @@ static int damon_stat_start(void)
 	err = damon_start(&damon_stat_context, 1, true);
 	if (err)
 		return err;
+
+	damon_stat_last_refresh_jiffies = jiffies;
 	call_control.data = damon_stat_context;
 	return damon_call(damon_stat_context, &call_control);
 }
-- 
2.43.0
Powered by blists - more mailing lists
 
