The names of the idle states in the output of cpupower monitor command are truncated to 4 characters. On POWER9, this creates ambiguity as the states are named "stop0", "stop1", etc. root:~# cpupower monitor |Idle_Stats PKG |CORE|CPU | snoo | stop | stop | stop | stop | stop | stop 0| 0| 0| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 1.90 0| 0| 1| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00 0| 0| 2| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00 0| 0| 3| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00 This patch modifies the output to print the state name that results in a legible output. The names will be printed with atmost 1 padding in left. root:~# cpupower monitor | Idle_Stats PKG|CORE| CPU|snooze|stop0L| stop0|stop1L| stop1|stop2L| stop2 0| 0| 0| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.72 0| 0| 1| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00 0| 0| 2| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00 0| 0| 3| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00| 0.00 This patch does not affect the output for intel. Output for intel before applying the patch: root:~# cpupower monitor |Idle_Stats CPU | POLL | C1-S | C1E- | C3-S | C6-S | C7s- | C8-S | C9-S | C10- 0| 0.00| 0.14| 0.39| 0.35| 7.41| 0.00| 17.67| 1.01| 70.03 2| 0.00| 0.19| 0.47| 0.10| 6.50| 0.00| 29.66| 2.17| 58.07 1| 0.00| 0.11| 0.50| 1.50| 9.11| 0.18| 18.19| 0.40| 66.63 3| 0.00| 0.67| 0.42| 0.03| 5.84| 0.00| 12.58| 0.77| 77.14 Output for intel after applying the patch: root:~# cpupower monitor | Idle_Stats CPU| POLL | C1-S | C1E- | C3-S | C6-S | C7s- | C8-S | C9-S | C10- 0| 0.03| 0.33| 1.01| 0.27| 3.03| 0.00| 19.18| 0.00| 71.24 2| 0.00| 1.58| 0.58| 0.42| 8.55| 0.09| 21.11| 0.99| 63.32 1| 0.00| 1.26| 0.88| 0.43| 9.00| 0.02| 7.78| 4.65| 71.91 3| 0.00| 0.30| 0.42| 0.06| 13.62| 0.21| 30.29| 0.00| 52.45 Signed-off-by: Abhishek Goel <huntbag@linux.vnet.ibm.com> Signed-off-by: Shuah Khan (Samsung OSG) <shuah@kernel.org>
95 lines
2.3 KiB
C
95 lines
2.3 KiB
C
/*
|
|
* (C) 2010,2011 Thomas Renninger <trenn@suse.de>, Novell Inc.
|
|
*
|
|
* Licensed under the terms of the GNU GPL License version 2.
|
|
*
|
|
*/
|
|
|
|
#ifndef __CPUIDLE_INFO_HW__
|
|
#define __CPUIDLE_INFO_HW__
|
|
|
|
#include <stdarg.h>
|
|
#include <time.h>
|
|
|
|
#include "idle_monitor/idle_monitors.h"
|
|
|
|
#define MONITORS_MAX 20
|
|
#define MONITOR_NAME_LEN 20
|
|
|
|
/* CSTATE_NAME_LEN is limited by header field width defined
|
|
* in cpupower-monitor.c. Header field width is defined to be
|
|
* sum of percent width and two spaces for padding.
|
|
*/
|
|
#ifdef __powerpc__
|
|
#define CSTATE_NAME_LEN 7
|
|
#else
|
|
#define CSTATE_NAME_LEN 5
|
|
#endif
|
|
#define CSTATE_DESC_LEN 60
|
|
|
|
int cpu_count;
|
|
|
|
/* Hard to define the right names ...: */
|
|
enum power_range_e {
|
|
RANGE_THREAD, /* Lowest in topology hierarcy, AMD: core, Intel: thread
|
|
kernel sysfs: cpu */
|
|
RANGE_CORE, /* AMD: unit, Intel: core, kernel_sysfs: core_id */
|
|
RANGE_PACKAGE, /* Package, processor socket */
|
|
RANGE_MACHINE, /* Machine, platform wide */
|
|
RANGE_MAX };
|
|
|
|
typedef struct cstate {
|
|
int id;
|
|
enum power_range_e range;
|
|
char name[CSTATE_NAME_LEN];
|
|
char desc[CSTATE_DESC_LEN];
|
|
|
|
/* either provide a percentage or a general count */
|
|
int (*get_count_percent)(unsigned int self_id, double *percent,
|
|
unsigned int cpu);
|
|
int (*get_count)(unsigned int self_id, unsigned long long *count,
|
|
unsigned int cpu);
|
|
} cstate_t;
|
|
|
|
struct cpuidle_monitor {
|
|
/* Name must not contain whitespaces */
|
|
char name[MONITOR_NAME_LEN];
|
|
int name_len;
|
|
int hw_states_num;
|
|
cstate_t *hw_states;
|
|
int (*start) (void);
|
|
int (*stop) (void);
|
|
struct cpuidle_monitor* (*do_register) (void);
|
|
void (*unregister)(void);
|
|
unsigned int overflow_s;
|
|
int needs_root;
|
|
};
|
|
|
|
extern long long timespec_diff_us(struct timespec start, struct timespec end);
|
|
|
|
#define print_overflow_err(mes, ov) \
|
|
{ \
|
|
fprintf(stderr, gettext("Measure took %u seconds, but registers could " \
|
|
"overflow at %u seconds, results " \
|
|
"could be inaccurate\n"), mes, ov); \
|
|
}
|
|
|
|
|
|
/* Taken over from x86info project sources -> return 0 on success */
|
|
#include <sched.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
static inline int bind_cpu(int cpu)
|
|
{
|
|
cpu_set_t set;
|
|
|
|
if (sched_getaffinity(getpid(), sizeof(set), &set) == 0) {
|
|
CPU_ZERO(&set);
|
|
CPU_SET(cpu, &set);
|
|
return sched_setaffinity(getpid(), sizeof(set), &set);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
#endif /* __CPUIDLE_INFO_HW__ */
|