Framework 13 Running Ubuntu 24.04 fails hibernate when using suspend-then-hibernate

Which Linux distro are you using?

Ubuntu

Which release version?
(if rolling release without a release version, skip this question)

(If rolling release, last date updated?)

24.04

Which kernel are you using?

6.17.0-23-generic

Which BIOS version are you using?

3.18

Which Framework Laptop 13 model are you using? (AMD Ryzen™ AI 300 Series, AMD Ryzen™ 7040 Series, Intel® Core™ Ultra Series 1, 13th Gen Intel® Core™ , 12th Gen Intel® Core™, 11th Gen Intel® Core™)

AMD Ryzen 5 7640U

I am having an intermittent issue where suspend-then-hibernate fails to enter hibernation after the set time in sleep.conf. Checking the logs I see the following:

May 11 21:43:17 Framework kernel: printk: Suspending console(s) (use no_console_suspend to debug)
May 11 21:43:17 Framework systemd-sleep[18184]: System returned from sleep operation 'suspend-then-hibernate'.
May 11 21:43:17 Framework kernel: PM: suspend exit
May 11 21:43:46 Framework kernel: printk: Suspending console(s) (use no_console_suspend to debug)
May 11 21:43:46 Framework kernel: systemd-sleep: page allocation failure: order:0, mode:0x820(GFP_ATOMIC), nodemask=(null),cpuset=systemd-suspend-then-hibernate.service,mems_allowed=0
May 11 21:43:46 Framework kernel:  swsusp_arch_suspend+0x5f/0x70
May 11 21:43:46 Framework systemd-sleep[18184]: Couldn't hibernate, will try to suspend again.
May 11 21:43:46 Framework systemd-sleep[18184]: Performing sleep operation 'suspend'...
May 11 21:43:46 Framework kernel: PM: suspend entry (s2idle)

I check the swap space and I should have plenty:
NAME TYPE SIZE USED PRIO
/dev/nvme0n1p3 partition 35.4G 913M -2

Any ideas on how to fix this?

I was trying to figure out when your kernel was released, as I have experienced similar issues since switching to the 7.0.5 kernel. I did find download links, so I assume it is the latest? given that did you have the same problem before switching?

Can you clarify your question?

This issue started at somepoint over the last few weeks/months and I haven’t knowingly updated the kernel, only sudo apt update && sudo apt upgrade -y.

When did you last run sudo apt update? and did sleep work fine before last week?

I can’t say for sure when I ran sudo apt update because I runt it pretty regularly but suspend-then-hibernate was definitely work in the past. I dug a bit deeper into my logs to see if I could find when the issue first started. I found new entries related to hibernation failure:

May 02 19:00:43 Framework systemd-sleep[229779]: Performing sleep operation 'hibernate'...
May 02 19:01:14 Framework systemd-sleep[229779]: Failed to put system to sleep. System resumed again: Cannot allocate memory
May 02 19:01:14 Framework systemd-sleep[229779]: Couldn't hibernate, will try to suspend again.

The earliest instance of kernel: systemd-sleep: page allocation failure I could find was on April 12th.

Are you thinking that there is a package that was updated that is causing this?

What do you find in your log after running the following command?

echo /dev/nvme0n1p3 > /sys/power/resume

loginctl hibernate

I’m not sure if I’m supposed to run each line separately but this is what I get:

joe@Framework:~$ echo /dev/nvme0n1p3 > /sys/power/resume
bash: /sys/power/resume: Permission denied

Trying to run this with sudo produces no output:

joe@Framework:~$ echo /dev/nvme0n1p3 > sudo /sys/power/resume
joe@Framework:~$ 

Then the other command fails.

joe@Framework:~$ loginctl hibernate
Unknown command verb 'hibernate'.

It shouldn’t, it set your resume device, so the kernel knows where to dump the memory.

Then the other command fails.

Which is weird can you run loginctl with —help to see if the command show up?

this is the output I get

System Commands:
[...]
  hibernate                Hibernate the system

There are no System Commands:

joe@Framework:~$ loginctl --help
loginctl [OPTIONS...] COMMAND ...

Send control commands to or query the login manager.

Session Commands:
  list-sessions            List sessions
  session-status [ID...]   Show session status
  show-session [ID...]     Show properties of sessions or the manager
  activate [ID]            Activate a session
  lock-session [ID...]     Screen lock one or more sessions
  unlock-session [ID...]   Screen unlock one or more sessions
  lock-sessions            Screen lock all current sessions
  unlock-sessions          Screen unlock all current sessions
  terminate-session ID...  Terminate one or more sessions
  kill-session ID...       Send signal to processes of a session

User Commands:
  list-users               List users
  user-status [USER...]    Show user status
  show-user [USER...]      Show properties of users or the manager
  enable-linger [USER...]  Enable linger state of one or more users
  disable-linger [USER...] Disable linger state of one or more users
  terminate-user USER...   Terminate all sessions of one or more users
  kill-user USER...        Send signal to processes of a user

Seat Commands:
  list-seats               List seats
  seat-status [NAME...]    Show seat status
  show-seat [NAME...]      Show properties of seats or the manager
  attach NAME DEVICE...    Attach one or more devices to a seat
  flush-devices            Flush all device associations
  terminate-seat NAME...   Terminate all sessions on one or more seats

Options:
  -h --help                Show this help
     --version             Show package version
     --no-pager            Do not pipe output into a pager
     --no-legend           Do not show the headers and footers
     --no-ask-password     Don't prompt for password
  -H --host=[USER@]HOST    Operate on remote host
  -M --machine=CONTAINER   Operate on local container
  -p --property=NAME       Show only properties by this name
  -P NAME                  Equivalent to --value --property=NAME
  -a --all                 Show all properties, including empty ones
     --value               When showing properties, only print the value
  -l --full                Do not ellipsize output
     --kill-whom=WHOM      Whom to send signal to
  -s --signal=SIGNAL       Which signal to send
  -n --lines=INTEGER       Number of journal entries to show
  -o --output=STRING       Change journal output mode (short, short-precise,
                             short-iso, short-iso-precise, short-full,
                             short-monotonic, short-unix, short-delta,
                             json, json-pretty, json-sse, json-seq, cat,
                             verbose, export, with-unit)

See the loginctl(1) man page for details.

And as root?

Same:

joe@Framework:~$ sudo loginctl --help
Place your right index finger on the fingerprint reader
loginctl [OPTIONS...] COMMAND ...

Send control commands to or query the login manager.

Session Commands:
  list-sessions            List sessions
  session-status [ID...]   Show session status
  show-session [ID...]     Show properties of sessions or the manager
  activate [ID]            Activate a session
  lock-session [ID...]     Screen lock one or more sessions
  unlock-session [ID...]   Screen unlock one or more sessions
  lock-sessions            Screen lock all current sessions
  unlock-sessions          Screen unlock all current sessions
  terminate-session ID...  Terminate one or more sessions
  kill-session ID...       Send signal to processes of a session

User Commands:
  list-users               List users
  user-status [USER...]    Show user status
  show-user [USER...]      Show properties of users or the manager
  enable-linger [USER...]  Enable linger state of one or more users
  disable-linger [USER...] Disable linger state of one or more users
  terminate-user USER...   Terminate all sessions of one or more users
  kill-user USER...        Send signal to processes of a user

Seat Commands:
  list-seats               List seats
  seat-status [NAME...]    Show seat status
  show-seat [NAME...]      Show properties of seats or the manager
  attach NAME DEVICE...    Attach one or more devices to a seat
  flush-devices            Flush all device associations
  terminate-seat NAME...   Terminate all sessions on one or more seats

Options:
  -h --help                Show this help
     --version             Show package version
     --no-pager            Do not pipe output into a pager
     --no-legend           Do not show the headers and footers
     --no-ask-password     Don't prompt for password
  -H --host=[USER@]HOST    Operate on remote host
  -M --machine=CONTAINER   Operate on local container
  -p --property=NAME       Show only properties by this name
  -P NAME                  Equivalent to --value --property=NAME
  -a --all                 Show all properties, including empty ones
     --value               When showing properties, only print the value
  -l --full                Do not ellipsize output
     --kill-whom=WHOM      Whom to send signal to
  -s --signal=SIGNAL       Which signal to send
  -n --lines=INTEGER       Number of journal entries to show
  -o --output=STRING       Change journal output mode (short, short-precise,
                             short-iso, short-iso-precise, short-full,
                             short-monotonic, short-unix, short-delta,
                             json, json-pretty, json-sse, json-seq, cat,
                             verbose, export, with-unit)

See the loginctl(1) man page for details.

Weird. let’s ignore that tangent.

Run the first command as root, and then hibernate the system. the hope is that the issue was that you hibernate device got uninstalled for whatever reason.

Please be aware you might lose your data or corrupt the file system if anything goes wrong :)

I run the sync command before I hibernate, I don’t know if it makes any difference.

I should have mentioned this earlier but manually hibernation hasn’t been an issue the few times I’ve tried it. It’s the suspend-to-hibernate that is the problem. I can see if it triggers the next time it crosses the threshold.

Looks like it failed to both suspend-then-hibernate and manual hibernate.

You can see that the device went to sleep at 16:51, woke up at 18:51 and returned a battery error then went back to sleep. Then at 19:18 I tried to manually hibernate and it failed with a memory allocation error.

May 13 16:51:15 Framework systemd-sleep[64474]: Performing sleep operation 'suspend'...
May 13 16:58:07 Framework systemd-sleep[64474]: System returned from sleep operation 'suspend-then-hibernate'.
May 13 16:59:01 Framework systemd-sleep[64841]: Performing sleep operation 'suspend'...
May 13 18:59:01 Framework systemd-sleep[64841]: System returned from sleep operation 'suspend-then-hibernate'.
May 13 18:59:01 Framework systemd-sleep[64841]: BAT1: Failed to update battery discharge rate, ignoring: Numerical result out of range
May 13 18:59:30 Framework systemd-sleep[65211]: Performing sleep operation 'suspend'...
May 13 19:14:53 Framework systemd-sleep[65211]: System returned from sleep operation 'suspend-then-hibernate'.
May 13 19:18:13 Framework systemd-sleep[66163]: Performing sleep operation 'hibernate'...
May 13 19:18:43 Framework systemd-sleep[66163]: Failed to put system to sleep. System resumed again: Cannot allocate memory

I noticed that there was some allocated swap space in htop so I disabled swap with sudo swapoff -a and the reenabled swap, sudo swapon -a and tried to hibernate and it worked. My current operating theory is that something is taking up some swap space and then I try to hibernate there isn’t enough space to dump the memory to.

That is correct. There is not enough space on the hibernate partition to hold all of RAM due to the swap space being used for swap.

Try to configure a separate hibernate partition.

What does /proc/meminfo, and /proc/vmstat tell you?

How is that?, if his htop image is correct he has more swap then memory, unless I’m missing something.

In Linux, swap space is virtual memory.
Linux will attempt to use all of RAM + SWAP as if it was all RAM. It makes the CPU think you have more RAM than you actually do, but of course it is slow, because swap space to disk is slower than RAM.
Now, if Linux uses all of RAM and too much of SWAP, because you were running some application at the time that needed it. Hibernate would then fail because hibernate is essentially just attempting to swap out all of RAM to disk. So for that, one needs the unused SWAP space to be >= RAM size.
Now, the actual behavior is a bit more finessed that what I explain above, but the above is generally correct.

What I find odd is that I have way more memory than I actually need so I’m not sure why any swap would be used. I have 32 GB and regularly use under 10. This is what I see just now after resuming from hibernation: