#include "utils_time.h"
#include <asm/msr-index.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <err.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <sys/resource.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <dirent.h>
-#include <string.h>
-#include <ctype.h>
-#include <sched.h>
#include <cpuid.h>
+#ifdef HAVE_SYS_CAPABILITY_H
#include <sys/capability.h>
+#endif /* HAVE_SYS_CAPABILITY_H */
#define PLUGIN_NAME "turbostat"
unsigned long long pc9;
unsigned long long pc10;
unsigned int package_id;
- unsigned int energy_pkg; /* MSR_PKG_ENERGY_STATUS */
- unsigned int energy_dram; /* MSR_DRAM_ENERGY_STATUS */
- unsigned int energy_cores; /* MSR_PP0_ENERGY_STATUS */
- unsigned int energy_gfx; /* MSR_PP1_ENERGY_STATUS */
+ uint32_t energy_pkg; /* MSR_PKG_ENERGY_STATUS */
+ uint32_t energy_dram; /* MSR_DRAM_ENERGY_STATUS */
+ uint32_t energy_cores; /* MSR_PP0_ENERGY_STATUS */
+ uint32_t energy_gfx; /* MSR_PP1_ENERGY_STATUS */
unsigned int tcc_activation_temp;
unsigned int pkg_temp_c;
} *package_delta, *package_even, *package_odd;
#define GET_PKG(pkg_base, pkg_no) (pkg_base + pkg_no)
struct cpu_topology {
- int package_id;
- int core_id;
+ unsigned int package_id;
+ unsigned int core_id;
_Bool first_core_in_package;
_Bool first_thread_in_core;
};
static struct topology {
- int max_cpu_id;
- int num_packages;
- int num_cores;
- int num_threads;
+ unsigned int max_cpu_id;
+ unsigned int num_packages;
+ unsigned int num_cores;
+ unsigned int num_threads;
struct cpu_topology *cpus;
} topology;
* Can change the scheduling affinity of the current process if multiple_read is 1
*/
static int __attribute__((warn_unused_result))
-open_msr(int cpu, _Bool multiple_read)
+open_msr(unsigned int cpu, _Bool multiple_read)
{
char pathname[32];
int fd;
* Open a MSR device for reading, read the value asked for and close it.
* This call will not affect the scheduling affinity of this thread.
*/
-static int __attribute__((warn_unused_result))
-get_msr(int cpu, off_t offset, unsigned long long *msr)
+static ssize_t __attribute__((warn_unused_result))
+get_msr(unsigned int cpu, off_t offset, unsigned long long *msr)
{
ssize_t retval;
int fd;
static int __attribute__((warn_unused_result))
get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
{
- int cpu = t->cpu_id;
+ unsigned int cpu = t->cpu_id;
unsigned long long msr;
int msr_fd;
int retval = 0;
**********************************/
/*
- * Do delta = new - old on 32bits cyclique intergers
- */
-#define DELTA_WRAP32(delta, new, old) \
- if (new > old) { \
- delta = new - old; \
- } else { \
- delta = 0x100000000 + new - old; \
- }
-
-/*
* Extract the evolution old->new in delta at a package level
* (some are not new-delta, e.g. temperature)
*/
delta->pc10 = new->pc10 - old->pc10;
delta->pkg_temp_c = new->pkg_temp_c;
- DELTA_WRAP32(delta->energy_pkg, new->energy_pkg, old->energy_pkg);
- DELTA_WRAP32(delta->energy_cores, new->energy_cores, old->energy_cores);
- DELTA_WRAP32(delta->energy_gfx, new->energy_gfx, old->energy_gfx);
- DELTA_WRAP32(delta->energy_dram, new->energy_dram, old->energy_dram);
+ delta->energy_pkg = new->energy_pkg - old->energy_pkg;
+ delta->energy_cores = new->energy_cores - old->energy_cores;
+ delta->energy_gfx = new->energy_gfx - old->energy_gfx;
+ delta->energy_dram = new->energy_dram - old->energy_dram;
}
/*
* Check if a given cpu id is in our compiled list of existing CPUs
*/
static int
-cpu_is_not_present(int cpu)
+cpu_is_not_present(unsigned int cpu)
{
return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set);
}
for_all_cpus(int (func)(struct thread_data *, struct core_data *, struct pkg_data *),
struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base)
{
- int retval, pkg_no, core_no, thread_no;
+ int retval;
+ unsigned int pkg_no, core_no, thread_no;
for (pkg_no = 0; pkg_no < topology.num_packages; ++pkg_no) {
for (core_no = 0; core_no < topology.num_cores; ++core_no) {
for_all_cpus_delta(const struct thread_data *thread_new_base, const struct core_data *core_new_base, const struct pkg_data *pkg_new_base,
const struct thread_data *thread_old_base, const struct core_data *core_old_base, const struct pkg_data *pkg_old_base)
{
- int retval, pkg_no, core_no, thread_no;
+ int retval;
+ unsigned int pkg_no, core_no, thread_no;
for (pkg_no = 0; pkg_no < topology.num_packages; ++pkg_no) {
for (core_no = 0; core_no < topology.num_cores; ++core_no) {
}
static int
-get_threads_on_core(int cpu)
+get_threads_on_core(unsigned int cpu)
{
char path[80];
FILE *filep;
* return max_cpu number
*/
static int __attribute__((warn_unused_result))
-for_all_proc_cpus(int (func)(int))
+for_all_proc_cpus(int (func)(unsigned int))
{
FILE *fp;
- int cpu_num;
+ unsigned int cpu_num;
int retval;
fp = fopen("/proc/stat", "r");
* Update the stored topology.max_cpu_id
*/
static int
-update_max_cpu_id(int cpu)
+update_max_cpu_id(unsigned int cpu)
{
if (topology.max_cpu_id < cpu)
topology.max_cpu_id = cpu;
}
static int
-mark_cpu_present(int cpu)
+mark_cpu_present(unsigned int cpu)
{
CPU_SET_S(cpu, cpu_present_setsize, cpu_present_set);
return 0;
static int __attribute__((warn_unused_result))
topology_probe()
{
- int i;
+ unsigned int i;
int ret;
- int max_package_id, max_core_id, max_thread_id;
- max_package_id = max_core_id = max_thread_id = 0;
+ unsigned int max_package_id, max_core_id, max_threads;
+ max_package_id = max_core_id = max_threads = 0;
/* Clean topology */
free(topology.cpus);
* find max_core_id, max_package_id
*/
for (i = 0; i <= topology.max_cpu_id; ++i) {
- int num_threads;
+ unsigned int num_threads;
struct cpu_topology *cpu = &topology.cpus[i];
if (cpu_is_not_present(i)) {
if (ret < 0)
goto err;
else
- cpu->package_id = ret;
+ cpu->package_id = (unsigned int) ret;
if (cpu->package_id > max_package_id)
max_package_id = cpu->package_id;
if (ret < 0)
goto err;
else
- cpu->core_id = ret;
+ cpu->core_id = (unsigned int) ret;
if (cpu->core_id > max_core_id)
max_core_id = cpu->core_id;
ret = parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_siblings_list", i);
if (ret < 0)
goto err;
- else if (ret == i)
+ else if ((unsigned int) ret == i)
cpu->first_core_in_package = 1;
ret = get_threads_on_core(i);
if (ret < 0)
goto err;
else
- num_threads = ret;
- if (num_threads > max_thread_id)
- max_thread_id = num_threads;
+ num_threads = (unsigned int) ret;
+ if (num_threads > max_threads)
+ max_threads = num_threads;
ret = parse_int_file("/sys/devices/system/cpu/cpu%d/topology/thread_siblings_list", i);
if (ret < 0)
goto err;
- else if (ret == i)
+ else if ((unsigned int) ret == i)
cpu->first_thread_in_core = 1;
DEBUG("Turbostat plugin: cpu %d pkg %d core %d\n",
/* Num is max + 1 (need to count 0) */
topology.num_packages = max_package_id + 1;
topology.num_cores = max_core_id + 1;
- topology.num_threads = max_thread_id + 1;
+ topology.num_threads = max_threads;
return 0;
err:
static int
allocate_counters(struct thread_data **threads, struct core_data **cores, struct pkg_data **packages)
{
- int i;
- int total_threads, total_cores;
+ unsigned int i;
+ unsigned int total_threads, total_cores;
total_threads = topology.num_threads * topology.num_cores * topology.num_packages;
*threads = calloc(total_threads, sizeof(struct thread_data));
goto err;
for (i = 0; i < total_threads; ++i)
- (*threads)[i].cpu_id = -1;
+ (*threads)[i].cpu_id = topology.max_cpu_id + 1;
total_cores = topology.num_cores * topology.num_packages;
*cores = calloc(total_cores, sizeof(struct core_data));
if (*cores == NULL)
goto err_clean_threads;
- for (i = 0; i < total_cores; ++i)
- (*cores)[i].core_id = -1;
-
*packages = calloc(topology.num_packages, sizeof(struct pkg_data));
if (*packages == NULL)
goto err_clean_cores;
- for (i = 0; i < topology.num_packages; i++)
- (*packages)[i].package_id = i;
-
return 0;
err_clean_cores:
static void
init_counter(struct thread_data *thread_base, struct core_data *core_base,
- struct pkg_data *pkg_base, int cpu_id)
+ struct pkg_data *pkg_base, unsigned int cpu_id)
{
struct thread_data *t;
struct core_data *c;
static void
initialize_counters(void)
{
- int cpu_id;
+ unsigned int cpu_id;
for (cpu_id = 0; cpu_id <= topology.max_cpu_id; ++cpu_id) {
if (cpu_is_not_present(cpu_id))
static int
check_permissions(void)
{
+#ifdef HAVE_SYS_CAPABILITY_H
struct __user_cap_header_struct cap_header_data;
cap_user_header_t cap_header = &cap_header_data;
struct __user_cap_data_struct cap_data_data;
cap_user_data_t cap_data = &cap_data_data;
int ret = 0;
+#endif /* HAVE_SYS_CAPABILITY_H */
if (getuid() == 0) {
/* We have everything we need */
return 0;
+#ifndef HAVE_SYS_CAPABILITY_H
+ } else {
+ ERROR("Turbostat plugin: Initialization failed: this plugin "
+ "requires collectd to run as root");
+ return -1;
+ }
+#else /* HAVE_SYS_CAPABILITY_H */
}
/* check for CAP_SYS_RAWIO */
"collectd a special capability (CAP_SYS_RAWIO) and read "
"access to /dev/cpu/*/msr (see previous warnings)");
return ret;
+#endif /* HAVE_SYS_CAPABILITY_H */
}
static int