[PATCH -next] mm: vmstat: make refresh interval take effect immediately
From: Yang Yingliang
Date: Thu Mar 26 2026 - 03:59:57 EST
The refresh workqueue is re-queued after last timer is triggered, so when
the refresh interval is set, it doesn't take effect immediately.
It leads a problem like this: if current interval is 8640000s (100 days),
and we want changing it to 1s, the new interval can't take effect until
100 days later.
So call mod_delayed_work() after updating interval to make the new value
take effect immediately.
Signed-off-by: Yang Yingliang <yangyingliang@xxxxxxxxxx>
---
mm/vmstat.c | 37 ++++++++++++++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 2370c6fb1fcd..7b4a9c30cc80 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -1968,6 +1968,9 @@ static int sysctl_stat_interval __read_mostly = HZ;
static int vmstat_late_init_done;
#ifdef CONFIG_PROC_FS
+static int sysctl_stat_interval_handler(const struct ctl_table *table, int write,
+ void *buffer, size_t *length, loff_t *ppos);
+
static void refresh_vm_stats(struct work_struct *work)
{
refresh_cpu_vm_stats(true);
@@ -2151,6 +2154,38 @@ static void vmstat_shepherd(struct work_struct *w)
round_jiffies_relative(sysctl_stat_interval));
}
+#ifdef CONFIG_PROC_FS
+static int sysctl_stat_interval_handler(const struct ctl_table *table, int write,
+ void *buffer, size_t *length, loff_t *ppos)
+{
+ int cpu;
+ int ret = proc_dointvec_jiffies(table, write, buffer, length, ppos);
+
+ if (ret || !write)
+ return ret;
+
+ cpus_read_lock();
+ for_each_online_cpu(cpu) {
+ struct delayed_work *dw = &per_cpu(vmstat_work, cpu);
+
+ scoped_guard(rcu) {
+ if (cpu_is_isolated(cpu))
+ continue;
+
+ if (delayed_work_pending(dw))
+ mod_delayed_work(system_wq, dw, round_jiffies_relative(sysctl_stat_interval));
+ }
+
+ cond_resched();
+ }
+ cpus_read_unlock();
+
+ mod_delayed_work(system_wq, &shepherd, round_jiffies_relative(sysctl_stat_interval));
+
+ return ret;
+}
+#endif
+
static void __init start_shepherd_timer(void)
{
int cpu;
@@ -2237,7 +2272,7 @@ static const struct ctl_table vmstat_table[] = {
.data = &sysctl_stat_interval,
.maxlen = sizeof(sysctl_stat_interval),
.mode = 0644,
- .proc_handler = proc_dointvec_jiffies,
+ .proc_handler = sysctl_stat_interval_handler,
},
{
.procname = "stat_refresh",
--
2.25.1