[PATCH 1/2] mm: add gpu active/reclaim per-node stat counters (v2)
Christian König
christian.koenig at amd.com
Mon Jun 23 08:54:24 UTC 2025
On 6/19/25 09:20, Dave Airlie wrote:
> 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
Active certainly makes sense, but I think we should rather disable the pool on newer CPUs than adding reclaimable memory here.
Regards,
Christian.
> 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",
More information about the dri-devel
mailing list