Below the horizontal rule is an AI-generated summary of the issues I was having and how I solved it. I struggled for quite a while to diagnose this in my free time. I have confirmed 100% this is the fix. Apologies if this is a duplicate or if it’s at all foolish. I don’t have much time to spend on this, but I was thinking it’d be good of me to share what worked, notwithstanding. Debian Sid, BTW.
Hibernate resume failures on Framework 13 AMD (Ryzen AI 300 / Krackan): A/B-tested workaround — pm_async=0
TL;DR: After months of intermittent (~15%) hibernate-resume failures — black-screen freeze or instant reset right after typing the LUKS passphrase — setting /sys/power/pm_async to 0 gave many consecutive clean cycles. Flipping it back to 1 (the kernel default) reproduced the failure on the very first cycle. This looks like an async device-resume ordering race (most likely amdgpu) in the restored kernel, and serializing device PM works around it. Would love others on AI 300 hardware to A/B this and report back.
Hardware / software
-
Framework Laptop 13, Ryzen AI 7 350 / Radeon 860M (“Krackan”, RDNA 3.5, gfx1152), BIOS 03.05
-
Debian sid, kernel 7.0.10, LVM-on-LUKS, 64 GB swapfile,
HibernateMode=shutdown, initramfs resume target aligned to the swapfile (resume=+resume_offset=)
Symptom
Hibernate write works every time (machine powers off properly). The failure is on restore: power on → GRUB → type LUKS passphrase → resume starts → either freezes on a black screen or instantly resets back to a second LUKS prompt, and you cold-boot with the session lost. Roughly 1 cycle in 7 over a 10-day tally.
Two things that confused diagnosis for months, in case they’re confusing yours:
-
The failed restore consumes the swap signature, so the next boot logs
PM: Image not found (code -22). That line looks like the image was never written — it wasn’t; it’s the tombstone of a restore that started and died. -
The crash happens before journald exists, so the failing boot logs nothing. Even
panic=30+ full SysRq + efi_pstore captured zero bytes — the instant-reset variant dies below the kernel’s reach.
The experiment
As instrumentation (not a fix), I set pm_async=0 + pm_print_times=1, so device resume would run serially and a frozen screen’s last line would name the culprit device. With that in place: many, many consecutive clean hibernate/resume cycles — suspiciously clean for a ~15% bug.
So I flipped it back: echo 1 | sudo tee /sys/power/pm_async, hibernated once. First restore attempt: instant reset after the LUKS passphrase. Same kernel, same config, same evening — the only variable was the knob.
Why the knob matters on the restore side: pm_async lives in kernel memory, so its value is saved inside the hibernation image and governs the restored kernel’s device re-init — exactly the window where these failures strike. 1 = devices resume concurrently (ordering races possible), 0 = serially in dependency order.
Try it
echo 0 | sudo tee /sys/power/pm_async
To persist (there’s no kernel cmdline parameter for this; a tmpfiles rule is the canonical way):
# /etc/tmpfiles.d/pm-async-workaround.conf
w /sys/power/pm_async - - - - 0
Cost: device suspend/resume runs serially, so hibernate entry/exit is somewhat slower. No functional downside I’ve found.
Honest caveats
-
n=1 machine. ~A dozen clean cycles at
0plus a first-try failure at1is about a 2% coincidence under my old failure rate — strong, not proof. -
This may be the same bug as the “hibernate is spotty at best” reports in the AI 300 threads (and possibly the resume freezes where
dcdebugmask=0x10,sg_display=0,cwsr_enable=0, BIOS/firmware updates, and kernel hopping didn’t help — none of them helped here either), but I can’t confirm that for anyone else’s machine. -
If you A/B it, toggle both directions and count cycles — one clean cycle means nothing with an intermittent bug.
If this holds for others, it’s also a useful data point for the amdgpu maintainers: it would localize the failure to an async ordering dependency in the restore path rather than a flat driver bug.