1 // SPDX-License-Identifier: GPL-2.0-only
3 * (C) 2016 SUSE Software Solutions GmbH
4 * Thomas Renninger <trenn@suse.de>
7 #if defined(__i386__) || defined(__x86_64__)
17 #include "idle_monitor/cpupower-monitor.h"
18 #include "helpers/helpers.h"
21 #define MAX_RAPL_ZONES 10
24 cstate_t rapl_zones[MAX_RAPL_ZONES];
25 struct powercap_zone *rapl_zones_pt[MAX_RAPL_ZONES] = { 0 };
27 unsigned long long rapl_zone_previous_count[MAX_RAPL_ZONES];
28 unsigned long long rapl_zone_current_count[MAX_RAPL_ZONES];
29 unsigned long long rapl_max_count;
31 static int rapl_get_count_uj(unsigned int id, unsigned long long *count,
34 if (rapl_zones_pt[id] == NULL)
38 *count = rapl_zone_current_count[id] - rapl_zone_previous_count[id];
43 static int powercap_count_zones(struct powercap_zone *zone)
48 if (rapl_zone_count >= MAX_RAPL_ZONES)
51 if (!zone->has_energy_uj)
54 printf("%s\n", zone->sys_name);
55 uj = powercap_get_energy_uj(zone, &val);
58 strncpy(rapl_zones[rapl_zone_count].name, zone->name, CSTATE_NAME_LEN - 1);
59 strcpy(rapl_zones[rapl_zone_count].desc, "");
60 rapl_zones[rapl_zone_count].id = rapl_zone_count;
61 rapl_zones[rapl_zone_count].range = RANGE_MACHINE;
62 rapl_zones[rapl_zone_count].get_count = rapl_get_count_uj;
63 rapl_zones_pt[rapl_zone_count] = zone;
69 static int rapl_start(void)
74 for (i = 0; i < rapl_zone_count; i++) {
75 ret = powercap_get_energy_uj(rapl_zones_pt[i], &uj_val);
78 rapl_zone_previous_count[i] = uj_val;
84 static int rapl_stop(void)
89 for (i = 0; i < rapl_zone_count; i++) {
92 ret = powercap_get_energy_uj(rapl_zones_pt[i], &uj_val);
95 rapl_zone_current_count[i] = uj_val;
96 if (rapl_max_count < uj_val)
97 rapl_max_count = uj_val - rapl_zone_previous_count[i];
102 struct cpuidle_monitor *rapl_register(void)
104 struct powercap_zone *root_zone;
105 char line[MAX_LINE_LEN] = "";
108 ret = powercap_get_driver(line, MAX_LINE_LEN);
110 dprint("No powercapping driver loaded\n");
114 dprint("Driver: %s\n", line);
115 ret = powercap_get_enabled(&val);
119 dprint("Powercapping is disabled\n");
123 dprint("Powercap domain hierarchy:\n\n");
124 root_zone = powercap_init_zones();
126 if (root_zone == NULL) {
127 dprint("No powercap info found\n");
131 powercap_walk_zones(root_zone, powercap_count_zones);
132 rapl_monitor.hw_states_num = rapl_zone_count;
134 return &rapl_monitor;
137 struct cpuidle_monitor rapl_monitor = {
139 .hw_states = rapl_zones,
143 .do_register = rapl_register,
144 .flags.needs_root = 0,
145 .overflow_s = 60 * 60 * 24 * 100, /* To be implemented */