Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #define _GNU_SOURCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) #include <errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <stdio.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <stdlib.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <signal.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <unistd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <fcntl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <locale.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <sys/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include <sys/stat.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #include <sys/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #include <sys/resource.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #include <sys/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #include <bpf/bpf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) #include <bpf/libbpf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) static int cstate_map_fd, pstate_map_fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) #define MAX_CPU			8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define MAX_PSTATE_ENTRIES	5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) #define MAX_CSTATE_ENTRIES	3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #define MAX_STARS		40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #define CPUFREQ_MAX_SYSFS_PATH	"/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #define CPUFREQ_LOWEST_FREQ	"208000"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #define CPUFREQ_HIGHEST_FREQ	"12000000"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) struct cpu_stat_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	unsigned long cstate[MAX_CSTATE_ENTRIES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 	unsigned long pstate[MAX_PSTATE_ENTRIES];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) static struct cpu_stat_data stat_data[MAX_CPU];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) static void cpu_stat_print(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	char state_str[sizeof("cstate-9")];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	struct cpu_stat_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	/* Clear screen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	printf("\033[2J");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	/* Header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	printf("\nCPU states statistics:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	printf("%-10s ", "state(ms)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	for (i = 0; i < MAX_CSTATE_ENTRIES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 		sprintf(state_str, "cstate-%d", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 		printf("%-11s ", state_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	for (i = 0; i < MAX_PSTATE_ENTRIES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 		sprintf(state_str, "pstate-%d", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		printf("%-11s ", state_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	for (j = 0; j < MAX_CPU; j++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 		data = &stat_data[j];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		printf("CPU-%-6d ", j);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		for (i = 0; i < MAX_CSTATE_ENTRIES; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 			printf("%-11ld ", data->cstate[i] / 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		for (i = 0; i < MAX_PSTATE_ENTRIES; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 			printf("%-11ld ", data->pstate[i] / 1000000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		printf("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) static void cpu_stat_update(int cstate_fd, int pstate_fd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	unsigned long key, value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	int c, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 	for (c = 0; c < MAX_CPU; c++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 		for (i = 0; i < MAX_CSTATE_ENTRIES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 			key = c * MAX_CSTATE_ENTRIES + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 			bpf_map_lookup_elem(cstate_fd, &key, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 			stat_data[c].cstate[i] = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 		for (i = 0; i < MAX_PSTATE_ENTRIES; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 			key = c * MAX_PSTATE_ENTRIES + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 			bpf_map_lookup_elem(pstate_fd, &key, &value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 			stat_data[c].pstate[i] = value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  * This function is copied from 'idlestat' tool function
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  * idlestat_wake_all() in idlestate.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)  * It sets the self running task affinity to cpus one by one so can wake up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)  * the specific CPU to handle scheduling; this results in all cpus can be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)  * waken up once and produce ftrace event 'trace_cpu_idle'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static int cpu_stat_inject_cpu_idle_event(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	int rcpu, i, ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 	cpu_set_t cpumask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	cpu_set_t original_cpumask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	ret = sysconf(_SC_NPROCESSORS_CONF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	rcpu = sched_getcpu();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	if (rcpu < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	/* Keep track of the CPUs we will run on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	sched_getaffinity(0, sizeof(original_cpumask), &original_cpumask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	for (i = 0; i < ret; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 		/* Pointless to wake up ourself */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		if (i == rcpu)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		/* Pointless to wake CPUs we will not run on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 		if (!CPU_ISSET(i, &original_cpumask))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 		CPU_ZERO(&cpumask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 		CPU_SET(i, &cpumask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		sched_setaffinity(0, sizeof(cpumask), &cpumask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	/* Enable all the CPUs of the original mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	sched_setaffinity(0, sizeof(original_cpumask), &original_cpumask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)  * It's possible to have no any frequency change for long time and cannot
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)  * get ftrace event 'trace_cpu_frequency' for long period, this introduces
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)  * big deviation for pstate statistics.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  * To solve this issue, below code forces to set 'scaling_max_freq' to 208MHz
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)  * for triggering ftrace event 'trace_cpu_frequency' and then recovery back to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)  * the maximum frequency value 1.2GHz.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static int cpu_stat_inject_cpu_frequency_event(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	int len, fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	fd = open(CPUFREQ_MAX_SYSFS_PATH, O_WRONLY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	if (fd < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		printf("failed to open scaling_max_freq, errno=%d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 		return fd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	len = write(fd, CPUFREQ_LOWEST_FREQ, strlen(CPUFREQ_LOWEST_FREQ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	if (len < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		printf("failed to open scaling_max_freq, errno=%d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	len = write(fd, CPUFREQ_HIGHEST_FREQ, strlen(CPUFREQ_HIGHEST_FREQ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	if (len < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		printf("failed to open scaling_max_freq, errno=%d\n", errno);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	close(fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) static void int_exit(int sig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	cpu_stat_inject_cpu_idle_event();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 	cpu_stat_inject_cpu_frequency_event();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	cpu_stat_update(cstate_map_fd, pstate_map_fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 	cpu_stat_print();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	exit(0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) int main(int argc, char **argv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 	struct bpf_link *link = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	struct bpf_program *prog;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 	struct bpf_object *obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 	char filename[256];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 	snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	obj = bpf_object__open_file(filename, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 	if (libbpf_get_error(obj)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		fprintf(stderr, "ERROR: opening BPF object file failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 	prog = bpf_object__find_program_by_name(obj, "bpf_prog1");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 	if (!prog) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		printf("finding a prog in obj file failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	/* load BPF program */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 	if (bpf_object__load(obj)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		fprintf(stderr, "ERROR: loading BPF object file failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	cstate_map_fd = bpf_object__find_map_fd_by_name(obj, "cstate_duration");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	pstate_map_fd = bpf_object__find_map_fd_by_name(obj, "pstate_duration");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	if (cstate_map_fd < 0 || pstate_map_fd < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		fprintf(stderr, "ERROR: finding a map in obj file failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 		goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	link = bpf_program__attach(prog);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 	if (libbpf_get_error(link)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 		fprintf(stderr, "ERROR: bpf_program__attach failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 		link = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 		goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 	ret = cpu_stat_inject_cpu_idle_event();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 	ret = cpu_stat_inject_cpu_frequency_event();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) 		return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) 	signal(SIGINT, int_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	signal(SIGTERM, int_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 	while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		cpu_stat_update(cstate_map_fd, pstate_map_fd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 		cpu_stat_print();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 		sleep(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 	bpf_link__destroy(link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	bpf_object__close(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }