Running xrandr wakes up the dGPU

TLDR; Running the configuration utility xrandr wakes up the dedicated GPU on your machine. This is not a problem on a desktop but running it periodically on a laptop will drain your battery and might have other unintended consequences.

The rest of the blog describes the issue I faced due to running xrandr repeatedly, how I identified and circumvented the problem. Let’s begin.

I have a new all AMD laptop, the Asus G513QY, running Arch Linux with the i3 window manager. I use the i3status-rust status bar. On it, I have a toggle button to control the second monitor connected via HDMI.

The toggle button on i3status-rust bar

The toggle button accepts the following parameters:

[[block]]
block = "toggle"

text = "HDMI"
command_state = "xrandr --listactivemonitors | grep HDMI1"
command_on = "~/bin/display/activate_hdmi.sh"
command_off = "~/bin/display/laptop_only.sh"
interval = 10

For the command_state parameter, I run xrandr --listactivemonitors | grep HDMI1 to determine if my HDMI monitor is connected. This command is run every 10 seconds. I’ve used this configuration on my previous laptop as well.

After the initial setup on the new laptop, I noticed some weird behavior. Every few seconds my mouse would get stuck, and inputs from the keyboard would be skipped. Reviewing the kernel logs I noticed the following lines appear multiple times:

[   50.657638] amdgpu 0000:03:00.0: [drm] Cannot find any crtc or sizes

Careful observation revealed that these lines were appearing exactly when I was experiencing the input lag. I could tell that the issue was related to the AMD GPU but not what was causing it.

Using amdgpu.runpm=0 as a temporary fix

Searching on the Internet revealed that on newer AMD graphics cards, system stability could be improved by setting amdgpu.runpm=0 kernel parameter. The Linux AMD GPU driver documentation page states the following about the runpm parameter:

Override for runtime power management control for dGPUs in PX/HG laptops. The amdgpu driver can dynamically power down the dGPU on PX/HG laptops when it is idle. The default is -1 (auto enable). Setting the value to 0 disables this functionality.

This kernel parameter fixed the lags for me but increased the power draw. When I was setting up the laptop, I had a lot of other issues to deal with, so fixing a high power draw was not on the top of my priority list.

Identifying the real issue

Recently, I was able to dedicate some time to investigate this further. I created a ticket on the Linux AMD driver issue tracker where I was informed that the log messages are harmless and get printed when the dGPU is powered up without a display attached. So that meant that something was waking up the dGPU periodically.

The amdgpu.runpm=0 kernel parameter disables power management for the GPU. This was fixing the issue as the GPU was never powering down at all. Now that I knew the reason for the issue, the next step was to identify what/who was causing it.

Closing down applications one by one revealed that the lag stopped once i3status-rust was shut down. Next, I removed blocks from the status bar 1-by-1. That helped narrow down the problem to the HDMI block, which runs the xrandr configuration utility every 10 seconds.

Working around the problem

Once I knew why and what was causing the issue, working around the problem was easy. I needed to find another way to identify if my external monitor was connected. I came up with the following,

cat /sys/class/drm/*HDMI*/dpms | grep On

Final thoughts

While I can understand why the xrandr command would need to wake up the dedicated GPU, I was not expecting it to cause lags. My previous laptop that had a dedicated NVIDIA MX150, was running the same command but did not have these problems.

With this issue fixed, my battery discharge rate dropped from 19W to around 13W without any USB devices connected. My previous laptop had a battery backup of around 5.5 hours, and I wonder if I could have gotten a lot more out of it if I had been aware of this problem.

The i3status-rust bar wiki mentions running xrandr to detect if an external monitor is connected. I’ve opened an issue on their issue tracker to add a warning about xrandr waking up the dedicated GPU.

3 Comments

  1. Noice

  2. For those finding this post looking for how to get current output geometry without waking up a dgpu: simply add –current to your xrandr query within any scripts that use them.

Leave a Reply