All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Dave Airlie" <airlied@gmail.com>
Cc: mkoutny@suse.com, tj@kernel.org, hannes@cmpxchg.org,
	dri-devel@lists.freedesktop.org
Subject: Re: [PATCH 01/10] memcg: add support for GPU page counters. (v4)
Date: Mon, 06 Jul 2026 03:01:07 +0000	[thread overview]
Message-ID: <20260706030107.F2C5C1F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260706024122.853329-2-airlied@gmail.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] mem_cgroup_move_gpu_page_reclaim silently fails to move pages to or from the root cgroup, bypassing memory limits and leaking charges.
- [High] Tagging GPU pages with MEMCG_DATA_KMEM without corresponding kmem counter charges causes global kmem underflows on standard page frees.
- [Medium] Cross-cgroup page moves in mem_cgroup_move_gpu_page_reclaim completely ignore the `to_reclaim` parameter and corrupt stats.
- [Low] Missing static inline stubs for GPU memory tracking APIs when CONFIG_MEMCG is disabled.
--

commit 497e4e8b1bbad8552dbc2f2daeb121cd40f196af
Author: Dave Airlie <airlied@redhat.com>

memcg: add support for GPU page counters. (v4)

This introduces new statistics and memcontrol APIs for dealing with GPU system
memory allocations. It allows charging, uncharging, and moving pages between
object cgroups and reclaim states.

> diff --git a/include/linux/memcontrol.h b/include/linux/memcontrol.h
> index e1f46a0016fcf..3a968c6be0c84 100644
> --- a/include/linux/memcontrol.h
> +++ b/include/linux/memcontrol.h
> @@ -1583,6 +1583,17 @@ static inline void mem_cgroup_flush_foreign(struct bdi_writeback *wb)
>  #endif	/* CONFIG_CGROUP_WRITEBACK */
>  
>  struct sock;
> +bool mem_cgroup_charge_gpu_page(struct obj_cgroup *objcg, struct page *page,
> +			   unsigned int order,
> +			   gfp_t gfp_mask, bool reclaim);
> +void mem_cgroup_uncharge_gpu_page(struct page *page,
> +				  unsigned int order,
> +				  bool reclaim);
> +bool mem_cgroup_move_gpu_page_reclaim(struct obj_cgroup *objcg,
> +				      struct page *page,
> +				      unsigned int order,
> +				      bool to_reclaim);
> +

[Severity: Low]
Are there missing static inline stubs for these APIs when CONFIG_MEMCG is
disabled? Will this cause undefined reference link errors for drivers using
these functions on non-memcg builds, since they are declared globally but
only implemented in mm/memcontrol.c?

>  #ifdef CONFIG_MEMCG
>  extern struct static_key_false memcg_sockets_enabled_key;
>  #define mem_cgroup_sockets_enabled static_branch_unlikely(&memcg_sockets_enabled_key)

[ ... ]

> diff --git a/mm/memcontrol.c b/mm/memcontrol.c
> index 6dc4888a90f3f..4c682b91cbbee 100644
> --- a/mm/memcontrol.c
> +++ b/mm/memcontrol.c

[ ... ]

> @@ -5508,6 +5512,106 @@ void mem_cgroup_flush_workqueue(void)
>  	flush_workqueue(memcg_wq);
>  }
>  
> +/**
> + * mem_cgroup_charge_gpu_page - charge a page to GPU memory tracking
> + * @objcg: objcg to charge, NULL charges root memcg

[ ... ]

> +bool mem_cgroup_charge_gpu_page(struct obj_cgroup *objcg, struct page *page,
> +				unsigned int order, gfp_t gfp_mask, bool reclaim)
> +{
> +	unsigned int nr_pages = 1 << order;
> +	struct mem_cgroup *memcg = NULL;
> +	struct lruvec *lruvec;
> +	int ret;
> +
> +	if (objcg) {
> +		memcg = get_mem_cgroup_from_objcg(objcg);
> +
> +		ret = try_charge_memcg(memcg, gfp_mask, nr_pages);
> +		if (ret) {
> +			mem_cgroup_put(memcg);
> +			return false;
> +		}
> +
> +		obj_cgroup_get(objcg);
> +		page_set_objcg(page, objcg);

[Severity: High]
Since page_set_objcg() embeds the MEMCG_DATA_KMEM flag into the page, if this
GPU page is later freed directly by the kernel rather than through
mem_cgroup_uncharge_gpu_page(), will the VM route the uncharge to
__memcg_kmem_uncharge_page()?

Could this improperly decrement the global kmem counters (which were never
incremented during the GPU page charging) and bypass the decrement of the
NR_GPU_ACTIVE or NR_GPU_RECLAIM stats?

> +	}
> +
> +	lruvec = mem_cgroup_lruvec(memcg, page_pgdat(page));
> +	mod_lruvec_state(lruvec, reclaim ? NR_GPU_RECLAIM : NR_GPU_ACTIVE, nr_pages);
> +
> +	mem_cgroup_put(memcg);
> +	return true;
> +}
> +EXPORT_SYMBOL_GPL(mem_cgroup_charge_gpu_page);

[ ... ]

> +/**
> + * mem_cgroup_move_gpu_reclaim - move pages from gpu to gpu reclaim and back
> + * @new_objcg: objcg to move page to, NULL if just stats update.
> + * @nr_pages: number of pages to move
> + * @to_reclaim: true moves pages into reclaim, false moves them back
> + */
> +bool mem_cgroup_move_gpu_page_reclaim(struct obj_cgroup *new_objcg,
> +				      struct page *page,
> +				      unsigned int order,
> +				      bool to_reclaim)
> +{
> +	struct obj_cgroup *objcg = page_objcg(page);
> +
> +	if (!objcg || !new_objcg || objcg == new_objcg) {

[Severity: High]
Does this conditional unintentionally merge cross-cgroup moves involving the
root cgroup (where objcg or new_objcg is NULL) into the fast-path for
in-place state transitions?

If a page is moved to or from the root cgroup, it looks like this will
silently fail to transfer ownership to the new child cgroup, bypassing memory
limits or leaving charges stuck in the original cgroup indefinitely.

> +		struct mem_cgroup *memcg = objcg ? get_mem_cgroup_from_objcg(objcg) : NULL;
> +		struct lruvec *lruvec;
> +		unsigned long flags;
> +		int nr_pages = 1 << order;
> +
> +		lruvec = mem_cgroup_lruvec(memcg, page_pgdat(page));
> +		local_irq_save(flags);
> +		mod_lruvec_state(lruvec, to_reclaim ? NR_GPU_RECLAIM : NR_GPU_ACTIVE, nr_pages);
> +		mod_lruvec_state(lruvec, to_reclaim ? NR_GPU_ACTIVE : NR_GPU_RECLAIM, -nr_pages);
> +		local_irq_restore(flags);
> +		mem_cgroup_put(memcg);
> +		return true;
> +	} else {
> +		mem_cgroup_uncharge_gpu_page(page, order, true);
> +		return mem_cgroup_charge_gpu_page(new_objcg, page, order, 0, false);

[Severity: Medium]
Does this block ignore the to_reclaim boolean parameter by hardcoding true
for the uncharge and false for the charge?

It looks like this will corrupt the stats by always decrementing the RECLAIM
counter of the old cgroup and always incrementing the ACTIVE counter of the
new cgroup, regardless of the caller's requested state.

> +	}
> +}
> +EXPORT_SYMBOL_GPL(mem_cgroup_move_gpu_page_reclaim);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260706024122.853329-1-airlied@gmail.com?part=1

  reply	other threads:[~2026-07-06  3:01 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-06  2:36 drm/ttm/memcg/lru: enable memcg tracking for ttm, xe and amdgpu driver (part 2) Dave Airlie
2026-07-06  2:36 ` [PATCH 01/10] memcg: add support for GPU page counters. (v4) Dave Airlie
2026-07-06  3:01   ` sashiko-bot [this message]
2026-07-06  2:36 ` [PATCH 02/10] ttm: add a memcg accounting flag to the alloc/populate APIs Dave Airlie
2026-07-06  2:58   ` sashiko-bot
2026-07-06  2:36 ` [PATCH 03/10] ttm/pool: initialise the shrinker earlier Dave Airlie
2026-07-06  2:56   ` sashiko-bot
2026-07-06  2:36 ` [PATCH 04/10] ttm: add objcg pointer to bo and tt (v2) Dave Airlie
2026-07-06  2:53   ` sashiko-bot
2026-07-06  2:36 ` [PATCH 05/10] ttm/pool: enable memcg tracking and shrinker. (v3) Dave Airlie
2026-07-06  2:59   ` sashiko-bot
2026-07-06  2:36 ` [PATCH 06/10] ttm: hook up memcg placement flags Dave Airlie
2026-07-06  3:01   ` sashiko-bot
2026-07-06  2:36 ` [PATCH 07/10] memcontrol: allow objcg api when memcg is config off Dave Airlie
2026-07-06  2:55   ` sashiko-bot
2026-07-06  2:36 ` [PATCH 08/10] amdgpu: add support for memory cgroups Dave Airlie
2026-07-06  3:14   ` sashiko-bot
2026-07-06  2:36 ` [PATCH 09/10] ttm: add support for a module option to disable memcg integration Dave Airlie
2026-07-06  3:10   ` sashiko-bot
2026-07-06  2:36 ` [PATCH 10/10] xe: create a flag to enable memcg accounting for XE as well Dave Airlie
2026-07-06  3:18   ` sashiko-bot
2026-07-06  7:59 ` drm/ttm/memcg/lru: enable memcg tracking for ttm, xe and amdgpu driver (part 2) Christian König

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260706030107.F2C5C1F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=airlied@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=hannes@cmpxchg.org \
    --cc=mkoutny@suse.com \
    --cc=sashiko-reviews@lists.linux.dev \
    --cc=tj@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.