protonscr

Against the Storm: uncached battery sysfs reads in ntdll cause ~82 ms main-thread stall every ~1 s on laptops with slow embedded controllers

protonclosed appid 1336490
ValveSoftware/Proton#9949 · opened 2026-07-05 by johndphipps-design · updated 2026-07-05 · 1 comments · github · game page · search this game
Jjohndphipps-design 2026-07-05 github

Compatibility Report

  • Name of the game with compatibility issues: Against the Storm
  • Steam AppID of the game: 1336490

System Information

  • GPU: NVIDIA RTX 3070 Mobile (hybrid with AMD Cezanne iGPU)
  • Video driver version: NVIDIA 580.159.04
  • Kernel version: 7.0.12 (Fedora 43)
  • Link to full system information report: https://gist.github.com/johndphipps-design/440efe100d0476da69f0c1d39c7a8b48
  • Proton version: GE-Proton10-34 (reproduced on multiple Proton versions; root
    cause verified present in current upstream Wine, see below)

Issue description

The game polls Windows battery status (GetSystemPowerStatus /
NtPowerInformation(SystemBatteryState)) ~46×/s from its main thread — it is a
Unity 2021 title and Unity exposes SystemInfo.batteryStatus.

Wine answers every call by re-reading /sys/class/power_supply/* — see
fill_battery_state() in dlls/ntdll/unix/system.c (current upstream master,
~line 4347): opendir + per-attribute reads of type/status/voltage_now/
charge_full/charge_now on each call, no caching. Windows answers this API from
cached data.

The Linux ACPI battery driver caches attribute values for 1 s
(/sys/module/battery/parameters/cache_time = 1000 default). Once per second
one read misses that cache and performs a synchronous embedded-controller
query. On this laptop (Lenovo IdeaPad, Ryzen 7 5800H) that query takes ~66 ms
with the game's main thread blocked:

read of BAT0/energy_now after cache expiry: 66.1 ms
immediate cached re-read:                    0.093 ms

Result: an ~82 ms frame spike every ~1.07 s (1 s kernel cache + 66 ms stall +
frame catch-up), i.e. a metronomic stutter for the whole play session.
MangoHud frametime logs: median spike 82 ms, median interval 1.071 s, ~100
spikes per 90 s. strace shows the main thread blocked ~65 ms in read() of
/sys/class/power_supply/ADP0/online, BAT0/* on the same period.

Not reproducible on native Windows (API is cached there) or on desktops
(no battery to read), which makes it look like a game/hardware problem —
it is likely underdiagnosed among laptop players. Main menu is unaffected
(no battery polling there), gameplay is affected from the first second.

Confirmed workaround

echo 600000 > /sys/module/battery/parameters/cache_time removes the stutter
completely (verified with frametime logs). Suggested proper fix: cache battery
state in ntdll for a few seconds, or refresh it off the calling thread.

Per-game workaround (auto-toggle via Steam launch options)

To avoid leaving the long cache system-wide, the following applies it only
while the game runs and restores the default on exit (including crashes):

Root-owned helper /usr/local/bin/battery-cache-set (validates input,
can only write this one file):

#!/bin/bash
if [[ "$1" =~ ^[0-9]{3,7}$ ]]; then
    echo "$1" > /sys/module/battery/parameters/cache_time
else
    echo "usage: battery-cache-set <milliseconds>" >&2
    exit 1
fi

Sudoers rule (file in /etc/sudoers.d/, mode 440, replace YOURUSER):

YOURUSER ALL=(root) NOPASSWD: /usr/local/bin/battery-cache-set

User wrapper script (executable, anywhere in your home):

#!/bin/bash
restore() { sudo -n /usr/local/bin/battery-cache-set 1000; }
trap restore EXIT
sudo -n /usr/local/bin/battery-cache-set 600000
"$@"

Steam launch options for the game:

/path/to/wrapper %command%

Note: while the long cache is active, desktop battery percentage and
low-battery warnings update lazily between AC plug/unplug events.

Reproduction

  1. Laptop whose EC battery query is slow (measure: read a BAT*/energy_now or
    charge_now attribute twice, >1 s apart, and time the reads).
  2. Launch Against the Storm under any Proton, load a settlement.
  3. Observe frametime graph: ~80 ms spike every ~1 s.

MangoHud frametime CSVs (before / after workaround) and system information:
https://gist.github.com/johndphipps-design/440efe100d0476da69f0c1d39c7a8b48
strace captures available on request.

Kkisak-valve maintainer 2026-07-05 github

Hello @johndphipps-design, we're using one issue report per unofficially supported game title, so I've gone ahead and transferred this issue report to https://github.com/ValveSoftware/Proton/issues/6489#issuecomment-4886783240.

Proton versions

Upstream links