Chapter 11. Controlling power management transitions
You can control power management transitions to improve latency.
Prerequisites
- You have root permissions on the system.
11.1. Power saving states
Modern processors actively transition to higher power saving states (C-states) from lower states. Unfortunately, transitioning from a high power saving state back to a running state can consume more time than is optimal for a real-time application. To prevent these transitions, an application can use the Power Management Quality of Service (PM QoS) interface.
With the PM QoS interface, the system can emulate the behavior of the idle=poll
and processor.max_cstate=1
parameters, but with a more fine-grained control of power saving states. idle=poll
prevents the processor from entering the idle
state. processor.max_cstate=1
prevents the processor from entering deeper C-states (energy-saving modes).
When an application holds the /dev/cpu_dma_latency
file open, the PM QoS interface prevents the processor from entering deep sleep states, which cause unexpected latencies when they are being exited. When the file is closed, the system returns to a power-saving state.
11.2. Configuring power management states
You can control power management transitions by configuring power management states. More specifically, you can write a value to the /dev/cpu_dma_latency
file to change the maximum response time for processes, in microseconds. Or you can reference this file in an application or a script.
Prerequisites
- You have administrator privileges.
Procedure
Create the
cpu_dma_latency
file.$ touch /dev/cpu_dma_latency
Open the file in a text editor.
$ sudo {EDITOR} /dev/cpu_dma_latency
Add the following program lines to the file.
#include <errno.h> #include <fcntl.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> FILE *fp; void start_low_latency() { char target = '0'; fp= fopen("/dev/cpu_dma_latency", "r+"); if (fp == NULL) { fprintf(stderr, "Failed to open PM QOS file: %s", strerror(errno)); exit(errno); } fputc(target, fp); } void stop_low_latency() { if (fp == NULL) fclose(fp); } int main() { start_low_latency(); //do some latency-sensitive tasks here stop_low_latency(); return 0; }
Compile the program.
$ sudo gcc $/dev/cpu_dma_latency -o ${output_name_of_choice}
Run the program.
$ sudo gcc $/dev/cpu_dma_latency -o ${output_name_of_choice}