Dear maintainers,

Please find the bug report below. Thanks!

Cheers,
BM


## Summary
Intermittent kernel oops (NULL/near-NULL deref) during hibernation *entry*, in the
TTM GPU-memory eviction path invoked by amdgpu's freeze callback
(ttm_device_prepare_hibernation -> ttm_bo_swapout -> LRU walk ->
ttm_resource_manager_next). The oops occurs in the device-freeze phase, before the hibernation image is written, so the next boot reports "PM: Image not found (code -22)" and the session is lost. On my machine oops=panic is set, so it escalates to a full
panic+reboot, but the underlying event is the NULL-deref oops shown below.

## Hardware
- Lenovo ThinkPad T14s Gen 4 (MT 21F8CTO1WW), BIOS R2EET46W 1.27 (2025-09-24)
- CPU/APU: AMD Ryzen 7 PRO 7840U (Phoenix)
- GPU: integrated Radeon 780M, gfx_v11_0, PCI 1002:15bf (rev dd), subsystem 17aa:50d8   - amdgpu reports "VRAM: 1024M ... (1024M used)" — UMA carve-out, no discrete VRAM - Storage: NVMe; root on LUKS+BTRFS; hibernation to a BTRFS swapfile (resume_offset set)

## Kernel
- 7.1.4 (vanilla upstream; distro build tag "#1-NixOS PREEMPT(lazy)")
- Taint: G O. The out-of-tree modules loaded are ddcci, ddcci_backlight, acpi_call,   v4l2loopback — none appear in the backtrace and none touch TTM; the taint is unrelated.

## Frequency / trigger
Intermittent: 2 failures out of 5 hibernation attempts over 5 days (3 clean successes with "PM: hibernation: hibernation exit"). Reproduces on both `systemctl hibernate` and systemd suspend-then-hibernate. Not correlated with a config change — fails and succeeds on the same kernel. The intermittency is consistent with a race dependent on GPU buffer
residency at freeze time (see analysis).

## Backtrace (from efi-pstore; consoles were already suspended, so this is what was captured)
PM: hibernation: hibernation entry
...
PM: hibernation: Allocated 12299604 kbytes in 7.45 seconds (1650.95 MB/s)
Freezing remaining freezable tasks completed (elapsed 0.001 seconds)
printk: Suspending console(s) (use no_console_suspend to debug)
BUG: kernel NULL pointer dereference, address: 0000000000000268
#PF: supervisor read access in kernel mode
#PF: error_code(0x0000) - not-present page
PGD 0 P4D 0
Oops: 0000 [#1] SMP NOPTI
CPU: 2 UID: 0 PID: 1026678 Comm: kworker/u64:16 Tainted: G    O        7.1.4 #1-NixOS PREEMPT(lazy) Hardware name: LENOVO 21F8CTO1WW/21F8CTO1WW, BIOS R2EET46W (1.27 ) 09/24/2025
Workqueue: async async_run_entry_fn
RIP: 0010:ttm_resource_manager_next+0x94/0x200 [ttm]
RSP: 0018:ffffd0f08294fba0 EFLAGS: 00010202
RAX: ffffd0f08294fc40 RBX: ffff8c0846d306a0 RCX: ffffd0f08294fc40
RDX: ffffd0f08294fc40 RSI: ffffd0f08294fc40 RDI: ffffd0f08294fc40
RBP: ffffd0f08294fc20 R08: 0000000000000001 R09: 0000000000000000
R10: ffff8c029c30ed90 R11: ffff8c04001c6880 R12: 0000000000000020
R13: ffffd0f08294fc40 R14: ffffd0f08294fcc0 R15: 0000000000000260
CR2: 0000000000000268
Call Trace:
 <TASK>
 __ttm_bo_lru_cursor_next+0x60/0x300 [ttm]
 ttm_lru_walk_for_evict+0xde/0x1d0 [ttm]
 ttm_bo_swapout+0x5c/0x80 [ttm]
 ttm_device_prepare_hibernation+0x71/0xb0 [ttm]
 amdgpu_device_evict_resources+0x62/0x80 [amdgpu]
 amdgpu_device_suspend+0x13a/0x230 [amdgpu]
 amdgpu_pmops_freeze+0x1e/0x70 [amdgpu]
 pci_pm_freeze+0x5b/0xe0
 dpm_run_callback+0x51/0x180
 device_suspend+0x1aa/0x5d0
 async_suspend+0x21/0x30
 async_run_entry_fn+0x34/0x150
 process_one_work+0x199/0x390
 worker_thread+0x177/0x2e0
 kthread+0xe2/0x110
 ret_from_fork+0x251/0x330
 ret_from_fork_asm+0x1a/0x30
 </TASK>
Kernel panic - not syncing: Fatal exception   (because this host runs with oops=panic)

## Source observations (v7.1.4)
Reading the faulting path in 7.1.4:
- The swapout walk __ttm_bo_lru_cursor_next() (drivers/gpu/drm/ttm/ttm_bo_util.c)   drops the lru_lock (spin_unlock at ~line 1012) and re-acquires it (~line 1031). Its   own comment (~lines 1016-1022) notes that in that window "the resource may have been   freed and allocated again with a different memory type." On the next iteration it calls
  ttm_resource_manager_next(&curs->res_curs) (~line 994).
- ttm_resource_manager_next() (drivers/gpu/drm/ttm/ttm_resource.c:690) has no guard on   cursor->man / the LRU state, whereas its sibling ttm_resource_manager_first() (:673)   does (WARN_ON_ONCE(!man)). CR2=0x268 with what looks like a valid manager in RBX   suggests the cursor walked into a freed/reallocated LRU entry rather than a NULL   top-level manager — i.e. a use-after-free/TOCTOU in the lock-dropped walk. - This tree already contains the "move swapped objects off the manager's LRU list"   rework (ttm_resource_is_swapped(), the `unevictable` list), so that earlier issue is
  not the cause here.
(These are just pointers for triage; I have not root-caused the exact freed object.)

Reply via email to