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

  1. Create the cpu_dma_latency file.

    $ touch /dev/cpu_dma_latency
  2. Open the file in a text editor.

    $ sudo {EDITOR} /dev/cpu_dma_latency
  3. 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;
    }
  4. Compile the program.

    $ sudo gcc $/dev/cpu_dma_latency -o ${output_name_of_choice}
  5. Run the program.

    $ sudo gcc $/dev/cpu_dma_latency -o ${output_name_of_choice}