diff options
Diffstat (limited to 'tools/power/x86')
-rw-r--r-- | tools/power/x86/turbostat/turbostat.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index 6436d54378c7..fa60872b9474 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
@@ -19,6 +19,7 @@ | |||
19 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. | 19 | * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define _GNU_SOURCE | ||
22 | #include <stdio.h> | 23 | #include <stdio.h> |
23 | #include <unistd.h> | 24 | #include <unistd.h> |
24 | #include <sys/types.h> | 25 | #include <sys/types.h> |
@@ -32,6 +33,7 @@ | |||
32 | #include <dirent.h> | 33 | #include <dirent.h> |
33 | #include <string.h> | 34 | #include <string.h> |
34 | #include <ctype.h> | 35 | #include <ctype.h> |
36 | #include <sched.h> | ||
35 | 37 | ||
36 | #define MSR_TSC 0x10 | 38 | #define MSR_TSC 0x10 |
37 | #define MSR_NEHALEM_PLATFORM_INFO 0xCE | 39 | #define MSR_NEHALEM_PLATFORM_INFO 0xCE |
@@ -72,6 +74,8 @@ char *progname; | |||
72 | int need_reinitialize; | 74 | int need_reinitialize; |
73 | 75 | ||
74 | int num_cpus; | 76 | int num_cpus; |
77 | cpu_set_t *cpu_mask; | ||
78 | size_t cpu_mask_size; | ||
75 | 79 | ||
76 | struct counters { | 80 | struct counters { |
77 | unsigned long long tsc; /* per thread */ | 81 | unsigned long long tsc; /* per thread */ |
@@ -100,6 +104,40 @@ struct timeval tv_even; | |||
100 | struct timeval tv_odd; | 104 | struct timeval tv_odd; |
101 | struct timeval tv_delta; | 105 | struct timeval tv_delta; |
102 | 106 | ||
107 | /* | ||
108 | * cpu_mask_init(ncpus) | ||
109 | * | ||
110 | * allocate and clear cpu_mask | ||
111 | * set cpu_mask_size | ||
112 | */ | ||
113 | void cpu_mask_init(int ncpus) | ||
114 | { | ||
115 | cpu_mask = CPU_ALLOC(ncpus); | ||
116 | if (cpu_mask == NULL) { | ||
117 | perror("CPU_ALLOC"); | ||
118 | exit(3); | ||
119 | } | ||
120 | cpu_mask_size = CPU_ALLOC_SIZE(ncpus); | ||
121 | CPU_ZERO_S(cpu_mask_size, cpu_mask); | ||
122 | } | ||
123 | |||
124 | void cpu_mask_uninit() | ||
125 | { | ||
126 | CPU_FREE(cpu_mask); | ||
127 | cpu_mask = NULL; | ||
128 | cpu_mask_size = 0; | ||
129 | } | ||
130 | |||
131 | int cpu_migrate(int cpu) | ||
132 | { | ||
133 | CPU_ZERO_S(cpu_mask_size, cpu_mask); | ||
134 | CPU_SET_S(cpu, cpu_mask_size, cpu_mask); | ||
135 | if (sched_setaffinity(0, cpu_mask_size, cpu_mask) == -1) | ||
136 | return -1; | ||
137 | else | ||
138 | return 0; | ||
139 | } | ||
140 | |||
103 | unsigned long long get_msr(int cpu, off_t offset) | 141 | unsigned long long get_msr(int cpu, off_t offset) |
104 | { | 142 | { |
105 | ssize_t retval; | 143 | ssize_t retval; |
@@ -471,6 +509,11 @@ void compute_average(struct counters *delta, struct counters *avg) | |||
471 | void get_counters(struct counters *cnt) | 509 | void get_counters(struct counters *cnt) |
472 | { | 510 | { |
473 | for ( ; cnt; cnt = cnt->next) { | 511 | for ( ; cnt; cnt = cnt->next) { |
512 | if (cpu_migrate(cnt->cpu)) { | ||
513 | need_reinitialize = 1; | ||
514 | return; | ||
515 | } | ||
516 | |||
474 | cnt->tsc = get_msr(cnt->cpu, MSR_TSC); | 517 | cnt->tsc = get_msr(cnt->cpu, MSR_TSC); |
475 | if (do_nhm_cstates) | 518 | if (do_nhm_cstates) |
476 | cnt->c3 = get_msr(cnt->cpu, MSR_CORE_C3_RESIDENCY); | 519 | cnt->c3 = get_msr(cnt->cpu, MSR_CORE_C3_RESIDENCY); |
@@ -752,6 +795,8 @@ void re_initialize(void) | |||
752 | free_all_counters(); | 795 | free_all_counters(); |
753 | num_cpus = for_all_cpus(alloc_new_counters); | 796 | num_cpus = for_all_cpus(alloc_new_counters); |
754 | need_reinitialize = 0; | 797 | need_reinitialize = 0; |
798 | cpu_mask_uninit(); | ||
799 | cpu_mask_init(num_cpus); | ||
755 | printf("num_cpus is now %d\n", num_cpus); | 800 | printf("num_cpus is now %d\n", num_cpus); |
756 | } | 801 | } |
757 | 802 | ||
@@ -984,6 +1029,7 @@ void turbostat_init() | |||
984 | check_super_user(); | 1029 | check_super_user(); |
985 | 1030 | ||
986 | num_cpus = for_all_cpus(alloc_new_counters); | 1031 | num_cpus = for_all_cpus(alloc_new_counters); |
1032 | cpu_mask_init(num_cpus); | ||
987 | 1033 | ||
988 | if (verbose) | 1034 | if (verbose) |
989 | print_nehalem_info(); | 1035 | print_nehalem_info(); |