GPU Troubleshooting Saga
I went on a journey fixing a GPU issue, and now you have to read about it.
I built an Arch Linux machine earlier this year and for longer than I’d like to admit I’ve noticed my RX 7600 XT GPU fans spinning when my computer was supposed to be at an idle state. My suspicions immediately went to some sort of crypto miner. I almost wish it was, it probably would have been a much easier problem to solve.
A little background on myself, I’m kind of an idiot and I don’t know what I’m doing but I don’t do it professionally, so don’t worry. This is a hobby. So keep that in mind for the rest of this troubleshooting saga.
Once when locking my KDE Plasma Arch desktop and watching the screen go to sleep, I noticed my GPU fans spinning up and I thought “That’s weird, it must be a crypto miner.” I started to make sure I closed all my apps, browser windows and tabs because, who knows, and still it kept happening, I knew eventually I’d have to deal with it.

The time came this weekend. I almost couldn’t do anything else my hyper fixation on solving this problem was so compelling. And it took almost 2 full days to achieve an acceptable solution. Naturally, I went to my buddy Claude AI.

I encountered many issues with Claude during this troubleshooting, it kept having ‘AHA!’ moments where it thought it solved the problem, but of course didn’t. Though, it did have some really interesting insights. It took me through crypto-miner suspicions which were eventually ruled out, some other red herrings and hallucinations that I guess could be blamed on poor frustrated prompts by yours truly, but eventually we together both found a sort of hacky, but still overall reasonable solution to the actual issue I was having.
I still don’t know what exactly the bug, if any, was. I am not smart enough to figure it out myself. Hence my use of AI. It seems that there is an issue with the way either Wayland or KDE Plasma and it’s kscreenlocker/powerdevil interact with my GPU or perhaps my dual mis-matched monitor setup. Whatever it was caused the GPU to max out usage at nearly 3000 MHz and 115W whenever the desktop was in a locked, idle state and the screen in power saving mode. It didn’t make sense to me, and the way it would ramp up and ramp down as soon as I touched peripherals is what made me suspect foul play at first. In a machine as custom built as this one, both in hardware assembly and OS installation, I couldn’t stand for either a compromised machine, and bug would be just plain irritating.
But this is what we like about Linux isn’t it? If the computer doesn’t do something the way we want or expect, we can typically alter some config files, run some commands, and make it. This time proved a bit trickier, until I started thinking differently. After toggling settings in .config/kwinrc (wtf is compositing, actually??) changing backgrounds, blur effects, etc. Nothing I was doing was going to do anything to fix the underlying problem. I was looking at it the wrong way. While Claude proved rather useful in crafting quick scripts to gather logs and then even parsing them for anything related to what I might have been encountering at an impressive speed, I was still getting nowhere.
A diagnostic script and parsing by Claude discovered a potential KWin issue, a reported ‘segfault’ in slotDesktopRemoved which I would have had no idea would have been related, or if it actually is. So when going down this path any KWin fixes would crash powerdevil, and restarting it would revert KWin changes, it was an indescribable mess and unfortunately I’m not the best person to report on it. Eventually I started editing grub config files and I knew I was going off the rails following this chatbots suggestions, but it’s not easy to find resources for something this specific and when you’re as deep as I am into an issue like this and dead-set on fixing it, it’s easy to get caught up in dead ends like these. I had to think a bit differently. All the tools were right in front of me, I just needed to put them together.
At one point during troubleshooting I noticed while monitoring resource usage that running the GPU log fetch/diagnostic script caused the GPU to immediately return to the expected and desired low power state one expects when their computer is at idle with little processes running, and upon reporting this to Claude it immediately whipped up a systemd service for me to enable what it posited was the act of reading GPU sysfiles, and created a systemd timer to use it to trigger a normal power state on a regular interval. This was my final dead end, plus it didn’t do anything to solve the problem.
But then I remembered, at one point using
cat /sys/class/drm/card1/device/power_dpm_force_performance_level
and retrieving a single word of ‘auto’ to give system information to Claude for debugging. I soon realized this was a tunable parameter, and quickly got Claude scripting a different systemd service this time.

By using the tools available I was able to create a systemd service that watches for a locked desktop state and then throttles the performance level of the GPU accordingly. You can read below for the precise steps to my digital duct-tape solution. It feels bit hacked together, but the tools are all there for situations like this, right? Everything in Linux is a file that can be manipulated, the GPU tunables were accessible. All the user needs to do is write a few bash scripts to tune the tunables and setup some files for a systemd service to watch the desktop for a locked state. It’s all right there to customize and use. And the solution works. My power draw at idle now sits below 10W and MHz have dropped to <400. Although it still jumps around, see above where it was at a constant 115W and 3000MHz when locked! Definitely an improvement. Even if it is hacky it feels like this kind of work around is exactly what Linux and FOSS is all about. Total control and freedom to do as you please with your hardware and software.
Except the final joke is on me, as soon as I tested out X11 (which I don’t know why I didn’t earlier, I knew it was likely a Wayland issue) the issue seemed to go away entirely, no more spikes. Ah well, at least I learned some new things!

Thanks for tuning in!
Solution
Use X11 or create a systemd service that automatically throttles the discrete GPU (RX 7600 XT) to low performance mode when screen locks, and restores to auto mode when unlocked.
System Information
- OS: Arch Linux x86_64
- Kernel: 6.12.56-1-lts
- DE: KDE Plasma 6.5.1
- GPU (Discrete): AMD Radeon RX 7600 XT (card1 - PCI ID 1002:7480)
- GPU (Integrated): AMD Raphael iGPU (card0 - PCI ID 1002:164E)
- Date Implemented: November 2, 2025
Implementation Steps
1. Created GPU Throttle Script
File: /usr/local/bin/gpu-lock-throttle.sh
#!/bin/bash
GPU_CARD="/sys/class/drm/card1/device/power_dpm_force_performance_level"
LOG_FILE="/var/log/gpu-throttle.log"
log_message() {
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" >> "$LOG_FILE"
}
case "$1" in
lock)
echo "low" > "$GPU_CARD"
log_message "GPU throttled to low (screen locked)"
;;
unlock)
echo "auto" > "$GPU_CARD"
log_message "GPU restored to auto (screen unlocked)"
;;
*)
echo "Usage: $0 {lock|unlock}"
exit 1
;;
esac
Made executable:
sudo chmod +x /usr/local/bin/gpu-lock-throttle.sh
2. Created Lock Monitor Script
File: /usr/local/bin/gpu-lock-monitor.sh
#!/bin/bash
# Monitor DBus for lock/unlock signals
dbus-monitor --session "type='signal',interface='org.freedesktop.ScreenSaver'" | while read -r line; do
if echo "$line" | grep -q "boolean true"; then
# Screen locked
pkexec /usr/local/bin/gpu-lock-throttle.sh lock
elif echo "$line" | grep -q "boolean false"; then
# Screen unlocked
pkexec /usr/local/bin/gpu-lock-throttle.sh unlock
fi
done
Made executable:
sudo chmod +x /usr/local/bin/gpu-lock-monitor.sh
3. Created Systemd User Service
File: ~/.config/systemd/user/gpu-throttle-on-lock.service
[Unit]
Description=Throttle GPU on screen lock
After=graphical-session.target
[Service]
Type=simple
ExecStart=/usr/local/bin/gpu-lock-monitor.sh
Restart=on-failure
[Install]
WantedBy=default.target
4. Created Polkit Rule for Password-less Execution
File: /etc/polkit-1/rules.d/50-gpu-throttle.rules (change username)
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.policykit.exec" &&
action.lookup("program") == "/usr/local/bin/gpu-lock-throttle.sh" &&
subject.user == "your_name_here") {
return polkit.Result.YES;
}
});
5. Enabled and Started Service
systemctl --user enable gpu-throttle-on-lock.service
systemctl --user start gpu-throttle-on-lock.service
Verification
Check Service Status
systemctl --user status gpu-throttle-on-lock.service
Check Current GPU Performance Level
cat /sys/class/drm/card1/device/power_dpm_force_performance_level
- Should show
lowwhen locked - Should show
autowhen unlocked
Check GPU Activity
cat /sys/class/drm/card1/device/gpu_busy_percent
View Logs
sudo cat /var/log/gpu-throttle.log
Results
- GPU throttles to ~15W max and few hundred MHz when locked (down from higher power/frequency)
- GPU activity may still show 100% utilization but at drastically reduced power consumption
- Successfully works around kscreenlocker/powerdevil bug
- Additional benefit: energy savings when screen is locked
Technical Details
AMD GPU Power Management Levels
- auto: Default automatic power management (normal)
- low: Lowest performance/power state
- high: Highest performance state
- manual: Manual control via other sysfs interfaces
DBus Signal Monitoring
The solution monitors the org.freedesktop.ScreenSaver interface for lock/unlock signals:
boolean true= screen lockedboolean false= screen unlocked
Maintenance
Disable Service (if needed)
systemctl --user stop gpu-throttle-on-lock.service
systemctl --user disable gpu-throttle-on-lock.service
Manually Test Throttling
# Throttle
sudo /usr/local/bin/gpu-lock-throttle.sh lock
# Restore
sudo /usr/local/bin/gpu-lock-throttle.sh unlock
If GPU Cards Change
If you reinstall, update drivers, or cards get renumbered, verify which card is which:
for card in /sys/class/drm/card?; do
echo "=== $(basename $card) ==="
cat $card/device/uevent 2>/dev/null | grep -E "PCI_ID|DRIVER"
done
- Update
GPU_CARDpath in/usr/local/bin/gpu-lock-throttle.shif needed
References
- AMD GPU sysfs documentation:
/sys/class/drm/card*/device/power_dpm_force_performance_level - DBus ScreenSaver interface:
org.freedesktop.ScreenSaver - Systemd user services:
~/.config/systemd/user/