Disabling CPU before suspend and enabling it after wake up

Hello,

on my Macbook pro 8,1 I have the problem that the CPU3 waking up slowly and the wake up process is 1 minute long.
This problem is very annoying.

i have temporary solved the problem disabling the 4th core:

In “/etc/default/grub” I have added “isolcpus=3” to “GRUB_CMDLINE_LINUX” after “…splash”

After a reboot the wake up time is now normal. But of course I lost 1 of 4 cores…

Can you help me to write 2 batches. The 1rd must disable the CPU3 writing 0 in /sys/devices/system/cpu/cpu3/online
(echo 0 > /sys/devices/system/cpu/cpu3/online give me Not permitted)
and then invoke suspension.

And the 2nd one must enable the CPU3 after the wake up…

It’s not the best solution, but it can work…

Thank you
Andrea

It sounds as if the processor itself may have a failing core. Try disabling that core in bios or replace the processor (or entire machine). Are you certain the processor has not been overheated? It may need cleaned and new thermal compound for the cooler.

Hello Jeff,

I don’t think that could be a hardware failure.
With other Distro (Debian based) there is not the problem. It’a a Fedora related problem.

Here the same problem is described by Steve:
https://discussion.fedoraproject.org/t/slow-to-wake-watchdog-bug-soft-lockup-cpu-3/78007

Andrea

My problem is how to edit the file ‘/sys/devices/system/cpu/cpu3/online’. I don’t have enough permissions even with sudo…
On files with “admin:///” I can edit the file without problems…

First part of the solution:

sudo sh -c “echo 0 > /sys/devices/system/cpu/cpu3/online”

2 Likes

I have the same issue on my macbook 8,1 with FC38. On rare occassions the wakeup from suspend is immediate. Mostly it takes around 4 minutes for me and when that happens I always see the crash with the line

watchdog: bug: soft lockup - cpu#3 stuck for 22s! [cpuhp/3:30]

Regarding your question regarding editing “/sys/devices/system/cpu/cpu3/online”, I guess one can create a systemd service that uses sleep.target. sleep.target gets pulled in everytime the system is suspended or hibernated.

Thank you for this post. I have fixed the wakup issue on my macbook thanks to you. I created a script /usr/lib/systemd/system-sleep/fix-macbook-wakeup

#!/bin/sh
case “$1/$2” in
pre/*)
echo 0 > /sys/devices/system/cpu/cpu3/online
;;
post/*)
echo 1 > /sys/devices/system/cpu/cpu3/online
;;
esac

chmod +x /usr/lib/systemd/system-sleep/fix-macbook-wakeup
systemctl daemon-reload

1 Like

Hello Manvendra Bhangui,

I am glad that you have also solved the problem. Yesterday I got a similar result by putting in

/lib/systemd/system-sleep/

the executable file:

#!/bin/sh
case $1/$2 in
  pre/*)
    echo "Going to $2..."
    sh -c "echo 0 > /sys/devices/system/cpu/cpu3/online"
    ;;
  post/*)
    echo "Waking up from $2..."
    sh -c "echo 1 > /sys/devices/system/cpu/cpu3/online"
required
    ;;
esac

The same solution in 2 different locations… (Maybe sh -c is not necessary…)

Now I need another help: when waking up I also have to launch a VPN client. But with this method every command is launched as root, whereas VPN requires a standard user and not root. I have tried several methods, but none of them work.
Can you suggest something?

Thanks
Andrea

Hi Andrea, You can use the command

su user -c “vpn_command arg1 arg2 …”

In case your vpn command needs supplementary groups, you can use the -G argument to su.

in case your vpn command needs few env variables you can use a variation using the env command. e.g.

su user -c “env HOME=/abcd USER=andreas vpn_command arg1 arg2 arg3 …”

It might require few trials before you get a solution that works.

Here the results:

as root:

[andrea@fedora ~]$ sudo protonvpn-cli

Running Proton VPN as root is not supported and is highly discouraged, as it might introduce undesirable side-effects.
Are you sure that you want to proceed (y/N): n

with my user on the 1st attempt:

[andrea@fedora ~]$ sudo su andrea -c "protonvpn-cli"

Running Proton VPN as root is not supported and is highly discouraged, as it might introduce undesirable side-effects.
Are you sure that you want to proceed (y/N): n

with my user on the 2nd attempt:

[andrea@fedora ~]$ sudo su andrea -c "env HOME=/andrea USER=andrea protonvpn-cli"

Running Proton VPN as root is not supported and is highly discouraged, as it might introduce undesirable side-effects.
Are you sure that you want to proceed (y/N): n

Yesterday I tested a lot of combinations, but no results.

Something change adding -l, but it’s not working properly

[andrea@fedora ~]$ sudo su andrea -l -c "protonvpn-cli c --cc CH"
Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/secretstorage/__init__.py", line 73, in dbus_init
    connection = open_dbus_connection()
                 ^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/jeepney/io/blocking.py", line 341, in open_dbus_connection
    bus_addr = get_bus(bus)
               ^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/jeepney/bus.py", line 53, in get_bus
    return find_session_bus()
           ^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/jeepney/bus.py", line 42, in find_session_bus
    addr = os.environ['DBUS_SESSION_BUS_ADDRESS']
           ~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^
...

That is certainly not required.
You are already user andrea so the only part of that command needed would be the “protonvpn-cli” part and skip using sudo entirely. Then protonvpn would be running as your user.

Maybe protovpn-cli is using some env variables which has been set by sudo. In the actual systemd script don’t use sudo because you are already root. You can put a shell script that gets called. The shell script should do strace and that way you could know what is happening. Three other things you could try

  1. Start with an empty env variables. e.g

su andrea -c “env - HOME=/andrea USER=/andrea XDG_RUNTIME_DIR=/run/user/1000 protonvpn-cli”

2.Create a user systemd unit that starts your vpn. I have never tried this. So not sure if it will work
3. Create a user level systemd-sleep unit. See this post Using systemd user units to react to sleep/suspend | Daniel Garajau

So I just had some fun by creating a user level sleep service that runs a command as myself when the lid is opened. You can try this to run your vpn command

Step 1
create /usr/lib/systemd/system/sleep@.service

sudo vi /usr/lib/systemd/system/sleep@.service

[Unit]
Description=Call user’s sleep target after system sleep
After=sleep.target

[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl --user --machine=%i@ start --wait sleep.target

[Install]
WantedBy=sleep.target

Step 2
Run the command as user

sudo systemctl daemon-reload && sudo systemctl enable sleep@$(whoami)

Step 3
create ~/.config/systemd/user/sleep.target

vi ~/.config/systemd/user/sleep.target

[Unit]
Description=User level Power Management Target
StopWhenUnneeded=yes
Wants=power-management.service

Step 4
create ~/.config/systemd/user/power-management.service. In my case my home directory is /home/mbhangui

vi ~/.config/systemd/user/power-management.service

[Unit]
Description=Power Management

[Service]
ExecStart=/home/mbhangui/bin/power-management
Type=oneshot
Restart=no

[Install]
WantedBy=sleep.target

Step 5
create ~/bin/power-management

vi ~/bin/power-management

#!/bin/sh
dbus-send --type=method_call --dest=org.gnome.ScreenSaver \
/org/gnome/ScreenSaver org.gnome.ScreenSaver.Lock

aplay /usr/share/sounds/speech-dispatcher/trumpet-12.wav

In my case the script above locks the screen on wakeup and plays the sound of a trumpet

Step 6

Run the commands as user

chmod +x ~/bin/power-management
systemctl --user daemon-reload

That is certainly not required.
You are already user andrea so the only part of that command needed would be the “protonvpn-cli” part and skip using sudo entirely. Then protonvpn would be running as your user.

Yes, I know of course. But I have to simulate on the command line the launch as root of the command by systemctl or similar service.

Usually the command is only protonvpn-cli… as you mentioned

How would I do this for Fedora Silverblue?

Hi Manvendra,
Your solution is working like a charm! Thank you, you have helped me a lot.

Now I would like to understand what the 3 scripts do, the fourth and last one in my case obviously calls the VPN client…

Now everything starts after waking up

I’m not an expert on systemd. I will attempt explaining this to the best of my knowledge. But feel free to correct anything that is wrong.

The example given above is about creating instance units from a template. See this link.

Now here we create sleep@.service. So When I run the command

systemctl enable sleep@$(whoami)

It creates a systemd service in /etc/systemd/system/sleep@mbhangui.service.

If you see this file we have the following two things in this service file

After=sleep.target
and
ExecStart=/usr/bin/systemctl --user --machine=%i@ start --wait sleep.target

Because of the above, systemd will execute the command below. (Since we had the @ in the filename, %i gets replaced with the username in my case mbhangui). You will have to read the above link to understand this.

systemctl --user=machine=mbhangui@ start --wait

The above command will use the unit file /home/mbhangui/.config/systemd/user/sleep.target, which will cause systemd to load /home/mbhangui/.config/systemd/user/power-management.service and hence execute the command /home/mbhangui/bin/power-management script.

Read systemd/user for a better understanding of this.

Sorry John, I have no idea about Fedora Silverblue. You can’t write anything to /usr/lib, /lib etc. But you can very well write to ~/.config/systemd/user.

So just follow from Step 3 onwards and see if that works.

[For Fedora Silverblue users]

I figured out a way of doing this without writing to /usr/lib or /lib.

Create a .service file in /etc/systemd/system I called mine CPU3OFF.service

[Unit]
Description=Turns off CPU#3 before suspend
Before=sleep.target

[Service]
Type=simple
ExecStart=/usr/bin/bash -c 'echo 0 > /sys/devices/system/cpu/cpu3/online'

[install]
WantedBy=sleep.target

After that create another .service file in the same directory I called it CPU3ON.service

[Unit]
Description=Turns on CPU#3 after resuming
After=suspend.target

[Service]
Type=simple
ExecStart=/usr/bin/bash -c 'echo 1 > /sys/devices/system/cpu/cpu3/online'

[install]
WantedBy=suspend.target

Open terminal run systemctl enable CPU3OFF.service && systemctl enable CPU3ON.service and you should be set.

1 Like

Hello!
I tried your solution with my 8 core 2013 MacBookPro11,3 and unfortunately for me - it didn’t work. It wakes very slowly. around 10 minutes.

I modified the daemon according to:

$ journalctl | grep watchdog
May 09 23:46:44 fedora kernel: watchdog: BUG: soft lockup - CPU#5 stuck for 22s! [cpuhp/5:40]

like so:

#!/bin/sh
case “$1/$2” in
pre/)
echo 0 > /sys/devices/system/cpu/cpu5/online
;;
post/
)
echo 1 > /sys/devices/system/cpu/cpu5/online
;;
esac

I’ll appreciate any help. Thank you.

P.S.
I’m lucky that you discussed this behavior these past few days since I just installed fedora today on a whim.