linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH -next] mm: make sure freeram is smaller than totalram
@ 2026-04-13 11:57 Yang Yingliang
  0 siblings, 0 replies; only message in thread
From: Yang Yingliang @ 2026-04-13 11:57 UTC (permalink / raw)
  To: akpm, david, ljs, Liam.Howlett, vbabka, rppt, surenb, mhocko
  Cc: linux-mm, linux-kernel, yangyingliang, hucool.lihua

The memory stat is not done in real time, it have some gap with
real value. In CPU-less NUMA node, the values of MemTotal and
MemFree can be nearly equal, the gap may cause MemFree bigger
than MemTotal, it leads MemUsed is negative which print as a large
positive number.

cat /sys/devices/system/node/node17/meminfo
Node 17 MemTotal:        4194304 kB
Node 17 MemFree:         4195552 kB
Node 17 MemUsed:        18446744073709550368 kB
Node 17 Active:               52 kB
Node 17 Inactive:            320 kB
Node 17 Active(anon):          0 kB
Node 17 Inactive(anon):        0 kB
Node 17 Active(file):         52 kB
Node 17 Inactive(file):      320 kB
Node 17 Unevictable:           0 kB
Node 17 Mlocked:               0 kB
Node 17 Dirty:                 0 kB
Node 17 Writeback:             0 kB
Node 17 FilePages:           372 kB
Node 17 Mapped:              320 kB
Node 17 AnonPages:             0 kB
Node 17 Shmem:                 0 kB
Node 17 KernelStack:           0 kB
Node 17 PageTables:            0 kB
Node 17 NFS_Unstable:          0 kB
Node 17 Bounce:                0 kB
Node 17 WritebackTmp:          0 kB
Node 17 KReclaimable:          0 kB
Node 17 Slab:                  0 kB
Node 17 SReclaimable:          0 kB
Node 17 SUnreclaim:            0 kB
Node 17 AnonHugePages:     79872 kB
Node 17 ShmemHugePages:        0 kB
Node 17 ShmemPmdMapped:        0 kB
Node 17 FileHugePages:        0 kB
Node 17 FilePmdMapped:        0 kB
Node 17 HugePages_Total:     0
Node 17 HugePages_Free:      0
Node 17 HugePages_Surp:      0

To avoid this exception by refreshing vm_stat, when MemFree
is bigger than MemTotal.

Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
---
 include/linux/vmstat.h |  1 +
 mm/show_mem.c          | 10 ++++++++++
 mm/vmstat.c            | 15 ++++++++++-----
 3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/include/linux/vmstat.h b/include/linux/vmstat.h
index 3c9c266cf782..6a7d2f3757b0 100644
--- a/include/linux/vmstat.h
+++ b/include/linux/vmstat.h
@@ -259,6 +259,7 @@ extern unsigned long node_page_state(struct pglist_data *pgdat,
 						enum node_stat_item item);
 extern unsigned long node_page_state_pages(struct pglist_data *pgdat,
 					   enum node_stat_item item);
+extern int refresh_node_page_state(void);
 extern void fold_vm_numa_events(void);
 #else
 #define sum_zone_node_page_state(node, item) global_zone_page_state(item)
diff --git a/mm/show_mem.c b/mm/show_mem.c
index 43aca5a2ac99..dc8d2b6056d3 100644
--- a/mm/show_mem.c
+++ b/mm/show_mem.c
@@ -106,6 +106,16 @@ void si_meminfo_node(struct sysinfo *val, int nid)
 	val->totalram = managed_pages;
 	val->sharedram = node_page_state(pgdat, NR_SHMEM);
 	val->freeram = sum_zone_node_page_state(nid, NR_FREE_PAGES);
+	if (val->freeram > val->totalram) {
+		int err = refresh_node_page_state();
+		if (err)
+			val->freeram = val->totalram;
+		else
+			val->freeram = sum_zone_node_page_state(nid, NR_FREE_PAGES);
+
+		if (val->freeram > val->totalram)
+			val->freeram = val->totalram;
+	}
 	val->totalhigh = managed_highpages;
 	val->freehigh = free_highpages;
 	val->mem_unit = PAGE_SIZE;
diff --git a/mm/vmstat.c b/mm/vmstat.c
index f534972f517d..96a2e03ec83e 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -881,6 +881,11 @@ static bool refresh_cpu_vm_stats(bool do_pagesets)
 	return changed;
 }
 
+static void refresh_vm_stats(struct work_struct *work)
+{
+	refresh_cpu_vm_stats(true);
+}
+
 /*
  * Fold the data for an offline cpu into the global array.
  * There cannot be any access by the offline cpu and therefore
@@ -1024,6 +1029,11 @@ unsigned long node_page_state(struct pglist_data *pgdat,
 
 	return node_page_state_pages(pgdat, item);
 }
+
+int refresh_node_page_state(void)
+{
+	return schedule_on_each_cpu(refresh_vm_stats);
+}
 #endif
 
 /*
@@ -1970,11 +1980,6 @@ static int sysctl_stat_interval __read_mostly = HZ;
 static int vmstat_late_init_done;
 
 #ifdef CONFIG_PROC_FS
-static void refresh_vm_stats(struct work_struct *work)
-{
-	refresh_cpu_vm_stats(true);
-}
-
 static int vmstat_refresh(const struct ctl_table *table, int write,
 		   void *buffer, size_t *lenp, loff_t *ppos)
 {
-- 
2.25.1



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2026-04-13 11:57 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-04-13 11:57 [PATCH -next] mm: make sure freeram is smaller than totalram Yang Yingliang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox