feat: experimental NVIDIA power control via RM ioctl interface

Adds an experimental power-cap mode using the undocumented RM ioctl
interface (based on panchovix's LACT PR #1205) to set power limits
below the VBIOS minimum (down to 30 W).

- hal/rm_power.py: RM ioctl power-cap read/write/reset + runtime probe
- limits.py: power_cap_mode (nvml/ioctl) with support detection
- config.py: persist power_cap_mode per GPU
- profiles: record/apply power_cap_mode
- server.py: POST /api/limits validates ioctl support (409 on failure)
- cli.py: profile save falls back to persisted mode
- client.py: power_cap_mode in Limits
- frontend: toggle + warning with panchovix attribution (LACT #1205)
- tests: test_rm_power.py (unit) + integration coverage
- Makefile: add test_rm_power.py to make test

Also includes automated linter reformatting (prettier, ruff, shellcheck,
isort, markdownlint) that the linter would apply anyway.
This commit is contained in:
ARIA committed 2026-09-17 22:44:27 +02:00
1 parent a8462e696c
commit e148c83622
21 files changed
+1641 -271

No files matched your search

+6
View File
@@ -98,7 +98,11 @@ export interface LimitsState {
power_limit_w: number | null;
default_power_limit_w: number | null;
min_power_limit_w: number | null;
min_power_limit_w_native: number | null;
max_power_limit_w: number | null;
// "nvml" (default) or "ioctl" (experimental RM power control)
power_cap_mode: "nvml" | "ioctl";
rm_power_supported: boolean;
// Clock offsets — current values
gpc_offset_mhz: number | null;
mem_offset_mhz: number | null;
@@ -136,6 +140,8 @@ export interface ProfileData {
curve_deltas: Record<string, number>;
mem_offset_mhz: number | null;
power_limit_w: number | null;
// "nvml" (default) or "ioctl" (experimental RM power control)
power_cap_mode: "nvml" | "ioctl" | null;
fan_curve: FanPoint[] | null;
fan_targets: number[] | null;
}