Commit 4c2122d4 authored by Len Brown's avatar Len Brown

tools/power turbostat: add optional APIC X2APIC columns

Add APIC and X2APIC columns to the topology section.

They are disabled-by-default -- enable like so:
--debug
or
--enable APIC,X2APIC
Signed-off-by: default avatarLen Brown <len.brown@intel.com>
parent d9d226ff
...@@ -56,7 +56,7 @@ name as necessary to disambiguate it from others is necessary. Note that option ...@@ -56,7 +56,7 @@ name as necessary to disambiguate it from others is necessary. Note that option
.PP .PP
\fB--hide column\fP do not show the specified built-in columns. May be invoked multiple times, or with a comma-separated list of column names. Use "--hide sysfs" to hide the sysfs statistics columns as a group. \fB--hide column\fP do not show the specified built-in columns. May be invoked multiple times, or with a comma-separated list of column names. Use "--hide sysfs" to hide the sysfs statistics columns as a group.
.PP .PP
\fB--enable column\fP show the specified built-in columns, which are otherwise disabled, by default. Currently the only built-in counters disabled by default are "usec" and "Time_Of_Day_Seconds". \fB--enable column\fP show the specified built-in columns, which are otherwise disabled, by default. Currently the only built-in counters disabled by default are "usec", "Time_Of_Day_Seconds", "APIC" and "X2APIC".
The column name "all" can be used to enable all disabled-by-default built-in counters. The column name "all" can be used to enable all disabled-by-default built-in counters.
.PP .PP
\fB--show column\fP show only the specified built-in columns. May be invoked multiple times, or with a comma-separated list of column names. Use "--show sysfs" to show the sysfs statistics columns as a group. \fB--show column\fP show only the specified built-in columns. May be invoked multiple times, or with a comma-separated list of column names. Use "--show sysfs" to show the sysfs statistics columns as a group.
......
...@@ -109,6 +109,7 @@ unsigned int has_hwp_activity_window; /* IA32_HWP_REQUEST[bits 41:32] */ ...@@ -109,6 +109,7 @@ unsigned int has_hwp_activity_window; /* IA32_HWP_REQUEST[bits 41:32] */
unsigned int has_hwp_epp; /* IA32_HWP_REQUEST[bits 31:24] */ unsigned int has_hwp_epp; /* IA32_HWP_REQUEST[bits 31:24] */
unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */ unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */
unsigned int has_misc_feature_control; unsigned int has_misc_feature_control;
unsigned int first_counter_read = 1;
#define RAPL_PKG (1 << 0) #define RAPL_PKG (1 << 0)
/* 0x610 MSR_PKG_POWER_LIMIT */ /* 0x610 MSR_PKG_POWER_LIMIT */
...@@ -170,6 +171,8 @@ struct thread_data { ...@@ -170,6 +171,8 @@ struct thread_data {
unsigned long long irq_count; unsigned long long irq_count;
unsigned int smi_count; unsigned int smi_count;
unsigned int cpu_id; unsigned int cpu_id;
unsigned int apic_id;
unsigned int x2apic_id;
unsigned int flags; unsigned int flags;
#define CPU_IS_FIRST_THREAD_IN_CORE 0x2 #define CPU_IS_FIRST_THREAD_IN_CORE 0x2
#define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4 #define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4
...@@ -435,10 +438,10 @@ struct msr_counter bic[] = { ...@@ -435,10 +438,10 @@ struct msr_counter bic[] = {
{ 0x0, "CPUGFX%" }, { 0x0, "CPUGFX%" },
{ 0x0, "Core" }, { 0x0, "Core" },
{ 0x0, "CPU" }, { 0x0, "CPU" },
{ 0x0, "APIC" },
{ 0x0, "X2APIC" },
}; };
#define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter)) #define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter))
#define BIC_USEC (1ULL << 0) #define BIC_USEC (1ULL << 0)
#define BIC_TOD (1ULL << 1) #define BIC_TOD (1ULL << 1)
...@@ -488,11 +491,13 @@ struct msr_counter bic[] = { ...@@ -488,11 +491,13 @@ struct msr_counter bic[] = {
#define BIC_CPUGFX (1ULL << 45) #define BIC_CPUGFX (1ULL << 45)
#define BIC_Core (1ULL << 46) #define BIC_Core (1ULL << 46)
#define BIC_CPU (1ULL << 47) #define BIC_CPU (1ULL << 47)
#define BIC_APIC (1ULL << 48)
#define BIC_X2APIC (1ULL << 49)
#define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD) #define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC)
unsigned long long bic_enabled = (0xFFFFFFFFFFFFFFFFULL & ~BIC_DISABLED_BY_DEFAULT); unsigned long long bic_enabled = (0xFFFFFFFFFFFFFFFFULL & ~BIC_DISABLED_BY_DEFAULT);
unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs; unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs | BIC_APIC | BIC_X2APIC;
#define DO_BIC(COUNTER_NAME) (bic_enabled & bic_present & COUNTER_NAME) #define DO_BIC(COUNTER_NAME) (bic_enabled & bic_present & COUNTER_NAME)
#define ENABLE_BIC(COUNTER_NAME) (bic_enabled |= COUNTER_NAME) #define ENABLE_BIC(COUNTER_NAME) (bic_enabled |= COUNTER_NAME)
...@@ -603,6 +608,10 @@ void print_header(char *delim) ...@@ -603,6 +608,10 @@ void print_header(char *delim)
outp += sprintf(outp, "%sCore", (printed++ ? delim : "")); outp += sprintf(outp, "%sCore", (printed++ ? delim : ""));
if (DO_BIC(BIC_CPU)) if (DO_BIC(BIC_CPU))
outp += sprintf(outp, "%sCPU", (printed++ ? delim : "")); outp += sprintf(outp, "%sCPU", (printed++ ? delim : ""));
if (DO_BIC(BIC_APIC))
outp += sprintf(outp, "%sAPIC", (printed++ ? delim : ""));
if (DO_BIC(BIC_X2APIC))
outp += sprintf(outp, "%sX2APIC", (printed++ ? delim : ""));
if (DO_BIC(BIC_Avg_MHz)) if (DO_BIC(BIC_Avg_MHz))
outp += sprintf(outp, "%sAvg_MHz", (printed++ ? delim : "")); outp += sprintf(outp, "%sAvg_MHz", (printed++ ? delim : ""));
if (DO_BIC(BIC_Busy)) if (DO_BIC(BIC_Busy))
...@@ -882,6 +891,10 @@ int format_counters(struct thread_data *t, struct core_data *c, ...@@ -882,6 +891,10 @@ int format_counters(struct thread_data *t, struct core_data *c,
outp += sprintf(outp, "%s-", (printed++ ? delim : "")); outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
if (DO_BIC(BIC_CPU)) if (DO_BIC(BIC_CPU))
outp += sprintf(outp, "%s-", (printed++ ? delim : "")); outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
if (DO_BIC(BIC_APIC))
outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
if (DO_BIC(BIC_X2APIC))
outp += sprintf(outp, "%s-", (printed++ ? delim : ""));
} else { } else {
if (DO_BIC(BIC_Package)) { if (DO_BIC(BIC_Package)) {
if (p) if (p)
...@@ -906,6 +919,10 @@ int format_counters(struct thread_data *t, struct core_data *c, ...@@ -906,6 +919,10 @@ int format_counters(struct thread_data *t, struct core_data *c,
} }
if (DO_BIC(BIC_CPU)) if (DO_BIC(BIC_CPU))
outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->cpu_id); outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->cpu_id);
if (DO_BIC(BIC_APIC))
outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->apic_id);
if (DO_BIC(BIC_X2APIC))
outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->x2apic_id);
} }
if (DO_BIC(BIC_Avg_MHz)) if (DO_BIC(BIC_Avg_MHz))
...@@ -1233,6 +1250,12 @@ delta_thread(struct thread_data *new, struct thread_data *old, ...@@ -1233,6 +1250,12 @@ delta_thread(struct thread_data *new, struct thread_data *old,
int i; int i;
struct msr_counter *mp; struct msr_counter *mp;
/* we run cpuid just the 1st time, copy the results */
if (DO_BIC(BIC_APIC))
new->apic_id = old->apic_id;
if (DO_BIC(BIC_X2APIC))
new->x2apic_id = old->x2apic_id;
/* /*
* the timestamps from start of measurement interval are in "old" * the timestamps from start of measurement interval are in "old"
* the timestamp from end of measurement interval are in "new" * the timestamp from end of measurement interval are in "new"
...@@ -1395,6 +1418,12 @@ int sum_counters(struct thread_data *t, struct core_data *c, ...@@ -1395,6 +1418,12 @@ int sum_counters(struct thread_data *t, struct core_data *c,
int i; int i;
struct msr_counter *mp; struct msr_counter *mp;
/* copy un-changing apic_id's */
if (DO_BIC(BIC_APIC))
average.threads.apic_id = t->apic_id;
if (DO_BIC(BIC_X2APIC))
average.threads.x2apic_id = t->x2apic_id;
/* remember first tv_begin */ /* remember first tv_begin */
if (average.threads.tv_begin.tv_sec == 0) if (average.threads.tv_begin.tv_sec == 0)
average.threads.tv_begin = t->tv_begin; average.threads.tv_begin = t->tv_begin;
...@@ -1621,6 +1650,34 @@ int get_mp(int cpu, struct msr_counter *mp, unsigned long long *counterp) ...@@ -1621,6 +1650,34 @@ int get_mp(int cpu, struct msr_counter *mp, unsigned long long *counterp)
return 0; return 0;
} }
void get_apic_id(struct thread_data *t)
{
unsigned int eax, ebx, ecx, edx, max_level;
eax = ebx = ecx = edx = 0;
if (!genuine_intel)
return;
__cpuid(0, max_level, ebx, ecx, edx);
__cpuid(1, eax, ebx, ecx, edx);
t->apic_id = (ebx >> 24) & 0xf;
if (max_level < 0xb)
return;
if (!DO_BIC(BIC_X2APIC))
return;
ecx = 0;
__cpuid(0xb, eax, ebx, ecx, edx);
t->x2apic_id = edx;
if (debug && (t->apic_id != t->x2apic_id))
fprintf(stderr, "cpu%d: apic 0x%x x2apic 0x%x\n", t->cpu_id, t->apic_id, t->x2apic_id);
}
/* /*
* get_counters(...) * get_counters(...)
* migrate to cpu * migrate to cpu
...@@ -1634,7 +1691,6 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) ...@@ -1634,7 +1691,6 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
struct msr_counter *mp; struct msr_counter *mp;
int i; int i;
gettimeofday(&t->tv_begin, (struct timezone *)NULL); gettimeofday(&t->tv_begin, (struct timezone *)NULL);
if (cpu_migrate(cpu)) { if (cpu_migrate(cpu)) {
...@@ -1642,6 +1698,8 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) ...@@ -1642,6 +1698,8 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p)
return -1; return -1;
} }
if (first_counter_read)
get_apic_id(t);
retry: retry:
t->tsc = rdtsc(); /* we are running on local CPU of interest */ t->tsc = rdtsc(); /* we are running on local CPU of interest */
...@@ -2881,6 +2939,7 @@ void do_sleep(void) ...@@ -2881,6 +2939,7 @@ void do_sleep(void)
} }
} }
void turbostat_loop() void turbostat_loop()
{ {
int retval; int retval;
...@@ -2894,6 +2953,7 @@ void turbostat_loop() ...@@ -2894,6 +2953,7 @@ void turbostat_loop()
snapshot_proc_sysfs_files(); snapshot_proc_sysfs_files();
retval = for_all_cpus(get_counters, EVEN_COUNTERS); retval = for_all_cpus(get_counters, EVEN_COUNTERS);
first_counter_read = 0;
if (retval < -1) { if (retval < -1) {
exit(retval); exit(retval);
} else if (retval == -1) { } else if (retval == -1) {
...@@ -4655,7 +4715,6 @@ void process_cpuid() ...@@ -4655,7 +4715,6 @@ void process_cpuid()
return; return;
} }
/* /*
* in /dev/cpu/ return success for names that are numbers * in /dev/cpu/ return success for names that are numbers
* ie. filter out ".", "..", "microcode". * ie. filter out ".", "..", "microcode".
...@@ -4949,6 +5008,7 @@ int fork_it(char **argv) ...@@ -4949,6 +5008,7 @@ int fork_it(char **argv)
snapshot_proc_sysfs_files(); snapshot_proc_sysfs_files();
status = for_all_cpus(get_counters, EVEN_COUNTERS); status = for_all_cpus(get_counters, EVEN_COUNTERS);
first_counter_read = 0;
if (status) if (status)
exit(status); exit(status);
/* clear affinity side-effect of get_counters() */ /* clear affinity side-effect of get_counters() */
...@@ -5384,7 +5444,7 @@ void cmdline(int argc, char **argv) ...@@ -5384,7 +5444,7 @@ void cmdline(int argc, char **argv)
break; break;
case 'e': case 'e':
/* --enable specified counter */ /* --enable specified counter */
bic_enabled |= bic_lookup(optarg, SHOW_LIST); bic_enabled = bic_enabled | bic_lookup(optarg, SHOW_LIST);
break; break;
case 'd': case 'd':
debug++; debug++;
...@@ -5468,7 +5528,6 @@ void cmdline(int argc, char **argv) ...@@ -5468,7 +5528,6 @@ void cmdline(int argc, char **argv)
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
outf = stderr; outf = stderr;
cmdline(argc, argv); cmdline(argc, argv);
if (!quiet) if (!quiet)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment