9/18/2021, 3:15:42 PM
One thing I noticed ever since I bought my second Dell XPS was that the battery life was relatively abysmal when the laptop was asleep. I'd suspend my laptop at work, bring the laptop home, and the next morning I'd be down 25-50% of my battery life! More than once, I'd leave my laptop for a couple days and come back to a completely dead laptop1.
My first inclination was that the laptop was waking up on its own. It does happen occasionally with Linux (which, in an of itself, is pretty concerning2), but in this case, I was reasonably certain it wasn't the case, as evidenced by the battery drop overnight when waking a still-sleeping laptop.
While there are a plethora of articles online about sleep/standby (suspend to RAM) and hibernate (suspend to disk), the root cause was that some hardware configurations support three different modes of sleep:
According to the Linux Kernel documentation:
[Suspend-to-idle] is a generic, pure software, light-weight variant of system suspend (also referred to as S2I or S2Idle). It allows more energy to be saved relative to runtime idle by freezing user space, suspending the timekeeping and putting all I/O devices into low-power states (possibly lower-power than available in the working state), such that the processors can spend time in their deepest idle states while the system is suspended.
[Standby] offers moderate, but real, energy savings, while providing a relatively straightforward transition back to the working state. No operating state is lost (the system core logic retains power), so the system can go back to where it left off easily enough.
[Suspend-to-RAM] offers significant energy savings as everything in the system is put into a low-power state, except for memory, which should be placed into the self-refresh mode to retain its contents.
You can see what mode your system is currently set to, by calling
cat /sys/power/mem_sleep as any user (source):
julian@roci:~$ cat /sys/power/mem_sleep [s2idle] deep
On my laptop, the hardware supports
deep, which represents Suspend-to-RAM. The tradeoff of switching to deep sleep is that the laptop will take a little longer to resume. An
s2idle wake would be near immediate, whereas a
deep wake would take perhaps 5 seconds; a tradeoff I was more than willing to accept.
To change this setting temporarily:
julian@roci:~$ sudo su root@roci:/home/julian# echo deep > /sys/power/mem_sleep
The first line logs me into the root user via
sudo, and the second changes the sleep mode.
To make this change permanent, you can pass a setting to the Grub bootloader (source). As the root user:
/etc/default/grubusing your favourite editor. Use
nanoif you do not have a favourite editor (trust me on this one, you don't want to get stuck inside vim)
mem_sleep_default=deepwithin the quotes. For me, the line would now read:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash mem_sleep_default=deep"
update-grubto re-generate the grub config
I've found that even with the above steps, occasionally my laptop will be set back to
s2idle. I have not figured out why that is the case. Think you might know why? Let me know as a comment here.
It seems I may not be the only one frustrated by this. I discovered today that this feature is called "modern suspend". Of note is that on Windows systems, modern suspend cannot be changed unless the OS is completely reinstalled. Dell's workaround to this issue is to create a shell file that shuts down the computer, and to use this option instead of sleeping 🤯. It is wonderful to know that this is a configurable option in Linux.
1 With a desktop at home, I occasionally leave my laptop in my bag for days on end. Modern suspend essentially precludes me from being able to reliably pick up my laptop and go. There have been times where I am on the train, am notified of a work emergency, and open my laptop to discover that I have 5 minutes of battery life left.
2 One time, my laptop woke up while I was in line at an airport screening checkpoint. Imagine my surprise when I pulled out a too-hot-to-handle laptop with its fan at full blast!