March 29, 2019

Technical Note: Sleep Issue on Dell XPS 9370 with Ubuntu 18.04 (Bionic Beaver)

I notice than when I close my lit of Dell XPS 9370, which is installed Ubuntu Linux 18.04 (Bionic Beaver),the OS does not get into deep sleep mode. It does turn off the display, and hard disk and CPU seems to get into low power mode. However, the OS consumes battery power as normal mode and if I forget to put my computer into my backpack in this sleep mode, the CPU rallies producing heats. This definitely reduce the life of my laptop and I know that I need to do something.

At first, I thought this issue relates to driver due to new hardware, but after a quick Google, I found out that Arch Linux user and Bionic Beaver users see the same issue. I think the answer made by monty47 is so complete that I need no further explanation. I copied his solution here including several references for my personal educational purposes.

1. Root cause and Solution

Linux Kernel supports 4 system sleep states, though some states depend on platform support codes. Those 4 states are represented by strings that can be written or read from /sys/power/state, which are
  • "mem"
  • "standby" - Power-On-Suspend
  • "freeze" - Suspend-To-Idle
  • "disk" - Hibernation
The "mem" represented available sleep modes supported by the platform. The modes could be referenced in /sys/power/mem_sleep, and could have following values
  • s2idle - Suspend-To-Idle
  • shallow - Power-on Suspend
  • deep - Suspend-To-Ram
"s2idle" seems always available, while "shallow" and "deep" depend on underlying platform and supporting code (I have not traced which layer's code). For example, my Dell XPS 9370 can only be in "s2idle" and "deep".

$ cat /sys/power/mem_sleep
[s2idle] deep

For detailed explanation, please refer to System Power Management Sleep States by Wysocki. Only in "deep" state, all system and devices but memory are put in low-power state, and kernel might pass controls to the BIOS.

So, for my Dell XPS 9370, if I don't put it into "deep" mem sleep state, it will maintain normal "s2idle", which is just a light-weight, pure software mode. CPU will spend most of its time in idle mode, it produces heat even in this mode (because I greedily chose a Core i7 chip).

To check which mode my computer is in by default, just put it into sleep mode using Fn+End and search for sleep keyword in journal.

$ cat /sys/power/mem_sleep
[s2idle] deep     # <-- highly="" in="" p="" s2idle="">$ # Fn + End to put to computer to sleep and wake it up
$ journalctl -S "2019-03-28" | grep "PM: suspend" | tail -2
Mar 28 19:08:27 ha-xps kernel: PM: suspend entry (s2idle)
Mar 28 22:29:35 ha-xps kernel: PM: suspend exit


To fix this issue, just temporarily change mem_sleep to "deep" mode by

$ echo deep | sudo tee /sys/power/mem_state

or permanently put that mode into kernel startup parameters.

$ sudo vim /etc/default/grub
...
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash mem_sleep_default=deep"
...
$ sudo grub-mkconfig -o /boot/grub/grub.cfg
$ sudo reboot
$ # Confirm after rebooted
$ sudo journalctl -b 0 | grep "PM: suspend" | tail -2
Mar 28 19:08:27 ha-xps kernel: PM: suspend entry (deep)
Mar 28 22:29:35 ha-xps kernel: PM: suspend exit 


2. Known Related Issues

This solution comes with 2 consequences (or related issues).

  1. Suspend will fails if you encrypts hard disk
  2. Bluetooth will not wake up after suspend. This means you cannot use bluetooth mouse after your system wakes up.
I, myself, have the No.2 issue and I need to reset bluetooth after startup. Restart bluetooth through UI seems not working to me and I don't know why (perhaps it is a bug?).

$ sudo systemctl start bluetooth
$ bluetoothctl
...
[NEW] Characteristic
        /org/bluez/hci0/dev_D7_4A_86_5E_2D_C4/service0008/char0009
        00002a05-0000-1000-8000-00805f9b34fb
        Service Changed
[NEW] Descriptor
        /org/bluez/hci0/dev_D7_4A_86_5E_2D_C4/service0008/char0009/desc000b
        00002902-0000-1000-8000-00805f9b34fb
        Client Characteristic Configuration
Agent registered
...


3. Future Consideration

This issue has not been fixed on my current Bionic HWE release.
Hope it will get fixed in upcoming version.