[<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