Re: [PATCH RFC v3 2/3] KVM: x86: add KVM_CAP_CSTATE_POLICY for per-VM C-state enforcement
From: Anthony Harivel
Date: Tue Sep 15 2026 - 10:50:07 EST
> Sorry, NAK, this doesn't belong in KVM. Given that the only way this can work
> is if vCPU are pinned 1:1 to pCPUs, then it should be very doable for the cpuidle
> subystem to provide an interface to let (privileged?) userspace restrict the
> maximum C-state on a per-CPU basis.
>
> My apologies for not responding to v1 or v2, I am guilty of Jim's axiom that
> upstream doesn't respond to RFCs without code.
>
Thanks for the review Sean, and no worries about v1/v2, I understand
the "no code, no review" reality.
I agree this belongs in cpuidle rather than KVM. A per-CPU userspace
interface is the right level of abstraction; it works for our pinned
vCPU use case and is useful beyond KVM (DPDK, bare-metal NFV, etc.).
> + Option B: Use forced_idle_latency_limit_ns on the pCPU.
> + Same per-CPU limitation, and latency-based rather than
> + state-index-based, less precise.
>
> Conceptually, (b) seems like the right approach. Per-task will be a mess because
> similar to a KVM-based interface, it can probably only work if tasks are pinned
> to pCPUs.
>
> And isn't abstracting away the exact C-state via forced_idle_latency_limit_ns a
> *good* thing? Without that, userspace will need to tune its configuration for
> each individual uarch based on the properties of various C-states for a given CPU.
I also agree that latency-based is better than C-state-index-based. I
mean "Max 10us
wakeup latency" is portable across Intel/AMD/ARM without needing to
know the C-state table for each uarch and that's a real plus.
I looked at forced_idle_latency_limit_ns as a starting point, but it
doesn't quite fit as-is. Currently it is:
1. Kernel-internal only, set by cpuidle_use_deepest_state(), called
exclusively from play_idle_precise() (idle injection for thermal).
2. A governor bypass, not a governor constraint, when set, the idle
path skips the normal governor select() entirely and calls
cpuidle_find_deepest_state() directly (in kernel/sched/idle.c).
This forces the deepest state *within* the limit rather than
letting the governor choose while *capping* at the limit.
3. Not exposed via sysfs. No userspace interface exists.
For our use case, I want the governor to keep making its normal
decisions (considering load, predicted idle duration, etc.) but with
an upper bound on the exit latency it can select. More of a ceiling
than a "force deepest" override.
I see two paths forward:
(a) Add a new per-CPU sysfs attribute under cpuidle, e.g.
/sys/devices/system/cpu/cpuN/cpuidle/latency_limit_ns
that sets a governor-respected ceiling. The governor's select()
would filter out states with exit_latency_ns > limit. This is
similar to how PM QoS cpu_latency works, but per-CPU rather
than system-wide.
(b) Reuse forced_idle_latency_limit_ns but change its semantics
to be a governor ceiling rather than a governor bypass. This
would affect the idle injection path though, so might not be
desirable.
I tend to choose (a). I've already done a PoC that is working as expected.
I'll send a patch queue to the cpuidle maintainers (Rafael Wysocki,
Daniel Lezcano).
Thanks,
Anthony