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(); |
