Skip to content

Instantly share code, notes, and snippets.

@locnnil
Created December 18, 2024 22:04
Show Gist options
  • Save locnnil/363c315581f983c96bf5dac9e771a5c9 to your computer and use it in GitHub Desktop.
Save locnnil/363c315581f983c96bf5dac9e771a5c9 to your computer and use it in GitHub Desktop.
Playing with CPU PM Quality Of Service Interface (/dev/cpu_dma_latency)
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <signal.h>
#include <sys/stat.h>
#include <errno.h>
static int32_t latency_target_value = 0;
static int latency_target_fd = -1;
void err_doit(int err, const char *fmt, va_list ap)
{
if (err)
fprintf(stderr, "%s\n", strerror(err));
vfprintf(stderr, fmt, ap);
return;
}
/* Print an error message, plus a message for err, and return */
void err_msg_n(int err, char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
err_doit(err, fmt, ap);
va_end(ap);
return;
}
/* Latency trick
* if the file /dev/cpu_dma_latency exists,
* open it and write a zero into it. This will tell
* the power management system not to transition to
* a high cstate (in fact, the system acts like idle=poll)
* When the fd to /dev/cpu_dma_latency is closed, the behavior
* goes back to the system default.
*
* Documentation/power/pm_qos_interface.txt
*/
static void set_latency_target(void)
{
struct stat s;
int err;
errno = 0;
err = stat("/dev/cpu_dma_latency", &s);
if (err == -1) {
err_msg_n(errno, "WARN: stat /dev/cpu_dma_latency failed");
return;
}
errno = 0;
latency_target_fd = open("/dev/cpu_dma_latency", O_RDWR);
if (latency_target_fd == -1) {
err_msg_n(errno, "WARN: open /dev/cpu_dma_latency");
return;
}
errno = 0;
err = write(latency_target_fd, &latency_target_value, 4);
if (err < 1) {
err_msg_n(errno, "# error setting cpu_dma_latency to %d!", latency_target_value);
close(latency_target_fd);
return;
}
printf("# /dev/cpu_dma_latency set to %dus\n", latency_target_value);
}
void handle_sigint(int sig) {
if (latency_target_fd >= 0) close(latency_target_fd);
printf("\nCaught signal %d (Ctrl+C). Exiting...\n", sig);
exit(0);
}
int main()
{
signal(SIGINT, handle_sigint);
set_latency_target();
while (1){}
return 0;
}
# Compiler and flags
CC = gcc
CFLAGS = -Wall -Wno-nonnull -Wextra -Wno-sign-compare
# Target names
TARGET = qos
SRCS = main.c
OBJS = $(SRCS:.c=.o)
# Default target
all: $(TARGET)
# Link the executable
$(TARGET): $(OBJS)
$(CC) -o $@ $^ $(CFLAGS)
# Compile .c files into .o
%.o: %.c
$(CC) -c $< -o $@ $(CFLAGS)
# Clean up build artifacts
clean:
rm -f $(OBJS) $(TARGET)
# Phony targets
.PHONY: all clean
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment