diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-20 16:25:04 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-20 16:25:04 -0500 |
commit | 82023bb7f75b0052f40d3e74169d191c3e4e6286 (patch) | |
tree | 06ad7f507852adf41a2ca33d5cb7100faeaf8499 /tools | |
parent | e6d69a60b77a6ea8d5f9d41765c7571bb8d45531 (diff) | |
parent | ed6a82546d2e8f6b5902269541733814d4adacc2 (diff) |
Merge tag 'pm+acpi-2-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
Pull more ACPI and power management updates from Rafael Wysocki:
- ACPI-based device hotplug fixes for issues introduced recently and a
fix for an older error code path bug in the ACPI PCI host bridge
driver
- Fix for recently broken OMAP cpufreq build from Viresh Kumar
- Fix for a recent hibernation regression related to s2disk
- Fix for a locking-related regression in the ACPI EC driver from
Puneet Kumar
- System suspend error code path fix related to runtime PM and runtime
PM documentation update from Ulf Hansson
- cpufreq's conservative governor fix from Xiaoguang Chen
- New processor IDs for intel_idle and turbostat and removal of an
obsolete Kconfig option from Len Brown
- New device IDs for the ACPI LPSS (Low-Power Subsystem) driver and
ACPI-based PCI hotplug (ACPIPHP) cleanup from Mika Westerberg
- Removal of several ACPI video DMI blacklist entries that are not
necessary any more from Aaron Lu
- Rework of the ACPI companion representation in struct device and code
cleanup related to that change from Rafael J Wysocki, Lan Tianyu and
Jarkko Nikula
- Fixes for assigning names to ACPI-enumerated I2C and SPI devices from
Jarkko Nikula
* tag 'pm+acpi-2-3.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm: (24 commits)
PCI / hotplug / ACPI: Drop unused acpiphp_debug declaration
ACPI / scan: Set flags.match_driver in acpi_bus_scan_fixed()
ACPI / PCI root: Clear driver_data before failing enumeration
ACPI / hotplug: Fix PCI host bridge hot removal
ACPI / hotplug: Fix acpi_bus_get_device() return value check
cpufreq: governor: Remove fossil comment in the cpufreq_governor_dbs()
ACPI / video: clean up DMI table for initial black screen problem
ACPI / EC: Ensure lock is acquired before accessing ec struct members
PM / Hibernate: Do not crash kernel in free_basic_memory_bitmaps()
ACPI / AC: Remove struct acpi_device pointer from struct acpi_ac
spi: Use stable dev_name for ACPI enumerated SPI slaves
i2c: Use stable dev_name for ACPI enumerated I2C slaves
ACPI: Provide acpi_dev_name accessor for struct acpi_device device name
ACPI / bind: Use (put|get)_device() on ACPI device objects too
ACPI: Eliminate the DEVICE_ACPI_HANDLE() macro
ACPI / driver core: Store an ACPI device pointer in struct acpi_dev_node
cpufreq: OMAP: Fix compilation error 'r & ret undeclared'
PM / Runtime: Fix error path for prepare
PM / Runtime: Update documentation around probe|remove|suspend
cpufreq: conservative: set requested_freq to policy max when it is over policy max
...
Diffstat (limited to 'tools')
-rw-r--r-- | tools/power/x86/turbostat/turbostat.c | 197 |
1 files changed, 141 insertions, 56 deletions
diff --git a/tools/power/x86/turbostat/turbostat.c b/tools/power/x86/turbostat/turbostat.c index fe702076ca46..9d77f13c2d25 100644 --- a/tools/power/x86/turbostat/turbostat.c +++ b/tools/power/x86/turbostat/turbostat.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * turbostat -- show CPU frequency and C-state residency | 2 | * turbostat -- show CPU frequency and C-state residency |
3 | * on modern Intel turbo-capable processors. | 3 | * on modern Intel turbo-capable processors. |
4 | * | 4 | * |
5 | * Copyright (c) 2012 Intel Corporation. | 5 | * Copyright (c) 2013 Intel Corporation. |
6 | * Len Brown <len.brown@intel.com> | 6 | * Len Brown <len.brown@intel.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
@@ -47,6 +47,8 @@ unsigned int skip_c1; | |||
47 | unsigned int do_nhm_cstates; | 47 | unsigned int do_nhm_cstates; |
48 | unsigned int do_snb_cstates; | 48 | unsigned int do_snb_cstates; |
49 | unsigned int do_c8_c9_c10; | 49 | unsigned int do_c8_c9_c10; |
50 | unsigned int do_slm_cstates; | ||
51 | unsigned int use_c1_residency_msr; | ||
50 | unsigned int has_aperf; | 52 | unsigned int has_aperf; |
51 | unsigned int has_epb; | 53 | unsigned int has_epb; |
52 | unsigned int units = 1000000000; /* Ghz etc */ | 54 | unsigned int units = 1000000000; /* Ghz etc */ |
@@ -81,6 +83,8 @@ double rapl_joule_counter_range; | |||
81 | #define RAPL_DRAM (1 << 3) | 83 | #define RAPL_DRAM (1 << 3) |
82 | #define RAPL_PKG_PERF_STATUS (1 << 4) | 84 | #define RAPL_PKG_PERF_STATUS (1 << 4) |
83 | #define RAPL_DRAM_PERF_STATUS (1 << 5) | 85 | #define RAPL_DRAM_PERF_STATUS (1 << 5) |
86 | #define RAPL_PKG_POWER_INFO (1 << 6) | ||
87 | #define RAPL_CORE_POLICY (1 << 7) | ||
84 | #define TJMAX_DEFAULT 100 | 88 | #define TJMAX_DEFAULT 100 |
85 | 89 | ||
86 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) | 90 | #define MAX(a, b) ((a) > (b) ? (a) : (b)) |
@@ -96,7 +100,7 @@ struct thread_data { | |||
96 | unsigned long long tsc; | 100 | unsigned long long tsc; |
97 | unsigned long long aperf; | 101 | unsigned long long aperf; |
98 | unsigned long long mperf; | 102 | unsigned long long mperf; |
99 | unsigned long long c1; /* derived */ | 103 | unsigned long long c1; |
100 | unsigned long long extra_msr64; | 104 | unsigned long long extra_msr64; |
101 | unsigned long long extra_delta64; | 105 | unsigned long long extra_delta64; |
102 | unsigned long long extra_msr32; | 106 | unsigned long long extra_msr32; |
@@ -266,7 +270,7 @@ void print_header(void) | |||
266 | outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64); | 270 | outp += sprintf(outp, " MSR 0x%03X", extra_msr_offset64); |
267 | if (do_nhm_cstates) | 271 | if (do_nhm_cstates) |
268 | outp += sprintf(outp, " %%c1"); | 272 | outp += sprintf(outp, " %%c1"); |
269 | if (do_nhm_cstates) | 273 | if (do_nhm_cstates && !do_slm_cstates) |
270 | outp += sprintf(outp, " %%c3"); | 274 | outp += sprintf(outp, " %%c3"); |
271 | if (do_nhm_cstates) | 275 | if (do_nhm_cstates) |
272 | outp += sprintf(outp, " %%c6"); | 276 | outp += sprintf(outp, " %%c6"); |
@@ -280,9 +284,9 @@ void print_header(void) | |||
280 | 284 | ||
281 | if (do_snb_cstates) | 285 | if (do_snb_cstates) |
282 | outp += sprintf(outp, " %%pc2"); | 286 | outp += sprintf(outp, " %%pc2"); |
283 | if (do_nhm_cstates) | 287 | if (do_nhm_cstates && !do_slm_cstates) |
284 | outp += sprintf(outp, " %%pc3"); | 288 | outp += sprintf(outp, " %%pc3"); |
285 | if (do_nhm_cstates) | 289 | if (do_nhm_cstates && !do_slm_cstates) |
286 | outp += sprintf(outp, " %%pc6"); | 290 | outp += sprintf(outp, " %%pc6"); |
287 | if (do_snb_cstates) | 291 | if (do_snb_cstates) |
288 | outp += sprintf(outp, " %%pc7"); | 292 | outp += sprintf(outp, " %%pc7"); |
@@ -480,7 +484,7 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
480 | if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) | 484 | if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) |
481 | goto done; | 485 | goto done; |
482 | 486 | ||
483 | if (do_nhm_cstates) | 487 | if (do_nhm_cstates && !do_slm_cstates) |
484 | outp += sprintf(outp, " %6.2f", 100.0 * c->c3/t->tsc); | 488 | outp += sprintf(outp, " %6.2f", 100.0 * c->c3/t->tsc); |
485 | if (do_nhm_cstates) | 489 | if (do_nhm_cstates) |
486 | outp += sprintf(outp, " %6.2f", 100.0 * c->c6/t->tsc); | 490 | outp += sprintf(outp, " %6.2f", 100.0 * c->c6/t->tsc); |
@@ -499,9 +503,9 @@ int format_counters(struct thread_data *t, struct core_data *c, | |||
499 | 503 | ||
500 | if (do_snb_cstates) | 504 | if (do_snb_cstates) |
501 | outp += sprintf(outp, " %6.2f", 100.0 * p->pc2/t->tsc); | 505 | outp += sprintf(outp, " %6.2f", 100.0 * p->pc2/t->tsc); |
502 | if (do_nhm_cstates) | 506 | if (do_nhm_cstates && !do_slm_cstates) |
503 | outp += sprintf(outp, " %6.2f", 100.0 * p->pc3/t->tsc); | 507 | outp += sprintf(outp, " %6.2f", 100.0 * p->pc3/t->tsc); |
504 | if (do_nhm_cstates) | 508 | if (do_nhm_cstates && !do_slm_cstates) |
505 | outp += sprintf(outp, " %6.2f", 100.0 * p->pc6/t->tsc); | 509 | outp += sprintf(outp, " %6.2f", 100.0 * p->pc6/t->tsc); |
506 | if (do_snb_cstates) | 510 | if (do_snb_cstates) |
507 | outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc); | 511 | outp += sprintf(outp, " %6.2f", 100.0 * p->pc7/t->tsc); |
@@ -648,17 +652,24 @@ delta_thread(struct thread_data *new, struct thread_data *old, | |||
648 | } | 652 | } |
649 | 653 | ||
650 | 654 | ||
651 | /* | 655 | if (use_c1_residency_msr) { |
652 | * As counter collection is not atomic, | 656 | /* |
653 | * it is possible for mperf's non-halted cycles + idle states | 657 | * Some models have a dedicated C1 residency MSR, |
654 | * to exceed TSC's all cycles: show c1 = 0% in that case. | 658 | * which should be more accurate than the derivation below. |
655 | */ | 659 | */ |
656 | if ((old->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > old->tsc) | 660 | } else { |
657 | old->c1 = 0; | 661 | /* |
658 | else { | 662 | * As counter collection is not atomic, |
659 | /* normal case, derive c1 */ | 663 | * it is possible for mperf's non-halted cycles + idle states |
660 | old->c1 = old->tsc - old->mperf - core_delta->c3 | 664 | * to exceed TSC's all cycles: show c1 = 0% in that case. |
665 | */ | ||
666 | if ((old->mperf + core_delta->c3 + core_delta->c6 + core_delta->c7) > old->tsc) | ||
667 | old->c1 = 0; | ||
668 | else { | ||
669 | /* normal case, derive c1 */ | ||
670 | old->c1 = old->tsc - old->mperf - core_delta->c3 | ||
661 | - core_delta->c6 - core_delta->c7; | 671 | - core_delta->c6 - core_delta->c7; |
672 | } | ||
662 | } | 673 | } |
663 | 674 | ||
664 | if (old->mperf == 0) { | 675 | if (old->mperf == 0) { |
@@ -872,13 +883,21 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) | |||
872 | if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64)) | 883 | if (get_msr(cpu, extra_msr_offset64, &t->extra_msr64)) |
873 | return -5; | 884 | return -5; |
874 | 885 | ||
886 | if (use_c1_residency_msr) { | ||
887 | if (get_msr(cpu, MSR_CORE_C1_RES, &t->c1)) | ||
888 | return -6; | ||
889 | } | ||
890 | |||
875 | /* collect core counters only for 1st thread in core */ | 891 | /* collect core counters only for 1st thread in core */ |
876 | if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) | 892 | if (!(t->flags & CPU_IS_FIRST_THREAD_IN_CORE)) |
877 | return 0; | 893 | return 0; |
878 | 894 | ||
879 | if (do_nhm_cstates) { | 895 | if (do_nhm_cstates && !do_slm_cstates) { |
880 | if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3)) | 896 | if (get_msr(cpu, MSR_CORE_C3_RESIDENCY, &c->c3)) |
881 | return -6; | 897 | return -6; |
898 | } | ||
899 | |||
900 | if (do_nhm_cstates) { | ||
882 | if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6)) | 901 | if (get_msr(cpu, MSR_CORE_C6_RESIDENCY, &c->c6)) |
883 | return -7; | 902 | return -7; |
884 | } | 903 | } |
@@ -898,7 +917,7 @@ int get_counters(struct thread_data *t, struct core_data *c, struct pkg_data *p) | |||
898 | if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) | 917 | if (!(t->flags & CPU_IS_FIRST_CORE_IN_PACKAGE)) |
899 | return 0; | 918 | return 0; |
900 | 919 | ||
901 | if (do_nhm_cstates) { | 920 | if (do_nhm_cstates && !do_slm_cstates) { |
902 | if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3)) | 921 | if (get_msr(cpu, MSR_PKG_C3_RESIDENCY, &p->pc3)) |
903 | return -9; | 922 | return -9; |
904 | if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6)) | 923 | if (get_msr(cpu, MSR_PKG_C6_RESIDENCY, &p->pc6)) |
@@ -977,7 +996,7 @@ void print_verbose_header(void) | |||
977 | ratio, bclk, ratio * bclk); | 996 | ratio, bclk, ratio * bclk); |
978 | 997 | ||
979 | get_msr(0, MSR_IA32_POWER_CTL, &msr); | 998 | get_msr(0, MSR_IA32_POWER_CTL, &msr); |
980 | fprintf(stderr, "cpu0: MSR_IA32_POWER_CTL: 0x%08llx (C1E: %sabled)\n", | 999 | fprintf(stderr, "cpu0: MSR_IA32_POWER_CTL: 0x%08llx (C1E auto-promotion: %sabled)\n", |
981 | msr, msr & 0x2 ? "EN" : "DIS"); | 1000 | msr, msr & 0x2 ? "EN" : "DIS"); |
982 | 1001 | ||
983 | if (!do_ivt_turbo_ratio_limit) | 1002 | if (!do_ivt_turbo_ratio_limit) |
@@ -1046,25 +1065,28 @@ print_nhm_turbo_ratio_limits: | |||
1046 | 1065 | ||
1047 | switch(msr & 0x7) { | 1066 | switch(msr & 0x7) { |
1048 | case 0: | 1067 | case 0: |
1049 | fprintf(stderr, "pc0"); | 1068 | fprintf(stderr, do_slm_cstates ? "no pkg states" : "pc0"); |
1050 | break; | 1069 | break; |
1051 | case 1: | 1070 | case 1: |
1052 | fprintf(stderr, do_snb_cstates ? "pc2" : "pc0"); | 1071 | fprintf(stderr, do_slm_cstates ? "no pkg states" : do_snb_cstates ? "pc2" : "pc0"); |
1053 | break; | 1072 | break; |
1054 | case 2: | 1073 | case 2: |
1055 | fprintf(stderr, do_snb_cstates ? "pc6-noret" : "pc3"); | 1074 | fprintf(stderr, do_slm_cstates ? "invalid" : do_snb_cstates ? "pc6-noret" : "pc3"); |
1056 | break; | 1075 | break; |
1057 | case 3: | 1076 | case 3: |
1058 | fprintf(stderr, "pc6"); | 1077 | fprintf(stderr, do_slm_cstates ? "invalid" : "pc6"); |
1059 | break; | 1078 | break; |
1060 | case 4: | 1079 | case 4: |
1061 | fprintf(stderr, "pc7"); | 1080 | fprintf(stderr, do_slm_cstates ? "pc4" : "pc7"); |
1062 | break; | 1081 | break; |
1063 | case 5: | 1082 | case 5: |
1064 | fprintf(stderr, do_snb_cstates ? "pc7s" : "invalid"); | 1083 | fprintf(stderr, do_slm_cstates ? "invalid" : do_snb_cstates ? "pc7s" : "invalid"); |
1084 | break; | ||
1085 | case 6: | ||
1086 | fprintf(stderr, do_slm_cstates ? "pc6" : "invalid"); | ||
1065 | break; | 1087 | break; |
1066 | case 7: | 1088 | case 7: |
1067 | fprintf(stderr, "unlimited"); | 1089 | fprintf(stderr, do_slm_cstates ? "pc7" : "unlimited"); |
1068 | break; | 1090 | break; |
1069 | default: | 1091 | default: |
1070 | fprintf(stderr, "invalid"); | 1092 | fprintf(stderr, "invalid"); |
@@ -1460,6 +1482,8 @@ int has_nehalem_turbo_ratio_limit(unsigned int family, unsigned int model) | |||
1460 | case 0x3F: /* HSW */ | 1482 | case 0x3F: /* HSW */ |
1461 | case 0x45: /* HSW */ | 1483 | case 0x45: /* HSW */ |
1462 | case 0x46: /* HSW */ | 1484 | case 0x46: /* HSW */ |
1485 | case 0x37: /* BYT */ | ||
1486 | case 0x4D: /* AVN */ | ||
1463 | return 1; | 1487 | return 1; |
1464 | case 0x2E: /* Nehalem-EX Xeon - Beckton */ | 1488 | case 0x2E: /* Nehalem-EX Xeon - Beckton */ |
1465 | case 0x2F: /* Westmere-EX Xeon - Eagleton */ | 1489 | case 0x2F: /* Westmere-EX Xeon - Eagleton */ |
@@ -1532,14 +1556,33 @@ int print_epb(struct thread_data *t, struct core_data *c, struct pkg_data *p) | |||
1532 | #define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */ | 1556 | #define RAPL_POWER_GRANULARITY 0x7FFF /* 15 bit power granularity */ |
1533 | #define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */ | 1557 | #define RAPL_TIME_GRANULARITY 0x3F /* 6 bit time granularity */ |
1534 | 1558 | ||
1559 | double get_tdp(model) | ||
1560 | { | ||
1561 | unsigned long long msr; | ||
1562 | |||
1563 | if (do_rapl & RAPL_PKG_POWER_INFO) | ||
1564 | if (!get_msr(0, MSR_PKG_POWER_INFO, &msr)) | ||
1565 | return ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units; | ||
1566 | |||
1567 | switch (model) { | ||
1568 | case 0x37: | ||
1569 | case 0x4D: | ||
1570 | return 30.0; | ||
1571 | default: | ||
1572 | return 135.0; | ||
1573 | } | ||
1574 | } | ||
1575 | |||
1576 | |||
1535 | /* | 1577 | /* |
1536 | * rapl_probe() | 1578 | * rapl_probe() |
1537 | * | 1579 | * |
1538 | * sets do_rapl | 1580 | * sets do_rapl, rapl_power_units, rapl_energy_units, rapl_time_units |
1539 | */ | 1581 | */ |
1540 | void rapl_probe(unsigned int family, unsigned int model) | 1582 | void rapl_probe(unsigned int family, unsigned int model) |
1541 | { | 1583 | { |
1542 | unsigned long long msr; | 1584 | unsigned long long msr; |
1585 | unsigned int time_unit; | ||
1543 | double tdp; | 1586 | double tdp; |
1544 | 1587 | ||
1545 | if (!genuine_intel) | 1588 | if (!genuine_intel) |
@@ -1555,11 +1598,15 @@ void rapl_probe(unsigned int family, unsigned int model) | |||
1555 | case 0x3F: /* HSW */ | 1598 | case 0x3F: /* HSW */ |
1556 | case 0x45: /* HSW */ | 1599 | case 0x45: /* HSW */ |
1557 | case 0x46: /* HSW */ | 1600 | case 0x46: /* HSW */ |
1558 | do_rapl = RAPL_PKG | RAPL_CORES | RAPL_GFX; | 1601 | do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_GFX | RAPL_PKG_POWER_INFO; |
1559 | break; | 1602 | break; |
1560 | case 0x2D: | 1603 | case 0x2D: |
1561 | case 0x3E: | 1604 | case 0x3E: |
1562 | do_rapl = RAPL_PKG | RAPL_CORES | RAPL_DRAM | RAPL_PKG_PERF_STATUS | RAPL_DRAM_PERF_STATUS; | 1605 | do_rapl = RAPL_PKG | RAPL_CORES | RAPL_CORE_POLICY | RAPL_DRAM | RAPL_PKG_PERF_STATUS | RAPL_DRAM_PERF_STATUS | RAPL_PKG_POWER_INFO; |
1606 | break; | ||
1607 | case 0x37: /* BYT */ | ||
1608 | case 0x4D: /* AVN */ | ||
1609 | do_rapl = RAPL_PKG | RAPL_CORES ; | ||
1563 | break; | 1610 | break; |
1564 | default: | 1611 | default: |
1565 | return; | 1612 | return; |
@@ -1570,19 +1617,22 @@ void rapl_probe(unsigned int family, unsigned int model) | |||
1570 | return; | 1617 | return; |
1571 | 1618 | ||
1572 | rapl_power_units = 1.0 / (1 << (msr & 0xF)); | 1619 | rapl_power_units = 1.0 / (1 << (msr & 0xF)); |
1573 | rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F)); | 1620 | if (model == 0x37) |
1574 | rapl_time_units = 1.0 / (1 << (msr >> 16 & 0xF)); | 1621 | rapl_energy_units = 1.0 * (1 << (msr >> 8 & 0x1F)) / 1000000; |
1622 | else | ||
1623 | rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F)); | ||
1575 | 1624 | ||
1576 | /* get TDP to determine energy counter range */ | 1625 | time_unit = msr >> 16 & 0xF; |
1577 | if (get_msr(0, MSR_PKG_POWER_INFO, &msr)) | 1626 | if (time_unit == 0) |
1578 | return; | 1627 | time_unit = 0xA; |
1579 | 1628 | ||
1580 | tdp = ((msr >> 0) & RAPL_POWER_GRANULARITY) * rapl_power_units; | 1629 | rapl_time_units = 1.0 / (1 << (time_unit)); |
1581 | 1630 | ||
1582 | rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp; | 1631 | tdp = get_tdp(model); |
1583 | 1632 | ||
1633 | rapl_joule_counter_range = 0xFFFFFFFF * rapl_energy_units / tdp; | ||
1584 | if (verbose) | 1634 | if (verbose) |
1585 | fprintf(stderr, "RAPL: %.0f sec. Joule Counter Range\n", rapl_joule_counter_range); | 1635 | fprintf(stderr, "RAPL: %.0f sec. Joule Counter Range, at %.0f Watts\n", rapl_joule_counter_range, tdp); |
1586 | 1636 | ||
1587 | return; | 1637 | return; |
1588 | } | 1638 | } |
@@ -1668,7 +1718,6 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) | |||
1668 | { | 1718 | { |
1669 | unsigned long long msr; | 1719 | unsigned long long msr; |
1670 | int cpu; | 1720 | int cpu; |
1671 | double local_rapl_power_units, local_rapl_energy_units, local_rapl_time_units; | ||
1672 | 1721 | ||
1673 | if (!do_rapl) | 1722 | if (!do_rapl) |
1674 | return 0; | 1723 | return 0; |
@@ -1686,23 +1735,13 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) | |||
1686 | if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr)) | 1735 | if (get_msr(cpu, MSR_RAPL_POWER_UNIT, &msr)) |
1687 | return -1; | 1736 | return -1; |
1688 | 1737 | ||
1689 | local_rapl_power_units = 1.0 / (1 << (msr & 0xF)); | ||
1690 | local_rapl_energy_units = 1.0 / (1 << (msr >> 8 & 0x1F)); | ||
1691 | local_rapl_time_units = 1.0 / (1 << (msr >> 16 & 0xF)); | ||
1692 | |||
1693 | if (local_rapl_power_units != rapl_power_units) | ||
1694 | fprintf(stderr, "cpu%d, ERROR: Power units mis-match\n", cpu); | ||
1695 | if (local_rapl_energy_units != rapl_energy_units) | ||
1696 | fprintf(stderr, "cpu%d, ERROR: Energy units mis-match\n", cpu); | ||
1697 | if (local_rapl_time_units != rapl_time_units) | ||
1698 | fprintf(stderr, "cpu%d, ERROR: Time units mis-match\n", cpu); | ||
1699 | |||
1700 | if (verbose) { | 1738 | if (verbose) { |
1701 | fprintf(stderr, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx " | 1739 | fprintf(stderr, "cpu%d: MSR_RAPL_POWER_UNIT: 0x%08llx " |
1702 | "(%f Watts, %f Joules, %f sec.)\n", cpu, msr, | 1740 | "(%f Watts, %f Joules, %f sec.)\n", cpu, msr, |
1703 | local_rapl_power_units, local_rapl_energy_units, local_rapl_time_units); | 1741 | rapl_power_units, rapl_energy_units, rapl_time_units); |
1704 | } | 1742 | } |
1705 | if (do_rapl & RAPL_PKG) { | 1743 | if (do_rapl & RAPL_PKG_POWER_INFO) { |
1744 | |||
1706 | if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr)) | 1745 | if (get_msr(cpu, MSR_PKG_POWER_INFO, &msr)) |
1707 | return -5; | 1746 | return -5; |
1708 | 1747 | ||
@@ -1714,6 +1753,9 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) | |||
1714 | ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units, | 1753 | ((msr >> 32) & RAPL_POWER_GRANULARITY) * rapl_power_units, |
1715 | ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units); | 1754 | ((msr >> 48) & RAPL_TIME_GRANULARITY) * rapl_time_units); |
1716 | 1755 | ||
1756 | } | ||
1757 | if (do_rapl & RAPL_PKG) { | ||
1758 | |||
1717 | if (get_msr(cpu, MSR_PKG_POWER_LIMIT, &msr)) | 1759 | if (get_msr(cpu, MSR_PKG_POWER_LIMIT, &msr)) |
1718 | return -9; | 1760 | return -9; |
1719 | 1761 | ||
@@ -1749,12 +1791,16 @@ int print_rapl(struct thread_data *t, struct core_data *c, struct pkg_data *p) | |||
1749 | 1791 | ||
1750 | print_power_limit_msr(cpu, msr, "DRAM Limit"); | 1792 | print_power_limit_msr(cpu, msr, "DRAM Limit"); |
1751 | } | 1793 | } |
1752 | if (do_rapl & RAPL_CORES) { | 1794 | if (do_rapl & RAPL_CORE_POLICY) { |
1753 | if (verbose) { | 1795 | if (verbose) { |
1754 | if (get_msr(cpu, MSR_PP0_POLICY, &msr)) | 1796 | if (get_msr(cpu, MSR_PP0_POLICY, &msr)) |
1755 | return -7; | 1797 | return -7; |
1756 | 1798 | ||
1757 | fprintf(stderr, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF); | 1799 | fprintf(stderr, "cpu%d: MSR_PP0_POLICY: %lld\n", cpu, msr & 0xF); |
1800 | } | ||
1801 | } | ||
1802 | if (do_rapl & RAPL_CORES) { | ||
1803 | if (verbose) { | ||
1758 | 1804 | ||
1759 | if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr)) | 1805 | if (get_msr(cpu, MSR_PP0_POWER_LIMIT, &msr)) |
1760 | return -9; | 1806 | return -9; |
@@ -1813,10 +1859,48 @@ int has_c8_c9_c10(unsigned int family, unsigned int model) | |||
1813 | } | 1859 | } |
1814 | 1860 | ||
1815 | 1861 | ||
1862 | int is_slm(unsigned int family, unsigned int model) | ||
1863 | { | ||
1864 | if (!genuine_intel) | ||
1865 | return 0; | ||
1866 | switch (model) { | ||
1867 | case 0x37: /* BYT */ | ||
1868 | case 0x4D: /* AVN */ | ||
1869 | return 1; | ||
1870 | } | ||
1871 | return 0; | ||
1872 | } | ||
1873 | |||
1874 | #define SLM_BCLK_FREQS 5 | ||
1875 | double slm_freq_table[SLM_BCLK_FREQS] = { 83.3, 100.0, 133.3, 116.7, 80.0}; | ||
1876 | |||
1877 | double slm_bclk(void) | ||
1878 | { | ||
1879 | unsigned long long msr = 3; | ||
1880 | unsigned int i; | ||
1881 | double freq; | ||
1882 | |||
1883 | if (get_msr(0, MSR_FSB_FREQ, &msr)) | ||
1884 | fprintf(stderr, "SLM BCLK: unknown\n"); | ||
1885 | |||
1886 | i = msr & 0xf; | ||
1887 | if (i >= SLM_BCLK_FREQS) { | ||
1888 | fprintf(stderr, "SLM BCLK[%d] invalid\n", i); | ||
1889 | msr = 3; | ||
1890 | } | ||
1891 | freq = slm_freq_table[i]; | ||
1892 | |||
1893 | fprintf(stderr, "SLM BCLK: %.1f Mhz\n", freq); | ||
1894 | |||
1895 | return freq; | ||
1896 | } | ||
1897 | |||
1816 | double discover_bclk(unsigned int family, unsigned int model) | 1898 | double discover_bclk(unsigned int family, unsigned int model) |
1817 | { | 1899 | { |
1818 | if (is_snb(family, model)) | 1900 | if (is_snb(family, model)) |
1819 | return 100.00; | 1901 | return 100.00; |
1902 | else if (is_slm(family, model)) | ||
1903 | return slm_bclk(); | ||
1820 | else | 1904 | else |
1821 | return 133.33; | 1905 | return 133.33; |
1822 | } | 1906 | } |
@@ -1873,7 +1957,7 @@ int set_temperature_target(struct thread_data *t, struct core_data *c, struct pk | |||
1873 | fprintf(stderr, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n", | 1957 | fprintf(stderr, "cpu%d: MSR_IA32_TEMPERATURE_TARGET: 0x%08llx (%d C)\n", |
1874 | cpu, msr, target_c_local); | 1958 | cpu, msr, target_c_local); |
1875 | 1959 | ||
1876 | if (target_c_local < 85 || target_c_local > 120) | 1960 | if (target_c_local < 85 || target_c_local > 127) |
1877 | goto guess; | 1961 | goto guess; |
1878 | 1962 | ||
1879 | tcc_activation_temp = target_c_local; | 1963 | tcc_activation_temp = target_c_local; |
@@ -1970,6 +2054,7 @@ void check_cpuid() | |||
1970 | do_smi = do_nhm_cstates; | 2054 | do_smi = do_nhm_cstates; |
1971 | do_snb_cstates = is_snb(family, model); | 2055 | do_snb_cstates = is_snb(family, model); |
1972 | do_c8_c9_c10 = has_c8_c9_c10(family, model); | 2056 | do_c8_c9_c10 = has_c8_c9_c10(family, model); |
2057 | do_slm_cstates = is_slm(family, model); | ||
1973 | bclk = discover_bclk(family, model); | 2058 | bclk = discover_bclk(family, model); |
1974 | 2059 | ||
1975 | do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model); | 2060 | do_nehalem_turbo_ratio_limit = has_nehalem_turbo_ratio_limit(family, model); |
@@ -2331,7 +2416,7 @@ int main(int argc, char **argv) | |||
2331 | cmdline(argc, argv); | 2416 | cmdline(argc, argv); |
2332 | 2417 | ||
2333 | if (verbose) | 2418 | if (verbose) |
2334 | fprintf(stderr, "turbostat v3.4 April 17, 2013" | 2419 | fprintf(stderr, "turbostat v3.5 April 26, 2013" |
2335 | " - Len Brown <lenb@kernel.org>\n"); | 2420 | " - Len Brown <lenb@kernel.org>\n"); |
2336 | 2421 | ||
2337 | turbostat_init(); | 2422 | turbostat_init(); |