[PATCH 1/2] mm: add gpu active/reclaim per-node stat counters (v2)
Dave Airlie
airlied at gmail.com
Thu Jun 19 07:20:25 UTC 2025
From: Dave Airlie <airlied at redhat.com>
While discussing memcg intergration with gpu memory allocations,
it was pointed out that there was no numa/system counters for
GPU memory allocations.
With more integrated memory GPU server systems turning up, and
more requirements for memory tracking it seems we should start
closing the gap.
Add two counters to track GPU per-node system memory allocations.
The first is currently allocated to GPU objects, and the second
is for memory that is stored in GPU page pools that can be reclaimed,
by the shrinker.
Cc: Christian Koenig <christian.koenig at amd.com>
Cc: Matthew Brost <matthew.brost at intel.com>
Cc: Johannes Weiner <hannes at cmpxchg.org>
Cc: linux-mm at kvack.org
Cc: Andrew Morton <akpm at linux-foundation.org>
Signed-off-by: Dave Airlie <airlied at redhat.com>
---
v2: add more info to the documentation on this memory.
I'd like to get acks to merge this via the drm tree, if possible,
Dave.
---
Documentation/filesystems/proc.rst | 8 ++++++++
drivers/base/node.c | 5 +++++
fs/proc/meminfo.c | 6 ++++++
include/linux/mmzone.h | 2 ++
mm/show_mem.c | 9 +++++++--
mm/vmstat.c | 2 ++
6 files changed, 30 insertions(+), 2 deletions(-)
diff --git a/Documentation/filesystems/proc.rst b/Documentation/filesystems/proc.rst
index 5236cb52e357..7cc5a9185190 100644
--- a/Documentation/filesystems/proc.rst
+++ b/Documentation/filesystems/proc.rst
@@ -1095,6 +1095,8 @@ Example output. You may not have all of these fields.
CmaFree: 0 kB
Unaccepted: 0 kB
Balloon: 0 kB
+ GPUActive: 0 kB
+ GPUReclaim: 0 kB
HugePages_Total: 0
HugePages_Free: 0
HugePages_Rsvd: 0
@@ -1273,6 +1275,12 @@ Unaccepted
Memory that has not been accepted by the guest
Balloon
Memory returned to Host by VM Balloon Drivers
+GPUActive
+ System memory allocated to active GPU objects
+GPUReclaim
+ System memory stored in GPU pools for reuse. This memory is not
+ counted in GPUActive. It is shrinker reclaimable memory kept in a reuse
+ pool because it has non-standard page table attributes, like WC or UC.
HugePages_Total, HugePages_Free, HugePages_Rsvd, HugePages_Surp, Hugepagesize, Hugetlb
See Documentation/admin-guide/mm/hugetlbpage.rst.
DirectMap4k, DirectMap2M, DirectMap1G
diff --git a/drivers/base/node.c b/drivers/base/node.c
index c19094481630..64406862314b 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -463,6 +463,8 @@ static ssize_t node_read_meminfo(struct device *dev,
#ifdef CONFIG_UNACCEPTED_MEMORY
"Node %d Unaccepted: %8lu kB\n"
#endif
+ "Node %d GPUActive: %8lu kB\n"
+ "Node %d GPUReclaim: %8lu kB\n"
,
nid, K(node_page_state(pgdat, NR_FILE_DIRTY)),
nid, K(node_page_state(pgdat, NR_WRITEBACK)),
@@ -496,6 +498,9 @@ static ssize_t node_read_meminfo(struct device *dev,
,
nid, K(sum_zone_node_page_state(nid, NR_UNACCEPTED))
#endif
+ ,
+ nid, K(node_page_state(pgdat, NR_GPU_ACTIVE)),
+ nid, K(node_page_state(pgdat, NR_GPU_RECLAIM))
);
len += hugetlb_report_node_meminfo(buf, len, nid);
return len;
diff --git a/fs/proc/meminfo.c b/fs/proc/meminfo.c
index bc2bc60c36cc..334948744e55 100644
--- a/fs/proc/meminfo.c
+++ b/fs/proc/meminfo.c
@@ -164,6 +164,12 @@ static int meminfo_proc_show(struct seq_file *m, void *v)
show_val_kb(m, "Balloon: ",
global_node_page_state(NR_BALLOON_PAGES));
+ show_val_kb(m, "GPUActive: ",
+ global_node_page_state(NR_GPU_ACTIVE));
+
+ show_val_kb(m, "GPUReclaim: ",
+ global_node_page_state(NR_GPU_RECLAIM));
+
hugetlb_report_meminfo(m);
arch_report_meminfo(m);
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 283913d42d7b..458a3465dd8f 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -241,6 +241,8 @@ enum node_stat_item {
NR_HUGETLB,
#endif
NR_BALLOON_PAGES,
+ NR_GPU_ACTIVE, /* GPU pages assigned to an object */
+ NR_GPU_RECLAIM, /* GPU pages in shrinkable pools */
NR_VM_NODE_STAT_ITEMS
};
diff --git a/mm/show_mem.c b/mm/show_mem.c
index 0cf8bf5d832d..072d33a50148 100644
--- a/mm/show_mem.c
+++ b/mm/show_mem.c
@@ -255,7 +255,9 @@ static void show_free_areas(unsigned int filter, nodemask_t *nodemask, int max_z
" sec_pagetables:%lukB"
" all_unreclaimable? %s"
" Balloon:%lukB"
- "\n",
+ " gpu_active:%lukB"
+ " gpu_reclaim:%lukB"
+ "\n",
pgdat->node_id,
K(node_page_state(pgdat, NR_ACTIVE_ANON)),
K(node_page_state(pgdat, NR_INACTIVE_ANON)),
@@ -281,7 +283,10 @@ static void show_free_areas(unsigned int filter, nodemask_t *nodemask, int max_z
K(node_page_state(pgdat, NR_PAGETABLE)),
K(node_page_state(pgdat, NR_SECONDARY_PAGETABLE)),
str_yes_no(pgdat->kswapd_failures >= MAX_RECLAIM_RETRIES),
- K(node_page_state(pgdat, NR_BALLOON_PAGES)));
+ K(node_page_state(pgdat, NR_BALLOON_PAGES)),
+ K(node_page_state(pgdat, NR_GPU_ACTIVE)),
+ K(node_page_state(pgdat, NR_GPU_RECLAIM)));
+
}
for_each_populated_zone(zone) {
diff --git a/mm/vmstat.c b/mm/vmstat.c
index 429ae5339bfe..25a74cf29473 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -1281,6 +1281,8 @@ const char * const vmstat_text[] = {
"nr_hugetlb",
#endif
"nr_balloon_pages",
+ "nr_gpu_active",
+ "nr_gpu_reclaim",
/* system-wide enum vm_stat_item counters */
"nr_dirty_threshold",
"nr_dirty_background_threshold",
--
2.49.0
More information about the dri-devel
mailing list