[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