diff options
author | Len Brown <len.brown@intel.com> | 2016-02-26 20:51:02 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2016-03-13 03:55:40 -0400 |
commit | 36229897ba966bb0dc9e060222ff17b198252367 (patch) | |
tree | 338ca7d3fa3ce6553b7b6a58bd40568a99a4a5de /tools/power | |
parent | 58cc30a4e6086d542302e04eea39b2a438e4c5dd (diff) |
tools/power turbostat: make fewer systems calls
skip the open(2)/close(2) on each msr read
by keeping the /dev/cpu/*/msr files open.
The remaining read(2) is generally far fewer cycles
than the removed open(2) system call.
Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'tools/power')
-rw-r--r-- | tools/power/x86/turbostat/turbostat.c | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index ad5bd5600467..2e47c2bc3e27 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
@@ -45,6 +45,7 @@ | |||
45 | 45 | ||
46 | char *proc_stat = "/proc/stat"; | 46 | char *proc_stat = "/proc/stat"; |
47 | FILE *outf; | 47 | FILE *outf; |
48 | int *fd_percpu; | ||
48 | struct timespec interval_ts = {5, 0}; | 49 | struct timespec interval_ts = {5, 0}; |
49 | unsigned int debug; | 50 | unsigned int debug; |
50 | unsigned int rapl_joules; | 51 | unsigned int rapl_joules; |
@@ -270,23 +271,34 @@ int cpu_migrate(int cpu) | |||
270 | else | 271 | else |
271 | return 0; | 272 | return 0; |
272 | } | 273 | } |
273 | 274 | int get_msr_fd(int cpu) | |
274 | int get_msr(int cpu, off_t offset, unsigned long long *msr) | ||
275 | { | 275 | { |
276 | ssize_t retval; | ||
277 | char pathname[32]; | 276 | char pathname[32]; |
278 | int fd; | 277 | int fd; |
279 | 278 | ||
279 | fd = fd_percpu[cpu]; | ||
280 | |||
281 | if (fd) | ||
282 | return fd; | ||
283 | |||
280 | sprintf(pathname, "/dev/cpu/%d/msr", cpu); | 284 | sprintf(pathname, "/dev/cpu/%d/msr", cpu); |
281 | fd = open(pathname, O_RDONLY); | 285 | fd = open(pathname, O_RDONLY); |
282 | if (fd < 0) | 286 | if (fd < 0) |
283 | err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, or run as root", pathname); | 287 | err(-1, "%s open failed, try chown or chmod +r /dev/cpu/*/msr, or run as root", pathname); |
284 | 288 | ||
285 | retval = pread(fd, msr, sizeof *msr, offset); | 289 | fd_percpu[cpu] = fd; |
286 | close(fd); | 290 | |
291 | return fd; | ||
292 | } | ||
293 | |||
294 | int get_msr(int cpu, off_t offset, unsigned long long *msr) | ||
295 | { | ||
296 | ssize_t retval; | ||
297 | |||
298 | retval = pread(get_msr_fd(cpu), msr, sizeof(*msr), offset); | ||
287 | 299 | ||
288 | if (retval != sizeof *msr) | 300 | if (retval != sizeof *msr) |
289 | err(-1, "%s offset 0x%llx read failed", pathname, (unsigned long long)offset); | 301 | err(-1, "msr %d offset 0x%llx read failed", cpu, (unsigned long long)offset); |
290 | 302 | ||
291 | return 0; | 303 | return 0; |
292 | } | 304 | } |
@@ -1453,19 +1465,30 @@ dump_config_tdp(void) | |||
1453 | fprintf(outf, "TDP_LEVEL=%d ", (unsigned int)(msr) & 0x3); | 1465 | fprintf(outf, "TDP_LEVEL=%d ", (unsigned int)(msr) & 0x3); |
1454 | fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1); | 1466 | fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1); |
1455 | fprintf(outf, ")\n"); | 1467 | fprintf(outf, ")\n"); |
1456 | 1468 | ||
1457 | get_msr(base_cpu, MSR_TURBO_ACTIVATION_RATIO, &msr); | 1469 | get_msr(base_cpu, MSR_TURBO_ACTIVATION_RATIO, &msr); |
1458 | fprintf(outf, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu, msr); | 1470 | fprintf(outf, "cpu%d: MSR_TURBO_ACTIVATION_RATIO: 0x%08llx (", base_cpu, msr); |
1459 | fprintf(outf, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0x7F); | 1471 | fprintf(outf, "MAX_NON_TURBO_RATIO=%d", (unsigned int)(msr) & 0x7F); |
1460 | fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1); | 1472 | fprintf(outf, " lock=%d", (unsigned int)(msr >> 31) & 1); |
1461 | fprintf(outf, ")\n"); | 1473 | fprintf(outf, ")\n"); |
1462 | } | 1474 | } |
1475 | void free_fd_percpu(void) | ||
1476 | { | ||
1477 | int i; | ||
1478 | |||
1479 | for (i = 0; i < topo.max_cpu_num; ++i) { | ||
1480 | if (fd_percpu[i] != 0) | ||
1481 | close(fd_percpu[i]); | ||
1482 | } | ||
1483 | |||
1484 | free(fd_percpu); | ||
1485 | } | ||
1463 | 1486 | ||
1464 | void free_all_buffers(void) | 1487 | void free_all_buffers(void) |
1465 | { | 1488 | { |
1466 | CPU_FREE(cpu_present_set); | 1489 | CPU_FREE(cpu_present_set); |
1467 | cpu_present_set = NULL; | 1490 | cpu_present_set = NULL; |
1468 | cpu_present_set = 0; | 1491 | cpu_present_setsize = 0; |
1469 | 1492 | ||
1470 | CPU_FREE(cpu_affinity_set); | 1493 | CPU_FREE(cpu_affinity_set); |
1471 | cpu_affinity_set = NULL; | 1494 | cpu_affinity_set = NULL; |
@@ -1490,6 +1513,8 @@ void free_all_buffers(void) | |||
1490 | free(output_buffer); | 1513 | free(output_buffer); |
1491 | output_buffer = NULL; | 1514 | output_buffer = NULL; |
1492 | outp = NULL; | 1515 | outp = NULL; |
1516 | |||
1517 | free_fd_percpu(); | ||
1493 | } | 1518 | } |
1494 | 1519 | ||
1495 | /* | 1520 | /* |
@@ -2449,7 +2474,7 @@ int print_thermal(struct thread_data *t, struct core_data *c, struct pkg_data *p | |||
2449 | 2474 | ||
2450 | return 0; | 2475 | return 0; |
2451 | } | 2476 | } |
2452 | 2477 | ||
2453 | void print_power_limit_msr(int cpu, unsigned long long msr, char *label) | 2478 | void print_power_limit_msr(int cpu, unsigned long long msr, char *label) |
2454 | { | 2479 | { |
2455 | fprintf(outf, "cpu%d: %s: %sabled (%f Watts, %f sec, clamp %sabled)\n", | 2480 | fprintf(outf, "cpu%d: %s: %sabled (%f Watts, %f sec, clamp %sabled)\n", |
@@ -3202,10 +3227,16 @@ void allocate_output_buffer() | |||
3202 | if (outp == NULL) | 3227 | if (outp == NULL) |
3203 | err(-1, "calloc output buffer"); | 3228 | err(-1, "calloc output buffer"); |
3204 | } | 3229 | } |
3205 | 3230 | void allocate_fd_percpu(void) | |
3231 | { | ||
3232 | fd_percpu = calloc(topo.max_cpu_num, sizeof(int)); | ||
3233 | if (fd_percpu == NULL) | ||
3234 | err(-1, "calloc fd_percpu"); | ||
3235 | } | ||
3206 | void setup_all_buffers(void) | 3236 | void setup_all_buffers(void) |
3207 | { | 3237 | { |
3208 | topology_probe(); | 3238 | topology_probe(); |
3239 | allocate_fd_percpu(); | ||
3209 | allocate_counters(&thread_even, &core_even, &package_even); | 3240 | allocate_counters(&thread_even, &core_even, &package_even); |
3210 | allocate_counters(&thread_odd, &core_odd, &package_odd); | 3241 | allocate_counters(&thread_odd, &core_odd, &package_odd); |
3211 | allocate_output_buffer(); | 3242 | allocate_output_buffer(); |