All of lore.kernel.org
 help / color / mirror / Atom feed
* [Powertop] [PATCH 1/5] RAPL Interface
@ 2013-04-09 16:20 Srinivas Pandruvada
  0 siblings, 0 replies; 2+ messages in thread
From: Srinivas Pandruvada @ 2013-04-09 16:20 UTC (permalink / raw)
  To: powertop

[-- Attachment #1: Type: text/plain, Size: 20116 bytes --]

Added RAPL interface class. This provides methods to get the status
of RAPL domains and get energy and power status.

Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada(a)linux.intel.com>
---
 src/Makefile.am                 |   3 +-
 src/cpu/rapl/rapl_interface.cpp | 662 ++++++++++++++++++++++++++++++++++++++++
 src/cpu/rapl/rapl_interface.h   |  87 ++++++
 3 files changed, 751 insertions(+), 1 deletion(-)
 create mode 100644 src/cpu/rapl/rapl_interface.cpp
 create mode 100644 src/cpu/rapl/rapl_interface.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 398b8a7..0983b51 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -31,7 +31,8 @@ powertop_SOURCES = parameters/persistent.cpp parameters/learn.cpp parameters/par
 		report/report-formatter-base.cpp report/report-formatter-base.h \
 		report/report-formatter-csv.cpp report/report-formatter-csv.h \
 		report/report-formatter-html.cpp report/report-formatter-html.h \
-		main.cpp css.h powertop.css cpu/intel_gpu.cpp
+		main.cpp css.h powertop.css cpu/intel_gpu.cpp \
+		cpu/rapl/rapl_interface.cpp
 
 
 powertop_CXXFLAGS = -fno-omit-frame-pointer -fstack-protector -Wall -Wshadow -Wformat $(NCURSES_CFLAGS) $(PCIUTILS_CFLAGS) $(LIBNL_CFLAGS) $(GLIB2_CFLAGS)
diff --git a/src/cpu/rapl/rapl_interface.cpp b/src/cpu/rapl/rapl_interface.cpp
new file mode 100644
index 0000000..3e54201
--- /dev/null
+++ b/src/cpu/rapl/rapl_interface.cpp
@@ -0,0 +1,662 @@
+/* rapl_interface.cpp: rapl interface for power top implementation
+ *
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * Author Name <Srinivas.Pandruvada(a)linux.intel.com>
+ *
+ */
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include "rapl_interface.h"
+
+#ifdef DEBUG
+#define RAPL_DBG_PRINT printf
+#define RAPL_ERROR_PRINT printf
+#else
+#define RAPL_DBG_PRINT(...)	((void) 0)
+#define RAPL_ERROR_PRINT(...) ((void) 0)
+#endif
+#define MAX_TEMP_STR_SIZE	20
+
+// RAPL interface
+#define MSR_RAPL_POWER_UNIT	0x606
+#define MSR_PKG_POWER_LIMIT	0x610
+
+#define MSR_PKG_ENERY_STATUS	0x611
+#define MSR_PKG_POWER_INFO	0x614
+#define MSR_PKG_PERF_STATUS	0x613
+
+#define MSR_DRAM_POWER_LIMIT	0x618
+#define MSR_DRAM_ENERY_STATUS	0x619
+#define MSR_DRAM_PERF_STATUS	0x61B
+#define MSR_DRAM_POWER_INFO	0x61c
+
+#define MSR_PP0_POWER_LIMIT	0x638
+#define MSR_PP0_ENERY_STATUS	0x639
+#define MSR_PP0_POLICY		0x63A
+#define MSR_PP0_PERF_STATUS	0x63B
+
+#define MSR_PP1_POWER_LIMIT	0x640
+#define MSR_PP1_ENERY_STATUS	0x641
+#define MSR_PP1_POLICY		0x642
+
+#define PKG_DOMAIN_PRESENT	0x01
+#define DRAM_DOMAIN_PRESENT	0x02
+#define PP0_DOMAIN_PRESENT	0x04
+#define PP1_DOMAIN_PRESENT	0x08
+
+c_rapl_interface::c_rapl_interface() :
+	measurment_interval(def_sampling_interval),
+	last_pkg_energy_status(0.0),
+	last_dram_energy_status(0.0),
+	last_pp0_energy_status(0.0),
+	last_pp1_energy_status(0.0)
+{
+	char path_str[MAX_TEMP_STR_SIZE];
+	unsigned long long value;
+	int ret;
+
+	no_of_cpus = 0;
+	for(int i = 0; i < 64; ++i)
+	{
+		struct stat s;
+		sprintf(path_str, "/dev/cpu/%d", i);
+		if(stat(path_str, &s) == 0) {
+			no_of_cpus++;
+		}
+	}
+
+	rapl_domains = 0;
+
+	// presence of each domain
+	// Check presence of PKG domain
+	ret = read_msr(0, MSR_PKG_ENERY_STATUS, &value);
+	if (ret > 0) {
+		rapl_domains |= PKG_DOMAIN_PRESENT;
+		RAPL_DBG_PRINT("Domain : PKG present\n");
+	} else {
+		RAPL_DBG_PRINT("Domain : PKG Not present\n");
+	}
+
+	// Check presence of DRAM domain
+	ret = read_msr(0, MSR_DRAM_ENERY_STATUS, &value);
+	if (ret > 0) {
+		rapl_domains |= DRAM_DOMAIN_PRESENT;
+		RAPL_DBG_PRINT("Domain : DRAM present\n");
+	} else {
+		RAPL_DBG_PRINT("Domain : DRAM Not present\n");
+	}
+
+	// Check presence of PP0 domain
+	ret = read_msr(0, MSR_PP0_ENERY_STATUS, &value);
+	if (ret > 0) {
+		rapl_domains |= PP0_DOMAIN_PRESENT;
+		RAPL_DBG_PRINT("Domain : PP0 present\n");
+	} else {
+		RAPL_DBG_PRINT("Domain : PP0 Not present\n");
+	}
+
+	// Check presence of PP1 domain
+	ret = read_msr(0, MSR_PP1_ENERY_STATUS, &value);
+	if (ret > 0) {
+		rapl_domains |= PP1_DOMAIN_PRESENT;
+		RAPL_DBG_PRINT("Domain : PP1 present\n");
+	} else {
+		RAPL_DBG_PRINT("Domain : PP1 Not present\n");
+	}
+
+	power_units = get_power_unit();
+	energy_status_units = get_energy_status_unit();
+	time_units = get_time_unit();
+
+	RAPL_DBG_PRINT("RAPL Domain mask: %x\n", rapl_domains);
+}
+
+bool c_rapl_interface::pkg_domain_present()
+{
+	if ((rapl_domains & PKG_DOMAIN_PRESENT)) {
+		return true;
+	}
+
+	return false;
+}
+
+bool c_rapl_interface::dram_domain_present()
+{
+	if ((rapl_domains & DRAM_DOMAIN_PRESENT)) {
+		return true;
+	}
+
+	return false;
+}
+
+bool c_rapl_interface::pp0_domain_present()
+{
+	if ((rapl_domains & PP0_DOMAIN_PRESENT)) {
+		return true;
+	}
+
+	return false;
+}
+
+bool c_rapl_interface::pp1_domain_present()
+{
+	if ((rapl_domains & PP1_DOMAIN_PRESENT)) {
+		return true;
+	}
+
+	return false;
+}
+
+int c_rapl_interface::get_no_cpus()
+{
+	return no_of_cpus;
+}
+
+int c_rapl_interface::read_msr(int cpu, unsigned int idx, unsigned long long *val)
+{
+	int ret =  - 1;
+	char path_str[MAX_TEMP_STR_SIZE];
+	struct stat s;
+
+	sprintf(path_str, "/dev/cpu/%d/msr", cpu);
+	if(stat(path_str, &s) == 0) {
+		int fd = ::open(path_str, O_RDONLY);
+		if(fd < 0)
+			return  -errno;
+		if(::lseek(fd, idx, SEEK_CUR) ==  - 1)
+			return  - errno;
+		ret = ::read(fd, val, sizeof(unsigned long long));
+		close(fd);
+	}
+
+	return ret;
+}
+
+int c_rapl_interface::write_msr(int cpu, unsigned int idx, unsigned long long val)
+{
+	int ret =  - 1;
+	char path_str[MAX_TEMP_STR_SIZE];
+	struct stat s;
+
+	sprintf(path_str, "/dev/cpu/%d/msr", cpu);
+	if(stat(path_str, &s) == 0) {
+		int fd = ::open(path_str, O_WRONLY);
+		if(fd < 0)
+			return  -errno;
+		if(::lseek(fd, idx, SEEK_CUR) ==  - 1)
+			return  - errno;
+		ret = ::write(fd, &val, sizeof(unsigned long long));
+		close(fd);
+	}
+
+	return ret;
+}
+
+unsigned int c_rapl_interface::int_2_pow(int pow)
+{
+	int i;
+	int _pow = 1;
+
+	for(i = 0; i < pow; ++i)
+		_pow = _pow * 2;
+
+	return _pow;
+}
+
+int c_rapl_interface::get_rapl_power_unit(unsigned long long *value)
+{
+	int ret;
+
+	ret = read_msr(0, MSR_RAPL_POWER_UNIT, value);
+
+	return ret;
+}
+
+double c_rapl_interface::get_power_unit()
+{
+	int ret;
+	unsigned long long value;
+
+	ret = get_rapl_power_unit(&value);
+	if(ret < 0)
+	{
+		return ret;
+	}
+
+	return (double) 1/int_2_pow(value & 0xf);
+}
+
+double c_rapl_interface::get_energy_status_unit()
+{
+	int ret;
+	unsigned long long value;
+
+	ret = get_rapl_power_unit(&value);
+	if(ret < 0)
+	{
+		return ret;
+	}
+
+	return (double)1/ int_2_pow((value & 0x1f00) >> 8);
+}
+
+double c_rapl_interface::get_time_unit()
+{
+	int ret;
+	unsigned long long value;
+
+	ret = get_rapl_power_unit(&value);
+	if(ret < 0)
+	{
+		return ret;
+	}
+
+	return (double)1 / int_2_pow((value & 0xf0000) >> 16);
+}
+
+int c_rapl_interface::get_pkg_energy_status(double *status)
+{
+	int ret;
+	unsigned long long value;
+
+	if (!(rapl_domains & PKG_DOMAIN_PRESENT)) {
+		return -1;
+	}
+
+	ret = read_msr(0, MSR_PKG_ENERY_STATUS, &value);
+	if(ret < 0)
+	{
+		RAPL_ERROR_PRINT("get_pkg_energy_status failed\n");
+		return ret;
+	}
+
+	*status = (double) (value & 0xffffffff) * get_energy_status_unit();
+
+	return ret;
+}
+
+int c_rapl_interface::get_pkg_power_info(double *thermal_spec_power,
+			double *max_power, double *min_power, double *max_time_window)
+{
+	int ret;
+	unsigned long long value;
+
+	if (!(rapl_domains & PKG_DOMAIN_PRESENT)) {
+		return -1;
+	}
+	ret = read_msr(0, MSR_PKG_POWER_INFO, &value);
+	if(ret < 0)
+	{
+		RAPL_ERROR_PRINT("get_pkg_power_info failed\n");
+		return ret;
+	}
+	*thermal_spec_power =  (value & 0x7FFF) * power_units;
+	*min_power =  ((value & 0x7FFF0000) >> 16) * power_units;
+	*max_power =  ((value & 0x7FFF00000000) >> 32) * power_units;
+	*max_time_window = ((value & 0x3f000000000000)>>48) * time_units;
+
+	return ret;
+}
+
+int c_rapl_interface::get_pkg_power_limit(unsigned long long *value)
+{
+	int ret;
+
+	if (!(rapl_domains & PKG_DOMAIN_PRESENT)) {
+		return -1;
+	}
+
+	ret = read_msr(0, MSR_PKG_POWER_LIMIT, value);
+	if(ret < 0)
+	{
+		RAPL_ERROR_PRINT("get_pkg_power_limit failed\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+int c_rapl_interface::set_pkg_power_limit(unsigned long long value)
+{
+	int ret;
+
+	if (!(rapl_domains & PKG_DOMAIN_PRESENT)) {
+		return -1;
+	}
+
+	ret = write_msr(0, MSR_PKG_POWER_LIMIT, value);
+	if(ret < 0)
+	{
+		RAPL_ERROR_PRINT("set_pkg_power_limit failed\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+int c_rapl_interface::get_dram_energy_status(double *status)
+{
+	int ret;
+	unsigned long long value;
+
+	if (!(rapl_domains & DRAM_DOMAIN_PRESENT)) {
+		return -1;
+	}
+
+	ret = read_msr(0, MSR_DRAM_ENERY_STATUS, &value);
+	if(ret < 0)
+	{
+		RAPL_ERROR_PRINT("get_dram_energy_status failed\n");
+		return ret;
+	}
+
+	*status = (double) (value & 0xffffffff) * get_energy_status_unit();
+
+	return ret;
+}
+
+int c_rapl_interface::get_dram_power_info(double *thermal_spec_power,
+			double *max_power, double *min_power, double *max_time_window)
+{
+	int ret;
+	unsigned long long value;
+
+	if (!(rapl_domains & DRAM_DOMAIN_PRESENT)) {
+		return -1;
+	}
+	ret = read_msr(0, MSR_DRAM_POWER_INFO, &value);
+	if(ret < 0)
+	{
+		RAPL_ERROR_PRINT("get_dram_power_info failed\n");
+		return ret;
+	}
+
+	*thermal_spec_power =  (value & 0x7FFF) * power_units;
+	*min_power =  ((value & 0x7FFF0000) >> 16) * power_units;
+	*max_power =  ((value & 0x7FFF00000000) >> 32) * power_units;
+	*max_time_window = ((value & 0x3f000000000000)>>48) * time_units;
+
+	return ret;
+}
+
+int c_rapl_interface::get_dram_power_limit(unsigned long long *value)
+{
+	int ret;
+
+	if (!(rapl_domains & DRAM_DOMAIN_PRESENT)) {
+		return -1;
+	}
+
+	ret = read_msr(0, MSR_DRAM_POWER_LIMIT, value);
+	if(ret < 0)
+	{
+		RAPL_ERROR_PRINT("get_dram_power_limit failed\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+int c_rapl_interface::set_dram_power_limit(unsigned long long value)
+{
+	int ret;
+
+	if (!(rapl_domains & DRAM_DOMAIN_PRESENT)) {
+		return -1;
+	}
+
+	ret = write_msr(0, MSR_DRAM_POWER_LIMIT, value);
+	if(ret < 0)
+	{
+		RAPL_ERROR_PRINT("set_dram_power_limit failed\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+int c_rapl_interface::get_pp0_energy_status(double *status)
+{
+	int ret;
+	unsigned long long value;
+
+	if (!(rapl_domains & PP0_DOMAIN_PRESENT)) {
+		return -1;
+	}
+
+	ret = read_msr(0, MSR_PP0_ENERY_STATUS, &value);
+	if(ret < 0)
+	{
+		RAPL_ERROR_PRINT("get_pp0_energy_status failed\n");
+		return ret;
+	}
+
+	*status = (double) (value & 0xffffffff) * get_energy_status_unit();
+
+	return ret;
+}
+
+int c_rapl_interface::get_pp0_power_limit(unsigned long long *value)
+{
+	int ret;
+
+	if (!(rapl_domains & PP0_DOMAIN_PRESENT)) {
+		return -1;
+	}
+
+	ret = read_msr(0, MSR_PP0_POWER_LIMIT, value);
+	if(ret < 0)
+	{
+		RAPL_ERROR_PRINT("get_pp0_power_limit failed\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+int c_rapl_interface::set_pp0_power_limit(unsigned long long value)
+{
+	int ret;
+
+	if (!(rapl_domains & PP0_DOMAIN_PRESENT)) {
+		return -1;
+	}
+
+	ret = write_msr(0, MSR_PP0_POWER_LIMIT, value);
+	if(ret < 0)
+	{
+		RAPL_ERROR_PRINT("set_pp0_power_limit failed\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+int c_rapl_interface::get_pp0_power_policy(unsigned int *pp0_power_policy)
+{
+	int ret;
+	unsigned long long value;
+
+	if (!(rapl_domains & PP0_DOMAIN_PRESENT)) {
+		return -1;
+	}
+
+	ret = read_msr(0, MSR_PP0_POLICY, &value);
+	if(ret < 0)
+	{
+		RAPL_ERROR_PRINT("get_pp0_power_policy failed\n");
+		return ret;
+	}
+
+	*pp0_power_policy =  value & 0x0f;
+
+	return ret;
+}
+
+int c_rapl_interface::get_pp1_energy_status(double *status)
+{
+	int ret;
+	unsigned long long value;
+
+	if (!(rapl_domains & PP1_DOMAIN_PRESENT)) {
+		return -1;
+	}
+
+	ret = read_msr(0, MSR_PP1_ENERY_STATUS, &value);
+	if(ret < 0)
+	{
+		RAPL_ERROR_PRINT("get_pp1_energy_status failed\n");
+		return ret;
+	}
+
+	*status = (double) (value & 0xffffffff) * get_energy_status_unit();
+
+	return ret;
+}
+
+int c_rapl_interface::get_pp1_power_limit(unsigned long long *value)
+{
+	int ret;
+
+	if (!(rapl_domains & PP1_DOMAIN_PRESENT)) {
+		return -1;
+	}
+
+	ret = read_msr(0, MSR_PP1_POWER_LIMIT, value);
+	if(ret < 0)
+	{
+		RAPL_ERROR_PRINT("get_pp1_power_info failed\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+int c_rapl_interface::set_pp1_power_limit(unsigned long long value)
+{
+	int ret;
+
+	if (!(rapl_domains & PP1_DOMAIN_PRESENT)) {
+		return -1;
+	}
+
+	ret = write_msr(0, MSR_PP1_POWER_LIMIT, value);
+	if(ret < 0)
+	{
+		RAPL_ERROR_PRINT("set_pp1_power_limit failed\n");
+		return ret;
+	}
+
+	return ret;
+}
+
+int c_rapl_interface::get_pp1_power_policy(unsigned int *pp1_power_policy)
+{
+	int ret;
+	unsigned long long value;
+
+	if (!(rapl_domains & PP1_DOMAIN_PRESENT)) {
+		return -1;
+	}
+
+	ret = read_msr(0, MSR_PP1_POLICY, &value);
+	if(ret < 0)
+	{
+		RAPL_ERROR_PRINT("get_pp1_power_policy failed\n");
+		return ret;
+	}
+
+	*pp1_power_policy =  value & 0x0f;
+
+	return ret;
+}
+
+void c_rapl_interface::rapl_measure_energy()
+{
+#ifdef RAPL_TEST_MODE
+	int ret;
+	double energy_status;
+	double thermal_spec_power;
+	double max_power;
+	double min_power;
+	double max_time_window;
+	double pkg_watts = 0;
+	double dram_watts = 0;
+	double pp0_watts = 0;
+	double pp1_watts = 0;
+	double pkg_joules = 0;
+	double dram_joules = 0;
+	double pp0_joules = 0;
+	double pp1_joules = 0;
+
+	ret = get_pkg_power_info(&thermal_spec_power, &max_power, &min_power, &max_time_window);
+	RAPL_DBG_PRINT("Pkg Power Info: Thermal spec %f watts, max %f watts, min %f watts, max time window %f seconds\n", thermal_spec_power, max_power, min_power, max_time_window);
+	ret = get_dram_power_info(&thermal_spec_power, &max_power, &min_power, &max_time_window);
+	RAPL_DBG_PRINT("DRAM Power Info: Thermal spec %f watts, max %f watts, min %f watts, max time window %f seconds\n", thermal_spec_power, max_power, min_power, max_time_window);
+
+	for (;;) {
+		if (pkg_domain_present()) {
+			ret = get_pkg_energy_status(&energy_status);
+			if (last_pkg_energy_status == 0)
+				last_pkg_energy_status = energy_status;
+			if (ret > 0) {
+				pkg_joules = energy_status;
+				pkg_watts = (energy_status-last_pkg_energy_status)/measurment_interval;
+			}
+			last_pkg_energy_status = energy_status;
+		}
+		if (dram_domain_present()) {
+			ret = get_dram_energy_status(&energy_status);
+			if (last_dram_energy_status == 0)
+				last_dram_energy_status = energy_status;
+			if (ret > 0){
+				dram_joules = energy_status;
+				dram_watts = (energy_status-last_dram_energy_status)/measurment_interval;
+			}
+			last_dram_energy_status = energy_status;
+		}
+		if (pp0_domain_present()) {
+			ret = get_pp0_energy_status(&energy_status);
+			if (last_pp0_energy_status == 0)
+				last_pp0_energy_status = energy_status;
+			if (ret > 0){
+				pp0_joules = energy_status;
+				pp0_watts = (energy_status-last_pp0_energy_status)/measurment_interval;
+			}
+			last_pp0_energy_status = energy_status;
+		}
+		if (pp1_domain_present()) {
+			ret = get_pp1_energy_status(&energy_status);
+			if (last_pp1_energy_status == 0)
+				last_pp1_energy_status = energy_status;
+			if (ret > 0){
+				pp1_joules = energy_status;
+				pp1_watts = (energy_status-last_pp1_energy_status)/measurment_interval;
+			}
+			last_pp1_energy_status = energy_status;
+		}
+		RAPL_DBG_PRINT("%f, %f, %f, %f\n", pkg_watts, dram_watts, pp0_watts, pp1_watts);
+		sleep(measurment_interval);
+	}
+#endif
+}
diff --git a/src/cpu/rapl/rapl_interface.h b/src/cpu/rapl/rapl_interface.h
new file mode 100644
index 0000000..f9f2098
--- /dev/null
+++ b/src/cpu/rapl/rapl_interface.h
@@ -0,0 +1,87 @@
+/* rapl_interface.h: rapl interface for power top
+ *
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ *
+ * Author Name <Srinivas.Pandruvada(a)linux.intel.com>
+ *
+ */
+
+#ifndef RAPL_INTERFACE_H
+#define RAPL_INTERFACE_H
+
+class c_rapl_interface
+{
+private:
+	static const int def_sampling_interval = 1; //In seconds
+	int no_of_cpus;
+	unsigned char rapl_domains;
+	int measurment_interval;
+
+	double power_units;
+	double energy_status_units;
+	double time_units;
+
+	double last_pkg_energy_status;
+	double last_dram_energy_status;
+	double last_pp0_energy_status;
+	double last_pp1_energy_status;
+
+	int get_no_cpus();
+	int read_msr(int cpu, unsigned int idx, unsigned long long *val);
+	int write_msr(int cpu, unsigned int idx, unsigned long long val);
+
+public:
+	c_rapl_interface();
+
+	unsigned int int_2_pow(int pow);
+	int get_rapl_power_unit(unsigned long long *value);
+	double get_power_unit();
+	double get_energy_status_unit();
+	double get_time_unit();
+
+	int get_pkg_energy_status(double *status);
+	int get_pkg_power_info(double *thermal_spec_power,
+			double *max_power, double *min_power, double *max_time_window);
+	int get_pkg_power_limit(unsigned long long *value);
+	int set_pkg_power_limit(unsigned long long value);
+
+	int get_dram_energy_status(double *status);
+	int get_dram_power_info(double *thermal_spec_power,
+			double *max_power, double *min_power, double *max_time_window);
+	int get_dram_power_limit(unsigned long long *value);
+	int set_dram_power_limit(unsigned long long value);
+
+	int get_pp0_energy_status(double *status);
+	int get_pp0_power_limit(unsigned long long *value);
+	int set_pp0_power_limit(unsigned long long value);
+	int get_pp0_power_policy(unsigned int *pp0_power_policy);
+
+	int get_pp1_energy_status(double *status);
+	int get_pp1_power_limit(unsigned long long *value);
+	int set_pp1_power_limit(unsigned long long value);
+	int get_pp1_power_policy(unsigned int *pp1_power_policy);
+
+	bool pkg_domain_present();
+	bool dram_domain_present();
+	bool pp0_domain_present();
+	bool pp1_domain_present();
+
+	void rapl_measure_energy();
+};
+
+#endif
-- 
1.7.11.7


^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [Powertop] [PATCH 1/5] RAPL Interface
@ 2013-04-11 13:31 Sergey Senozhatsky
  0 siblings, 0 replies; 2+ messages in thread
From: Sergey Senozhatsky @ 2013-04-11 13:31 UTC (permalink / raw)
  To: powertop

[-- Attachment #1: Type: text/plain, Size: 22482 bytes --]

Hello,

On (04/09/13 09:20), Srinivas Pandruvada wrote:
> Date: Tue,  9 Apr 2013 09:20:07 -0700
> From: Srinivas Pandruvada <srinivas.pandruvada(a)linux.intel.com>
> To: powertop(a)lists.01.org
> Subject: [Powertop] [PATCH 1/5] RAPL Interface
> X-Mailer: git-send-email 1.7.11.7
> 
> Added RAPL interface class. This provides methods to get the status
> of RAPL domains and get energy and power status.
> 
> Signed-off-by: Srinivas Pandruvada <srinivas.pandruvada(a)linux.intel.com>
> ---
>  src/Makefile.am                 |   3 +-
>  src/cpu/rapl/rapl_interface.cpp | 662 ++++++++++++++++++++++++++++++++++++++++
>  src/cpu/rapl/rapl_interface.h   |  87 ++++++
>  3 files changed, 751 insertions(+), 1 deletion(-)
>  create mode 100644 src/cpu/rapl/rapl_interface.cpp
>  create mode 100644 src/cpu/rapl/rapl_interface.h
> 
> diff --git a/src/Makefile.am b/src/Makefile.am
> index 398b8a7..0983b51 100644
> --- a/src/Makefile.am
> +++ b/src/Makefile.am
> @@ -31,7 +31,8 @@ powertop_SOURCES = parameters/persistent.cpp parameters/learn.cpp parameters/par
>  		report/report-formatter-base.cpp report/report-formatter-base.h \
>  		report/report-formatter-csv.cpp report/report-formatter-csv.h \
>  		report/report-formatter-html.cpp report/report-formatter-html.h \
> -		main.cpp css.h powertop.css cpu/intel_gpu.cpp
> +		main.cpp css.h powertop.css cpu/intel_gpu.cpp \
> +		cpu/rapl/rapl_interface.cpp
>  
>  
>  powertop_CXXFLAGS = -fno-omit-frame-pointer -fstack-protector -Wall -Wshadow -Wformat $(NCURSES_CFLAGS) $(PCIUTILS_CFLAGS) $(LIBNL_CFLAGS) $(GLIB2_CFLAGS)
> diff --git a/src/cpu/rapl/rapl_interface.cpp b/src/cpu/rapl/rapl_interface.cpp
> new file mode 100644
> index 0000000..3e54201
> --- /dev/null
> +++ b/src/cpu/rapl/rapl_interface.cpp
> @@ -0,0 +1,662 @@
> +/* rapl_interface.cpp: rapl interface for power top implementation
> + *
> + * Copyright (C) 2012 Intel Corporation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License version
> + * 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> + * 02110-1301, USA.
> + *
> + *
> + * Author Name <Srinivas.Pandruvada(a)linux.intel.com>
> + *
> + */
> +#include <stdio.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <fcntl.h>
> +#include <unistd.h>
> +#include <errno.h>
> +#include "rapl_interface.h"
> +
> +#ifdef DEBUG
> +#define RAPL_DBG_PRINT printf
> +#define RAPL_ERROR_PRINT printf
> +#else
> +#define RAPL_DBG_PRINT(...)	((void) 0)
> +#define RAPL_ERROR_PRINT(...) ((void) 0)
> +#endif
> +#define MAX_TEMP_STR_SIZE	20
> +
> +// RAPL interface
> +#define MSR_RAPL_POWER_UNIT	0x606
> +#define MSR_PKG_POWER_LIMIT	0x610
> +
> +#define MSR_PKG_ENERY_STATUS	0x611
> +#define MSR_PKG_POWER_INFO	0x614
> +#define MSR_PKG_PERF_STATUS	0x613
> +
> +#define MSR_DRAM_POWER_LIMIT	0x618
> +#define MSR_DRAM_ENERY_STATUS	0x619
> +#define MSR_DRAM_PERF_STATUS	0x61B
> +#define MSR_DRAM_POWER_INFO	0x61c
> +
> +#define MSR_PP0_POWER_LIMIT	0x638
> +#define MSR_PP0_ENERY_STATUS	0x639
> +#define MSR_PP0_POLICY		0x63A
> +#define MSR_PP0_PERF_STATUS	0x63B
> +
> +#define MSR_PP1_POWER_LIMIT	0x640
> +#define MSR_PP1_ENERY_STATUS	0x641
> +#define MSR_PP1_POLICY		0x642
> +
> +#define PKG_DOMAIN_PRESENT	0x01
> +#define DRAM_DOMAIN_PRESENT	0x02
> +#define PP0_DOMAIN_PRESENT	0x04
> +#define PP1_DOMAIN_PRESENT	0x08
> +
> +c_rapl_interface::c_rapl_interface() :
> +	measurment_interval(def_sampling_interval),
> +	last_pkg_energy_status(0.0),
> +	last_dram_energy_status(0.0),
> +	last_pp0_energy_status(0.0),
> +	last_pp1_energy_status(0.0)
> +{
> +	char path_str[MAX_TEMP_STR_SIZE];
> +	unsigned long long value;
> +	int ret;
> +
> +	no_of_cpus = 0;
> +	for(int i = 0; i < 64; ++i)

			^^^^^^^^
why 64?


> +	{
> +		struct stat s;
> +		sprintf(path_str, "/dev/cpu/%d", i);
> +		if(stat(path_str, &s) == 0) {
> +			no_of_cpus++;
> +		}
> +	}
> +

sysconf(_SC_NPROCESSORS_ONLN) ?


> +	rapl_domains = 0;
> +
> +	// presence of each domain
> +	// Check presence of PKG domain
> +	ret = read_msr(0, MSR_PKG_ENERY_STATUS, &value);
> +	if (ret > 0) {
> +		rapl_domains |= PKG_DOMAIN_PRESENT;
> +		RAPL_DBG_PRINT("Domain : PKG present\n");
> +	} else {
> +		RAPL_DBG_PRINT("Domain : PKG Not present\n");
> +	}
> +
> +	// Check presence of DRAM domain
> +	ret = read_msr(0, MSR_DRAM_ENERY_STATUS, &value);
> +	if (ret > 0) {
> +		rapl_domains |= DRAM_DOMAIN_PRESENT;
> +		RAPL_DBG_PRINT("Domain : DRAM present\n");
> +	} else {
> +		RAPL_DBG_PRINT("Domain : DRAM Not present\n");
> +	}
> +
> +	// Check presence of PP0 domain
> +	ret = read_msr(0, MSR_PP0_ENERY_STATUS, &value);
> +	if (ret > 0) {
> +		rapl_domains |= PP0_DOMAIN_PRESENT;
> +		RAPL_DBG_PRINT("Domain : PP0 present\n");
> +	} else {
> +		RAPL_DBG_PRINT("Domain : PP0 Not present\n");
> +	}
> +
> +	// Check presence of PP1 domain
> +	ret = read_msr(0, MSR_PP1_ENERY_STATUS, &value);
> +	if (ret > 0) {
> +		rapl_domains |= PP1_DOMAIN_PRESENT;
> +		RAPL_DBG_PRINT("Domain : PP1 present\n");
> +	} else {
> +		RAPL_DBG_PRINT("Domain : PP1 Not present\n");
> +	}
> +
> +	power_units = get_power_unit();
> +	energy_status_units = get_energy_status_unit();
> +	time_units = get_time_unit();
> +
> +	RAPL_DBG_PRINT("RAPL Domain mask: %x\n", rapl_domains);
> +}
> +
> +bool c_rapl_interface::pkg_domain_present()
> +{
> +	if ((rapl_domains & PKG_DOMAIN_PRESENT)) {
> +		return true;
> +	}
> +
> +	return false;
> +}
> +
> +bool c_rapl_interface::dram_domain_present()
> +{
> +	if ((rapl_domains & DRAM_DOMAIN_PRESENT)) {
> +		return true;
> +	}
> +
> +	return false;
> +}
> +
> +bool c_rapl_interface::pp0_domain_present()
> +{
> +	if ((rapl_domains & PP0_DOMAIN_PRESENT)) {
> +		return true;
> +	}
> +
> +	return false;
> +}
> +
> +bool c_rapl_interface::pp1_domain_present()
> +{
> +	if ((rapl_domains & PP1_DOMAIN_PRESENT)) {
> +		return true;
> +	}
> +
> +	return false;
> +}
> +
> +int c_rapl_interface::get_no_cpus()
> +{
> +	return no_of_cpus;
> +}
> +
> +int c_rapl_interface::read_msr(int cpu, unsigned int idx, unsigned long long *val)
> +{
> +	int ret =  - 1;
> +	char path_str[MAX_TEMP_STR_SIZE];
> +	struct stat s;
> +

we have that code in src/cpu/intel_cpus.cpp get_msr(int cpu, uint64_t offset).
can we make it general and move to lib part?


> +	sprintf(path_str, "/dev/cpu/%d/msr", cpu);
> +	if(stat(path_str, &s) == 0) {
> +		int fd = ::open(path_str, O_RDONLY);
> +		if(fd < 0)
> +			return  -errno;
> +		if(::lseek(fd, idx, SEEK_CUR) ==  - 1)
> +			return  - errno;
> +		ret = ::read(fd, val, sizeof(unsigned long long));
> +		close(fd);
> +	}
> +
> +	return ret;
> +}
> +
> +int c_rapl_interface::write_msr(int cpu, unsigned int idx, unsigned long long val)
> +{
> +	int ret =  - 1;
> +	char path_str[MAX_TEMP_STR_SIZE];
> +	struct stat s;
> +
> +	sprintf(path_str, "/dev/cpu/%d/msr", cpu);
> +	if(stat(path_str, &s) == 0) {
> +		int fd = ::open(path_str, O_WRONLY);
> +		if(fd < 0)
> +			return  -errno;
> +		if(::lseek(fd, idx, SEEK_CUR) ==  - 1)
> +			return  - errno;
> +		ret = ::write(fd, &val, sizeof(unsigned long long));
> +		close(fd);
> +	}
> +
> +	return ret;
> +}
> +
> +unsigned int c_rapl_interface::int_2_pow(int pow)
> +{
> +	int i;
> +	int _pow = 1;
> +
> +	for(i = 0; i < pow; ++i)
> +		_pow = _pow * 2;
> +

why not c++ pow()?

> +	return _pow;
> +}
> +
> +int c_rapl_interface::get_rapl_power_unit(unsigned long long *value)
> +{
> +	int ret;
> +
> +	ret = read_msr(0, MSR_RAPL_POWER_UNIT, value);
> +
> +	return ret;
> +}
> +
> +double c_rapl_interface::get_power_unit()
> +{
> +	int ret;
> +	unsigned long long value;
> +
> +	ret = get_rapl_power_unit(&value);
> +	if(ret < 0)
> +	{
> +		return ret;
> +	}
> +
> +	return (double) 1/int_2_pow(value & 0xf);
> +}
> +
> +double c_rapl_interface::get_energy_status_unit()
> +{
> +	int ret;
> +	unsigned long long value;
> +
> +	ret = get_rapl_power_unit(&value);
> +	if(ret < 0)
> +	{
> +		return ret;
> +	}
> +
> +	return (double)1/ int_2_pow((value & 0x1f00) >> 8);
> +}
> +
> +double c_rapl_interface::get_time_unit()
> +{
> +	int ret;
> +	unsigned long long value;
> +
> +	ret = get_rapl_power_unit(&value);
> +	if(ret < 0)
> +	{
> +		return ret;
> +	}
> +
> +	return (double)1 / int_2_pow((value & 0xf0000) >> 16);
> +}
> +
> +int c_rapl_interface::get_pkg_energy_status(double *status)
> +{
> +	int ret;
> +	unsigned long long value;
> +
> +	if (!(rapl_domains & PKG_DOMAIN_PRESENT)) {
> +		return -1;
> +	}
> +

well, then why have c_rapl_interface::pkg_domain_present()?
+ a bunch of direct rapl_domains bit checks.



> +	ret = read_msr(0, MSR_PKG_ENERY_STATUS, &value);
> +	if(ret < 0)
> +	{
> +		RAPL_ERROR_PRINT("get_pkg_energy_status failed\n");
> +		return ret;
> +	}
> +
> +	*status = (double) (value & 0xffffffff) * get_energy_status_unit();
> +
> +	return ret;
> +}
> +
> +int c_rapl_interface::get_pkg_power_info(double *thermal_spec_power,
> +			double *max_power, double *min_power, double *max_time_window)
> +{
> +	int ret;
> +	unsigned long long value;
> +
> +	if (!(rapl_domains & PKG_DOMAIN_PRESENT)) {
> +		return -1;
> +	}
> +	ret = read_msr(0, MSR_PKG_POWER_INFO, &value);
> +	if(ret < 0)
> +	{
> +		RAPL_ERROR_PRINT("get_pkg_power_info failed\n");
> +		return ret;
> +	}
> +	*thermal_spec_power =  (value & 0x7FFF) * power_units;
> +	*min_power =  ((value & 0x7FFF0000) >> 16) * power_units;
> +	*max_power =  ((value & 0x7FFF00000000) >> 32) * power_units;
> +	*max_time_window = ((value & 0x3f000000000000)>>48) * time_units;
> +
> +	return ret;
> +}
> +
> +int c_rapl_interface::get_pkg_power_limit(unsigned long long *value)
> +{
> +	int ret;
> +
> +	if (!(rapl_domains & PKG_DOMAIN_PRESENT)) {
> +		return -1;
> +	}
> +
> +	ret = read_msr(0, MSR_PKG_POWER_LIMIT, value);
> +	if(ret < 0)
> +	{
> +		RAPL_ERROR_PRINT("get_pkg_power_limit failed\n");
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +int c_rapl_interface::set_pkg_power_limit(unsigned long long value)
> +{
> +	int ret;
> +
> +	if (!(rapl_domains & PKG_DOMAIN_PRESENT)) {
> +		return -1;
> +	}
> +
> +	ret = write_msr(0, MSR_PKG_POWER_LIMIT, value);
> +	if(ret < 0)
> +	{
> +		RAPL_ERROR_PRINT("set_pkg_power_limit failed\n");
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +int c_rapl_interface::get_dram_energy_status(double *status)
> +{
> +	int ret;
> +	unsigned long long value;
> +
> +	if (!(rapl_domains & DRAM_DOMAIN_PRESENT)) {
> +		return -1;
> +	}
> +
> +	ret = read_msr(0, MSR_DRAM_ENERY_STATUS, &value);
> +	if(ret < 0)
> +	{
> +		RAPL_ERROR_PRINT("get_dram_energy_status failed\n");
> +		return ret;
> +	}
> +
> +	*status = (double) (value & 0xffffffff) * get_energy_status_unit();
> +
> +	return ret;
> +}
> +
> +int c_rapl_interface::get_dram_power_info(double *thermal_spec_power,
> +			double *max_power, double *min_power, double *max_time_window)
> +{
> +	int ret;
> +	unsigned long long value;
> +
> +	if (!(rapl_domains & DRAM_DOMAIN_PRESENT)) {
> +		return -1;
> +	}
> +	ret = read_msr(0, MSR_DRAM_POWER_INFO, &value);
> +	if(ret < 0)
> +	{
> +		RAPL_ERROR_PRINT("get_dram_power_info failed\n");
> +		return ret;
> +	}
> +
> +	*thermal_spec_power =  (value & 0x7FFF) * power_units;
> +	*min_power =  ((value & 0x7FFF0000) >> 16) * power_units;
> +	*max_power =  ((value & 0x7FFF00000000) >> 32) * power_units;
> +	*max_time_window = ((value & 0x3f000000000000)>>48) * time_units;
> +
> +	return ret;
> +}
> +
> +int c_rapl_interface::get_dram_power_limit(unsigned long long *value)
> +{
> +	int ret;
> +
> +	if (!(rapl_domains & DRAM_DOMAIN_PRESENT)) {
> +		return -1;
> +	}
> +
> +	ret = read_msr(0, MSR_DRAM_POWER_LIMIT, value);
> +	if(ret < 0)
> +	{
> +		RAPL_ERROR_PRINT("get_dram_power_limit failed\n");
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +int c_rapl_interface::set_dram_power_limit(unsigned long long value)
> +{
> +	int ret;
> +
> +	if (!(rapl_domains & DRAM_DOMAIN_PRESENT)) {
> +		return -1;
> +	}
> +
> +	ret = write_msr(0, MSR_DRAM_POWER_LIMIT, value);
> +	if(ret < 0)
> +	{
> +		RAPL_ERROR_PRINT("set_dram_power_limit failed\n");
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +int c_rapl_interface::get_pp0_energy_status(double *status)
> +{
> +	int ret;
> +	unsigned long long value;
> +
> +	if (!(rapl_domains & PP0_DOMAIN_PRESENT)) {
> +		return -1;
> +	}
> +
> +	ret = read_msr(0, MSR_PP0_ENERY_STATUS, &value);
> +	if(ret < 0)
> +	{
> +		RAPL_ERROR_PRINT("get_pp0_energy_status failed\n");
> +		return ret;
> +	}
> +
> +	*status = (double) (value & 0xffffffff) * get_energy_status_unit();
> +
> +	return ret;
> +}
> +
> +int c_rapl_interface::get_pp0_power_limit(unsigned long long *value)
> +{
> +	int ret;
> +
> +	if (!(rapl_domains & PP0_DOMAIN_PRESENT)) {
> +		return -1;
> +	}
> +
> +	ret = read_msr(0, MSR_PP0_POWER_LIMIT, value);
> +	if(ret < 0)
> +	{
> +		RAPL_ERROR_PRINT("get_pp0_power_limit failed\n");
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +int c_rapl_interface::set_pp0_power_limit(unsigned long long value)
> +{
> +	int ret;
> +
> +	if (!(rapl_domains & PP0_DOMAIN_PRESENT)) {
> +		return -1;
> +	}
> +
> +	ret = write_msr(0, MSR_PP0_POWER_LIMIT, value);
> +	if(ret < 0)
> +	{
> +		RAPL_ERROR_PRINT("set_pp0_power_limit failed\n");
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +int c_rapl_interface::get_pp0_power_policy(unsigned int *pp0_power_policy)
> +{
> +	int ret;
> +	unsigned long long value;
> +
> +	if (!(rapl_domains & PP0_DOMAIN_PRESENT)) {
> +		return -1;
> +	}
> +
> +	ret = read_msr(0, MSR_PP0_POLICY, &value);
> +	if(ret < 0)
> +	{
> +		RAPL_ERROR_PRINT("get_pp0_power_policy failed\n");
> +		return ret;
> +	}
> +
> +	*pp0_power_policy =  value & 0x0f;
> +
> +	return ret;
> +}
> +
> +int c_rapl_interface::get_pp1_energy_status(double *status)
> +{
> +	int ret;
> +	unsigned long long value;
> +
> +	if (!(rapl_domains & PP1_DOMAIN_PRESENT)) {
> +		return -1;
> +	}
> +
> +	ret = read_msr(0, MSR_PP1_ENERY_STATUS, &value);
> +	if(ret < 0)
> +	{
> +		RAPL_ERROR_PRINT("get_pp1_energy_status failed\n");
> +		return ret;
> +	}
> +
> +	*status = (double) (value & 0xffffffff) * get_energy_status_unit();
> +
> +	return ret;
> +}
> +
> +int c_rapl_interface::get_pp1_power_limit(unsigned long long *value)
> +{
> +	int ret;
> +
> +	if (!(rapl_domains & PP1_DOMAIN_PRESENT)) {
> +		return -1;
> +	}
> +
> +	ret = read_msr(0, MSR_PP1_POWER_LIMIT, value);
> +	if(ret < 0)
> +	{
> +		RAPL_ERROR_PRINT("get_pp1_power_info failed\n");
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +int c_rapl_interface::set_pp1_power_limit(unsigned long long value)
> +{
> +	int ret;
> +
> +	if (!(rapl_domains & PP1_DOMAIN_PRESENT)) {
> +		return -1;
> +	}
> +
> +	ret = write_msr(0, MSR_PP1_POWER_LIMIT, value);
> +	if(ret < 0)
> +	{
> +		RAPL_ERROR_PRINT("set_pp1_power_limit failed\n");
> +		return ret;
> +	}
> +
> +	return ret;
> +}
> +
> +int c_rapl_interface::get_pp1_power_policy(unsigned int *pp1_power_policy)
> +{
> +	int ret;
> +	unsigned long long value;
> +
> +	if (!(rapl_domains & PP1_DOMAIN_PRESENT)) {
> +		return -1;
> +	}
> +
> +	ret = read_msr(0, MSR_PP1_POLICY, &value);
> +	if(ret < 0)
> +	{
> +		RAPL_ERROR_PRINT("get_pp1_power_policy failed\n");
> +		return ret;
> +	}
> +
> +	*pp1_power_policy =  value & 0x0f;
> +
> +	return ret;
> +}
> +
> +void c_rapl_interface::rapl_measure_energy()
> +{
> +#ifdef RAPL_TEST_MODE
> +	int ret;
> +	double energy_status;
> +	double thermal_spec_power;
> +	double max_power;
> +	double min_power;
> +	double max_time_window;
> +	double pkg_watts = 0;
> +	double dram_watts = 0;
> +	double pp0_watts = 0;
> +	double pp1_watts = 0;
> +	double pkg_joules = 0;
> +	double dram_joules = 0;
> +	double pp0_joules = 0;
> +	double pp1_joules = 0;
> +
> +	ret = get_pkg_power_info(&thermal_spec_power, &max_power, &min_power, &max_time_window);
> +	RAPL_DBG_PRINT("Pkg Power Info: Thermal spec %f watts, max %f watts, min %f watts, max time window %f seconds\n", thermal_spec_power, max_power, min_power, max_time_window);
> +	ret = get_dram_power_info(&thermal_spec_power, &max_power, &min_power, &max_time_window);
> +	RAPL_DBG_PRINT("DRAM Power Info: Thermal spec %f watts, max %f watts, min %f watts, max time window %f seconds\n", thermal_spec_power, max_power, min_power, max_time_window);
> +
> +	for (;;) {
> +		if (pkg_domain_present()) {
> +			ret = get_pkg_energy_status(&energy_status);
> +			if (last_pkg_energy_status == 0)
> +				last_pkg_energy_status = energy_status;
> +			if (ret > 0) {
> +				pkg_joules = energy_status;
> +				pkg_watts = (energy_status-last_pkg_energy_status)/measurment_interval;
> +			}
> +			last_pkg_energy_status = energy_status;
> +		}
> +		if (dram_domain_present()) {
> +			ret = get_dram_energy_status(&energy_status);
> +			if (last_dram_energy_status == 0)
> +				last_dram_energy_status = energy_status;
> +			if (ret > 0){
> +				dram_joules = energy_status;
> +				dram_watts = (energy_status-last_dram_energy_status)/measurment_interval;
> +			}
> +			last_dram_energy_status = energy_status;
> +		}
> +		if (pp0_domain_present()) {
> +			ret = get_pp0_energy_status(&energy_status);
> +			if (last_pp0_energy_status == 0)
> +				last_pp0_energy_status = energy_status;
> +			if (ret > 0){
> +				pp0_joules = energy_status;
> +				pp0_watts = (energy_status-last_pp0_energy_status)/measurment_interval;
> +			}
> +			last_pp0_energy_status = energy_status;
> +		}
> +		if (pp1_domain_present()) {
> +			ret = get_pp1_energy_status(&energy_status);
> +			if (last_pp1_energy_status == 0)
> +				last_pp1_energy_status = energy_status;
> +			if (ret > 0){
> +				pp1_joules = energy_status;
> +				pp1_watts = (energy_status-last_pp1_energy_status)/measurment_interval;
> +			}
> +			last_pp1_energy_status = energy_status;
> +		}
> +		RAPL_DBG_PRINT("%f, %f, %f, %f\n", pkg_watts, dram_watts, pp0_watts, pp1_watts);
> +		sleep(measurment_interval);
> +	}
> +#endif
> +}
> diff --git a/src/cpu/rapl/rapl_interface.h b/src/cpu/rapl/rapl_interface.h
> new file mode 100644
> index 0000000..f9f2098
> --- /dev/null
> +++ b/src/cpu/rapl/rapl_interface.h
> @@ -0,0 +1,87 @@
> +/* rapl_interface.h: rapl interface for power top
> + *
> + * Copyright (C) 2012 Intel Corporation. All rights reserved.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License version
> + * 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> + * 02110-1301, USA.
> + *
> + *
> + * Author Name <Srinivas.Pandruvada(a)linux.intel.com>
> + *
> + */
> +
> +#ifndef RAPL_INTERFACE_H
> +#define RAPL_INTERFACE_H
> +
> +class c_rapl_interface
> +{
> +private:
> +	static const int def_sampling_interval = 1; //In seconds
> +	int no_of_cpus;
> +	unsigned char rapl_domains;
> +	int measurment_interval;
> +
> +	double power_units;
> +	double energy_status_units;
> +	double time_units;
> +
> +	double last_pkg_energy_status;
> +	double last_dram_energy_status;
> +	double last_pp0_energy_status;
> +	double last_pp1_energy_status;
> +
> +	int get_no_cpus();
> +	int read_msr(int cpu, unsigned int idx, unsigned long long *val);
> +	int write_msr(int cpu, unsigned int idx, unsigned long long val);
> +
> +public:
> +	c_rapl_interface();
> +
> +	unsigned int int_2_pow(int pow);
> +	int get_rapl_power_unit(unsigned long long *value);
> +	double get_power_unit();
> +	double get_energy_status_unit();
> +	double get_time_unit();
> +
> +	int get_pkg_energy_status(double *status);
> +	int get_pkg_power_info(double *thermal_spec_power,
> +			double *max_power, double *min_power, double *max_time_window);
> +	int get_pkg_power_limit(unsigned long long *value);
> +	int set_pkg_power_limit(unsigned long long value);
> +
> +	int get_dram_energy_status(double *status);
> +	int get_dram_power_info(double *thermal_spec_power,
> +			double *max_power, double *min_power, double *max_time_window);
> +	int get_dram_power_limit(unsigned long long *value);
> +	int set_dram_power_limit(unsigned long long value);
> +
> +	int get_pp0_energy_status(double *status);
> +	int get_pp0_power_limit(unsigned long long *value);
> +	int set_pp0_power_limit(unsigned long long value);
> +	int get_pp0_power_policy(unsigned int *pp0_power_policy);
> +
> +	int get_pp1_energy_status(double *status);
> +	int get_pp1_power_limit(unsigned long long *value);
> +	int set_pp1_power_limit(unsigned long long value);
> +	int get_pp1_power_policy(unsigned int *pp1_power_policy);
> +
> +	bool pkg_domain_present();
> +	bool dram_domain_present();
> +	bool pp0_domain_present();
> +	bool pp1_domain_present();
> +
> +	void rapl_measure_energy();
> +};
> +
> +#endif
> -- 
> 1.7.11.7
> 
> _______________________________________________
> PowerTop mailing list
> PowerTop(a)lists.01.org
> https://lists.01.org/mailman/listinfo/powertop
> 

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2013-04-11 13:31 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-04-11 13:31 [Powertop] [PATCH 1/5] RAPL Interface Sergey Senozhatsky
  -- strict thread matches above, loose matches on Subject: below --
2013-04-09 16:20 Srinivas Pandruvada

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.