brintos

brintos / linux-shallow public Read only

0
0
Text · 3.1 KiB · 46153f1 Raw
149 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 *  (C) 2016 SUSE Software Solutions GmbH4 *           Thomas Renninger <trenn@suse.de>5 */6 7#if defined(__i386__) || defined(__x86_64__)8 9#include <stdio.h>10#include <stdlib.h>11#include <stdint.h>12#include <time.h>13#include <string.h>14 15#include <pci/pci.h>16 17#include "idle_monitor/cpupower-monitor.h"18#include "helpers/helpers.h"19#include "powercap.h"20 21#define MAX_RAPL_ZONES 1022 23int rapl_zone_count;24cstate_t rapl_zones[MAX_RAPL_ZONES];25struct powercap_zone *rapl_zones_pt[MAX_RAPL_ZONES] = { 0 };26 27unsigned long long rapl_zone_previous_count[MAX_RAPL_ZONES];28unsigned long long rapl_zone_current_count[MAX_RAPL_ZONES];29unsigned long long rapl_max_count;30 31static int rapl_get_count_uj(unsigned int id, unsigned long long *count,32			     unsigned int cpu)33{34	if (rapl_zones_pt[id] == NULL)35		/* error */36		return -1;37 38	*count = rapl_zone_current_count[id] - rapl_zone_previous_count[id];39 40	return 0;41}42 43static int powercap_count_zones(struct powercap_zone *zone)44{45	uint64_t val;46	int uj;47 48	if (rapl_zone_count >= MAX_RAPL_ZONES)49		return -1;50 51	if (!zone->has_energy_uj)52		return 0;53 54	printf("%s\n", zone->sys_name);55	uj = powercap_get_energy_uj(zone, &val);56	printf("%d\n", uj);57 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;64	rapl_zone_count++;65 66	return 0;67}68 69static int rapl_start(void)70{71	int i, ret;72	uint64_t uj_val;73 74	for (i = 0; i < rapl_zone_count; i++) {75		ret = powercap_get_energy_uj(rapl_zones_pt[i], &uj_val);76		if (ret)77			return ret;78		rapl_zone_previous_count[i] = uj_val;79	}80 81	return 0;82}83 84static int rapl_stop(void)85{86	int i;87	uint64_t uj_val;88 89	for (i = 0; i < rapl_zone_count; i++) {90		int ret;91 92		ret = powercap_get_energy_uj(rapl_zones_pt[i], &uj_val);93		if (ret)94			return ret;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];98	}99	return 0;100}101 102struct cpuidle_monitor *rapl_register(void)103{104	struct powercap_zone *root_zone;105	char line[MAX_LINE_LEN] = "";106	int ret, val;107 108	ret = powercap_get_driver(line, MAX_LINE_LEN);109	if (ret < 0) {110		dprint("No powercapping driver loaded\n");111		return NULL;112	}113 114	dprint("Driver: %s\n", line);115	ret = powercap_get_enabled(&val);116	if (ret < 0)117		return NULL;118	if (!val) {119		dprint("Powercapping is disabled\n");120		return NULL;121	}122 123	dprint("Powercap domain hierarchy:\n\n");124	root_zone = powercap_init_zones();125 126	if (root_zone == NULL) {127		dprint("No powercap info found\n");128		return NULL;129	}130 131	powercap_walk_zones(root_zone, powercap_count_zones);132	rapl_monitor.hw_states_num = rapl_zone_count;133 134	return &rapl_monitor;135}136 137struct cpuidle_monitor rapl_monitor = {138	.name			= "RAPL",139	.hw_states		= rapl_zones,140	.hw_states_num		= 0,141	.start			= rapl_start,142	.stop			= rapl_stop,143	.do_register		= rapl_register,144	.flags.needs_root	= 0,145	.overflow_s		= 60 * 60 * 24 * 100, /* To be implemented */146};147 148#endif149