Optimus laptop issues


#161
/usr/bin/echo '\_SB.PCI0.PEG0.PEGP._ON' | tee /proc/acpi/call

results in no access. So we’re back to scripts?
I changed the script

[Unit]
Description=nvidia gpu on/off hook
Before=sleep.target
StopWhenUnneeded=yes

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/turn_on_gpu.sh 
ExecStop=/usr/bin/turn_off_gpu_wake.sh

[Install]
WantedBy=sleep.target

result of status

sudo systemctl status gpu-on-off-sleep.service
● gpu-on-off-sleep.service - nvidia gpu on/off hook
   Loaded: loaded (/etc/systemd/system/gpu-on-off-sleep.service; enabled; vendor preset: disabled)
   Active: inactive (dead)

lut 04 20:52:21 jakub-pc systemd[1]: gpu-on-off-sleep.service: Failed to enqueue stop job, ignoring: Tran>
lut 04 20:52:21 jakub-pc systemd[1]: Starting nvidia gpu on/off hook...
lut 04 20:52:21 jakub-pc turn_on_gpu.sh[2577]: Trying \_SB.PCI0.PEG0.PEGP._ON: /usr/bin/turn_on_gpu.sh: l>
lut 04 20:52:21 jakub-pc turn_on_gpu.sh[2577]: works!
lut 04 20:52:21 jakub-pc systemd[1]: Started nvidia gpu on/off hook.
lut 04 20:52:21 jakub-pc systemd[1]: gpu-on-off-sleep.service: Unit not needed anymore. Stopping.
lut 04 20:52:21 jakub-pc systemd[1]: Stopping nvidia gpu on/off hook...
lut 04 20:52:51 jakub-pc turn_off_gpu_wake.sh[2581]: Trying \_SB.PCI0.PEG0.PEGP._OFF: /usr/bin/turn_off_g>
lut 04 20:52:51 jakub-pc turn_off_gpu_wake.sh[2581]: works!
lut 04 20:52:51 jakub-pc systemd[1]: Stopped nvidia gpu on/off hook.


#162
#/etc/systemd/system/gpu-on-off-sleep.service
#sudo systemctl enable gpu-on-off-sleep.service
#sudo systemctl start gpu-on-off-sleep.service
#sudo systemctl status gpu-on-off-sleep.service
#sudo systemctl daemon-reload

[Unit]
Description=nvidia gpu on/off hook
Before=sleep.target
StopWhenUnneeded=yes

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/turn_gpu_on.sh 
ExecStop=/usr/bin/turn_gpu_off.sh

[Install]
WantedBy=sleep.target

edit scripts contents

turn_on_gpu.sh:

#!/bin/bash

echo _SB.PCI0.PEG0.PEGP._ON | sudo tee /proc/acpi/call
sleep 5

exit

turn_off_gpu.sh:

#!/bin/bash

sleep 20
echo _SB.PCI0.PEG0.PEGP._OFF | sudo tee /proc/acpi/call

exit

sudo chmod 755 /usr/bin/turn_on_gpu.sh
sudo chmod 755 /usr/bin/turn_off_gpu.sh

EDIT: added sleep to each of the scripts, adjust if necessary. and:
sudo systemctl disable gpu-on-off-sleep.service
sudo systemctl enable gpu-on-off-sleep.service
sudo systemctl daemon-reload

cross-fingers, knock on wood, dont step on any cracks, then see if it works :sweat_smile:


#163

I did exactly what you posted, freeze at sleep again. I will try what I have written before - with changed test script from acpi_call


#164

add a longer sleep time on the turn gpu on script so it waits a bit longer after turning on before it tried to suspend.

disable the service and try it out manually.
echo _SB.PCI0.PEG0.PEGP._ON | sudo tee /proc/acpi/call
if you try and suspend right away does it freeze?
what if you turn gpu on and wait 10s? 15s? 20s? it may just need more time before sleep


#165

Ok I don’t understand anything now here are the scripts:

turn_on_gpu.sh

#!/bin/bash
sleep 5

if lsmod | grep -q acpi_call; then
methods="
\_SB.PCI0.PEG0.PEGP._ON
"

for m in $methods; do
    echo -n "Trying $m: "
    echo $m > /proc/acpi/call
    result=$(cat /proc/acpi/call)
    case "$result" in
        Error*)
            echo "failed"
        ;;
        *)
            echo "works!"
            # break # try out outher methods too
        ;;
    esac
done

else
    echo "The acpi_call module is not loaded, try running 'modprobe acpi_call' or 'insmod acpi_call.ko' as root"
    exit 1
fi
turn_off_gpu_wake.sh

#!/bin/bash
sleep 20

if lsmod | grep -q acpi_call; then
methods="
\_SB.PCI0.PEG0.PEGP._OFF
"

for m in $methods; do
    echo -n "Trying $m: "
    echo $m > /proc/acpi/call
    result=$(cat /proc/acpi/call)
    case "$result" in
        Error*)
            echo "failed"
        ;;
        *)
            echo "works!"
            # break # try out outher methods too
        ;;
    esac
done

else
    echo "The acpi_call module is not loaded, try running 'modprobe acpi_call' or 'insmod acpi_call.ko' as root"
    exit 1
fi
gpu-on-off-sleep.service

[Unit]
Description=nvidia gpu on/off hook
Before=sleep.target
StopWhenUnneeded=yes

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/bin/turn_on_gpu.sh 
ExecStop=/usr/bin/turn_off_gpu_wake.sh

[Install]
WantedBy=sleep.target

after disabling / enabling / reloading the service and reboot just in case I’ve suspended the device
result:

sudo systemctl status gpu-on-off-sleep.service
● gpu-on-off-sleep.service - nvidia gpu on/off hook
   Loaded: loaded (/etc/systemd/system/gpu-on-off-sleep.service; enabled; vendor preset: disabled)
   Active: inactive (dead)

lut 04 21:27:14 jakub-pc systemd[1]: Starting nvidia gpu on/off hook...
lut 04 21:27:19 jakub-pc turn_on_gpu.sh[1731]: Trying \_SB.PCI0.PEG0.PEGP._ON: /usr/bin/turn_on_gpu.sh: l>
lut 04 21:27:19 jakub-pc turn_on_gpu.sh[1731]: works!
lut 04 21:27:19 jakub-pc systemd[1]: Started nvidia gpu on/off hook.
lut 04 21:27:27 jakub-pc systemd[1]: gpu-on-off-sleep.service: Unit not needed anymore. Stopping.
lut 04 21:27:27 jakub-pc systemd[1]: Stopping nvidia gpu on/off hook...
lut 04 21:27:48 jakub-pc turn_off_gpu_wake.sh[1955]: Trying \_SB.PCI0.PEG0.PEGP._OFF: /usr/bin/turn_off_g>
lut 04 21:27:48 jakub-pc turn_off_gpu_wake.sh[1955]: works!
lut 04 21:27:48 jakub-pc systemd[1]: Stopped nvidia gpu on/off hook.

So it works, right? No it doesn’t, battery life doesn’t go back up to right value even after several minutes. I have even run the original script (the one that runs at boot) and it still doesn’t do anything even though result is:

sudo /usr/bin/turn_off_gpu.sh 
Trying \_SB.PCI0.PEG0.PEGP._OFF: /usr/bin/turn_off_gpu.sh: linia 12: uwaga: podstawienie polecenia: zignorowano zerowy bajt na wejściu
works!

I will try again your solution with more sleep time in a sec.


#166

ok, then the service or the gpu scripts are getting stuck after trying them off and on.

make changes to both scripts, and btw, all that is needed in the scripts is:

turn_on_gpu.sh:

#!/bin/bash
sleep 5
echo _SB.PCI0.PEG0.PEGP._ON | sudo tee /proc/acpi/call
sleep 15

exit

turn_off_gpu.sh:

#!/bin/bash

sleep 40
echo _SB.PCI0.PEG0.PEGP._OFF | sudo tee /proc/acpi/call
sleep 5

exit

then just to be sure:

sudo chmod 755 /usr/bin/turn_on_gpu.sh
sudo chmod 755 /usr/bin/turn_off_gpu.sh

sudo systemctl disable gpu-on-off-sleep.service
sudo systemctl enable gpu-on-off-sleep.service
sudo systemctl daemon-reload

after doing exactly as it is above, please reboot and let the startup script disable the gpu after 40s
there is only a need for 1 on script and 1 off script. you dont need a separate one for boot, make sure the startup service your using points to the same gpu off script. also make sure you dont have any other services you may or may not have enabled as duplicates (only you know this).

this should turn the gpu off 40 seconds after boot (change to 60 if you like)
on sleep: turn gpu on > sleep 20 > sleep
wake: sleep 40 > turn off gpu

i added a short sleep before each acpi call also. when you test sleep/wake give it at least a minute after going to sleep before you try and wake it .

another thing, if the battery life indicator does not go up right away that doesnt mean the gpu didnt shut of, could just mean it didnt update right away. watch with powertop so you get the power usage in real time.


#167

I did exactly what you said - changed contents of turn_off_gpu.sh to one from your post and did everything else you stated. Now gpu doesn’t get turned off at all. Issuing the command from terminal also doesn’t do anything.


#168

not even on boot?


#169

No, not even at boot.


#170

do you still have gpuonatsuspend.service and gpuoffatsuspend.service enabled?
just one service for boot (multi-user.target) and the other service for sleep/wake.

make sure there are no unneeded/leftover services running. can you post the service your using to turn off gpu at boot.

along with status
systemctl status nameofbootservice
systemctl status nameofsleepwakeservice


#171

No, both are off. Also I just did again my script from test-script and results are as this:
powertop says discharge after boot (gpu off) ~4,3W
With gpu on ~8,5W
after suspend/wake ~5,5-6W

!?

Ok it looks like after about 10 minutes it goes down back to 4,3W. It’s strange, I’m going to observe this for a bit


#172

so power does go to desired level after a few?


#173

Nah false alarm it went to desired just for a bit and now it’s steady at above 6W


#174

ok so right now from terminal this command does nothing?
echo _SB.PCI0.PEG0.PEGP._OFF | sudo tee /proc/acpi/call
what about like this (from a clean new terminal):
sudo echo _SB.PCI0.PEG0.PEGP._OFF | tee /proc/acpi/call


#175

Nothing, no change. The second one says no access. But it looks like something is happening - with nvidia on power consumption is at 8.5W and now it’s around 6W all the time. This is really strange. Maybe some service is running in the background? Highest usage I see is on firefox, but it’s to be expected as this is only application I’m running atm.


#176

does running the original gpu off test script work to shut it off? (the one from the acpi_call/examples/ folder) ?

any output from:
systemctl --failed --all


#177

Just thought I would mention something. I’ve been wrestling with these systemd units for months to get certain functions to work on Manjaro.

I’ve only recently been playing with this option, so don’t expect a great explanation. It seems to be necessary to load certain things in the user environment that still must be run as root.

I believe video drivers are one of the things that need loading via the users environment. I have been playing around with this for a while, and just yesterday I made a very promising discovery.

Adding -E to the sudo command works to preserve the users environment while still allowing the command to be executed as root in a systemd unit. I only got this to work hours ago, so I’m still in the experimental stage.

Here is an example of launching a script via root (systemd system unit) using sudo as the user, while also allowing the command be run in the users environment.

I haven’t gotten to testing it on loading video drivers yet as I have been working with suspend issues and other system components. If this works for video drivers it will be a huge improvement on the suspend issues I’ve been working on.

No promises but here’s a simple example:

ExecStart=/usr/bin/sudo -E  /home/htpc/bin/usb-suspend.sh

The script is located in the users home directory and owned by the user. This ensures the users environment is used for execution. The unit itself must be a system unit, (not a --user unit).

I have also tested as:

ExecStart=/usr/bin/sudo -E  /home/$USER/bin/usb-suspend.sh

This is a little more of a complication because then User=root must be specified in the service file. For simplicity during most tests I have been using the explicit paths.

As I stated I’m only in the early testing stages with this method, but it seems to work when nothing else does.

Hope that helps.


#178

No, the test-script doesn’t change anything either atm.

sudo systemctl --failed --all
[sudo] hasło użytkownika jakub: 
0 loaded units listed.
To show all installed unit files use 'systemctl list-unit-files'.

@tbg thanks for suggestion, I will look into that tomorrow


#179

After further observation it looks like battery life issue is not related to gpu switching, but touchpad driver is causing abnormal wakes(wakelocks?) after waking system from sleep (ELAN1200 has some known issues). As this is not related to the topic, and the last solution is working properly when it comes to gpu switching and suspend/wake I think we can safely say the problem is solved. I’m going to update the solution post now.


#180

it only took 180 posts, were good at this :sunglasses:
there’s no shortage of touchpad threads so get your reading glasses, if nothing works create a new thread.