Repository navigation
[BUG] linux-cachyos 7.2.4-1: TTM NULL dereference after global OOM on RX 7800 XT #1058
Description
This is a CachyOS package report for a TTM Oops that may be covered by recent upstream fixes.
Pre-flight:
- Existing issues were searched. [BUG] amdgpu TTM eviction livelock causes multi-second desktop freezes during Proton gaming (RX 9070 XT) #926 covers a different TTM eviction livelock on RX 9070 XT; this report has a global OOM followed by a NULL dereference in
ttm_resource_add_bulk_move(). - The current CachyOS 7.2.6 source was checked and still contains the old
if (!ret)condition, but 7.2.6 has not been boot-tested on the affected host. - Arch vanilla and an untainted upstream kernel have not been tested. No native kernel A/B will be performed on this host.
I hit a kernel Oops in the AMDGPU/TTM swapout path on a Radeon RX 7800 XT. The
failure happened immediately after a global OOM condition and was followed by an
RCU stall and a host reset.
The kernel was 7.2.4-1-cachyos on CachyOS. The GPU is a Sapphire Navi32 / RX
7800 XT (1002:747e, subsystem 1da2:475d). The relevant userspace versions
were Mesa 26.2.2-2, KWin/Plasma 6.7.5-1.1, and libdrm 2.4.134-1.1.
The first failure in the affected boot was:
kswapd0 invoked oom-killer: gfp_mask=0xcc0(GFP_KERNEL), order=0
oom-kill: ... global_oom ...
Out of memory: Killed process <redacted>
amdgpu 0000:03:00.0: [drm] *ERROR* Not enough memory for command submission!
WARNING: drivers/gpu/drm/ttm/ttm_resource.c:235
at ttm_resource_add_bulk_move+0x124/0x150 [ttm]
BUG: kernel NULL pointer dereference, address: 0000000000000008
Oops: Oops: 0000 [#1] SMP NOPTI
RIP: ttm_resource_add_bulk_move+0xc9/0x150 [ttm]
The call chain was:
ttm_resource_add_bulk_move
ttm_resource_alloc
ttm_bo_swapout_cb
ttm_lru_walk_for_evict
ttm_bo_swapout
ttm_global_swapout
ttm_tt_populate
ttm_bo_populate
ttm_bo_vm_fault_reserved
amdgpu_gem_fault
After the Oops, an amdgpu KFD cleanup worker and an amdgpu_drm_release
path were both blocked on TTM-related spinlocks. The journal does not contain
Kernel panic - not syncing; I am calling this an Oops followed by a lockup or
reset, not a confirmed formal panic.
This looks related to the recent TTM fixes:
- 3db7d7d
fixes swapped-out resources remaining in abulk_moverange. - fcfe647
changes the cleanup condition afterttm_tt_swapout()fromif (!ret)to
if (ret > 0).
I checked the source release used for linux-cachyos 7.2.4-1:
cachyos-7.2.4-1.
It still contains:
ret = ttm_tt_swapout(bdev, tt, swapout_walk->gfp_flags);
if (!ret) {
ttm_resource_del_bulk_move_unevictable(bo->resource, bo);
ttm_resource_move_to_lru_tail(bo->resource);
}The installed ttm.ko has the matching test eax,eax / jne branch, so the
installed binary also has the old zero-only condition. The CachyOS 7.2.4
packaging recipe does not list a TTM bulk-move patch. The current
cachyos-7.2.6-1 source release also still contains if (!ret) at this call
site; 7.2.6 has not been boot-tested on the affected host.
The kernel was tainted with CPU_OUT_OF_SPEC, OOT_MODULE, and
UNSIGNED_MODULE; the Oops also set WARN and DIE.
Does this match the stale bulk_move endpoint issue fixed by 3db7d7d/fcfe647,
and should those fixes be backported to kernels based on 7.2.4?
Activity
kvnloo commentedon Sep 20, 2026
One backport detail that may be worth making explicit: "3db7d7d" should not be taken by itself.
I traced both upstream commits. "3db7d7d" intended to change the condition after "ttm_tt_swapout()", but the one-line change was accidentally applied to the earlier "ttm_resource_try_charge()" check instead. "fcfe647" then does two things together:
Both commits carry "Cc: stable@vger.kernel.org # v7.1+".
I also checked "cachyos-7.2.6-1", and its "ttm_bo_swapout_cb()" still has the old "if (!ret)" condition.
So if this is backported before the corresponding stable update lands, I think the safe unit is the corrected two-commit state rather than cherry-picking "3db7d7d" alone.
nekomario28 commentedon Sep 25, 2026
A ready-to-apply backport for the swapout-site condition, verified against the
cachyos-7.2.7-1source release (patch --dry-run -p1applies with zero fuzz; a real apply produces the intendedif (ret > 0)inttm_bo_swapout_cb()).Upstream
fcfe64715bcarries two hunks: (1) revert the misappliedif (ret > 0)inttm_bo_alloc_at_place(), and (2) change the intendedif (!ret)inttm_bo_swapout_cb()toif (ret > 0). CachyOS 7.2.x does not carry3db7d7d, so hunk (1) is unnecessary — this is the swapout-site hunk only:From fcfe64715b425262af1b36f498f9197f3537ceed Mon Sep 17 00:00:00 2001 From: Vadim Nikitushkin <bub4z0r@gmail.com> Date: Thu, 10 Sep 2026 17:34:51 +0300 Subject: [PATCH] drm/ttm: apply the swapout bulk_move fix to the intended condition (backport hunk) Backport of the swapout-site hunk of upstream fcfe647 ("drm/ttm: apply the swapout bulk_move fix to the intended condition"). CachyOS 7.2.x does not carry 3db7d7d, so the companion revert hunk in ttm_bo_alloc_at_place() is not needed; only the ttm_bo_swapout_cb() condition change applies. ttm_tt_swapout() returns the number of pages swapped out on success (>0 for a populated ttm), so gating the bulk_move removal on "if (!ret)" skips it on every successful swapout. A swapped-out resource then stays inside its BO's bulk_move range while unevictable; a later ttm_resource_free()/ttm_bo_set_bulk_move() skips it via the !ttm_resource_unevictable() guard and the range endpoint dangles — seen as WARN in ttm_lru_bulk_move_add(), "list_del corruption" in ttm_resource_move_to_lru_tail(), or NULL dereference in ttm_resource_add_bulk_move()/ttm_resource_manager_next(). Observed on RX 7800 XT (Navi32): kernel NULL dereference in ttm_resource_add_bulk_move+0xc9 after a global OOM, reached via amdgpu_gem_fault -> ttm_tt_populate -> ttm_global_swapout, followed by an RCU stall and host reset (CachyOS/linux-cachyos issue #1058). Fixes: b2ed01e7ad3d ("drm/ttm: Fix ttm_bo_swapout() infinite LRU walk on swapout failure") Upstream: fcfe64715b425262af1b36f498f9197f3537ceed (Cc: stable # v7.1+) Signed-off-by: Vadim Nikitushkin <bub4z0r@gmail.com> --- drivers/gpu/drm/ttm/ttm_bo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1343,7 +1343,7 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo) if (ttm_tt_is_populated(tt)) { ret = ttm_tt_swapout(bdev, tt, swapout_walk->gfp_flags); - if (!ret) { + if (ret > 0) { spin_lock(&bdev->lru_lock); ttm_resource_del_bulk_move_unevictable(bo->resource, bo); ttm_resource_move_to_lru_tail(bo->resource);To carry it ahead of the stable queue: drop the file into
kernel-patchesunder7.2/misc/and add onesource+=()line in the PKGBUILD.fcfe647already hasCc: stable # v7.1+, so the same line will arrive via the next 7.2.y regardless — this just skips the wait.nekomario28 commentedon Oct 24, 2026
Closing this, as the issue is fixed upstream now.
Thanks to everyone who helped with the confirmation.