Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disabling CPU idle C-states from kernel-mode driver

I'm writing an audio device driver which needs to process device interrupts in real-time. When the CPU enters C3 state, interrupts are delayed, causing problems to the driver.

Is there a way for the driver to tell the OS not to enter idle C-states?

What I've found is that idle C-states can be disabled from user-space:

const DWORD DISABLED = 1;
const DWORD ENABLED = 0;
GUID *scheme;
PowerGetActiveScheme(NULL, &scheme);
PowerWriteACValueIndex(NULL, scheme, &GUID_PROCESSOR_SETTINGS_SUBGROUP, &GUID_PROCESSOR_IDLE_DISABLE, DISABLED);
PowerSetActiveScheme(NULL, scheme);

However, it is a global setting, which can be overwritten by the user or another application (e.g., when the user changes the Power Plan).

What I need is something like PoRegisterSystemState, but not for S- and P-states, but for C-states.

Reference: Microsoft Learn — Preventing System Power State Changes

How do I achieve this?

like image 394
Svetoslav Ilkov Enchev Avatar asked Sep 09 '25 23:09

Svetoslav Ilkov Enchev


1 Answers

This answer was provided by Svetoslav Ilkov Enchev.


It turns out there isn't a supported way to disable idle C-states from kernel space, and there isn't a service in user space to provide a common API to do this.

The way to control C-states is from "Processor Power Management" in "Change advanced power settings" dialog, through registry, or via C API PowerWriteACValueIndex/PowerWriteDCValueIndex.

The original problem was delayed interrupts in all but C1 idle state, so I needed to disable both C2, C3 and deeper idle states. The issue with disabling all idle C-states, including C1 (as shown in the example code PowerWriteACValueIndex(NULL, scheme, &GUID_PROCESSOR_SETTINGS_SUBGROUP, &GUID_PROCESSOR_IDLE_DISABLE, DISABLED)) is that the CPU usage is reported as 100%, and some applications (DAWs) get confused.

The solution is to disable all but C1 idle state, which can be done by setting the following values in the Processor Power Management:

  • Processor idle threshold scaling -> Disable scaling;
  • Processor idle promote threshold -> 100%;
  • Processor idle demote threshold -> 100%.

Perhaps I'll create a service that does just that, that will use the PowerWriteACValueIndex/PowerWriteDCValueIndex API.

like image 94
2 revsCPPUIX Avatar answered Sep 12 '25 13:09

2 revsCPPUIX