All of lore.kernel.org
 help / color / mirror / Atom feed
From: Natalie Vock <nat@pixelcluster.dev>
To: "Maarten Lankhorst" <dev@lankhorst.se>,
	"Maxime Ripard" <mripard@kernel.org>, "Tejun Heo" <tj@kernel.org>,
	"Johannes Weiner" <hannes@cmpxchg.org>,
	"Michal Koutný" <mkoutny@suse.com>,
	"Christian Koenig" <christian.koenig@amd.com>,
	"Huang Rui" <ray.huang@amd.com>,
	"Matthew Auld" <matthew.auld@intel.com>,
	"Matthew Brost" <matthew.brost@intel.com>,
	"Maarten Lankhorst" <maarten.lankhorst@linux.intel.com>,
	"Thomas Zimmermann" <tzimmermann@suse.de>,
	"David Airlie" <airlied@gmail.com>,
	"Simona Vetter" <simona@ffwll.ch>,
	"Tvrtko Ursulin" <tursulin@ursulin.net>,
	"Thadeu Lima de Souza Cascardo" <cascardo@igalia.com>,
	"Timur Kristóf" <timur.kristof@gmail.com>
Cc: cgroups@vger.kernel.org, dri-devel@lists.freedesktop.org
Subject: Re: [PATCH v8 2/6] cgroup,cgroup/dmem: Add (dmem_)cgroup_common_ancestor helper
Date: Tue, 4 Aug 2026 22:26:56 +0200	[thread overview]
Message-ID: <7b2887b1-ecb7-4d6e-ad34-068ab1d7d41e@pixelcluster.dev> (raw)
In-Reply-To: <b5b80acd-feea-408b-87eb-4264ffc7e2cd@lankhorst.se>

On 8/4/26 22:18, Maarten Lankhorst wrote:
> 
> 
> On 8/4/26 10:25, Natalie Vock wrote:
>> This helps to find a common subtree of two resources, which is important
>> when determining whether it's helpful to evict one resource in favor of
>> another.
>>
>> To facilitate this, add a common helper to find the ancestor of two
>> cgroups using each cgroup's ancestor array.
>>
>> Signed-off-by: Natalie Vock <natalie.vock@gmx.de>
>> ---
>>   include/linux/cgroup.h      | 21 +++++++++++++++++++++
>>   include/linux/cgroup_dmem.h |  9 +++++++++
>>   kernel/cgroup/dmem.c        | 41 +++++++++++++++++++++++++++++++++++++++++
>>   3 files changed, 71 insertions(+)
>>
>> diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h
>> index f2aa46a4f871e..83a17ded1c516 100644
>> --- a/include/linux/cgroup.h
>> +++ b/include/linux/cgroup.h
>> @@ -623,6 +623,27 @@ static inline struct cgroup *cgroup_ancestor(struct cgroup *cgrp,
>>   	return cgrp->ancestors[ancestor_level];
>>   }
>>   
>> +/**
>> + * cgroup_common_ancestor - find common ancestor of two cgroups
>> + * @a: first cgroup to find common ancestor of
>> + * @b: second cgroup to find common ancestor of
>> + *
>> + * Find the first cgroup that is an ancestor of both @a and @b, if it exists
>> + * and return a pointer to it. If such a cgroup doesn't exist, return NULL.
>> + *
>> + * This function is safe to call as long as both @a and @b are accessible.
>> + */
>> +static inline struct cgroup *cgroup_common_ancestor(struct cgroup *a,
>> +						    struct cgroup *b)
>> +{
>> +	int level;
>> +
>> +	for (level = min(a->level, b->level); level >= 0; level--)
>> +		if (a->ancestors[level] == b->ancestors[level])
>> +			return a->ancestors[level];
>> +	return NULL;
>> +}
>> +
>>   /**
>>    * task_under_cgroup_hierarchy - test task's membership of cgroup ancestry
>>    * @task: the task to be tested
>> diff --git a/include/linux/cgroup_dmem.h b/include/linux/cgroup_dmem.h
>> index 1a88cd0c9eb00..9d72457c4cb9d 100644
>> --- a/include/linux/cgroup_dmem.h
>> +++ b/include/linux/cgroup_dmem.h
>> @@ -28,6 +28,8 @@ bool dmem_cgroup_below_min(struct dmem_cgroup_pool_state *root,
>>   			   struct dmem_cgroup_pool_state *test);
>>   bool dmem_cgroup_below_low(struct dmem_cgroup_pool_state *root,
>>   			   struct dmem_cgroup_pool_state *test);
>> +struct dmem_cgroup_pool_state *dmem_cgroup_get_common_ancestor(struct dmem_cgroup_pool_state *a,
>> +							       struct dmem_cgroup_pool_state *b);
>>   
>>   void dmem_cgroup_pool_state_put(struct dmem_cgroup_pool_state *pool);
>>   #else
>> @@ -75,6 +77,13 @@ static inline bool dmem_cgroup_below_low(struct dmem_cgroup_pool_state *root,
>>   	return false;
>>   }
>>   
>> +static inline
>> +struct dmem_cgroup_pool_state *dmem_cgroup_get_common_ancestor(struct dmem_cgroup_pool_state *a,
>> +							       struct dmem_cgroup_pool_state *b)
>> +{
>> +	return NULL;
>> +}
>> +
>>   static inline void dmem_cgroup_pool_state_put(struct dmem_cgroup_pool_state *pool)
>>   { }
>>   
>> diff --git a/kernel/cgroup/dmem.c b/kernel/cgroup/dmem.c
>> index 9df3b33c65046..a587611ca2235 100644
>> --- a/kernel/cgroup/dmem.c
>> +++ b/kernel/cgroup/dmem.c
>> @@ -762,6 +762,47 @@ bool dmem_cgroup_below_low(struct dmem_cgroup_pool_state *root,
>>   }
>>   EXPORT_SYMBOL_GPL(dmem_cgroup_below_low);
>>   
>> +/**
>> + * dmem_cgroup_get_common_ancestor(): Find the first common ancestor of two pools.
>> + * @a: First pool to find the common ancestor of.
>> + * @b: First pool to find the common ancestor of.
>> + *
>> + * Return: The first pool that is a parent of both @a and @b, or NULL if either @a or @b are NULL,
>> + * or if such a pool does not exist. A reference to the returned pool is grabbed and must be
>> + * released by the caller when it is done using the pool.
>> + */
>> +struct dmem_cgroup_pool_state *dmem_cgroup_get_common_ancestor(struct dmem_cgroup_pool_state *a,
>> +							       struct dmem_cgroup_pool_state *b)
>> +{
>> +	struct cgroup *ancestor_cgroup;
>> +	struct cgroup_subsys_state *ancestor_css;
>> +	struct dmemcg_state *ancestor_dmemcs = NULL;
>> +	struct dmem_cgroup_pool_state *pool = NULL;
>> +
>> +	if (!a || !b)
>> +		return NULL;
>> +
>> +	ancestor_cgroup = cgroup_common_ancestor(a->cs->css.cgroup, b->cs->css.cgroup);
>> +	if (!ancestor_cgroup)
>> +		return NULL;
>> +
>> +	rcu_read_lock();
>> +	ancestor_css = cgroup_e_css(ancestor_cgroup, &dmem_cgrp_subsys);
>> +	if (css_tryget(ancestor_css))
>> +		ancestor_dmemcs = css_to_dmemcs(ancestor_css);
>> +	rcu_read_unlock();
>> +
>> +	if (ancestor_dmemcs) {
>> +		pool = get_cg_pool_unlocked(css_to_dmemcs(ancestor_css),
>> +					    a->region);
>> +		if (IS_ERR(pool))
>> +			pool = NULL;
> This should probably be a warn_on as this can never happen, sashiko is wrong here.
> 
> If a and b are charged, all their ancestors are charged too. And when they share a
> common ancestor, then the common ancestor has to have an existing charged pool as
> well because there's a huge bug in the code otherwise.
> 
>> +		css_put(ancestor_css);
>> +	}
>> +	return pool;
>> +}
>> +EXPORT_SYMBOL_GPL(dmem_cgroup_get_common_ancestor);
>> +
>>   static int dmem_cgroup_region_capacity_show(struct seq_file *sf, void *v)
>>   {
>>   	struct dmem_cgroup_region *region;
>>
> 
> Otherwise looks good, so feel free to extend my r-b to this patch too, and with that minor fix up commit it.

Thanks a lot! Correct me if I'm wrong here as it's been a while, but I 
think sashiko's current comment about the css_put(ancestor_css) being 
wrong seems to have merit too? Since dmem_cgroup_pool_state_put() also 
puts a css reference but get_cg_pool_unlocked does not get another 
reference to the css on its own? (Kind of a footgun if you ask me, but 
not something for this series)

Mind if I also drop the css_put() line while I'm at it and *then* 
(finally :D) commit?

Natalie

> 
> Reviewed-by: Maarten Lankhorst <dev@lankhorst.se>
> 


  reply	other threads:[~2026-08-04 20:27 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-04  8:25 [PATCH v8 0/6] cgroup/dmem,drm/ttm: Improve protection in contended cases Natalie Vock
2026-08-04  8:25 ` [PATCH v8 1/6] cgroup/dmem: Add queries for protection values Natalie Vock
2026-08-04  8:41   ` sashiko-bot
2026-08-04  8:25 ` [PATCH v8 2/6] cgroup,cgroup/dmem: Add (dmem_)cgroup_common_ancestor helper Natalie Vock
2026-08-04 20:18   ` Maarten Lankhorst
2026-08-04 20:26     ` Natalie Vock [this message]
2026-08-04 20:41       ` Maarten Lankhorst
2026-08-04 20:56         ` Thadeu Lima de Souza Cascardo
2026-08-04 21:08           ` Natalie Vock
2026-08-04 22:06             ` Thadeu Lima de Souza Cascardo
2026-08-05  2:08               ` Thadeu Lima de Souza Cascardo
2026-08-05  6:30           ` Maarten Lankhorst
2026-08-04  8:25 ` [PATCH v8 3/6] drm/ttm: Extract code for attempting allocation in a place Natalie Vock
2026-08-04  8:41   ` sashiko-bot
2026-08-04  8:25 ` [PATCH v8 4/6] drm/ttm: Split cgroup charge and resource allocation Natalie Vock
2026-08-04  8:44   ` sashiko-bot
2026-08-04  8:25 ` [PATCH v8 5/6] drm/ttm: Be more aggressive when allocating below protection limit Natalie Vock
2026-08-04  8:40   ` sashiko-bot
2026-08-04  8:25 ` [PATCH v8 6/6] drm/ttm: Use common ancestor of evictor and evictee as limit pool Natalie Vock
2026-08-04  8:53   ` sashiko-bot
2026-08-04 15:36 ` [PATCH v8 0/6] cgroup/dmem, drm/ttm: Improve protection in contended cases Timur Kristóf
2026-08-04 15:36   ` [PATCH v8 0/6] cgroup/dmem,drm/ttm: " Timur Kristóf
2026-08-05  8:42 ` Natalie Vock

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=7b2887b1-ecb7-4d6e-ad34-068ab1d7d41e@pixelcluster.dev \
    --to=nat@pixelcluster.dev \
    --cc=airlied@gmail.com \
    --cc=cascardo@igalia.com \
    --cc=cgroups@vger.kernel.org \
    --cc=christian.koenig@amd.com \
    --cc=dev@lankhorst.se \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=hannes@cmpxchg.org \
    --cc=maarten.lankhorst@linux.intel.com \
    --cc=matthew.auld@intel.com \
    --cc=matthew.brost@intel.com \
    --cc=mkoutny@suse.com \
    --cc=mripard@kernel.org \
    --cc=ray.huang@amd.com \
    --cc=simona@ffwll.ch \
    --cc=timur.kristof@gmail.com \
    --cc=tj@kernel.org \
    --cc=tursulin@ursulin.net \
    --cc=tzimmermann@suse.de \
    /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.