80 W out of 175: how my RTX 5080 Laptop ran at half power under Ubuntu
I thought 21 tokens per second was all my laptop's RTX 5080 could manage running Qwen3.8-27B. Turns out the card was working at 80 watts out of the 175 it is rated for.
I noticed by accident, while measuring why a local model was computing slower than its memory bandwidth said it should. Under full load the card sat at exactly 79.9 W and would not go above it under any conditions. And nvidia-smi reported the situation honestly all along: current limit 80, maximum 175.
Not even root could raise it:
$ sudo nvidia-smi -pl 175
Changing power management limit is not supported in current scope
Two days of dead ends
Built llama.cpp with CUDA instead of Vulkan — zero difference in generation. Tried multi-token prediction — worse on long context. Restarted nvidia-powerd, switched power profiles, went into the BIOS. Nothing.
The cause was not Linux
It was one missing command. OMEN Gaming Hub on Windows sends the firmware two WMI commands: the thermal profile and the power limit unlock. The hp-wmi driver in the kernel sends only the first. The second one, for my board, it does not send at all.
How it was found
Claude Code took it from there, and it did not work by guessing. It dumped the ACPI tables of my own laptop, disassembled them and read what exactly the firmware does in response to those commands. It found the precise packet layout, found that two field names are swapped in other people's implementations, and found that yet another method those projects call is addressed to the AMD integrated graphics, not to the NVIDIA card at all.
The interesting part, though, is that four attempts failed. The firmware accepted the unlock flags, confirmed them on read-back, and the power did not move by a single watt. What was missing was a third command both of us had considered optional: reading the fan count. An ordinary data query — what could it possibly change?
In the stock kernel driver that function is called hp_wmi_get_fan_count_userdefine_trigger. The word "trigger" in the name was the answer: the read has a side effect in the embedded controller. We put the call first in the sequence — and the limit came off.
What came out of it
| Before | After | |
|---|---|---|
| Power | 79.4 W | 169.7 W |
| GPU clock | 1426 MHz | 2141 MHz |
| Generation | 20.8 tok/s | 31.2 tok/s |
| Prefill | 697 tok/s | 1020 tok/s |
Plus 50% generation speed on the same card and the same quant of the model.
That is a benchmark, though, and a benchmark is short. On real work — an agent writing code, prompts from 55 thousand tokens up — median generation rose from 17.2 to 24.4 tok/s, that is by 42%. And on the very longest prompts there is no gain at all: there the bottleneck is no longer watts but memory bandwidth, and the extra power has nowhere to go. The shorter the prompt, the bigger the win.
About temperature
Checked under sustained load: the temperature reaches a plateau of 87 °C and stays there. That is exactly the card's target temperature — it aims for it on its own and from there gives power back smoothly to hold it. Hardware thermal slowdown never engaged once. So this is not overclocking on the edge, it is the stock mode that the laptop's firmware simply would not let me turn on.
The irony
In kernel 7.1 all of this is already done, and for my exact board at that — the commit landed on 10 April. Set platform_profile to performance and the driver runs the whole sequence itself. But Ubuntu 26.04 ships kernel 7.0, and 7.1 will never arrive there: the next HWE kernel comes from an interim release, which means it will already be 7.2, and not before February. Fedora, for what it is worth, has had 7.1.8 since 11 August — in the current release and in the previous one.
While we wait, a kernel module of my own is running with a watchdog timer: if the temperature supervisor dies for any reason, the kernel drops the unlock by itself within five seconds. Verified the crudest way possible, with kill -9.