feat: Backport VRAM management patches for dmem cgroup#1889
Conversation
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}.
Signed-off-by: Natalie Vock <natalie.vock@gmx.de>
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>
Backport the following patches from pixelcluster's dmemcg-aggressive-protect branch, adapted for kernel 6.18.y: - drm/ttm: Extract code for attempting allocation in a place Introduce ttm_bo_alloc_state and ttm_bo_alloc_at_place() to better organize allocation logic. Move limit_pool from ttm_bo_evict_walk to the new alloc_state structure. - drm/ttm: Split cgroup charge and resource allocation Separate cgroup charging from resource allocation to fix race conditions when charge succeeds but allocation fails. Add ttm_resource_try_charge() for pre-charging cgroups before resource allocation attempts. - drm/ttm: Be more aggressive when allocating below protection limit When the cgroup's memory usage is below the low/min limit and allocation fails, try evicting unprotected buffers to make space. This prevents application buffers from being forced into GTT even though usage is below the protection limit. - drm/ttm: Use common ancestor of evictor and evictee as limit pool When checking whether to skip protected buffers, use the common ancestor of evictor and evictee cgroups as the limit pool. This ensures correct protection calculation for sibling cgroups. Original patches by Natalie Vock <natalie.vock@gmx.de> Adapted for deepin-community/kernel linux-6.18.y branch.
There was a problem hiding this comment.
Sorry @deepin-wm, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
|
Hi @deepin-wm. Thanks for your PR. 😃 |
|
Hi @deepin-wm. Thanks for your PR. I'm waiting for a deepin-community member to verify that this patch is reasonable to test. If it is, they should reply with Once the patch is verified, the new status will be reflected by the I understand the commands that are listed here. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. |
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
There was a problem hiding this comment.
Pull request overview
Backports VRAM (TTM) eviction/allocation changes and adds dmem-cgroup helpers to make allocations for cgroups under dmem.low/dmem.min more likely to stay in VRAM by preferentially evicting unprotected buffers.
Changes:
- Add dmem-cgroup helpers to query whether a pool is below effective
min/low, and to compute the common ancestor pool for correct subtree protection calculations. - Introduce
ttm_resource_try_charge()and changettm_resource_alloc()to separate cgroup charging from resource allocation. - Refactor TTM allocation/eviction flow (
ttm_bo_alloc_at_place()and updated eviction walk) to be more aggressive when the allocating cgroup is protected.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| kernel/cgroup/dmem.c | Adds below_min/low queries and a common-ancestor helper used by TTM’s protection-aware eviction decisions. |
| include/linux/cgroup.h | Adds cgroup_common_ancestor() helper to support common-ancestor queries. |
| include/linux/cgroup_dmem.h | Exposes new dmem-cgroup helper APIs to other subsystems (TTM). |
| include/drm/ttm/ttm_resource.h | Updates TTM resource API to separate charging (try_charge) from allocation. |
| drivers/gpu/drm/ttm/ttm_resource.c | Implements ttm_resource_try_charge() and updates ttm_resource_alloc() to accept a pre-charged pool. |
| drivers/gpu/drm/ttm/ttm_bo.c | Refactors allocation/eviction and integrates dmem-cgroup protection logic into the eviction walk. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 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; |
There was a problem hiding this comment.
Fixed in bd7e681. Added if (!test) return false; at the start of dmem_cgroup_below_min() to treat NULL test as 'not protected'.
| 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; |
There was a problem hiding this comment.
Fixed in bd7e681. Added if (!test) return false; at the start of dmem_cgroup_below_low() to treat NULL test as 'not protected'.
| 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; | ||
|
|
||
| if (!a || !b) | ||
| return NULL; | ||
|
|
||
| ancestor_cgroup = cgroup_common_ancestor(a->cs->css.cgroup, b->cs->css.cgroup); | ||
| if (!ancestor_cgroup) | ||
| return NULL; | ||
|
|
||
| ancestor_css = cgroup_e_css(ancestor_cgroup, &dmem_cgrp_subsys); | ||
| css_get(ancestor_css); | ||
|
|
||
| return get_cg_pool_unlocked(css_to_dmemcs(ancestor_css), a->region); | ||
| } |
There was a problem hiding this comment.
Fixed in bd7e681. Added IS_ERR_OR_NULL check on get_cg_pool_unlocked return value, with css_put(ancestor_css) on error path. Returns NULL on failure.
| * 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. | ||
| * |
There was a problem hiding this comment.
Fixed in bd7e681. Changed @b: First pool to @b: Second pool in the kernel-doc.
| if (!alloc_state->in_evict) { | ||
| may_evict |= dmem_cgroup_below_min(NULL, alloc_state->charge_pool); | ||
| alloc_state->may_try_low = may_evict; | ||
|
|
||
| may_evict |= dmem_cgroup_below_low(NULL, alloc_state->charge_pool); | ||
| } |
There was a problem hiding this comment.
Fixed in bd7e681. Guarded the protection checks with if (!alloc_state->in_evict && alloc_state->charge_pool) so they only run when a pool was actually charged.
| if (!evict_walk->alloc_state->may_try_low && | ||
| bo->resource->css == evict_walk->alloc_state->charge_pool) | ||
| return 0; |
There was a problem hiding this comment.
Fixed in bd7e681. Added alloc_state->charge_pool check before the same-cgroup comparison, so uncharged BOs are not incorrectly skipped.
| evict_valuable = dmem_cgroup_state_evict_valuable(limit_pool, bo->resource->css, | ||
| evict_walk->try_low, | ||
| &evict_walk->hit_low); |
There was a problem hiding this comment.
Fixed in bd7e681. Added early return with evict_valuable = true when bo->resource->css is NULL, treating uncharged resources as unprotected and evictable.
Fix issues identified by Copilot code review: dmem.c: - Add NULL test pointer check in dmem_cgroup_below_min/low to prevent NULL dereference when called with uncharged pools - Fix dmem_cgroup_get_common_ancestor ERR_PTR handling: check for IS_ERR_OR_NULL return from get_cg_pool_unlocked and release css reference on failure - Fix kernel-doc: @b parameter was incorrectly described as 'First pool' ttm_bo.c: - Guard dmem_cgroup_below_min/low calls with charge_pool check to prevent NULL dereference when resource manager has no dmem cgroup - Only skip same-cgroup BOs during eviction when charge_pool is non-NULL to avoid blocking all uncharged resource eviction - Handle NULL css in eviction callback: treat uncharged resources as unprotected/evictable instead of passing NULL to dmem_cgroup_state_evict_valuable
Summary
Backport VRAM management patches from pixelcluster's dmemcg-aggressive-protect branch to improve VRAM allocation for low-end GPUs.
These patches fix AMDGPU's VRAM management so that applications protected by dmem cgroup limits (dmem.low/dmem.min) are more aggressive about evicting unprotected buffers, preventing protected application buffers from being forced into GTT (system RAM) even when they are within their protection limits.
Changes
Patch 1: cgroup/dmem: Add queries for protection values
Add
dmem_cgroup_below_min()anddmem_cgroup_below_low()helpers, counterparts to memcg'smem_cgroup_below_{min,low}. Callers can use these to be more aggressive in making space for allocations of a protected cgroup.Patch 2: cgroup,cgroup/dmem: Add (dmem_)cgroup_common_ancestor helper
Add a helper to find the common ancestor of two cgroup pool states. This is needed to determine the correct subtree when making eviction decisions about protected buffers.
Patches 3-6 (adapted for 6.18.y):
struct ttm_bo_alloc_stateandttm_bo_alloc_at_place()for better allocation logic organization.ttm_resource_try_charge()to fix race conditions when charge succeeds but allocation fails.Source
Patches from: https://pixelcluster.github.io/VRAM-Mgmt-fixed/
Original commits by Natalie Vock natalie.vock@gmx.de
Notes