From b32e00480222567132a8df051d81fe492aa5a42a68bec4bafc92bf90c1dbc566 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Fri, 21 Oct 2022 14:57:41 +0000 Subject: [PATCH] Accepting request 1030419 from home:dimstar:Factory - clean up sources: drop rapl_monitor.patch and cpupower_rapl.patch. This allows the fixed package to be submitted to Factory OBS-URL: https://build.opensuse.org/request/show/1030419 OBS-URL: https://build.opensuse.org/package/show/hardware/cpupower?expand=0&rev=125 --- cpupower.changes | 6 + cpupower.spec | 6 +- cpupower_rapl.patch | 600 -------------------------------------------- rapl_monitor.patch | 191 -------------- 4 files changed, 7 insertions(+), 796 deletions(-) delete mode 100644 cpupower_rapl.patch delete mode 100644 rapl_monitor.patch diff --git a/cpupower.changes b/cpupower.changes index 8bec708..047de99 100644 --- a/cpupower.changes +++ b/cpupower.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Fri Oct 21 13:59:41 UTC 2022 - Dominique Leuenberger + +- clean up sources: drop rapl_monitor.patch and + cpupower_rapl.patch. + ------------------------------------------------------------------- Fri Oct 7 15:59:26 UTC 2022 - Callum Farmer diff --git a/cpupower.spec b/cpupower.spec index 08b3004..32e350e 100644 --- a/cpupower.spec +++ b/cpupower.spec @@ -30,8 +30,6 @@ Summary: Tools to determine and set CPU Power related Settings License: GPL-2.0-only Group: System/Base URL: https://git.kernel.org/cgit/linux/kernel/git/rafael/linux-pm.git -#Patch1: cpupower_rapl.patch -#Patch2: rapl_monitor.patch Patch3: cpupower_exclude_kernel_Makefile.patch Patch6: amd_do_not_show_amount_of_boost_states_if_zero.patch BuildRequires: gettext-tools @@ -76,8 +74,8 @@ powersave module. %package bash-completion Summary: Bash completion for cpupower Group: System/Shells -Requires: bash-completion Requires: %{name} +Requires: bash-completion Supplements: (%{name} and bash-completion) %description bash-completion @@ -101,8 +99,6 @@ There is no reason to install this package. (cd %{_prefix}/src/linux ; tar -cf - COPYING CREDITS README tools include scripts Kbuild Makefile arch/*/{include,lib,Makefile} lib) | tar -xf - chmod +x tools/power/cpupower/utils/version-gen.sh cd %{maindir} -#%%patch1 -p1 -#%%patch2 -p1 %patch3 -p1 %patch6 -p1 diff --git a/cpupower_rapl.patch b/cpupower_rapl.patch deleted file mode 100644 index 1a69d05..0000000 --- a/cpupower_rapl.patch +++ /dev/null @@ -1,600 +0,0 @@ -cpupower: Introduce powercap intel-rapl library helpers and powercap-info command - -Read out powercap zone information via: -cpupower powercap-info -and show the zone hierarchy to the user: - -./cpupower powercap-info -Driver: intel-rapl -Powercap domain hierarchy: - -Zone: package-0 (enabled) -Power consumption can be monitored in micro Watts - - Zone: core (disabled) - Power consumption can be monitored in micro Watts - - Zone: uncore (disabled) - Power consumption can be monitored in micro Watts - - Zone: dram (disabled) - Power consumption can be monitored in micro Watts - -There is a dummy -a option for powercap-info which can/should be used to show -more detailed info later. Like that other args can be added easily later as well. - -Signed-off-by: Thomas Renninger - ---- - Makefile | 11 + - lib/powercap.c | 290 +++++++++++++++++++++++++++++++++++++++++++ - lib/powercap.h | 54 ++++++++ - man/cpupower-powercap-info.1 | 25 +++ - utils/builtin.h | 2 - utils/cpupower.c | 1 - utils/powercap-info.c | 113 ++++++++++++++++ - 7 files changed, 492 insertions(+), 4 deletions(-) - ---- a/Makefile -+++ b/Makefile -@@ -133,7 +133,7 @@ - utils/idle_monitor/mperf_monitor.o utils/idle_monitor/cpupower-monitor.o \ - utils/cpupower.o utils/cpufreq-info.o utils/cpufreq-set.o \ - utils/cpupower-set.o utils/cpupower-info.o utils/cpuidle-info.o \ -- utils/cpuidle-set.o -+ utils/cpuidle-set.o utils/powercap-info.o - - UTIL_SRC := $(UTIL_OBJS:.o=.c) - -@@ -143,9 +143,9 @@ - utils/helpers/bitmask.h \ - utils/idle_monitor/idle_monitors.h utils/idle_monitor/idle_monitors.def - --LIB_HEADERS = lib/cpufreq.h lib/cpupower.h lib/cpuidle.h --LIB_SRC = lib/cpufreq.c lib/cpupower.c lib/cpuidle.c --LIB_OBJS = lib/cpufreq.o lib/cpupower.o lib/cpuidle.o -+LIB_HEADERS = lib/cpufreq.h lib/cpupower.h lib/cpuidle.h lib/powercap.h -+LIB_SRC = lib/cpufreq.c lib/cpupower.c lib/cpuidle.c lib/powercap.c -+LIB_OBJS = lib/cpufreq.o lib/cpupower.o lib/cpuidle.o lib/powercap.o - LIB_OBJS := $(addprefix $(OUTPUT),$(LIB_OBJS)) - - override CFLAGS += -pipe -@@ -276,6 +276,7 @@ - $(INSTALL) -d $(DESTDIR)${includedir} - $(INSTALL_DATA) lib/cpufreq.h $(DESTDIR)${includedir}/cpufreq.h - $(INSTALL_DATA) lib/cpuidle.h $(DESTDIR)${includedir}/cpuidle.h -+ $(INSTALL_DATA) lib/powercap.h $(DESTDIR)${includedir}/powercap.h - - install-tools: $(OUTPUT)cpupower - $(INSTALL) -d $(DESTDIR)${bindir} -@@ -292,6 +293,7 @@ - $(INSTALL_DATA) -D man/cpupower-set.1 $(DESTDIR)${mandir}/man1/cpupower-set.1 - $(INSTALL_DATA) -D man/cpupower-info.1 $(DESTDIR)${mandir}/man1/cpupower-info.1 - $(INSTALL_DATA) -D man/cpupower-monitor.1 $(DESTDIR)${mandir}/man1/cpupower-monitor.1 -+ $(INSTALL_DATA) -D man/cpupower-powercap-info.1 $(DESTDIR)${mandir}/man1/cpupower-powercap-info.1 - - install-gmo: create-gmo - $(INSTALL) -d $(DESTDIR)${localedir} -@@ -321,6 +323,7 @@ - - rm -f $(DESTDIR)${mandir}/man1/cpupower-set.1 - - rm -f $(DESTDIR)${mandir}/man1/cpupower-info.1 - - rm -f $(DESTDIR)${mandir}/man1/cpupower-monitor.1 -+ - rm -f $(DESTDIR)${mandir}/man1/cpupower-powercap-info.1 - - for HLANG in $(LANGUAGES); do \ - rm -f $(DESTDIR)${localedir}/$$HLANG/LC_MESSAGES/cpupower.mo; \ - done; ---- /dev/null -+++ b/lib/powercap.c -@@ -0,0 +1,290 @@ -+/* -+ * (C) 2016 Thomas Renninger -+ * -+ * Licensed under the terms of the GNU GPL License version 2. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "powercap.h" -+ -+static unsigned int sysfs_read_file(const char *path, char *buf, size_t buflen) -+{ -+ int fd; -+ ssize_t numread; -+ -+ fd = open(path, O_RDONLY); -+ if (fd == -1) -+ return 0; -+ -+ numread = read(fd, buf, buflen - 1); -+ if (numread < 1) { -+ close(fd); -+ return 0; -+ } -+ -+ buf[numread] = '\0'; -+ close(fd); -+ -+ return (unsigned int) numread; -+} -+ -+static int sysfs_get_enabled(char *path, int *mode) -+{ -+ int fd; -+ char yes_no; -+ -+ *mode = 0; -+ -+ fd = open(path, O_RDONLY); -+ if (fd == -1) -+ return -1; -+ -+ if (read(fd, &yes_no, 1) != 1) { -+ close(fd); -+ return -1; -+ } -+ -+ if (yes_no == '1') { -+ *mode = 1; -+ return 0; -+ } else if (yes_no == '0') { -+ return 0; -+ } -+ return -1; -+} -+ -+int powercap_get_enabled(int *mode) -+{ -+ char path[SYSFS_PATH_MAX] = PATH_TO_POWERCAP "/intel-rapl/enabled"; -+ return sysfs_get_enabled(path, mode); -+} -+ -+/* -+ * Hardcoded, because rapl is the only powercap implementation -+- * this needs to get more generic if more powercap implementations -+ * should show up -+ */ -+int powercap_get_driver(char *driver, int buflen) -+{ -+ char file[SYSFS_PATH_MAX] = PATH_TO_RAPL; -+ struct stat statbuf; -+ -+ if (stat(file, &statbuf) != 0 || !S_ISDIR(statbuf.st_mode)) { -+ driver = ""; -+ return -1; -+ } else if (buflen > 10) { -+ strcpy(driver, "intel-rapl"); -+ return 0; -+ } else -+ return -1; -+} -+ -+enum powercap_get64 { -+ GET_ENERGY_UJ, -+ GET_MAX_ENERGY_RANGE_UJ, -+ GET_POWER_UW, -+ GET_MAX_POWER_RANGE_UW, -+ MAX_GET_64_FILES -+}; -+ -+static const char *powercap_get64_files[MAX_GET_64_FILES] = { -+ [GET_POWER_UW] = "power_uw", -+ [GET_MAX_POWER_RANGE_UW] = "max_power_range_uw", -+ [GET_ENERGY_UJ] = "energy_uj", -+ [GET_MAX_ENERGY_RANGE_UJ] = "max_energy_range_uj", -+}; -+ -+static int sysfs_powercap_get64_val(struct powercap_zone *zone, -+ enum powercap_get64 which, -+ uint64_t *val) -+{ -+ char file[SYSFS_PATH_MAX] = PATH_TO_POWERCAP "/"; -+ int ret; -+ char buf[MAX_LINE_LEN]; -+ -+ strcat(file, zone->sys_name); -+ strcat(file, "/"); -+ strcat (file, powercap_get64_files[which]); -+ -+ ret = sysfs_read_file(file, buf, MAX_LINE_LEN); -+ if (ret < 0 ) -+ return ret; -+ if (ret == 0) -+ return -1; -+ -+ *val = strtoll(buf, NULL, 10); -+ return 0; -+} -+ -+ -+int powercap_get_max_energy_range_uj (struct powercap_zone *zone, uint64_t *val) -+{ -+ return sysfs_powercap_get64_val(zone, GET_MAX_ENERGY_RANGE_UJ, val); -+} -+ -+int powercap_get_energy_uj (struct powercap_zone *zone, uint64_t *val) -+{ -+ return sysfs_powercap_get64_val(zone, GET_ENERGY_UJ, val); -+} -+ -+int powercap_get_max_power_range_uw (struct powercap_zone *zone, uint64_t *val) -+{ -+ return sysfs_powercap_get64_val(zone, GET_MAX_POWER_RANGE_UW, val); -+} -+ -+int powercap_get_power_uw (struct powercap_zone *zone, uint64_t *val) -+{ -+ return sysfs_powercap_get64_val(zone, GET_POWER_UW, val); -+} -+ -+int powercap_zone_get_enabled (struct powercap_zone *zone, int *mode) -+{ -+ char path[SYSFS_PATH_MAX] = PATH_TO_POWERCAP; -+ -+ if ((strlen(PATH_TO_POWERCAP) + strlen(zone->sys_name)) + -+ strlen("/enabled") + 1 >= SYSFS_PATH_MAX) -+ return -1; -+ -+ strcat(path, "/"); -+ strcat(path, zone->sys_name); -+ strcat(path, "/enabled"); -+ -+ return sysfs_get_enabled(path, mode); -+} -+ -+int powercap_zone_set_enabled (struct powercap_zone *zone, int mode) -+{ -+ /* To be done if needed */ -+ return 0; -+} -+ -+ -+int powercap_read_zone(struct powercap_zone *zone) -+{ -+ struct dirent* dent; -+ DIR* zone_dir; -+ char sysfs_dir[SYSFS_PATH_MAX] = PATH_TO_POWERCAP; -+ struct powercap_zone *child_zone; -+ char file[SYSFS_PATH_MAX] = PATH_TO_POWERCAP; -+ int i, ret = 0; -+ uint64_t val = 0; -+ -+ strcat(sysfs_dir, "/"); -+ strcat(sysfs_dir, zone->sys_name); -+ -+ zone_dir = opendir(sysfs_dir); -+ if (zone_dir == NULL) -+ return -1; -+ -+ strcat(file, "/"); -+ strcat(file, zone->sys_name); -+ strcat(file, "/name"); -+ sysfs_read_file(file, zone->name, MAX_LINE_LEN); -+ if (zone->parent) -+ zone->tree_depth = zone->parent->tree_depth + 1; -+ ret = powercap_get_energy_uj(zone, &val); -+ if (ret == 0) -+ zone->has_energy_uj = 1; -+ ret = powercap_get_power_uw(zone, &val); -+ if (ret == 0) -+ zone->has_power_uw = 1; -+ -+ while((dent = readdir(zone_dir)) != NULL) { -+ struct stat st; -+ -+ if(strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) -+ continue; -+ -+ if (stat(dent->d_name, &st) != 0 || !S_ISDIR(st.st_mode)) -+ if (fstatat(dirfd(zone_dir), dent->d_name, &st, 0) < 0) -+ continue; -+ -+ if (strncmp(dent->d_name, "intel-rapl:", 11) != 0) -+ continue; -+ -+ child_zone = calloc(1, sizeof(struct powercap_zone)); -+ if (child_zone == NULL) -+ return -1; -+ for (i = 0; i < POWERCAP_MAX_CHILD_ZONES; i++) { -+ if (zone->children[i] == NULL) { -+ zone->children[i] = child_zone; -+ break; -+ } -+ if (i == POWERCAP_MAX_CHILD_ZONES - 1) { -+ free(child_zone); -+ fprintf(stderr, "Reached POWERCAP_MAX_CHILD_ZONES %d\n", -+ POWERCAP_MAX_CHILD_ZONES); -+ return -1; -+ } -+ } -+ strcpy(child_zone->sys_name, zone->sys_name); -+ strcat(child_zone->sys_name, "/"); -+ strcat(child_zone->sys_name, dent->d_name); -+ child_zone->parent = zone; -+ if (zone->tree_depth >= POWERCAP_MAX_TREE_DEPTH) { -+ fprintf(stderr, "Maximum zone hierachy depth[%d] reached\n", -+ POWERCAP_MAX_TREE_DEPTH); -+ ret = -1; -+ break; -+ } -+ powercap_read_zone(child_zone); -+ } -+ closedir(zone_dir); -+ return ret; -+} -+ -+struct powercap_zone *powercap_init_zones() -+{ -+ int enabled; -+ struct powercap_zone *root_zone; -+ int ret; -+ char file[SYSFS_PATH_MAX] = PATH_TO_RAPL "/enabled"; -+ -+ ret = sysfs_get_enabled(file, &enabled); -+ -+ if (ret) -+ return NULL; -+ -+ if (!enabled) -+ return NULL; -+ -+ root_zone = calloc(1, sizeof(struct powercap_zone)); -+ if (!root_zone) -+ return NULL; -+ -+ strcpy(root_zone->sys_name, "intel-rapl/intel-rapl:0"); -+ -+ powercap_read_zone(root_zone); -+ -+ return root_zone; -+} -+ -+/* Call function *f on the passed zone and all its children */ -+ -+int powercap_walk_zones(struct powercap_zone *zone, -+ int (*f)(struct powercap_zone *zone)) -+{ -+ int i, ret; -+ -+ if (!zone) -+ return -1; -+ -+ ret = f(zone); -+ if (ret) -+ return ret; -+ -+ for (i = 0; i < POWERCAP_MAX_CHILD_ZONES; i++) { -+ if (zone->children[i] != NULL) { -+ powercap_walk_zones(zone->children[i], f); -+ } -+ } -+ return 0; -+} ---- /dev/null -+++ b/lib/powercap.h -@@ -0,0 +1,54 @@ -+/* -+ * (C) 2016 Thomas Renninger -+ * -+ * Licensed under the terms of the GNU GPL License version 2. -+ */ -+ -+#ifndef __CPUPOWER_RAPL_H__ -+#define __CPUPOWER_RAPL_H__ -+ -+#define PATH_TO_POWERCAP "/sys/devices/virtual/powercap" -+#define PATH_TO_RAPL "/sys/devices/virtual/powercap/intel-rapl" -+#define PATH_TO_RAPL_CLASS "/sys/devices/virtual/powercap/intel-rapl" -+ -+#define POWERCAP_MAX_CHILD_ZONES 10 -+#define POWERCAP_MAX_TREE_DEPTH 10 -+ -+#define MAX_LINE_LEN 4096 -+#define SYSFS_PATH_MAX 255 -+ -+#include -+ -+struct powercap_zone { -+ char name[MAX_LINE_LEN]; -+ /* -+ * sys_name relative to PATH_TO_POWERCAP, -+ * do not forget the / in between -+ */ -+ char sys_name[SYSFS_PATH_MAX]; -+ int tree_depth; -+ struct powercap_zone *parent; -+ struct powercap_zone *children[POWERCAP_MAX_CHILD_ZONES]; -+ /* More possible caps or attributes to be added? */ -+ uint32_t has_power_uw:1, -+ has_energy_uj:1; -+ -+}; -+ -+int powercap_walk_zones(struct powercap_zone *zone, -+ int (*f)(struct powercap_zone *zone)); -+ -+struct powercap_zone *powercap_init_zones(); -+int powercap_get_enabled(int *mode); -+int powercap_set_enabled(int mode); -+int powercap_get_driver(char *driver, int buflen); -+ -+int powercap_get_max_energy_range_uj (struct powercap_zone *zone, uint64_t *val); -+int powercap_get_energy_uj (struct powercap_zone *zone, uint64_t *val); -+int powercap_get_max_power_range_uw (struct powercap_zone *zone , uint64_t *val); -+int powercap_get_power_uw (struct powercap_zone *zone, uint64_t *val); -+int powercap_zone_get_enabled (struct powercap_zone *zone, int *mode); -+int powercap_zone_set_enabled (struct powercap_zone *zone, int mode); -+ -+ -+#endif /* __CPUPOWER_RAPL_H__ */ ---- /dev/null -+++ b/man/cpupower-powercap-info.1 -@@ -0,0 +1,25 @@ -+.TH CPUPOWER\-POWERCAP\-INFO "1" "05/08/2016" "" "cpupower Manual" -+.SH NAME -+cpupower\-powercap\-info \- Shows powercapping related kernel and hardware configurations -+.SH SYNOPSIS -+.ft B -+.B cpupower powercap-info -+ -+.SH DESCRIPTION -+\fBcpupower powercap-info \fP shows kernel powercapping subsystem information. -+This needs hardware support and a loaded powercapping driver (at this time only -+intel_rapl driver exits) exporting hardware values userspace via sysfs. -+ -+Some options are platform wide, some affect single cores. By default values -+of core zero are displayed only. cpupower --cpu all cpuinfo will show the -+settings of all cores, see cpupower(1) how to choose specific cores. -+ -+.SH "DOCUMENTATION" -+ -+kernel sources: -+Documentation/power/powercap/powercap.txt -+ -+ -+.SH "SEE ALSO" -+ -+cpupower(1) ---- a/utils/builtin.h -+++ b/utils/builtin.h -@@ -8,6 +8,8 @@ - extern int cmd_freq_info(int argc, const char **argv); - extern int cmd_idle_set(int argc, const char **argv); - extern int cmd_idle_info(int argc, const char **argv); -+extern int cmd_cap_info(int argc, const char **argv); -+extern int cmd_cap_set(int argc, const char **argv); - extern int cmd_monitor(int argc, const char **argv); - - #endif ---- a/utils/cpupower.c -+++ b/utils/cpupower.c -@@ -54,6 +54,7 @@ - { "frequency-set", cmd_freq_set, 1 }, - { "idle-info", cmd_idle_info, 0 }, - { "idle-set", cmd_idle_set, 1 }, -+ { "powercap-info", cmd_cap_info, 0 }, - { "set", cmd_set, 1 }, - { "info", cmd_info, 0 }, - { "monitor", cmd_monitor, 0 }, ---- /dev/null -+++ b/utils/powercap-info.c -@@ -0,0 +1,113 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "powercap.h" -+#include "helpers/helpers.h" -+ -+int powercap_show_all = 0; -+ -+static struct option info_opts[] = -+{ -+ { "all", no_argument, NULL, 'a'}, -+ { }, -+}; -+ -+static int powercap_print_one_zone(struct powercap_zone *zone) -+{ -+ int mode, i, ret = 0; -+ char pr_prefix[1024] = ""; -+ -+ for (i = 0; i < zone->tree_depth && i < POWERCAP_MAX_TREE_DEPTH; i++) -+ strcat (pr_prefix, "\t"); -+ -+ printf("%sZone: %s", pr_prefix, zone->name); -+ ret = powercap_zone_get_enabled(zone, &mode); -+ if (ret < 0) -+ return ret; -+ printf(" (%s)\n", mode ? "enabled" : "disabled"); -+ -+ if (zone->has_power_uw) -+printf(_("%sEnergy consumption can be monitored in micro Jules\n"), -+ pr_prefix); -+ -+ if (zone->has_energy_uj) -+printf(_("%sPower consumption can be monitored in micro Watts\n"), -+ pr_prefix); -+ -+ printf("\n"); -+ -+ if (ret != 0) -+ return ret; -+ return ret; -+} -+ -+static int powercap_show() -+{ -+ struct powercap_zone *root_zone; -+ char line[MAX_LINE_LEN] = ""; -+ int ret, val; -+ -+ ret = powercap_get_driver(line, MAX_LINE_LEN); -+ if (ret < 0) { -+ printf(_("No powercapping driver loaded\n")); -+ return ret; -+ } -+ -+ printf("Driver: %s\n", line); -+ ret = powercap_get_enabled(&val); -+ if (ret < 0) -+ return ret; -+ if (!val) { -+ printf(_("Powercapping is disabled\n")); -+ return -1; -+ } -+ -+ printf(_("Powercap domain hierarchy:\n\n")); -+ root_zone = powercap_init_zones(); -+ -+ if (root_zone == NULL) { -+ printf(_("No powercap info found\n")); -+ return 1; -+ } -+ -+ powercap_walk_zones(root_zone, powercap_print_one_zone); -+ -+ return 0; -+} -+ -+int cmd_cap_set(int argc, char **argv) -+{ -+ return 0; -+}; -+int cmd_cap_info(int argc, char **argv) -+{ -+ extern char *optarg; -+ extern int optind, opterr, optopt; -+ int ret = 0, cont = 1; -+ do { -+ ret = getopt_long(argc, argv, "a", info_opts, NULL); -+ switch (ret) { -+ case '?': -+ cont = 0; -+ break; -+ case -1: -+ cont = 0; -+ break; -+ case 'a': -+ powercap_show_all = 1; -+ break; -+ default: -+ fprintf(stderr, _("invalid or unknown argument\n")); -+ return EXIT_FAILURE; -+ } -+ } while (cont); -+ -+ powercap_show(); -+ return 0; -+} diff --git a/rapl_monitor.patch b/rapl_monitor.patch deleted file mode 100644 index 687cf70..0000000 --- a/rapl_monitor.patch +++ /dev/null @@ -1,191 +0,0 @@ -cpupower: rapl monitor - shows the used power consumption in uj for each rapl domain - - -Signed-off-by: Thomas Renninger - ---- - Makefile | 1 - utils/idle_monitor/cpupower-monitor.c | 7 - - utils/idle_monitor/idle_monitors.def | 1 - utils/idle_monitor/rapl_monitor.c | 141 ++++++++++++++++++++++++++++++++++ - 4 files changed, 147 insertions(+), 3 deletions(-) - ---- a/Makefile -+++ b/Makefile -@@ -131,6 +131,7 @@ - utils/idle_monitor/hsw_ext_idle.o \ - utils/idle_monitor/amd_fam14h_idle.o utils/idle_monitor/cpuidle_sysfs.o \ - utils/idle_monitor/mperf_monitor.o utils/idle_monitor/cpupower-monitor.o \ -+ utils/idle_monitor/rapl_monitor.o \ - utils/cpupower.o utils/cpufreq-info.o utils/cpufreq-set.o \ - utils/cpupower-set.o utils/cpupower-info.o utils/cpuidle-info.o \ - utils/cpuidle-set.o utils/powercap-info.o ---- a/utils/idle_monitor/cpupower-monitor.c -+++ b/utils/idle_monitor/cpupower-monitor.c -@@ -459,9 +459,10 @@ - print_results(1, cpu); - } - -- for (num = 0; num < avail_monitors; num++) -- monitors[num]->unregister(); -- -+ for (num = 0; num < avail_monitors; num++) { -+ if (monitors[num]->unregister) -+ monitors[num]->unregister(); -+ } - cpu_topology_release(cpu_top); - return 0; - } ---- a/utils/idle_monitor/idle_monitors.def -+++ b/utils/idle_monitor/idle_monitors.def -@@ -4,5 +4,6 @@ - DEF(intel_snb) - DEF(intel_hsw_ext) - DEF(mperf) -+DEF(rapl) - #endif - DEF(cpuidle_sysfs) ---- /dev/null -+++ b/utils/idle_monitor/rapl_monitor.c -@@ -0,0 +1,141 @@ -+/* -+ * (C) 2016 Thomas Renninger -+ * -+ * Licensed under the terms of the GNU GPL License version 2. -+ * -+ */ -+ -+#if defined(__i386__) || defined(__x86_64__) -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "idle_monitor/cpupower-monitor.h" -+#include "helpers/helpers.h" -+#include "powercap.h" -+ -+#define MAX_RAPL_ZONES 10 -+ -+int rapl_zone_count = 0; -+cstate_t rapl_zones[MAX_RAPL_ZONES]; -+struct powercap_zone *rapl_zones_pt[MAX_RAPL_ZONES] = { 0 }; -+ -+unsigned long long rapl_zone_previous_count[MAX_RAPL_ZONES]; -+unsigned long long rapl_zone_current_count[MAX_RAPL_ZONES]; -+unsigned long long rapl_max_count; -+ -+static int rapl_get_count_uj(unsigned int id, unsigned long long *count, -+ unsigned int cpu) -+{ -+ if (rapl_zones_pt[id] == NULL) -+ /* error */ -+ return -1; -+ -+ *count = rapl_zone_current_count[id] - rapl_zone_previous_count[id]; -+ -+ return 0; -+} -+ -+static int powercap_count_zones(struct powercap_zone *zone) -+{ -+ if (rapl_zone_count >= MAX_RAPL_ZONES) -+ return -1; -+ -+ if (!zone->has_energy_uj) -+ return 0; -+ -+ strncpy(rapl_zones[rapl_zone_count].name, zone->name, CSTATE_NAME_LEN - 1); -+ strcpy(rapl_zones[rapl_zone_count].desc, ""); -+ rapl_zones[rapl_zone_count].id = rapl_zone_count; -+ rapl_zones[rapl_zone_count].range = RANGE_MACHINE; -+ rapl_zones[rapl_zone_count].get_count = rapl_get_count_uj; -+ rapl_zones_pt[rapl_zone_count] = zone; -+ rapl_zone_count++; -+ -+ return 0; -+} -+ -+static int rapl_start(void) -+{ -+ int i, ret; -+ uint64_t uj_val; -+ -+ for (i = 0; i < rapl_zone_count; i++) { -+ ret = powercap_get_energy_uj(rapl_zones_pt[i], &uj_val); -+ if (ret) -+ return ret; -+ rapl_zone_previous_count[i] = uj_val; -+ } -+ -+ return 0; -+} -+ -+static int rapl_stop(void) -+{ -+ int i; -+ uint64_t uj_val; -+ -+ for (i = 0; i < rapl_zone_count; i++) { -+ int ret; -+ ret = powercap_get_energy_uj(rapl_zones_pt[i], &uj_val); -+ if (ret) -+ return ret; -+ rapl_zone_current_count[i] = uj_val; -+ if (rapl_max_count < uj_val) -+ rapl_max_count = uj_val - rapl_zone_previous_count[i]; -+ } -+ return 0; -+} -+ -+struct cpuidle_monitor *rapl_register(void) -+{ -+ struct powercap_zone *root_zone; -+ char line[MAX_LINE_LEN] = ""; -+ int ret, val; -+ -+ ret = powercap_get_driver(line, MAX_LINE_LEN); -+ if (ret < 0) { -+ dprint("No powercapping driver loaded\n"); -+ return NULL; -+ } -+ -+ dprint("Driver: %s\n", line); -+ ret = powercap_get_enabled(&val); -+ if (ret < 0) -+ return NULL; -+ if (!val) { -+ dprint("Powercapping is disabled\n"); -+ return NULL; -+ } -+ -+ dprint("Powercap domain hierarchy:\n\n"); -+ root_zone = powercap_init_zones(); -+ -+ if (root_zone == NULL) { -+ dprint("No powercap info found\n"); -+ return NULL; -+ } -+ -+ powercap_walk_zones(root_zone, powercap_count_zones); -+ rapl_monitor.hw_states_num = rapl_zone_count; -+ -+ return &rapl_monitor; -+} -+ -+struct cpuidle_monitor rapl_monitor = { -+ .name = "RAPL", -+ .hw_states = rapl_zones, -+ .hw_states_num = 0, -+ .start = rapl_start, -+ .stop = rapl_stop, -+ .do_register = rapl_register, -+ .flags.needs_root = 0, -+ .overflow_s = 60 * 60 * 24 * 100, /* To be implemented */ -+}; -+ -+#endif