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
next prev parent 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.