Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'pm-4.18-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management updates from Rafael Wysocki:
"These are mostly fixes, including some fixes for changes made during
the recent merge window and some "stable" material, plus some minor
extensions of the turbostat utility.

Specifics:

- Fix the PM core to avoid introducing a runtime PM usage counter
imbalance when adding device links during driver probe (Rafael
Wysocki).

- Fix the operating performance points (OPP) framework to ensure that
the regulator voltage is always updated as appropriate when
updating clock rates (Waldemar Rymarkiewicz).

- Fix the intel_pstate driver to use correct max/min limits for cores
with differing maximum frequences (Srinivas Pandruvada).

- Fix a typo in the intel_pstate driver documentation (Rafael
Wysocki).

- Fix two issues with the recently added Kryo cpufreq driver (Ilia
Lin).

- Fix two recent regressions and some other minor issues in the
turbostat utility and extend it to provide some more diagnostic
information (Len Brown, Nathan Ciobanu)"

* tag 'pm-4.18-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
Documentation: intel_pstate: Fix typo
tools/power turbostat: version 18.06.20
tools/power turbostat: add the missing command line switches
tools/power turbostat: add single character tokens to help
tools/power turbostat: alphabetize the help output
tools/power turbostat: fix segfault on 'no node' machines
tools/power turbostat: add optional APIC X2APIC columns
tools/power turbostat: decode cpuid.1.HT
tools/power turbostat: fix show/hide issues resulting from mis-merge
PM / OPP: Update voltage in case freq == old_freq
cpufreq: intel_pstate: Fix scaling max/min limits with Turbo 3.0
cpufreq: kryo: Add module remove and exit
cpufreq: kryo: Fix possible error code dereference
PM / core: Fix supplier device runtime PM usage counter imbalance

+223 -88
+1 -1
Documentation/admin-guide/pm/intel_pstate.rst
··· 410 410 That only is supported in some configurations, though (for example, if 411 411 the `HWP feature is enabled in the processor <Active Mode With HWP_>`_, 412 412 the operation mode of the driver cannot be changed), and if it is not 413 - supported in the current configuration, writes to this attribute with 413 + supported in the current configuration, writes to this attribute will 414 414 fail with an appropriate error. 415 415 416 416 Interpretation of Policy Attributes
+11 -4
drivers/base/core.c
··· 236 236 link->rpm_active = true; 237 237 } 238 238 pm_runtime_new_link(consumer); 239 + /* 240 + * If the link is being added by the consumer driver at probe 241 + * time, balance the decrementation of the supplier's runtime PM 242 + * usage counter after consumer probe in driver_probe_device(). 243 + */ 244 + if (consumer->links.status == DL_DEV_PROBING) 245 + pm_runtime_get_noresume(supplier); 239 246 } 240 247 get_device(supplier); 241 248 link->supplier = supplier; ··· 262 255 switch (consumer->links.status) { 263 256 case DL_DEV_PROBING: 264 257 /* 265 - * Balance the decrementation of the supplier's 266 - * runtime PM usage counter after consumer probe 267 - * in driver_probe_device(). 258 + * Some callers expect the link creation during 259 + * consumer driver probe to resume the supplier 260 + * even without DL_FLAG_RPM_ACTIVE. 268 261 */ 269 262 if (flags & DL_FLAG_PM_RUNTIME) 270 - pm_runtime_get_sync(supplier); 263 + pm_runtime_resume(supplier); 271 264 272 265 link->status = DL_STATE_CONSUMER_PROBE; 273 266 break;
+22 -5
drivers/cpufreq/intel_pstate.c
··· 294 294 static struct pstate_funcs pstate_funcs __read_mostly; 295 295 296 296 static int hwp_active __read_mostly; 297 + static int hwp_mode_bdw __read_mostly; 297 298 static bool per_cpu_limits __read_mostly; 298 299 static bool hwp_boost __read_mostly; 299 300 ··· 1414 1413 cpu->pstate.turbo_pstate = pstate_funcs.get_turbo(); 1415 1414 cpu->pstate.scaling = pstate_funcs.get_scaling(); 1416 1415 cpu->pstate.max_freq = cpu->pstate.max_pstate * cpu->pstate.scaling; 1417 - cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * cpu->pstate.scaling; 1416 + 1417 + if (hwp_active && !hwp_mode_bdw) { 1418 + unsigned int phy_max, current_max; 1419 + 1420 + intel_pstate_get_hwp_max(cpu->cpu, &phy_max, &current_max); 1421 + cpu->pstate.turbo_freq = phy_max * cpu->pstate.scaling; 1422 + } else { 1423 + cpu->pstate.turbo_freq = cpu->pstate.turbo_pstate * cpu->pstate.scaling; 1424 + } 1418 1425 1419 1426 if (pstate_funcs.get_aperf_mperf_shift) 1420 1427 cpu->aperf_mperf_shift = pstate_funcs.get_aperf_mperf_shift(); ··· 2476 2467 static inline void intel_pstate_request_control_from_smm(void) {} 2477 2468 #endif /* CONFIG_ACPI */ 2478 2469 2470 + #define INTEL_PSTATE_HWP_BROADWELL 0x01 2471 + 2472 + #define ICPU_HWP(model, hwp_mode) \ 2473 + { X86_VENDOR_INTEL, 6, model, X86_FEATURE_HWP, hwp_mode } 2474 + 2479 2475 static const struct x86_cpu_id hwp_support_ids[] __initconst = { 2480 - { X86_VENDOR_INTEL, 6, X86_MODEL_ANY, X86_FEATURE_HWP }, 2476 + ICPU_HWP(INTEL_FAM6_BROADWELL_X, INTEL_PSTATE_HWP_BROADWELL), 2477 + ICPU_HWP(INTEL_FAM6_BROADWELL_XEON_D, INTEL_PSTATE_HWP_BROADWELL), 2478 + ICPU_HWP(X86_MODEL_ANY, 0), 2481 2479 {} 2482 2480 }; 2483 2481 2484 2482 static int __init intel_pstate_init(void) 2485 2483 { 2484 + const struct x86_cpu_id *id; 2486 2485 int rc; 2487 2486 2488 2487 if (no_load) 2489 2488 return -ENODEV; 2490 2489 2491 - if (x86_match_cpu(hwp_support_ids)) { 2490 + id = x86_match_cpu(hwp_support_ids); 2491 + if (id) { 2492 2492 copy_cpu_funcs(&core_funcs); 2493 2493 if (!no_hwp) { 2494 2494 hwp_active++; 2495 + hwp_mode_bdw = id->driver_data; 2495 2496 intel_pstate.attr = hwp_cpufreq_attrs; 2496 2497 goto hwp_cpu_matched; 2497 2498 } 2498 2499 } else { 2499 - const struct x86_cpu_id *id; 2500 - 2501 2500 id = x86_match_cpu(intel_pstate_cpu_ids); 2502 2501 if (!id) 2503 2502 return -ENODEV;
+22 -3
drivers/cpufreq/qcom-cpufreq-kryo.c
··· 42 42 NUM_OF_MSM8996_VERSIONS, 43 43 }; 44 44 45 + struct platform_device *cpufreq_dt_pdev, *kryo_cpufreq_pdev; 46 + 45 47 static enum _msm8996_version __init qcom_cpufreq_kryo_get_msm_id(void) 46 48 { 47 49 size_t len; ··· 76 74 static int qcom_cpufreq_kryo_probe(struct platform_device *pdev) 77 75 { 78 76 struct opp_table *opp_tables[NR_CPUS] = {0}; 79 - struct platform_device *cpufreq_dt_pdev; 80 77 enum _msm8996_version msm8996_version; 81 78 struct nvmem_cell *speedbin_nvmem; 82 79 struct device_node *np; ··· 116 115 117 116 speedbin = nvmem_cell_read(speedbin_nvmem, &len); 118 117 nvmem_cell_put(speedbin_nvmem); 118 + if (IS_ERR(speedbin)) 119 + return PTR_ERR(speedbin); 119 120 120 121 switch (msm8996_version) { 121 122 case MSM8996_V3: ··· 130 127 BUG(); 131 128 break; 132 129 } 130 + kfree(speedbin); 133 131 134 132 for_each_possible_cpu(cpu) { 135 133 cpu_dev = get_cpu_device(cpu); ··· 166 162 return ret; 167 163 } 168 164 165 + static int qcom_cpufreq_kryo_remove(struct platform_device *pdev) 166 + { 167 + platform_device_unregister(cpufreq_dt_pdev); 168 + return 0; 169 + } 170 + 169 171 static struct platform_driver qcom_cpufreq_kryo_driver = { 170 172 .probe = qcom_cpufreq_kryo_probe, 173 + .remove = qcom_cpufreq_kryo_remove, 171 174 .driver = { 172 175 .name = "qcom-cpufreq-kryo", 173 176 }, ··· 209 198 if (unlikely(ret < 0)) 210 199 return ret; 211 200 212 - ret = PTR_ERR_OR_ZERO(platform_device_register_simple( 213 - "qcom-cpufreq-kryo", -1, NULL, 0)); 201 + kryo_cpufreq_pdev = platform_device_register_simple( 202 + "qcom-cpufreq-kryo", -1, NULL, 0); 203 + ret = PTR_ERR_OR_ZERO(kryo_cpufreq_pdev); 214 204 if (0 == ret) 215 205 return 0; 216 206 ··· 219 207 return ret; 220 208 } 221 209 module_init(qcom_cpufreq_kryo_init); 210 + 211 + static void __init qcom_cpufreq_kryo_exit(void) 212 + { 213 + platform_device_unregister(kryo_cpufreq_pdev); 214 + platform_driver_unregister(&qcom_cpufreq_kryo_driver); 215 + } 216 + module_exit(qcom_cpufreq_kryo_exit); 222 217 223 218 MODULE_DESCRIPTION("Qualcomm Technologies, Inc. Kryo CPUfreq driver"); 224 219 MODULE_LICENSE("GPL v2");
+1 -1
drivers/opp/core.c
··· 598 598 } 599 599 600 600 /* Scaling up? Scale voltage before frequency */ 601 - if (freq > old_freq) { 601 + if (freq >= old_freq) { 602 602 ret = _set_opp_voltage(dev, reg, new_supply); 603 603 if (ret) 604 604 goto restore_voltage;
+1 -1
tools/power/x86/turbostat/turbostat.8
··· 56 56 .PP 57 57 \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. 58 58 .PP 59 - \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". 59 + \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". 60 60 The column name "all" can be used to enable all disabled-by-default built-in counters. 61 61 .PP 62 62 \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.
+165 -73
tools/power/x86/turbostat/turbostat.c
··· 109 109 unsigned int has_hwp_epp; /* IA32_HWP_REQUEST[bits 31:24] */ 110 110 unsigned int has_hwp_pkg; /* IA32_HWP_REQUEST_PKG */ 111 111 unsigned int has_misc_feature_control; 112 + unsigned int first_counter_read = 1; 112 113 113 114 #define RAPL_PKG (1 << 0) 114 115 /* 0x610 MSR_PKG_POWER_LIMIT */ ··· 171 170 unsigned long long irq_count; 172 171 unsigned int smi_count; 173 172 unsigned int cpu_id; 173 + unsigned int apic_id; 174 + unsigned int x2apic_id; 174 175 unsigned int flags; 175 176 #define CPU_IS_FIRST_THREAD_IN_CORE 0x2 176 177 #define CPU_IS_FIRST_CORE_IN_PACKAGE 0x4 ··· 384 381 } 385 382 386 383 /* 387 - * Each string in this array is compared in --show and --hide cmdline. 388 - * Thus, strings that are proper sub-sets must follow their more specific peers. 384 + * This list matches the column headers, except 385 + * 1. built-in only, the sysfs counters are not here -- we learn of those at run-time 386 + * 2. Core and CPU are moved to the end, we can't have strings that contain them 387 + * matching on them for --show and --hide. 389 388 */ 390 389 struct msr_counter bic[] = { 391 390 { 0x0, "usec" }, 392 391 { 0x0, "Time_Of_Day_Seconds" }, 393 392 { 0x0, "Package" }, 393 + { 0x0, "Node" }, 394 394 { 0x0, "Avg_MHz" }, 395 + { 0x0, "Busy%" }, 395 396 { 0x0, "Bzy_MHz" }, 396 397 { 0x0, "TSC_MHz" }, 397 398 { 0x0, "IRQ" }, 398 399 { 0x0, "SMI", "", 32, 0, FORMAT_DELTA, NULL}, 399 - { 0x0, "Busy%" }, 400 + { 0x0, "sysfs" }, 400 401 { 0x0, "CPU%c1" }, 401 402 { 0x0, "CPU%c3" }, 402 403 { 0x0, "CPU%c6" }, ··· 431 424 { 0x0, "Cor_J" }, 432 425 { 0x0, "GFX_J" }, 433 426 { 0x0, "RAM_J" }, 434 - { 0x0, "Core" }, 435 - { 0x0, "CPU" }, 436 427 { 0x0, "Mod%c6" }, 437 - { 0x0, "sysfs" }, 438 428 { 0x0, "Totl%C0" }, 439 429 { 0x0, "Any%C0" }, 440 430 { 0x0, "GFX%C0" }, 441 431 { 0x0, "CPUGFX%" }, 442 - { 0x0, "Node%" }, 432 + { 0x0, "Core" }, 433 + { 0x0, "CPU" }, 434 + { 0x0, "APIC" }, 435 + { 0x0, "X2APIC" }, 443 436 }; 444 - 445 - 446 437 447 438 #define MAX_BIC (sizeof(bic) / sizeof(struct msr_counter)) 448 439 #define BIC_USEC (1ULL << 0) 449 440 #define BIC_TOD (1ULL << 1) 450 441 #define BIC_Package (1ULL << 2) 451 - #define BIC_Avg_MHz (1ULL << 3) 452 - #define BIC_Bzy_MHz (1ULL << 4) 453 - #define BIC_TSC_MHz (1ULL << 5) 454 - #define BIC_IRQ (1ULL << 6) 455 - #define BIC_SMI (1ULL << 7) 456 - #define BIC_Busy (1ULL << 8) 457 - #define BIC_CPU_c1 (1ULL << 9) 458 - #define BIC_CPU_c3 (1ULL << 10) 459 - #define BIC_CPU_c6 (1ULL << 11) 460 - #define BIC_CPU_c7 (1ULL << 12) 461 - #define BIC_ThreadC (1ULL << 13) 462 - #define BIC_CoreTmp (1ULL << 14) 463 - #define BIC_CoreCnt (1ULL << 15) 464 - #define BIC_PkgTmp (1ULL << 16) 465 - #define BIC_GFX_rc6 (1ULL << 17) 466 - #define BIC_GFXMHz (1ULL << 18) 467 - #define BIC_Pkgpc2 (1ULL << 19) 468 - #define BIC_Pkgpc3 (1ULL << 20) 469 - #define BIC_Pkgpc6 (1ULL << 21) 470 - #define BIC_Pkgpc7 (1ULL << 22) 471 - #define BIC_Pkgpc8 (1ULL << 23) 472 - #define BIC_Pkgpc9 (1ULL << 24) 473 - #define BIC_Pkgpc10 (1ULL << 25) 474 - #define BIC_CPU_LPI (1ULL << 26) 475 - #define BIC_SYS_LPI (1ULL << 27) 476 - #define BIC_PkgWatt (1ULL << 26) 477 - #define BIC_CorWatt (1ULL << 27) 478 - #define BIC_GFXWatt (1ULL << 28) 479 - #define BIC_PkgCnt (1ULL << 29) 480 - #define BIC_RAMWatt (1ULL << 30) 481 - #define BIC_PKG__ (1ULL << 31) 482 - #define BIC_RAM__ (1ULL << 32) 483 - #define BIC_Pkg_J (1ULL << 33) 484 - #define BIC_Cor_J (1ULL << 34) 485 - #define BIC_GFX_J (1ULL << 35) 486 - #define BIC_RAM_J (1ULL << 36) 487 - #define BIC_Core (1ULL << 37) 488 - #define BIC_CPU (1ULL << 38) 489 - #define BIC_Mod_c6 (1ULL << 39) 490 - #define BIC_sysfs (1ULL << 40) 491 - #define BIC_Totl_c0 (1ULL << 41) 492 - #define BIC_Any_c0 (1ULL << 42) 493 - #define BIC_GFX_c0 (1ULL << 43) 494 - #define BIC_CPUGFX (1ULL << 44) 495 - #define BIC_Node (1ULL << 45) 442 + #define BIC_Node (1ULL << 3) 443 + #define BIC_Avg_MHz (1ULL << 4) 444 + #define BIC_Busy (1ULL << 5) 445 + #define BIC_Bzy_MHz (1ULL << 6) 446 + #define BIC_TSC_MHz (1ULL << 7) 447 + #define BIC_IRQ (1ULL << 8) 448 + #define BIC_SMI (1ULL << 9) 449 + #define BIC_sysfs (1ULL << 10) 450 + #define BIC_CPU_c1 (1ULL << 11) 451 + #define BIC_CPU_c3 (1ULL << 12) 452 + #define BIC_CPU_c6 (1ULL << 13) 453 + #define BIC_CPU_c7 (1ULL << 14) 454 + #define BIC_ThreadC (1ULL << 15) 455 + #define BIC_CoreTmp (1ULL << 16) 456 + #define BIC_CoreCnt (1ULL << 17) 457 + #define BIC_PkgTmp (1ULL << 18) 458 + #define BIC_GFX_rc6 (1ULL << 19) 459 + #define BIC_GFXMHz (1ULL << 20) 460 + #define BIC_Pkgpc2 (1ULL << 21) 461 + #define BIC_Pkgpc3 (1ULL << 22) 462 + #define BIC_Pkgpc6 (1ULL << 23) 463 + #define BIC_Pkgpc7 (1ULL << 24) 464 + #define BIC_Pkgpc8 (1ULL << 25) 465 + #define BIC_Pkgpc9 (1ULL << 26) 466 + #define BIC_Pkgpc10 (1ULL << 27) 467 + #define BIC_CPU_LPI (1ULL << 28) 468 + #define BIC_SYS_LPI (1ULL << 29) 469 + #define BIC_PkgWatt (1ULL << 30) 470 + #define BIC_CorWatt (1ULL << 31) 471 + #define BIC_GFXWatt (1ULL << 32) 472 + #define BIC_PkgCnt (1ULL << 33) 473 + #define BIC_RAMWatt (1ULL << 34) 474 + #define BIC_PKG__ (1ULL << 35) 475 + #define BIC_RAM__ (1ULL << 36) 476 + #define BIC_Pkg_J (1ULL << 37) 477 + #define BIC_Cor_J (1ULL << 38) 478 + #define BIC_GFX_J (1ULL << 39) 479 + #define BIC_RAM_J (1ULL << 40) 480 + #define BIC_Mod_c6 (1ULL << 41) 481 + #define BIC_Totl_c0 (1ULL << 42) 482 + #define BIC_Any_c0 (1ULL << 43) 483 + #define BIC_GFX_c0 (1ULL << 44) 484 + #define BIC_CPUGFX (1ULL << 45) 485 + #define BIC_Core (1ULL << 46) 486 + #define BIC_CPU (1ULL << 47) 487 + #define BIC_APIC (1ULL << 48) 488 + #define BIC_X2APIC (1ULL << 49) 496 489 497 - #define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD) 490 + #define BIC_DISABLED_BY_DEFAULT (BIC_USEC | BIC_TOD | BIC_APIC | BIC_X2APIC) 498 491 499 492 unsigned long long bic_enabled = (0xFFFFFFFFFFFFFFFFULL & ~BIC_DISABLED_BY_DEFAULT); 500 - unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs; 493 + unsigned long long bic_present = BIC_USEC | BIC_TOD | BIC_sysfs | BIC_APIC | BIC_X2APIC; 501 494 502 495 #define DO_BIC(COUNTER_NAME) (bic_enabled & bic_present & COUNTER_NAME) 503 496 #define ENABLE_BIC(COUNTER_NAME) (bic_enabled |= COUNTER_NAME) ··· 524 517 "when COMMAND completes.\n" 525 518 "If no COMMAND is specified, turbostat wakes every 5-seconds\n" 526 519 "to print statistics, until interrupted.\n" 527 - "--add add a counter\n" 528 - " eg. --add msr0x10,u64,cpu,delta,MY_TSC\n" 529 - "--cpu cpu-set limit output to summary plus cpu-set:\n" 530 - " {core | package | j,k,l..m,n-p }\n" 531 - "--quiet skip decoding system configuration header\n" 532 - "--interval sec.subsec Override default 5-second measurement interval\n" 533 - "--help print this help message\n" 534 - "--list list column headers only\n" 535 - "--num_iterations num number of the measurement iterations\n" 536 - "--out file create or truncate \"file\" for all output\n" 537 - "--version print version information\n" 520 + " -a, --add add a counter\n" 521 + " eg. --add msr0x10,u64,cpu,delta,MY_TSC\n" 522 + " -c, --cpu cpu-set limit output to summary plus cpu-set:\n" 523 + " {core | package | j,k,l..m,n-p }\n" 524 + " -d, --debug displays usec, Time_Of_Day_Seconds and more debugging\n" 525 + " -D, --Dump displays the raw counter values\n" 526 + " -e, --enable [all | column]\n" 527 + " shows all or the specified disabled column\n" 528 + " -H, --hide [column|column,column,...]\n" 529 + " hide the specified column(s)\n" 530 + " -i, --interval sec.subsec\n" 531 + " Override default 5-second measurement interval\n" 532 + " -J, --Joules displays energy in Joules instead of Watts\n" 533 + " -l, --list list column headers only\n" 534 + " -n, --num_iterations num\n" 535 + " number of the measurement iterations\n" 536 + " -o, --out file\n" 537 + " create or truncate \"file\" for all output\n" 538 + " -q, --quiet skip decoding system configuration header\n" 539 + " -s, --show [column|column,column,...]\n" 540 + " show only the specified column(s)\n" 541 + " -S, --Summary\n" 542 + " limits output to 1-line system summary per interval\n" 543 + " -T, --TCC temperature\n" 544 + " sets the Thermal Control Circuit temperature in\n" 545 + " degrees Celsius\n" 546 + " -h, --help print this help message\n" 547 + " -v, --version print version information\n" 538 548 "\n" 539 549 "For more help, run \"man turbostat\"\n"); 540 550 } ··· 625 601 outp += sprintf(outp, "%sCore", (printed++ ? delim : "")); 626 602 if (DO_BIC(BIC_CPU)) 627 603 outp += sprintf(outp, "%sCPU", (printed++ ? delim : "")); 604 + if (DO_BIC(BIC_APIC)) 605 + outp += sprintf(outp, "%sAPIC", (printed++ ? delim : "")); 606 + if (DO_BIC(BIC_X2APIC)) 607 + outp += sprintf(outp, "%sX2APIC", (printed++ ? delim : "")); 628 608 if (DO_BIC(BIC_Avg_MHz)) 629 609 outp += sprintf(outp, "%sAvg_MHz", (printed++ ? delim : "")); 630 610 if (DO_BIC(BIC_Busy)) ··· 908 880 outp += sprintf(outp, "%s-", (printed++ ? delim : "")); 909 881 if (DO_BIC(BIC_CPU)) 910 882 outp += sprintf(outp, "%s-", (printed++ ? delim : "")); 883 + if (DO_BIC(BIC_APIC)) 884 + outp += sprintf(outp, "%s-", (printed++ ? delim : "")); 885 + if (DO_BIC(BIC_X2APIC)) 886 + outp += sprintf(outp, "%s-", (printed++ ? delim : "")); 911 887 } else { 912 888 if (DO_BIC(BIC_Package)) { 913 889 if (p) ··· 936 904 } 937 905 if (DO_BIC(BIC_CPU)) 938 906 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->cpu_id); 907 + if (DO_BIC(BIC_APIC)) 908 + outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->apic_id); 909 + if (DO_BIC(BIC_X2APIC)) 910 + outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->x2apic_id); 939 911 } 940 912 941 913 if (DO_BIC(BIC_Avg_MHz)) ··· 1267 1231 int i; 1268 1232 struct msr_counter *mp; 1269 1233 1234 + /* we run cpuid just the 1st time, copy the results */ 1235 + if (DO_BIC(BIC_APIC)) 1236 + new->apic_id = old->apic_id; 1237 + if (DO_BIC(BIC_X2APIC)) 1238 + new->x2apic_id = old->x2apic_id; 1239 + 1270 1240 /* 1271 1241 * the timestamps from start of measurement interval are in "old" 1272 1242 * the timestamp from end of measurement interval are in "new" ··· 1434 1392 { 1435 1393 int i; 1436 1394 struct msr_counter *mp; 1395 + 1396 + /* copy un-changing apic_id's */ 1397 + if (DO_BIC(BIC_APIC)) 1398 + average.threads.apic_id = t->apic_id; 1399 + if (DO_BIC(BIC_X2APIC)) 1400 + average.threads.x2apic_id = t->x2apic_id; 1437 1401 1438 1402 /* remember first tv_begin */ 1439 1403 if (average.threads.tv_begin.tv_sec == 0) ··· 1667 1619 return 0; 1668 1620 } 1669 1621 1622 + void get_apic_id(struct thread_data *t) 1623 + { 1624 + unsigned int eax, ebx, ecx, edx, max_level; 1625 + 1626 + eax = ebx = ecx = edx = 0; 1627 + 1628 + if (!genuine_intel) 1629 + return; 1630 + 1631 + __cpuid(0, max_level, ebx, ecx, edx); 1632 + 1633 + __cpuid(1, eax, ebx, ecx, edx); 1634 + t->apic_id = (ebx >> 24) & 0xf; 1635 + 1636 + if (max_level < 0xb) 1637 + return; 1638 + 1639 + if (!DO_BIC(BIC_X2APIC)) 1640 + return; 1641 + 1642 + ecx = 0; 1643 + __cpuid(0xb, eax, ebx, ecx, edx); 1644 + t->x2apic_id = edx; 1645 + 1646 + if (debug && (t->apic_id != t->x2apic_id)) 1647 + fprintf(stderr, "cpu%d: apic 0x%x x2apic 0x%x\n", t->cpu_id, t->apic_id, t->x2apic_id); 1648 + } 1649 + 1670 1650 /* 1671 1651 * get_counters(...) 1672 1652 * migrate to cpu ··· 1708 1632 struct msr_counter *mp; 1709 1633 int i; 1710 1634 1711 - 1712 1635 gettimeofday(&t->tv_begin, (struct timezone *)NULL); 1713 1636 1714 1637 if (cpu_migrate(cpu)) { ··· 1715 1640 return -1; 1716 1641 } 1717 1642 1643 + if (first_counter_read) 1644 + get_apic_id(t); 1718 1645 retry: 1719 1646 t->tsc = rdtsc(); /* we are running on local CPU of interest */ 1720 1647 ··· 2509 2432 if (pni[pkg].count > topo.nodes_per_pkg) 2510 2433 topo.nodes_per_pkg = pni[0].count; 2511 2434 2435 + /* Fake 1 node per pkg for machines that don't 2436 + * expose nodes and thus avoid -nan results 2437 + */ 2438 + if (topo.nodes_per_pkg == 0) 2439 + topo.nodes_per_pkg = 1; 2440 + 2512 2441 for (cpu = 0; cpu < topo.num_cpus; cpu++) { 2513 2442 pkg = cpus[cpu].physical_package_id; 2514 2443 node = cpus[cpu].physical_node_id; ··· 2962 2879 } 2963 2880 } 2964 2881 2882 + 2965 2883 void turbostat_loop() 2966 2884 { 2967 2885 int retval; ··· 2976 2892 2977 2893 snapshot_proc_sysfs_files(); 2978 2894 retval = for_all_cpus(get_counters, EVEN_COUNTERS); 2895 + first_counter_read = 0; 2979 2896 if (retval < -1) { 2980 2897 exit(retval); 2981 2898 } else if (retval == -1) { ··· 4477 4392 if (!quiet) { 4478 4393 fprintf(outf, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n", 4479 4394 max_level, family, model, stepping, family, model, stepping); 4480 - fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s\n", 4395 + fprintf(outf, "CPUID(1): %s %s %s %s %s %s %s %s %s %s\n", 4481 4396 ecx & (1 << 0) ? "SSE3" : "-", 4482 4397 ecx & (1 << 3) ? "MONITOR" : "-", 4483 4398 ecx & (1 << 6) ? "SMX" : "-", ··· 4486 4401 edx & (1 << 4) ? "TSC" : "-", 4487 4402 edx & (1 << 5) ? "MSR" : "-", 4488 4403 edx & (1 << 22) ? "ACPI-TM" : "-", 4404 + edx & (1 << 28) ? "HT" : "-", 4489 4405 edx & (1 << 29) ? "TM" : "-"); 4490 4406 } 4491 4407 ··· 4738 4652 return; 4739 4653 } 4740 4654 4741 - 4742 4655 /* 4743 4656 * in /dev/cpu/ return success for names that are numbers 4744 4657 * ie. filter out ".", "..", "microcode". ··· 4927 4842 struct core_data *c; 4928 4843 struct pkg_data *p; 4929 4844 4845 + 4846 + /* Workaround for systems where physical_node_id==-1 4847 + * and logical_node_id==(-1 - topo.num_cpus) 4848 + */ 4849 + if (node_id < 0) 4850 + node_id = 0; 4851 + 4930 4852 t = GET_THREAD(thread_base, thread_id, core_id, node_id, pkg_id); 4931 4853 c = GET_CORE(core_base, core_id, node_id, pkg_id); 4932 4854 p = GET_PKG(pkg_base, pkg_id); ··· 5038 4946 5039 4947 snapshot_proc_sysfs_files(); 5040 4948 status = for_all_cpus(get_counters, EVEN_COUNTERS); 4949 + first_counter_read = 0; 5041 4950 if (status) 5042 4951 exit(status); 5043 4952 /* clear affinity side-effect of get_counters() */ ··· 5102 5009 } 5103 5010 5104 5011 void print_version() { 5105 - fprintf(outf, "turbostat version 18.06.01" 5012 + fprintf(outf, "turbostat version 18.06.20" 5106 5013 " - Len Brown <lenb@kernel.org>\n"); 5107 5014 } 5108 5015 ··· 5474 5381 break; 5475 5382 case 'e': 5476 5383 /* --enable specified counter */ 5477 - bic_enabled |= bic_lookup(optarg, SHOW_LIST); 5384 + bic_enabled = bic_enabled | bic_lookup(optarg, SHOW_LIST); 5478 5385 break; 5479 5386 case 'd': 5480 5387 debug++; ··· 5558 5465 int main(int argc, char **argv) 5559 5466 { 5560 5467 outf = stderr; 5561 - 5562 5468 cmdline(argc, argv); 5563 5469 5564 5470 if (!quiet)