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 'power-utilities-2026.04.25' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux

Pull power utility updates from Len Brown:
"x86_energy_perf_policy:
- Initial SoC Slider support

turbostat:
- Display HT siblings in cpu# order
- Add Module-ID column
- Print Core-ID and APIC-ID in hex
- Fix misc bugs"

* tag 'power-utilities-2026.04.25' of git://git.kernel.org/pub/scm/linux/kernel/git/lenb/linux:
tools/power x86_energy_perf_policy: Version 2026.04.25
tools/power x86_energy_perf_policy.8: Document SoC Slider Options
tools/power x86_energy_perf_policy: Enhances SoC Slider related checks
tools/power turbostat: v2026.04.21
tools/power turbostat: Process HT siblings in CPU order
tools/power turbostat: Show module_id column
tools/power turbostat: Print core_id and apic_id in hex
tools/power turbostat: Cleanup print helper functions
tools/power turbostat: Fix --cpu-set 1 regression on HT systems
tools/power turbostat: Fix --cpu-set 0 regression on HT systems
tools/power turbostat: Fix unrecognized option '-P'
tools/power turbostat: Fix AMD RAPL regression on big systems
tools/power/x86: Add SOC slider and platform profile support

+461 -195
+153 -78
tools/power/x86/turbostat/turbostat.c
··· 191 191 { 0x0, "Any%C0", NULL, 0, 0, 0, NULL, 0 }, 192 192 { 0x0, "GFX%C0", NULL, 0, 0, 0, NULL, 0 }, 193 193 { 0x0, "CPUGFX%", NULL, 0, 0, 0, NULL, 0 }, 194 + { 0x0, "Module", NULL, 0, 0, 0, NULL, 0 }, 194 195 { 0x0, "Core", NULL, 0, 0, 0, NULL, 0 }, 195 196 { 0x0, "CPU", NULL, 0, 0, 0, NULL, 0 }, 196 197 { 0x0, "APIC", NULL, 0, 0, 0, NULL, 0 }, ··· 265 264 BIC_Any_c0, 266 265 BIC_GFX_c0, 267 266 BIC_CPUGFX, 267 + BIC_Module, 268 268 BIC_Core, 269 269 BIC_CPU, 270 270 BIC_APIC, ··· 366 364 SET_BIC(BIC_Node, &bic_group_topology); 367 365 SET_BIC(BIC_CoreCnt, &bic_group_topology); 368 366 SET_BIC(BIC_PkgCnt, &bic_group_topology); 367 + SET_BIC(BIC_Module, &bic_group_topology); 369 368 SET_BIC(BIC_Core, &bic_group_topology); 370 369 SET_BIC(BIC_CPU, &bic_group_topology); 371 370 SET_BIC(BIC_Die, &bic_group_topology); ··· 2386 2383 struct cpu_topology { 2387 2384 int cpu_id; 2388 2385 int core_id; /* unique within a package */ 2386 + int module_id; 2389 2387 int package_id; 2390 2388 int die_id; 2391 2389 int l3_id; ··· 2408 2404 int allowed_cores; 2409 2405 int max_cpu_num; 2410 2406 int max_core_id; /* within a package */ 2407 + int min_module_id; /* system wide */ 2408 + int max_module_id; /* system wide */ 2411 2409 int max_package_id; 2412 2410 int max_die_id; 2413 2411 int max_l3_id; ··· 2433 2427 2434 2428 int cpu_is_not_present(int cpu) 2435 2429 { 2430 + if (cpu < 0) 2431 + return 1; 2432 + 2436 2433 return !CPU_ISSET_S(cpu, cpu_present_setsize, cpu_present_set); 2437 2434 } 2438 2435 2439 2436 int cpu_is_not_allowed(int cpu) 2440 2437 { 2438 + if (cpu < 0) 2439 + return 1; 2440 + 2441 2441 return !CPU_ISSET_S(cpu, cpu_allowed_setsize, cpu_allowed_set); 2442 2442 } 2443 2443 ··· 2454 2442 */ 2455 2443 2456 2444 #define PER_THREAD_PARAMS struct thread_data *t, struct core_data *c, struct pkg_data *p 2445 + 2446 + int has_allowed_lower_ht_sibling(int cpu) 2447 + { 2448 + int i; 2449 + 2450 + for (i = 0; i <= cpus[cpu].ht_id; ++i) { 2451 + int sibling_cpu_id = cpus[cpu].ht_sibling_cpu_id[i]; 2452 + 2453 + if (sibling_cpu_id == cpu) 2454 + return 0; 2455 + 2456 + if (!cpu_is_not_allowed(sibling_cpu_id)) 2457 + return 1; 2458 + } 2459 + return 0; 2460 + } 2457 2461 2458 2462 int for_all_cpus(int (func) (struct thread_data *, struct core_data *, struct pkg_data *), 2459 2463 struct thread_data *thread_base, struct core_data *core_base, struct pkg_data *pkg_base) ··· 2488 2460 if (cpu_is_not_allowed(cpu)) 2489 2461 continue; 2490 2462 2491 - if (cpus[cpu].ht_id > 0) /* skip HT sibling */ 2463 + if (has_allowed_lower_ht_sibling(cpu)) /* skip HT sibling */ 2492 2464 continue; 2493 2465 2494 2466 t = &thread_base[cpu]; ··· 2497 2469 2498 2470 retval |= func(t, c, p); 2499 2471 2500 - /* Handle HT sibling now */ 2472 + /* Handle other HT siblings now */ 2501 2473 int i; 2502 2474 2503 - for (i = MAX_HT_ID; i > 0; --i) { /* ht_id 0 is self */ 2504 - if (cpus[cpu].ht_sibling_cpu_id[i] <= 0) 2475 + for (i = 0; i <= MAX_HT_ID; ++i) { 2476 + int sibling_cpu_id = cpus[cpu].ht_sibling_cpu_id[i]; 2477 + 2478 + if (sibling_cpu_id < 0) 2479 + break; 2480 + 2481 + if (sibling_cpu_id == cpu) 2505 2482 continue; 2506 - t = &thread_base[cpus[cpu].ht_sibling_cpu_id[i]]; 2483 + 2484 + if (cpu_is_not_allowed(sibling_cpu_id)) 2485 + continue; 2486 + 2487 + t = &thread_base[sibling_cpu_id]; 2507 2488 2508 2489 retval |= func(t, c, p); 2509 2490 } ··· 2872 2835 static inline int print_name(int width, int *printed, char *delim, char *name, enum counter_type type, enum counter_format format) 2873 2836 { 2874 2837 UNUSED(type); 2838 + char *sep = (*printed)++ ? delim : ""; 2875 2839 2876 2840 if (format == FORMAT_RAW && width >= 64) 2877 - return (sprintf(outp, "%s%-8s", ((*printed)++ ? delim : ""), name)); 2841 + return sprintf(outp, "%s%-8s", sep, name); 2878 2842 else 2879 - return (sprintf(outp, "%s%s", ((*printed)++ ? delim : ""), name)); 2843 + return sprintf(outp, "%s%s", sep, name); 2880 2844 } 2881 2845 2882 2846 static inline int print_hex_value(int width, int *printed, char *delim, unsigned long long value) 2883 2847 { 2848 + char *sep = (*printed)++ ? delim : ""; 2849 + 2884 2850 if (width <= 32) 2885 - return (sprintf(outp, "%s%08x", ((*printed)++ ? delim : ""), (unsigned int)value)); 2851 + return sprintf(outp, "%s%08llx", sep, value); 2886 2852 else 2887 - return (sprintf(outp, "%s%016llx", ((*printed)++ ? delim : ""), value)); 2853 + return sprintf(outp, "%s%016llx", sep, value); 2888 2854 } 2889 2855 2890 2856 static inline int print_decimal_value(int width, int *printed, char *delim, unsigned long long value) 2891 2857 { 2858 + char *sep = (*printed)++ ? delim : ""; 2859 + 2892 2860 UNUSED(width); 2893 2861 2894 - return (sprintf(outp, "%s%lld", ((*printed)++ ? delim : ""), value)); 2862 + return sprintf(outp, "%s%lld", sep, value); 2895 2863 } 2896 2864 2897 2865 static inline int print_float_value(int *printed, char *delim, double value) 2898 2866 { 2899 - return (sprintf(outp, "%s%0.2f", ((*printed)++ ? delim : ""), value)); 2867 + char *sep = (*printed)++ ? delim : ""; 2868 + 2869 + return sprintf(outp, "%s%0.2f", sep, value); 2900 2870 } 2901 2871 2902 2872 void print_header(char *delim) ··· 2925 2881 outp += sprintf(outp, "%sL3", (printed++ ? delim : "")); 2926 2882 if (DO_BIC(BIC_Node)) 2927 2883 outp += sprintf(outp, "%sNode", (printed++ ? delim : "")); 2884 + if (DO_BIC(BIC_Module)) 2885 + outp += sprintf(outp, "%sModule", (printed++ ? delim : "")); 2928 2886 if (DO_BIC(BIC_Core)) 2929 2887 outp += sprintf(outp, "%sCore", (printed++ ? delim : "")); 2930 2888 if (DO_BIC(BIC_CPU)) ··· 3222 3176 } 3223 3177 3224 3178 if (c && is_cpu_first_thread_in_core(t, c)) { 3225 - outp += sprintf(outp, "core: %d\n", cpus[t->cpu_id].core_id); 3179 + outp += sprintf(outp, "core: 0x%x\n", cpus[t->cpu_id].core_id); 3226 3180 outp += sprintf(outp, "c3: %016llX\n", c->c3); 3227 3181 outp += sprintf(outp, "c6: %016llX\n", c->c6); 3228 3182 outp += sprintf(outp, "c7: %016llX\n", c->c7); ··· 3396 3350 outp += sprintf(outp, "%s-", (printed++ ? delim : "")); 3397 3351 if (DO_BIC(BIC_Node)) 3398 3352 outp += sprintf(outp, "%s-", (printed++ ? delim : "")); 3353 + if (DO_BIC(BIC_Module)) 3354 + outp += sprintf(outp, "%s-", (printed++ ? delim : "")); 3399 3355 if (DO_BIC(BIC_Core)) 3400 3356 outp += sprintf(outp, "%s-", (printed++ ? delim : "")); 3401 3357 if (DO_BIC(BIC_CPU)) ··· 3431 3383 else 3432 3384 outp += sprintf(outp, "%s-", (printed++ ? delim : "")); 3433 3385 } 3386 + if (DO_BIC(BIC_Module)) { 3387 + if (c) 3388 + outp += sprintf(outp, "%s0x%x", (printed++ ? delim : ""), cpus[t->cpu_id].module_id); 3389 + else 3390 + outp += sprintf(outp, "%s-", (printed++ ? delim : "")); 3391 + } 3434 3392 if (DO_BIC(BIC_Core)) { 3435 3393 if (c) 3436 - outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), cpus[t->cpu_id].core_id); 3394 + outp += sprintf(outp, "%s0x%x", (printed++ ? delim : ""), cpus[t->cpu_id].core_id); 3437 3395 else 3438 3396 outp += sprintf(outp, "%s-", (printed++ ? delim : "")); 3439 3397 } 3440 3398 if (DO_BIC(BIC_CPU)) 3441 3399 outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->cpu_id); 3442 3400 if (DO_BIC(BIC_APIC)) 3443 - outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->apic_id); 3401 + outp += sprintf(outp, "%s0x%x", (printed++ ? delim : ""), t->apic_id); 3444 3402 if (DO_BIC(BIC_X2APIC)) 3445 - outp += sprintf(outp, "%s%d", (printed++ ? delim : ""), t->x2apic_id); 3403 + outp += sprintf(outp, "%s0x%x", (printed++ ? delim : ""), t->x2apic_id); 3446 3404 } 3447 3405 3448 3406 if (DO_BIC(BIC_Avg_MHz)) ··· 5209 5155 if (!platform->has_per_core_rapl) 5210 5156 return topo.num_packages; 5211 5157 5212 - return topo.num_cores; 5158 + return GLOBAL_CORE_ID(topo.max_core_id, topo.num_packages) + 1; 5213 5159 } 5214 5160 5215 5161 static inline int get_rapl_domain_id(int cpu) ··· 6095 6041 return parse_int_file("/sys/devices/system/cpu/cpu%d/cache/index3/id", cpu); 6096 6042 } 6097 6043 6044 + int get_module_id(int cpu) 6045 + { 6046 + return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/cluster_id", cpu); 6047 + } 6048 + 6098 6049 int get_core_id(int cpu) 6099 6050 { 6100 6051 return parse_int_file("/sys/devices/system/cpu/cpu%d/topology/core_id", cpu); ··· 6219 6160 return 0; 6220 6161 } 6221 6162 6222 - int set_thread_siblings(struct cpu_topology *thiscpu) 6223 - { 6224 - char path[80], character; 6225 - FILE *filep; 6226 - unsigned long map; 6227 - int so, shift, sib_core; 6228 - int cpu = thiscpu->cpu_id; 6229 - int offset = topo.max_cpu_num + 1; 6230 - size_t size; 6231 - int thread_id = 0; 6232 - 6233 - thiscpu->put_ids = CPU_ALLOC((topo.max_cpu_num + 1)); 6234 - if (thiscpu->ht_id < 0) 6235 - thiscpu->ht_id = thread_id++; 6236 - if (!thiscpu->put_ids) 6237 - return -1; 6238 - 6239 - size = CPU_ALLOC_SIZE((topo.max_cpu_num + 1)); 6240 - CPU_ZERO_S(size, thiscpu->put_ids); 6241 - 6242 - sprintf(path, "/sys/devices/system/cpu/cpu%d/topology/thread_siblings", cpu); 6243 - filep = fopen(path, "r"); 6244 - 6245 - if (!filep) { 6246 - warnx("%s: open failed", path); 6247 - return -1; 6248 - } 6249 - do { 6250 - offset -= BITMASK_SIZE; 6251 - if (fscanf(filep, "%lx%c", &map, &character) != 2) 6252 - err(1, "%s: failed to parse file", path); 6253 - for (shift = 0; shift < BITMASK_SIZE; shift++) { 6254 - if ((map >> shift) & 0x1) { 6255 - so = shift + offset; 6256 - sib_core = get_core_id(so); 6257 - if (sib_core == thiscpu->core_id) { 6258 - CPU_SET_S(so, size, thiscpu->put_ids); 6259 - if ((so != cpu) && (cpus[so].ht_id < 0)) { 6260 - cpus[so].ht_id = thread_id; 6261 - cpus[cpu].ht_sibling_cpu_id[thread_id] = so; 6262 - if (debug) 6263 - fprintf(stderr, "%s: cpu%d.ht_sibling_cpu_id[%d] = %d\n", __func__, cpu, thread_id, so); 6264 - thread_id += 1; 6265 - } 6266 - } 6267 - } 6268 - } 6269 - } while (character == ','); 6270 - fclose(filep); 6271 - 6272 - return CPU_COUNT_S(size, thiscpu->put_ids); 6273 - } 6274 - 6275 6163 /* 6276 6164 * run func(thread, core, package) in topology order 6277 6165 * skip non-present cpus ··· 6242 6236 if (cpu_is_not_allowed(cpu)) 6243 6237 continue; 6244 6238 6245 - if (cpus[cpu].ht_id > 0) /* skip HT sibling */ 6239 + if (has_allowed_lower_ht_sibling(cpu)) /* skip HT sibling */ 6246 6240 continue; 6247 6241 6248 6242 t = &thread_base[cpu]; ··· 6257 6251 /* Handle HT sibling now */ 6258 6252 int i; 6259 6253 6260 - for (i = MAX_HT_ID; i > 0; --i) { /* ht_id 0 is self */ 6261 - if (cpus[cpu].ht_sibling_cpu_id[i] <= 0) 6254 + for (i = 0; i <= MAX_HT_ID; ++i) { 6255 + int sibling_cpu_id = cpus[cpu].ht_sibling_cpu_id[i]; 6256 + 6257 + if (sibling_cpu_id < 0) 6258 + break; 6259 + 6260 + if (sibling_cpu_id == cpu) 6262 6261 continue; 6263 - t = &thread_base[cpus[cpu].ht_sibling_cpu_id[i]]; 6264 - t2 = &thread_base2[cpus[cpu].ht_sibling_cpu_id[i]]; 6262 + 6263 + if (cpu_is_not_allowed(sibling_cpu_id)) 6264 + continue; 6265 + 6266 + t = &thread_base[sibling_cpu_id]; 6267 + t2 = &thread_base2[sibling_cpu_id]; 6265 6268 6266 6269 retval |= func(t, c, p, t2, c2, p2); 6267 6270 } ··· 9490 9475 return 0; 9491 9476 } 9492 9477 9478 + int set_thread_siblings(struct cpu_topology *thiscpu) 9479 + { 9480 + char path[80]; 9481 + int cpu = thiscpu->cpu_id; 9482 + size_t size; 9483 + int ht_id = 0; 9484 + int i; 9485 + 9486 + thiscpu->put_ids = CPU_ALLOC((topo.max_cpu_num + 1)); 9487 + if (thiscpu->ht_id < 0) 9488 + thiscpu->ht_id = 0; /* first CPU in core */ 9489 + if (!thiscpu->put_ids) 9490 + return -1; 9491 + 9492 + size = CPU_ALLOC_SIZE((topo.max_cpu_num + 1)); 9493 + CPU_ZERO_S(size, thiscpu->put_ids); 9494 + 9495 + sprintf(path, "/sys/devices/system/cpu/cpu%d/topology", cpu); 9496 + 9497 + initialize_cpu_set_from_sysfs(thiscpu->put_ids, path, "thread_siblings_list"); 9498 + 9499 + for (i = 0; i <= topo.max_cpu_num; ++i) 9500 + if (CPU_ISSET_S(i, size, thiscpu->put_ids)) { 9501 + cpus[i].ht_id = ht_id; 9502 + cpus[cpu].ht_sibling_cpu_id[ht_id] = i; 9503 + ht_id += 1; 9504 + } 9505 + 9506 + return (ht_id - 1); 9507 + } 9508 + 9493 9509 void topology_probe(bool startup) 9494 9510 { 9495 9511 int i; ··· 9551 9505 cpu_present_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1)); 9552 9506 CPU_ZERO_S(cpu_present_setsize, cpu_present_set); 9553 9507 for_all_proc_cpus(mark_cpu_present); 9508 + if (debug) 9509 + print_cpu_set("present set", cpu_present_set); 9554 9510 9555 9511 /* 9556 9512 * Allocate and initialize cpu_possible_set ··· 9563 9515 cpu_possible_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1)); 9564 9516 CPU_ZERO_S(cpu_possible_setsize, cpu_possible_set); 9565 9517 initialize_cpu_set_from_sysfs(cpu_possible_set, "/sys/devices/system/cpu", "possible"); 9518 + if (debug) 9519 + print_cpu_set("possible set", cpu_possible_set); 9566 9520 9567 9521 /* 9568 9522 * Allocate and initialize cpu_effective_set ··· 9575 9525 cpu_effective_setsize = CPU_ALLOC_SIZE((topo.max_cpu_num + 1)); 9576 9526 CPU_ZERO_S(cpu_effective_setsize, cpu_effective_set); 9577 9527 update_effective_set(startup); 9528 + if (debug) 9529 + print_cpu_set("effective set", cpu_effective_set); 9578 9530 9579 9531 /* 9580 9532 * Allocate and initialize cpu_allowed_set ··· 9620 9568 9621 9569 CPU_SET_S(i, cpu_allowed_setsize, cpu_allowed_set); 9622 9570 } 9571 + if (debug) 9572 + print_cpu_set("allowed set", cpu_allowed_set); 9623 9573 9624 9574 if (!CPU_COUNT_S(cpu_allowed_setsize, cpu_allowed_set)) 9625 9575 err(-ENODEV, "No valid cpus found"); ··· 9644 9590 * For online cpus 9645 9591 * find max_core_id, max_package_id, num_cores (per system) 9646 9592 */ 9593 + topo.min_module_id = 0x7FFFFFFF; 9647 9594 for (i = 0; i <= topo.max_cpu_num; ++i) { 9648 9595 int siblings; 9649 9596 ··· 9676 9621 if (cpus[i].physical_node_id > topo.max_node_num) 9677 9622 topo.max_node_num = cpus[i].physical_node_id; 9678 9623 9624 + /* get module information */ 9625 + cpus[i].module_id = get_module_id(i); 9626 + if (cpus[i].module_id > topo.max_module_id) 9627 + topo.max_module_id = cpus[i].module_id; 9628 + if (cpus[i].module_id < topo.min_module_id) 9629 + topo.min_module_id = cpus[i].module_id; 9630 + 9679 9631 /* get core information */ 9680 9632 cpus[i].core_id = get_core_id(i); 9681 9633 if (cpus[i].core_id > max_core_id) ··· 9703 9641 fprintf(outf, "max_core_id %d, sizing for %d cores per package\n", max_core_id, topo.cores_per_pkg); 9704 9642 if (!summary_only) 9705 9643 BIC_PRESENT(BIC_Core); 9644 + 9645 + if (debug > 1) 9646 + fprintf(outf, "min_module_id %d max_module_id %d\n", topo.min_module_id, topo.max_module_id); 9647 + if (!summary_only && (topo.min_module_id != topo.max_module_id)) 9648 + BIC_PRESENT(BIC_Module); 9706 9649 9707 9650 topo.num_die = topo.max_die_id + 1; 9708 9651 if (debug > 1) ··· 9738 9671 return; 9739 9672 9740 9673 for (i = 0; i <= topo.max_cpu_num; ++i) { 9674 + int ht_id; 9675 + 9741 9676 if (cpu_is_not_present(i)) 9742 9677 continue; 9743 9678 fprintf(outf, 9744 - "cpu %d pkg %d die %d l3 %d node %d lnode %d core %d thread %d\n", 9679 + "cpu %d pkg %d die %d l3 %d node %d lnode %d module 0x%x core %d ht_id %d", 9745 9680 i, cpus[i].package_id, cpus[i].die_id, cpus[i].l3_id, 9746 - cpus[i].physical_node_id, cpus[i].logical_node_id, cpus[i].core_id, cpus[i].ht_id); 9681 + cpus[i].physical_node_id, cpus[i].logical_node_id, cpus[i].module_id, cpus[i].core_id, cpus[i].ht_id); 9682 + fprintf(outf, " siblings"); 9683 + for (ht_id = 0; ht_id <= MAX_HT_ID; ++ht_id) 9684 + fprintf(outf, " %d", cpus[i].ht_sibling_cpu_id[ht_id]); 9685 + fprintf(outf, "\n"); 9747 9686 } 9748 9687 9749 9688 } ··· 9890 9817 topo.allowed_cores = 0; 9891 9818 topo.allowed_packages = 0; 9892 9819 for_all_cpus(update_topo, ODD_COUNTERS); 9820 + if (debug) 9821 + fprintf(stderr, "allowed_cpus %d allowed_cores %d allowed_packages %d\n", topo.allowed_cpus, topo.allowed_cores, topo.allowed_packages); 9893 9822 } 9894 9823 9895 9824 void setup_all_buffers(bool startup) ··· 10608 10533 10609 10534 void print_version() 10610 10535 { 10611 - fprintf(outf, "turbostat version 2026.02.14 - Len Brown <lenb@kernel.org>\n"); 10536 + fprintf(outf, "turbostat version 2026.04.21 - Len Brown <lenb@kernel.org>\n"); 10612 10537 } 10613 10538 10614 10539 #define COMMAND_LINE_SIZE 2048 ··· 11524 11449 } 11525 11450 optind = 0; 11526 11451 11527 - while ((opt = getopt_long_only(argc, argv, "+C:c:Dde:hi:Jn:N:o:qMST:v", long_options, &option_index)) != -1) { 11452 + while ((opt = getopt_long_only(argc, argv, "+C:c:Dde:hi:Jn:N:o:qMPST:v", long_options, &option_index)) != -1) { 11528 11453 switch (opt) { 11529 11454 case 'a': 11530 11455 parse_add_command(optarg);
+26
tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.8
··· 15 15 .br 16 16 .RB "other: (\-\-force | \-\-hwp-enable | \-\-turbo-enable) value)" 17 17 .br 18 + .RB "soc-slider: --soc-slider-balance # | --soc-slider-offset # | --platform-profile <name>" 19 + .br 18 20 .RB "value: # | default | performance | balance-performance | balance-power | power" 19 21 .SH DESCRIPTION 20 22 \fBx86_energy_perf_policy\fP ··· 156 154 in the sliding window that HWP uses to maintain average frequency. 157 155 This parameter is meaningful only when the "desired" field above is non-zero. 158 156 Default is 0, allowing the HW to choose. 157 + .SH SOC SLIDER OPTIONS 158 + .PP 159 + Note that the Platform Profile Name must be "SoC Slider", and the 160 + Platform Profile must be "balanced" for the --soc-slider-balance 161 + and --soc-slider-offset options to take effect. 162 + .PP 163 + \fB--soc-slider-balance #\fP write numeric value to the SoC Slider. 164 + Values range from 0 to 6. 165 + Lower values result in higher performance, 166 + and higher values improve energy efficiency. 167 + Actual values are model specific. 168 + .PP 169 + \fB--soc-slider-offset #\fP write the numeric value to the Soc Slider Offset. 170 + The slider offset is the maximum value that software allows the SoC to 171 + autonomously add to the SoC Slider to improve energy efficiency. 172 + The value 0 prohibits the SoC from autonomously changing the slider. 173 + .PP 174 + \fB--platform-profile <name>"\fP set the platform profile to <name>. 175 + Available choices are in platform-profile-0/choices. The Soc Slider 176 + driver currently supports "low-power", "balanced", and "performance". 159 177 .SH OTHER OPTIONS 160 178 .PP 161 179 \fB-f, --force\fP writes the specified values without bounds checking. ··· 230 208 EPB: /sys/devices/system/cpu/cpu*/power/energy_perf_bias 231 209 EPP: /sys/devices/system/cpu/cpu*/cpufreq/energy_performance_preference 232 210 MSR: /dev/cpu/*/msr 211 + Platform Profile Name: /sys/class/platform-profile/platform-profile-0/name 212 + Platform Profile: /sys/class/platform-profile/platform-profile-0/profile 213 + SOC Slider Balanced: /sys/module/processor_thermal_soc_slider/parameters/slider_balance 214 + SOC Slider Balanced Offset: /sys/module/processor_thermal_soc_slider/parameters/slider_offset 233 215 .fi 234 216 .SH "SEE ALSO" 235 217 .nf
+282 -117
tools/power/x86/x86_energy_perf_policy/x86_energy_perf_policy.c
··· 4 4 * policy preference bias on recent X86 processors. 5 5 */ 6 6 /* 7 - * Copyright (c) 2010 - 2025 Intel Corporation. 7 + * Copyright (c) 2010 - 2026 Intel Corporation. 8 8 * Len Brown <len.brown@intel.com> 9 9 */ 10 10 ··· 82 82 83 83 char *proc_stat = "/proc/stat"; 84 84 85 - unsigned int has_epb; /* MSR_IA32_ENERGY_PERF_BIAS */ 86 - unsigned int has_hwp; /* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */ 85 + unsigned int has_epb; /* MSR_IA32_ENERGY_PERF_BIAS */ 86 + unsigned int has_hwp; /* IA32_PM_ENABLE, IA32_HWP_CAPABILITIES */ 87 87 /* IA32_HWP_REQUEST, IA32_HWP_STATUS */ 88 - unsigned int has_hwp_notify; /* IA32_HWP_INTERRUPT */ 88 + unsigned int has_hwp_notify; /* IA32_HWP_INTERRUPT */ 89 89 unsigned int has_hwp_activity_window; /* IA32_HWP_REQUEST[bits 41:32] */ 90 90 unsigned int has_hwp_epp; /* IA32_HWP_REQUEST[bits 31:24] */ 91 91 unsigned int has_hwp_request_pkg; /* IA32_HWP_REQUEST_PKG */ 92 92 93 93 unsigned int bdx_highest_ratio; 94 94 95 + unsigned char update_soc_slider_balance; 96 + unsigned char update_soc_slider_offset; 97 + unsigned char update_platform_profile; 98 + int soc_slider_balance; 99 + int soc_slider_offset; 100 + char platform_profile[64]; 101 + 95 102 #define PATH_TO_CPU "/sys/devices/system/cpu/" 96 103 #define SYSFS_PATH_MAX 255 104 + #define PATH_SOC_SLIDER_BALANCE "/sys/module/processor_thermal_soc_slider/parameters/slider_balance" 105 + #define PATH_SOC_SLIDER_OFFSET "/sys/module/processor_thermal_soc_slider/parameters/slider_offset" 106 + #define PATH_PLATFORM_PROFILE "/sys/class/platform-profile/platform-profile-0/profile" 107 + #define PATH_PLATFORM_PROFILE_NAME "/sys/class/platform-profile/platform-profile-0/name" 108 + #define POWER_SLIDER_NAME "SoC Power Slider" 97 109 98 110 static int use_android_msr_path; 111 + 112 + static unsigned int read_sysfs(const char *, char *, size_t); 113 + static int sysfs_read_string(const char *, char *, size_t); 99 114 100 115 /* 101 116 * maintain compatibility with original implementation, but don't document it: ··· 121 106 fprintf(stderr, "scope: --cpu cpu-list [--hwp-use-pkg #] | --pkg pkg-list\n"); 122 107 fprintf(stderr, "field: --all | --epb | --hwp-epp | --hwp-min | --hwp-max | --hwp-desired\n"); 123 108 fprintf(stderr, "other: --hwp-enable | --turbo-enable (0 | 1) | --help | --force\n"); 124 - fprintf(stderr, 125 - "value: ( # | \"normal\" | \"performance\" | \"balance-performance\" | \"balance-power\"| \"power\")\n"); 109 + fprintf(stderr, "soc-slider: --soc-slider-balance # | --soc-slider-offset # | --platform-profile <name>\n"); 110 + fprintf(stderr, "value: ( # | \"normal\" | \"performance\" | \"balance-performance\" | \"balance-power\"| \"power\")\n"); 126 111 fprintf(stderr, "--hwp-window usec\n"); 127 112 128 113 fprintf(stderr, "Specify only Energy Performance BIAS (legacy usage):\n"); ··· 150 135 151 136 return msr_perf; 152 137 } 138 + 153 139 int msr_perf_2_ratio(int msr_perf) 154 140 { 155 141 int ratio; ··· 159 143 if (!bdx_highest_ratio) 160 144 return msr_perf; 161 145 162 - d = (double)msr_perf * (double) bdx_highest_ratio / 255.0; 163 - d = d + 0.5; /* round */ 146 + d = (double)msr_perf * (double)bdx_highest_ratio / 255.0; 147 + d = d + 0.5; /* round */ 164 148 ratio = (int)d; 165 149 166 150 if (debug) ··· 168 152 169 153 return ratio; 170 154 } 155 + 171 156 int parse_cmdline_epb(int i) 172 157 { 173 158 if (!has_epb) ··· 215 198 } 216 199 return i; 217 200 } 201 + 218 202 /* 219 203 * "power" changes hwp_max to cap.lowest 220 204 * All others leave it at cap.highest ··· 235 217 } 236 218 return i; 237 219 } 220 + 238 221 /* 239 222 * for --hwp-des, all strings leave it in autonomous mode 240 223 * If you want to change it, you need to explicitly pick a value ··· 273 254 fprintf(stderr, "--hwp-window: 0 for auto; 1 - 1270000000 usec for window duration\n"); 274 255 usage(); 275 256 } 276 - for (exponent = 0; ; ++exponent) { 257 + for (exponent = 0;; ++exponent) { 277 258 if (debug) 278 259 printf("%d 10^%d\n", i, exponent); 279 260 ··· 287 268 288 269 return (exponent << 7) | i; 289 270 } 271 + 290 272 int parse_cmdline_hwp_epp(int i) 291 273 { 292 274 update_hwp_epp = 1; ··· 309 289 } 310 290 return i; 311 291 } 292 + 312 293 int parse_cmdline_turbo(int i) 313 294 { 314 295 update_turbo = 1; ··· 529 508 } 530 509 } 531 510 532 - void for_packages(unsigned long long pkg_set, int (func)(int)) 511 + void for_packages(unsigned long long pkg_set, int (func) (int)) 533 512 { 534 513 int pkg_num; 535 514 ··· 539 518 } 540 519 } 541 520 521 + static int parse_cmdline_int(const char *s, int *out) 522 + { 523 + char *endp; 524 + long val; 525 + 526 + val = strtol(s, &endp, 0); 527 + if (endp == s || errno == ERANGE) 528 + return -1; 529 + if (*endp != '\0') 530 + return -1; 531 + if (val < INT_MIN || val > INT_MAX) 532 + return -1; 533 + 534 + *out = (int)val; 535 + return 0; 536 + } 537 + 542 538 void print_version(void) 543 539 { 544 - printf("x86_energy_perf_policy 2025.11.22 Len Brown <lenb@kernel.org>\n"); 540 + printf("x86_energy_perf_policy 2026.04.25 Len Brown <lenb@kernel.org>\n"); 541 + } 542 + 543 + static int platform_profile_access(int mode) 544 + { 545 + if (access(PATH_PLATFORM_PROFILE, mode)) { 546 + if (debug) 547 + fprintf(stderr, "Can not access %s\n", PATH_PLATFORM_PROFILE); 548 + return 0; 549 + } 550 + 551 + return 1; 552 + } 553 + 554 + static int platform_profile_name_is(char *name) 555 + { 556 + char buf[64]; 557 + 558 + if (sysfs_read_string(PATH_PLATFORM_PROFILE_NAME, buf, sizeof(buf)) != 0) { 559 + if (debug) 560 + fprintf(stderr, "Can not read %s\n", PATH_PLATFORM_PROFILE_NAME); 561 + return 0; 562 + } 563 + 564 + if (strncmp(buf, name, 16)) { 565 + if (debug) 566 + fprintf(stderr, "%s does not match '%s'\n", PATH_PLATFORM_PROFILE_NAME, name); 567 + return 0; 568 + } 569 + 570 + return 1; 571 + } 572 + 573 + static int soc_slider_access(int mode) 574 + { 575 + if (!platform_profile_access(R_OK)) 576 + return 0; 577 + 578 + if (!platform_profile_name_is(POWER_SLIDER_NAME)) 579 + return 0; 580 + 581 + if (access(PATH_SOC_SLIDER_BALANCE, mode)) { 582 + if (debug) 583 + fprintf(stderr, "Can not access %s\n", PATH_SOC_SLIDER_BALANCE); 584 + return 0; 585 + } 586 + 587 + if (access(PATH_SOC_SLIDER_OFFSET, mode)) { 588 + if (debug) 589 + fprintf(stderr, "Can not access %s\n", PATH_SOC_SLIDER_OFFSET); 590 + return 0; 591 + } 592 + 593 + return 1; 545 594 } 546 595 547 596 void cmdline(int argc, char **argv) ··· 620 529 int option_index = 0; 621 530 622 531 static struct option long_options[] = { 623 - {"all", required_argument, 0, 'a'}, 624 - {"cpu", required_argument, 0, 'c'}, 625 - {"pkg", required_argument, 0, 'p'}, 626 - {"debug", no_argument, 0, 'd'}, 627 - {"hwp-desired", required_argument, 0, 'D'}, 628 - {"epb", required_argument, 0, 'B'}, 629 - {"force", no_argument, 0, 'f'}, 630 - {"hwp-enable", no_argument, 0, 'e'}, 631 - {"help", no_argument, 0, 'h'}, 632 - {"hwp-epp", required_argument, 0, 'P'}, 633 - {"hwp-min", required_argument, 0, 'm'}, 634 - {"hwp-max", required_argument, 0, 'M'}, 635 - {"read", no_argument, 0, 'r'}, 636 - {"turbo-enable", required_argument, 0, 't'}, 637 - {"hwp-use-pkg", required_argument, 0, 'u'}, 638 - {"version", no_argument, 0, 'v'}, 639 - {"hwp-window", required_argument, 0, 'w'}, 640 - {0, 0, 0, 0 } 532 + { "all", required_argument, 0, 'a' }, 533 + { "cpu", required_argument, 0, 'c' }, 534 + { "pkg", required_argument, 0, 'p' }, 535 + { "debug", no_argument, 0, 'd' }, 536 + { "hwp-desired", required_argument, 0, 'D' }, 537 + { "epb", required_argument, 0, 'B' }, 538 + { "force", no_argument, 0, 'f' }, 539 + { "hwp-enable", no_argument, 0, 'e' }, 540 + { "help", no_argument, 0, 'h' }, 541 + { "hwp-epp", required_argument, 0, 'P' }, 542 + { "hwp-min", required_argument, 0, 'm' }, 543 + { "hwp-max", required_argument, 0, 'M' }, 544 + { "read", no_argument, 0, 'r' }, 545 + { "turbo-enable", required_argument, 0, 't' }, 546 + { "hwp-use-pkg", required_argument, 0, 'u' }, 547 + { "version", no_argument, 0, 'v' }, 548 + { "hwp-window", required_argument, 0, 'w' }, 549 + { "soc-slider-balance", required_argument, 0, 'S' }, 550 + { "soc-slider-offset", required_argument, 0, 'O' }, 551 + { "platform-profile", required_argument, 0, 'F' }, 552 + { 0, 0, 0, 0 } 641 553 }; 642 554 643 555 progname = argv[0]; 644 556 645 - while ((opt = getopt_long_only(argc, argv, "+a:c:dD:E:e:f:m:M:rt:u:vw:", 646 - long_options, &option_index)) != -1) { 557 + while ((opt = getopt_long_only(argc, argv, "+a:c:dD:E:e:f:m:M:rt:u:vw::S:O:F:", long_options, &option_index)) != -1) { 647 558 switch (opt) { 648 559 case 'a': 649 560 parse_cmdline_all(optarg); ··· 672 579 case 'D': 673 580 req_update.hwp_desired = parse_cmdline_hwp_desired(parse_optarg_string(optarg)); 674 581 break; 582 + case 'F': 583 + if (strlen(optarg) >= sizeof(platform_profile)) 584 + errx(1, "--platform-profile: value too long"); 585 + if (!platform_profile_access(W_OK)) 586 + errx(1, "Can not update platform-profile in '%s'", PATH_PLATFORM_PROFILE); 587 + strcpy(platform_profile, optarg); 588 + update_platform_profile = 1; 589 + break; 675 590 case 'm': 676 591 req_update.hwp_min = parse_cmdline_hwp_min(parse_optarg_string(optarg)); 677 592 break; 678 593 case 'M': 679 594 req_update.hwp_max = parse_cmdline_hwp_max(parse_optarg_string(optarg)); 595 + break; 596 + case 'O': 597 + if (parse_cmdline_int(optarg, &soc_slider_offset)) 598 + errx(1, "--soc-slider-offset: invalid value"); 599 + if (!soc_slider_access(W_OK)) 600 + errx(1, "Unable to write SOC Slider Offset"); 601 + update_soc_slider_offset = 1; 680 602 break; 681 603 case 'p': 682 604 parse_cmdline_pkg(optarg); ··· 701 593 break; 702 594 case 'r': 703 595 /* v1 used -r to specify read-only mode, now the default */ 596 + break; 597 + case 'S': 598 + if (parse_cmdline_int(optarg, &soc_slider_balance)) 599 + errx(1, "--soc-slider-balance: invalid value"); 600 + if (!soc_slider_access(W_OK)) 601 + errx(1, "Unable to write SOC Slider-Balance in '%s'", PATH_SOC_SLIDER_BALANCE); 602 + update_soc_slider_balance = 1; 704 603 break; 705 604 case 't': 706 605 turbo_update_value = parse_cmdline_turbo(parse_optarg_string(optarg)); ··· 796 681 free(buffer); 797 682 798 683 if (hypervisor) 799 - err(-1, 800 - "not supported on this virtual machine"); 684 + err(-1, "not supported on this virtual machine"); 801 685 } 802 686 803 687 int get_msr(int cpu, int offset, unsigned long long *msr) ··· 808 694 sprintf(pathname, use_android_msr_path ? "/dev/msr%d" : "/dev/cpu/%d/msr", cpu); 809 695 fd = open(pathname, O_RDONLY); 810 696 if (fd < 0) 811 - err(-1, "%s open failed, try chown or chmod +r %s, or run as root", 812 - pathname, use_android_msr_path ? "/dev/msr*" : "/dev/cpu/*/msr"); 813 - 697 + err(-1, "%s open failed, try chown or chmod +r %s, or run as root", pathname, use_android_msr_path ? "/dev/msr*" : "/dev/cpu/*/msr"); 814 698 815 699 retval = pread(fd, msr, sizeof(*msr), offset); 816 700 if (retval != sizeof(*msr)) { ··· 832 720 sprintf(pathname, use_android_msr_path ? "/dev/msr%d" : "/dev/cpu/%d/msr", cpu); 833 721 fd = open(pathname, O_RDWR); 834 722 if (fd < 0) 835 - err(-1, "%s open failed, try chown or chmod +r %s, or run as root", 836 - pathname, use_android_msr_path ? "/dev/msr*" : "/dev/cpu/*/msr"); 723 + err(-1, "%s open failed, try chown or chmod +r %s, or run as root", pathname, use_android_msr_path ? "/dev/msr*" : "/dev/cpu/*/msr"); 837 724 838 725 retval = pwrite(fd, &new_msr, sizeof(new_msr), offset); 839 726 if (retval != sizeof(new_msr)) ··· 864 753 buf[numread] = '\0'; 865 754 close(fd); 866 755 867 - return (unsigned int) numread; 756 + return (unsigned int)numread; 868 757 } 869 758 870 759 static unsigned int write_sysfs(const char *path, char *buf, size_t buflen) ··· 878 767 879 768 numwritten = write(fd, buf, buflen - 1); 880 769 if (numwritten < 1) { 881 - perror("write failed\n"); 770 + buf[strcspn(buf, "\n")] = '\0'; 771 + warn("Write '%s' to '%s' failed", buf, path); 882 772 close(fd); 883 773 return -1; 884 774 } 885 775 886 776 close(fd); 887 777 888 - return (unsigned int) numwritten; 778 + return (unsigned int)numwritten; 779 + } 780 + 781 + static int sysfs_read_string(const char *path, char *buf, size_t buflen) 782 + { 783 + unsigned int len; 784 + size_t n; 785 + 786 + len = read_sysfs(path, buf, buflen); 787 + if (!len) 788 + return -1; 789 + 790 + n = strcspn(buf, "\n"); 791 + buf[n] = '\0'; 792 + return 0; 793 + } 794 + 795 + static int sysfs_write_string(const char *path, const char *buf) 796 + { 797 + char tmp[128]; 798 + int len; 799 + 800 + len = snprintf(tmp, sizeof(tmp), "%s\n", buf); 801 + if (len < 0 || len >= (int)sizeof(tmp)) 802 + return -1; 803 + return write_sysfs(path, tmp, (size_t)len + 1) ? 0 : -1; 889 804 } 890 805 891 806 void print_hwp_cap(int cpu, struct msr_hwp_cap *cap, char *str) ··· 919 782 if (cpu != -1) 920 783 printf("cpu%d: ", cpu); 921 784 922 - printf("HWP_CAP: low %d eff %d guar %d high %d\n", 923 - cap->lowest, cap->efficient, cap->guaranteed, cap->highest); 785 + printf("HWP_CAP: low %d eff %d guar %d high %d\n", cap->lowest, cap->efficient, cap->guaranteed, cap->highest); 924 786 } 787 + 925 788 void read_hwp_cap(int cpu, struct msr_hwp_cap *cap, unsigned int msr_offset) 926 789 { 927 790 unsigned long long msr; ··· 943 806 printf("%s", str); 944 807 945 808 printf("HWP_REQ: min %d max %d des %d epp %d window 0x%x (%d*10^%dus) use_pkg %d\n", 946 - h->hwp_min, h->hwp_max, h->hwp_desired, h->hwp_epp, 947 - h->hwp_window, h->hwp_window & 0x7F, (h->hwp_window >> 7) & 0x7, h->hwp_use_pkg); 809 + h->hwp_min, h->hwp_max, h->hwp_desired, h->hwp_epp, h->hwp_window, h->hwp_window & 0x7F, (h->hwp_window >> 7) & 0x7, h->hwp_use_pkg); 948 810 } 811 + 949 812 void print_hwp_request_pkg(int pkg, struct msr_hwp_request *h, char *str) 950 813 { 951 814 printf("pkg%d: ", pkg); ··· 954 817 printf("%s", str); 955 818 956 819 printf("HWP_REQ_PKG: min %d max %d des %d epp %d window 0x%x (%d*10^%dus)\n", 957 - h->hwp_min, h->hwp_max, h->hwp_desired, h->hwp_epp, 958 - h->hwp_window, h->hwp_window & 0x7F, (h->hwp_window >> 7) & 0x7); 820 + h->hwp_min, h->hwp_max, h->hwp_desired, h->hwp_epp, h->hwp_window, h->hwp_window & 0x7F, (h->hwp_window >> 7) & 0x7); 959 821 } 822 + 960 823 void read_hwp_request_msr(int cpu, struct msr_hwp_request *hwp_req, unsigned int msr_offset) 961 824 { 962 825 unsigned long long msr; ··· 977 840 978 841 if (debug > 1) 979 842 printf("cpu%d: requesting min %d max %d des %d epp %d window 0x%0x use_pkg %d\n", 980 - cpu, hwp_req->hwp_min, hwp_req->hwp_max, 981 - hwp_req->hwp_desired, hwp_req->hwp_epp, 982 - hwp_req->hwp_window, hwp_req->hwp_use_pkg); 843 + cpu, hwp_req->hwp_min, hwp_req->hwp_max, hwp_req->hwp_desired, hwp_req->hwp_epp, hwp_req->hwp_window, hwp_req->hwp_use_pkg); 983 844 984 845 msr |= HWP_MIN_PERF(ratio_2_msr_perf(hwp_req->hwp_min)); 985 846 msr |= HWP_MAX_PERF(ratio_2_msr_perf(hwp_req->hwp_max)); ··· 1035 900 return (int)val; 1036 901 } 1037 902 903 + static void print_soc_slider(void) 904 + { 905 + char buf[64]; 906 + 907 + if (!soc_slider_access(R_OK)) 908 + return; 909 + 910 + if (sysfs_read_string(PATH_SOC_SLIDER_BALANCE, buf, sizeof(buf)) == 0) 911 + printf("soc-slider-balance: %s\n", buf); 912 + 913 + if (sysfs_read_string(PATH_SOC_SLIDER_OFFSET, buf, sizeof(buf)) == 0) 914 + printf("soc-slider-offset: %s\n", buf); 915 + } 916 + 917 + static void print_platform_profile(void) 918 + { 919 + char buf[64]; 920 + 921 + if (!platform_profile_access(R_OK)) 922 + return; 923 + 924 + if (sysfs_read_string(PATH_PLATFORM_PROFILE_NAME, buf, sizeof(buf)) == 0) 925 + printf("platform-profile-name: %s\n", buf); 926 + 927 + if (sysfs_read_string(PATH_PLATFORM_PROFILE, buf, sizeof(buf)) == 0) 928 + printf("platform-profile: %s\n", buf); 929 + } 930 + 931 + static int update_soc_slider(void) 932 + { 933 + char tmp[32]; 934 + 935 + if (update_soc_slider_balance) { 936 + snprintf(tmp, sizeof(tmp), "%d", soc_slider_balance); 937 + if (sysfs_write_string(PATH_SOC_SLIDER_BALANCE, tmp)) 938 + err(1, "soc-slider-balance write failed"); 939 + } 940 + 941 + if (update_soc_slider_offset) { 942 + snprintf(tmp, sizeof(tmp), "%d", soc_slider_offset); 943 + if (sysfs_write_string(PATH_SOC_SLIDER_OFFSET, tmp)) 944 + err(1, "soc-slider-offset write failed"); 945 + } 946 + 947 + if (update_platform_profile) { 948 + if (sysfs_write_string(PATH_PLATFORM_PROFILE, platform_profile)) 949 + err(1, "platform-profile write failed"); 950 + } 951 + 952 + return 0; 953 + } 954 + 1038 955 int print_cpu_msrs(int cpu) 1039 956 { 1040 957 struct msr_hwp_request req; ··· 1095 908 1096 909 epb = get_epb_sysfs(cpu); 1097 910 if (epb >= 0) 1098 - printf("cpu%d: EPB %u\n", cpu, (unsigned int) epb); 911 + printf("cpu%d: EPB %u\n", cpu, (unsigned int)epb); 1099 912 1100 913 if (!has_hwp) 1101 914 return 0; ··· 1123 936 if (has_hwp_notify) { 1124 937 get_msr(first_cpu_in_pkg[pkg], MSR_HWP_INTERRUPT, &msr); 1125 938 fprintf(stderr, 1126 - "pkg%d: MSR_HWP_INTERRUPT: 0x%08llx (Excursion_Min-%sabled, Guaranteed_Perf_Change-%sabled)\n", 1127 - pkg, msr, 1128 - ((msr) & 0x2) ? "EN" : "Dis", 1129 - ((msr) & 0x1) ? "EN" : "Dis"); 939 + "pkg%d: MSR_HWP_INTERRUPT: 0x%08llx (Excursion_Min-%sabled, Guaranteed_Perf_Change-%sabled)\n", 940 + pkg, msr, ((msr) & 0x2) ? "EN" : "Dis", ((msr) & 0x1) ? "EN" : "Dis"); 1130 941 } 1131 942 get_msr(first_cpu_in_pkg[pkg], MSR_HWP_STATUS, &msr); 1132 943 fprintf(stderr, 1133 944 "pkg%d: MSR_HWP_STATUS: 0x%08llx (%sExcursion_Min, %sGuaranteed_Perf_Change)\n", 1134 - pkg, msr, 1135 - ((msr) & 0x4) ? "" : "No-", 1136 - ((msr) & 0x1) ? "" : "No-"); 945 + pkg, msr, ((msr) & 0x4) ? "" : "No-", ((msr) & 0x1) ? "" : "No-"); 1137 946 1138 947 return 0; 1139 948 } ··· 1143 960 1144 961 return ratio * bclk_khz; 1145 962 } 963 + 1146 964 /* 1147 965 * If HWP is enabled and cpufreq sysfs attribtes are present, 1148 966 * then update via sysfs. The intel_pstate driver may modify (clip) ··· 1160 976 int retval; 1161 977 int khz; 1162 978 1163 - sprintf(pathname, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_%s_freq", 1164 - cpu, is_max ? "max" : "min"); 979 + sprintf(pathname, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_%s_freq", cpu, is_max ? "max" : "min"); 1165 980 1166 981 fp = fopen(pathname, "w"); 1167 982 if (!fp) { ··· 1212 1029 { 1213 1030 /* fail if min > max requested */ 1214 1031 if (req->hwp_min > req->hwp_max) { 1215 - errx(1, "cpu%d: requested hwp-min %d > hwp_max %d", 1216 - cpu, req->hwp_min, req->hwp_max); 1032 + errx(1, "cpu%d: requested hwp-min %d > hwp_max %d", cpu, req->hwp_min, req->hwp_max); 1217 1033 } 1218 1034 1219 1035 /* fail if desired > max requestd */ 1220 1036 if (req->hwp_desired && (req->hwp_desired > req->hwp_max)) { 1221 - errx(1, "cpu%d: requested hwp-desired %d > hwp_max %d", 1222 - cpu, req->hwp_desired, req->hwp_max); 1037 + errx(1, "cpu%d: requested hwp-desired %d > hwp_max %d", cpu, req->hwp_desired, req->hwp_max); 1223 1038 } 1224 1039 /* fail if desired < min requestd */ 1225 1040 if (req->hwp_desired && (req->hwp_desired < req->hwp_min)) { 1226 - errx(1, "cpu%d: requested hwp-desired %d < requested hwp_min %d", 1227 - cpu, req->hwp_desired, req->hwp_min); 1041 + errx(1, "cpu%d: requested hwp-desired %d < requested hwp_min %d", cpu, req->hwp_desired, req->hwp_min); 1228 1042 } 1229 1043 1230 1044 return 0; ··· 1231 1051 { 1232 1052 if (update_hwp_max) { 1233 1053 if (req->hwp_max > cap->highest) 1234 - errx(1, "cpu%d: requested max %d > capabilities highest %d, use --force?", 1235 - cpu, req->hwp_max, cap->highest); 1054 + errx(1, "cpu%d: requested max %d > capabilities highest %d, use --force?", cpu, req->hwp_max, cap->highest); 1236 1055 if (req->hwp_max < cap->lowest) 1237 - errx(1, "cpu%d: requested max %d < capabilities lowest %d, use --force?", 1238 - cpu, req->hwp_max, cap->lowest); 1056 + errx(1, "cpu%d: requested max %d < capabilities lowest %d, use --force?", cpu, req->hwp_max, cap->lowest); 1239 1057 } 1240 1058 1241 1059 if (update_hwp_min) { 1242 1060 if (req->hwp_min > cap->highest) 1243 - errx(1, "cpu%d: requested min %d > capabilities highest %d, use --force?", 1244 - cpu, req->hwp_min, cap->highest); 1061 + errx(1, "cpu%d: requested min %d > capabilities highest %d, use --force?", cpu, req->hwp_min, cap->highest); 1245 1062 if (req->hwp_min < cap->lowest) 1246 - errx(1, "cpu%d: requested min %d < capabilities lowest %d, use --force?", 1247 - cpu, req->hwp_min, cap->lowest); 1063 + errx(1, "cpu%d: requested min %d < capabilities lowest %d, use --force?", cpu, req->hwp_min, cap->lowest); 1248 1064 } 1249 1065 1250 1066 if (update_hwp_min && update_hwp_max && (req->hwp_min > req->hwp_max)) 1251 - errx(1, "cpu%d: requested min %d > requested max %d", 1252 - cpu, req->hwp_min, req->hwp_max); 1067 + errx(1, "cpu%d: requested min %d > requested max %d", cpu, req->hwp_min, req->hwp_max); 1253 1068 1254 1069 if (update_hwp_desired && req->hwp_desired) { 1255 1070 if (req->hwp_desired > req->hwp_max) 1256 - errx(1, "cpu%d: requested desired %d > requested max %d, use --force?", 1257 - cpu, req->hwp_desired, req->hwp_max); 1071 + errx(1, "cpu%d: requested desired %d > requested max %d, use --force?", cpu, req->hwp_desired, req->hwp_max); 1258 1072 if (req->hwp_desired < req->hwp_min) 1259 - errx(1, "cpu%d: requested desired %d < requested min %d, use --force?", 1260 - cpu, req->hwp_desired, req->hwp_min); 1073 + errx(1, "cpu%d: requested desired %d < requested min %d, use --force?", cpu, req->hwp_desired, req->hwp_min); 1261 1074 if (req->hwp_desired < cap->lowest) 1262 - errx(1, "cpu%d: requested desired %d < capabilities lowest %d, use --force?", 1263 - cpu, req->hwp_desired, cap->lowest); 1075 + errx(1, "cpu%d: requested desired %d < capabilities lowest %d, use --force?", cpu, req->hwp_desired, cap->lowest); 1264 1076 if (req->hwp_desired > cap->highest) 1265 - errx(1, "cpu%d: requested desired %d > capabilities highest %d, use --force?", 1266 - cpu, req->hwp_desired, cap->highest); 1077 + errx(1, "cpu%d: requested desired %d > capabilities highest %d, use --force?", cpu, req->hwp_desired, cap->highest); 1267 1078 } 1268 1079 1269 1080 return 0; ··· 1305 1134 } 1306 1135 return 0; 1307 1136 } 1137 + 1308 1138 int update_hwp_request_pkg_msr(int pkg) 1309 1139 { 1310 1140 struct msr_hwp_request req; ··· 1377 1205 set_epb_sysfs(cpu, new_epb); 1378 1206 1379 1207 if (verbose) 1380 - printf("cpu%d: ENERGY_PERF_BIAS old: %d new: %d\n", 1381 - cpu, epb, (unsigned int) new_epb); 1208 + printf("cpu%d: ENERGY_PERF_BIAS old: %d new: %d\n", cpu, epb, (unsigned int)new_epb); 1382 1209 1383 1210 return 0; 1384 1211 } ··· 1393 1222 1394 1223 turbo_is_present_and_disabled = ((msr & MSR_IA32_MISC_ENABLE_TURBO_DISABLE) != 0); 1395 1224 1396 - if (turbo_update_value == 1) { 1225 + if (turbo_update_value == 1) { 1397 1226 if (turbo_is_present_and_disabled) { 1398 1227 msr &= ~MSR_IA32_MISC_ENABLE_TURBO_DISABLE; 1399 1228 put_msr(cpu, MSR_IA32_MISC_ENABLE, msr); ··· 1462 1291 1463 1292 return 0; 1464 1293 } 1294 + 1465 1295 int mark_cpu_present(int cpu) 1466 1296 { 1467 1297 CPU_SET_S(cpu, cpu_setsize, cpu_present_set); ··· 1473 1301 * run func(cpu) on every cpu in /proc/stat 1474 1302 * return max_cpu number 1475 1303 */ 1476 - int for_all_proc_cpus(int (func)(int)) 1304 + int for_all_proc_cpus(int (func) (int)) 1477 1305 { 1478 1306 FILE *fp; 1479 1307 int cpu_num; ··· 1500 1328 return 0; 1501 1329 } 1502 1330 1503 - void for_all_cpus_in_set(size_t set_size, cpu_set_t *cpu_set, int (func)(int)) 1331 + void for_all_cpus_in_set(size_t set_size, cpu_set_t *cpu_set, int (func) (int)) 1504 1332 { 1505 1333 int cpu_num; 1506 1334 ··· 1508 1336 if (CPU_ISSET_S(cpu_num, set_size, cpu_set)) 1509 1337 func(cpu_num); 1510 1338 } 1511 - int for_all_cpus_in_set_and(size_t set_size, cpu_set_t *cpu_set, int (func)(int)) 1339 + 1340 + int for_all_cpus_in_set_and(size_t set_size, cpu_set_t *cpu_set, int (func) (int)) 1512 1341 { 1513 1342 int cpu_num; 1514 1343 int retval = 1; ··· 1558 1385 { 1559 1386 int retval; 1560 1387 1561 - if (!has_hwp) /* set in early_cpuid() */ 1388 + if (!has_hwp) /* set in early_cpuid() */ 1562 1389 return; 1563 1390 1564 1391 retval = for_all_cpus_in_set_and(cpu_setsize, cpu_selected_set, is_hwp_enabled_on_cpu); ··· 1575 1402 return 0; 1576 1403 1577 1404 /* fail if min > max requested */ 1578 - if ((update_hwp_max && update_hwp_min) && 1579 - (req_update.hwp_min > req_update.hwp_max)) { 1405 + if ((update_hwp_max && update_hwp_min) && (req_update.hwp_min > req_update.hwp_max)) { 1580 1406 printf("hwp-min %d > hwp_max %d\n", req_update.hwp_min, req_update.hwp_max); 1581 1407 return -EINVAL; 1582 1408 } 1583 1409 1584 1410 /* fail if desired > max requestd */ 1585 - if (req_update.hwp_desired && update_hwp_max && 1586 - (req_update.hwp_desired > req_update.hwp_max)) { 1411 + if (req_update.hwp_desired && update_hwp_max && (req_update.hwp_desired > req_update.hwp_max)) { 1587 1412 printf("hwp-desired cannot be greater than hwp_max\n"); 1588 1413 return -EINVAL; 1589 1414 } 1590 1415 /* fail if desired < min requestd */ 1591 - if (req_update.hwp_desired && update_hwp_min && 1592 - (req_update.hwp_desired < req_update.hwp_min)) { 1416 + if (req_update.hwp_desired && update_hwp_min && (req_update.hwp_desired < req_update.hwp_min)) { 1593 1417 printf("hwp-desired cannot be less than hwp_min\n"); 1594 1418 return -EINVAL; 1595 1419 } ··· 1629 1459 } 1630 1460 } 1631 1461 1632 - static void get_cpuid_or_exit(unsigned int leaf, 1633 - unsigned int *eax, unsigned int *ebx, 1634 - unsigned int *ecx, unsigned int *edx) 1462 + static void get_cpuid_or_exit(unsigned int leaf, unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) 1635 1463 { 1636 1464 if (!__get_cpuid(leaf, eax, ebx, ecx, edx)) 1637 1465 errx(1, "Processor not supported\n"); ··· 1683 1515 genuine_intel = 1; 1684 1516 1685 1517 if (debug) 1686 - fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ", 1687 - (char *)&ebx, (char *)&edx, (char *)&ecx); 1518 + fprintf(stderr, "CPUID(0): %.4s%.4s%.4s ", (char *)&ebx, (char *)&edx, (char *)&ecx); 1688 1519 1689 1520 get_cpuid_or_exit(1, &fms, &ebx, &ecx, &edx); 1690 1521 family = (fms >> 8) & 0xf; ··· 1693 1526 model += ((fms >> 16) & 0xf) << 4; 1694 1527 1695 1528 if (debug) { 1696 - fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n", 1697 - max_level, family, model, stepping, family, model, stepping); 1529 + fprintf(stderr, "%d CPUID levels; family:model:stepping 0x%x:%x:%x (%d:%d:%d)\n", max_level, family, model, stepping, family, model, stepping); 1698 1530 fprintf(stderr, "CPUID(1): %s %s %s %s %s %s %s %s\n", 1699 1531 ecx & (1 << 0) ? "SSE3" : "-", 1700 1532 ecx & (1 << 3) ? "MONITOR" : "-", 1701 1533 ecx & (1 << 7) ? "EIST" : "-", 1702 1534 ecx & (1 << 8) ? "TM2" : "-", 1703 - edx & (1 << 4) ? "TSC" : "-", 1704 - edx & (1 << 5) ? "MSR" : "-", 1705 - edx & (1 << 22) ? "ACPI-TM" : "-", 1706 - edx & (1 << 29) ? "TM" : "-"); 1535 + edx & (1 << 4) ? "TSC" : "-", edx & (1 << 5) ? "MSR" : "-", edx & (1 << 22) ? "ACPI-TM" : "-", edx & (1 << 29) ? "TM" : "-"); 1707 1536 } 1708 1537 1709 1538 if (!(edx & (1 << 5))) 1710 1539 errx(1, "CPUID: no MSR"); 1711 - 1712 1540 1713 1541 get_cpuid_or_exit(0x6, &eax, &ebx, &ecx, &edx); 1714 1542 /* turbo_is_enabled already set */ ··· 1724 1562 turbo_is_enabled ? "" : "No-", 1725 1563 has_hwp ? "" : "No-", 1726 1564 has_hwp_notify ? "" : "No-", 1727 - has_hwp_activity_window ? "" : "No-", 1728 - has_hwp_epp ? "" : "No-", 1729 - has_hwp_request_pkg ? "" : "No-", 1730 - has_epb ? "" : "No-"); 1565 + has_hwp_activity_window ? "" : "No-", has_hwp_epp ? "" : "No-", has_hwp_request_pkg ? "" : "No-", has_epb ? "" : "No-"); 1731 1566 1732 - return; /* success */ 1567 + return; /* success */ 1733 1568 } 1734 1569 1735 1570 int main(int argc, char **argv) ··· 1736 1577 probe_dev_msr(); 1737 1578 init_data_structures(); 1738 1579 1739 - early_cpuid(); /* initial cpuid parse before cmdline */ 1580 + early_cpuid(); /* initial cpuid parse before cmdline */ 1740 1581 1741 1582 cmdline(argc, argv); 1742 1583 ··· 1745 1586 1746 1587 parse_cpuid(); 1747 1588 1748 - /* If CPU-set and PKG-set are not initialized, default to all CPUs */ 1589 + /* If CPU-set and PKG-set are not initialized, default to all CPUs */ 1749 1590 if ((cpu_selected_set == 0) && (pkg_selected_set == 0)) 1750 1591 cpu_selected_set = cpu_present_set; 1751 1592 ··· 1763 1604 return -EINVAL; 1764 1605 1765 1606 /* display information only, no updates to settings */ 1766 - if (!update_epb && !update_turbo && !hwp_update_enabled()) { 1607 + if (!update_epb && !update_turbo && !hwp_update_enabled() && !update_soc_slider_balance && !update_soc_slider_offset && !update_platform_profile) { 1767 1608 if (cpu_selected_set) 1768 1609 for_all_cpus_in_set(cpu_setsize, cpu_selected_set, print_cpu_msrs); 1610 + 1611 + print_soc_slider(); 1612 + print_platform_profile(); 1769 1613 1770 1614 if (has_hwp_request_pkg) { 1771 1615 if (pkg_selected_set == 0) ··· 1789 1627 1790 1628 } else if (pkg_selected_set) 1791 1629 for_packages(pkg_selected_set, update_hwp_request_pkg_msr); 1630 + 1631 + if (update_soc_slider_balance || update_soc_slider_offset || update_platform_profile) 1632 + update_soc_slider(); 1792 1633 1793 1634 return 0; 1794 1635 }