All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Natalie Vock" <natalie.vock@gmx.de>
Cc: tj@kernel.org, hannes@cmpxchg.org, mkoutny@suse.com,
	dri-devel@lists.freedesktop.org
Subject: Re: [PATCH v8 1/6] cgroup/dmem: Add queries for protection values
Date: Tue, 04 Aug 2026 08:41:18 +0000	[thread overview]
Message-ID: <20260804084122.7B5591F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260804-dmemcg-aggressive-protect-v8-1-07af96681bf8@gmx.de>

Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:

New issues:
- [High] Missing ancestry check can result in using stale protection values for non-descendants.

Pre-existing issues:
- [High] O(N) cgroup tree traversal per isolated query causes massive overhead on eviction paths.
--

--- Patch [1]: [PATCH v8 1/6] cgroup/dmem: Add queries for protection values ---
commit def4bae1e53d26c789e6edbd5c551a0f50ade339
Author: Natalie Vock <nat@pixelcluster.dev>

cgroup/dmem: Add queries for protection values
    
Callers can use this feedback to be more aggressive in making space for
allocations of a cgroup if they know it is protected.
    
These are counterparts to memcg's mem_cgroup_below_{min,low}.

> diff --git a/kernel/cgroup/dmem.c b/kernel/cgroup/dmem.c
> index 39930c59cb769..9df3b33c65046 100644
> --- a/kernel/cgroup/dmem.c
> +++ b/kernel/cgroup/dmem.c

[ ... ]

> @@ -700,6 +700,68 @@ int dmem_cgroup_try_charge(struct dmem_cgroup_region *region, u64 size,
>  }
>  EXPORT_SYMBOL_GPL(dmem_cgroup_try_charge);
>  
> +/**
> + * dmem_cgroup_below_min() - Tests whether current usage is within min limit.
> + *
> + * @root: Root of the subtree to calculate protection for, or NULL to calculate global protection.
> + * @test: The pool to test the usage/min limit of.
> + *
> + * Return: true if usage is below min and the cgroup is protected, false otherwise.
> + */
> +bool dmem_cgroup_below_min(struct dmem_cgroup_pool_state *root,
> +			   struct dmem_cgroup_pool_state *test)
> +{
> +	if (root == test || !pool_parent(test))
> +		return false;
> +
> +	if (!root) {
> +		for (root = test; pool_parent(root); root = pool_parent(root))
> +			{}
> +	}
> +
> +	/*
> +	 * In mem_cgroup_below_min(), the memcg pendant, this call is missing.
> +	 * mem_cgroup_below_min() gets called during traversal of the cgroup tree, where
> +	 * protection is already calculated as part of the traversal. dmem cgroup eviction
> +	 * does not traverse the cgroup tree, so we need to recalculate effective protection
> +	 * here.
> +	 */
> +	dmem_cgroup_calculate_protection(root, test);

[Severity: High]
This isn't a bug introduced by this patch, but does calling 
dmem_cgroup_calculate_protection() here for isolated per-item queries cause 
massive overhead on eviction paths?

Looking at the pre-existing dmem_cgroup_calculate_protection() implementation:

kernel/cgroup/dmem.c:dmem_cgroup_calculate_protection() {
    ...
    css_for_each_descendant_pre(css, &limit_pool->cs->css) {
        ...
        page_counter_calculate_protection(climit, &found_pool->cnt, true);

        if (found_pool == test_pool)
            break;
    }
    ...
}

It performs a top-down pre-order traversal starting from root. When root is 
NULL and falls back to the global root, it forces a traversal over almost the 
entire system's cgroups. Executing this full subtree walk repeatedly during 
eviction scanning could lead to severe performance degradation.

> +	return page_counter_read(&test->cnt) <= READ_ONCE(test->cnt.emin);

[Severity: High]
If the caller passes a root and a test pool where test is not a descendant 
of root, dmem_cgroup_calculate_protection() will iterate only the descendants 
of root, never find test, and exit without updating test->cnt.emin.

Could this cause the function to read a stale emin value from a prior 
calculation and incorrectly return true, incorrectly shielding the cgroup 
from eviction?

Since dmem uses global lists and doesn't have per-cgroup LRUs, encountering 
non-descendants during eviction seems likely. Would it be safer to verify 
that test is a descendant of root and return false otherwise?

> +}
> +EXPORT_SYMBOL_GPL(dmem_cgroup_below_min);
> +
> +/**
> + * dmem_cgroup_below_low() - Tests whether current usage is within low limit.
> + *
> + * @root: Root of the subtree to calculate protection for, or NULL to calculate global protection.
> + * @test: The pool to test the usage/low limit of.
> + *
> + * Return: true if usage is below low and the cgroup is protected, false otherwise.
> + */
> +bool dmem_cgroup_below_low(struct dmem_cgroup_pool_state *root,
> +			   struct dmem_cgroup_pool_state *test)
> +{
> +	if (root == test || !pool_parent(test))
> +		return false;
> +
> +	if (!root) {
> +		for (root = test; pool_parent(root); root = pool_parent(root))
> +			{}
> +	}
> +
> +	/*
> +	 * In mem_cgroup_below_low(), the memcg pendant, this call is missing.
> +	 * mem_cgroup_below_low() gets called during traversal of the cgroup tree, where
> +	 * protection is already calculated as part of the traversal. dmem cgroup eviction
> +	 * does not traverse the cgroup tree, so we need to recalculate effective protection
> +	 * here.
> +	 */
> +	dmem_cgroup_calculate_protection(root, test);
> +	return page_counter_read(&test->cnt) <= READ_ONCE(test->cnt.elow);

[Severity: High]
Similarly to dmem_cgroup_below_min() above, does this missing ancestry check 
also expose dmem_cgroup_below_low() to using stale elow protection values if 
test is not a descendant of root?

> +}
> +EXPORT_SYMBOL_GPL(dmem_cgroup_below_low);

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260804-dmemcg-aggressive-protect-v8-0-07af96681bf8@gmx.de?part=1

  reply	other threads:[~2026-08-04  8:41 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 [this message]
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
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=20260804084122.7B5591F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=hannes@cmpxchg.org \
    --cc=mkoutny@suse.com \
    --cc=natalie.vock@gmx.de \
    --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.