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

Merge tag 'pm-5.6-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull more power manadement updates from Rafael Wysocki:
"Prevent cpufreq from creating excessively large stack frames and fix
the handling of devices deleted during system-wide resume in the PM
core (Rafael Wysocki), revert a problematic commit affecting the
cpupower utility and correct its man page (Thomas Renninger,
Brahadambal Srinivasan), and improve the intel_pstate_tracer utility
(Doug Smythies)"

* tag 'pm-5.6-rc1-2' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
tools/power/x86/intel_pstate_tracer: change several graphs to autoscale y-axis
tools/power/x86/intel_pstate_tracer: changes for python 3 compatibility
Correction to manpage of cpupower
cpufreq: Avoid creating excessively large stack frames
PM: core: Fix handling of devices deleted during system-wide resume
cpupower: Revert library ABI changes from commit ae2917093fb60bdc1ed3e

+266 -173
+37 -5
drivers/base/power/main.c
··· 273 273 device_links_read_unlock(idx); 274 274 } 275 275 276 - static void dpm_wait_for_superior(struct device *dev, bool async) 276 + static bool dpm_wait_for_superior(struct device *dev, bool async) 277 277 { 278 - dpm_wait(dev->parent, async); 278 + struct device *parent; 279 + 280 + /* 281 + * If the device is resumed asynchronously and the parent's callback 282 + * deletes both the device and the parent itself, the parent object may 283 + * be freed while this function is running, so avoid that by reference 284 + * counting the parent once more unless the device has been deleted 285 + * already (in which case return right away). 286 + */ 287 + mutex_lock(&dpm_list_mtx); 288 + 289 + if (!device_pm_initialized(dev)) { 290 + mutex_unlock(&dpm_list_mtx); 291 + return false; 292 + } 293 + 294 + parent = get_device(dev->parent); 295 + 296 + mutex_unlock(&dpm_list_mtx); 297 + 298 + dpm_wait(parent, async); 299 + put_device(parent); 300 + 279 301 dpm_wait_for_suppliers(dev, async); 302 + 303 + /* 304 + * If the parent's callback has deleted the device, attempting to resume 305 + * it would be invalid, so avoid doing that then. 306 + */ 307 + return device_pm_initialized(dev); 280 308 } 281 309 282 310 static void dpm_wait_for_consumers(struct device *dev, bool async) ··· 649 621 if (!dev->power.is_noirq_suspended) 650 622 goto Out; 651 623 652 - dpm_wait_for_superior(dev, async); 624 + if (!dpm_wait_for_superior(dev, async)) 625 + goto Out; 653 626 654 627 skip_resume = dev_pm_may_skip_resume(dev); 655 628 ··· 858 829 if (!dev->power.is_late_suspended) 859 830 goto Out; 860 831 861 - dpm_wait_for_superior(dev, async); 832 + if (!dpm_wait_for_superior(dev, async)) 833 + goto Out; 862 834 863 835 callback = dpm_subsys_resume_early_cb(dev, state, &info); 864 836 ··· 974 944 goto Complete; 975 945 } 976 946 977 - dpm_wait_for_superior(dev, async); 947 + if (!dpm_wait_for_superior(dev, async)) 948 + goto Complete; 949 + 978 950 dpm_watchdog_set(&wd, dev); 979 951 device_lock(dev); 980 952
+1 -1
drivers/cpufreq/cppc_cpufreq.c
··· 221 221 return ret; 222 222 } 223 223 224 - static int cppc_verify_policy(struct cpufreq_policy *policy) 224 + static int cppc_verify_policy(struct cpufreq_policy_data *policy) 225 225 { 226 226 cpufreq_verify_within_cpu_limits(policy); 227 227 return 0;
+1 -1
drivers/cpufreq/cpufreq-nforce2.c
··· 291 291 * nforce2_verify - verifies a new CPUFreq policy 292 292 * @policy: new policy 293 293 */ 294 - static int nforce2_verify(struct cpufreq_policy *policy) 294 + static int nforce2_verify(struct cpufreq_policy_data *policy) 295 295 { 296 296 unsigned int fsb_pol_max; 297 297
+71 -78
drivers/cpufreq/cpufreq.c
··· 74 74 static int cpufreq_start_governor(struct cpufreq_policy *policy); 75 75 static void cpufreq_stop_governor(struct cpufreq_policy *policy); 76 76 static void cpufreq_governor_limits(struct cpufreq_policy *policy); 77 + static int cpufreq_set_policy(struct cpufreq_policy *policy, 78 + struct cpufreq_governor *new_gov, 79 + unsigned int new_pol); 77 80 78 81 /** 79 82 * Two notifier lists: the "policy" list is involved in the ··· 619 616 return NULL; 620 617 } 621 618 622 - static int cpufreq_parse_policy(char *str_governor, 623 - struct cpufreq_policy *policy) 619 + static unsigned int cpufreq_parse_policy(char *str_governor) 624 620 { 625 - if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN)) { 626 - policy->policy = CPUFREQ_POLICY_PERFORMANCE; 627 - return 0; 628 - } 629 - if (!strncasecmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) { 630 - policy->policy = CPUFREQ_POLICY_POWERSAVE; 631 - return 0; 632 - } 633 - return -EINVAL; 621 + if (!strncasecmp(str_governor, "performance", CPUFREQ_NAME_LEN)) 622 + return CPUFREQ_POLICY_PERFORMANCE; 623 + 624 + if (!strncasecmp(str_governor, "powersave", CPUFREQ_NAME_LEN)) 625 + return CPUFREQ_POLICY_POWERSAVE; 626 + 627 + return CPUFREQ_POLICY_UNKNOWN; 634 628 } 635 629 636 630 /** 637 631 * cpufreq_parse_governor - parse a governor string only for has_target() 632 + * @str_governor: Governor name. 638 633 */ 639 - static int cpufreq_parse_governor(char *str_governor, 640 - struct cpufreq_policy *policy) 634 + static struct cpufreq_governor *cpufreq_parse_governor(char *str_governor) 641 635 { 642 636 struct cpufreq_governor *t; 643 637 ··· 648 648 649 649 ret = request_module("cpufreq_%s", str_governor); 650 650 if (ret) 651 - return -EINVAL; 651 + return NULL; 652 652 653 653 mutex_lock(&cpufreq_governor_mutex); 654 654 ··· 659 659 660 660 mutex_unlock(&cpufreq_governor_mutex); 661 661 662 - if (t) { 663 - policy->governor = t; 664 - return 0; 665 - } 666 - 667 - return -EINVAL; 662 + return t; 668 663 } 669 664 670 665 /** ··· 760 765 static ssize_t store_scaling_governor(struct cpufreq_policy *policy, 761 766 const char *buf, size_t count) 762 767 { 768 + char str_governor[16]; 763 769 int ret; 764 - char str_governor[16]; 765 - struct cpufreq_policy new_policy; 766 - 767 - memcpy(&new_policy, policy, sizeof(*policy)); 768 770 769 771 ret = sscanf(buf, "%15s", str_governor); 770 772 if (ret != 1) 771 773 return -EINVAL; 772 774 773 775 if (cpufreq_driver->setpolicy) { 774 - if (cpufreq_parse_policy(str_governor, &new_policy)) 776 + unsigned int new_pol; 777 + 778 + new_pol = cpufreq_parse_policy(str_governor); 779 + if (!new_pol) 775 780 return -EINVAL; 781 + 782 + ret = cpufreq_set_policy(policy, NULL, new_pol); 776 783 } else { 777 - if (cpufreq_parse_governor(str_governor, &new_policy)) 784 + struct cpufreq_governor *new_gov; 785 + 786 + new_gov = cpufreq_parse_governor(str_governor); 787 + if (!new_gov) 778 788 return -EINVAL; 789 + 790 + ret = cpufreq_set_policy(policy, new_gov, 791 + CPUFREQ_POLICY_UNKNOWN); 792 + 793 + module_put(new_gov->owner); 779 794 } 780 - 781 - ret = cpufreq_set_policy(policy, &new_policy); 782 - 783 - if (new_policy.governor) 784 - module_put(new_policy.governor->owner); 785 795 786 796 return ret ? ret : count; 787 797 } ··· 1053 1053 1054 1054 static int cpufreq_init_policy(struct cpufreq_policy *policy) 1055 1055 { 1056 - struct cpufreq_governor *gov = NULL, *def_gov = NULL; 1057 - struct cpufreq_policy new_policy; 1058 - 1059 - memcpy(&new_policy, policy, sizeof(*policy)); 1060 - 1061 - def_gov = cpufreq_default_governor(); 1056 + struct cpufreq_governor *def_gov = cpufreq_default_governor(); 1057 + struct cpufreq_governor *gov = NULL; 1058 + unsigned int pol = CPUFREQ_POLICY_UNKNOWN; 1062 1059 1063 1060 if (has_target()) { 1064 - /* 1065 - * Update governor of new_policy to the governor used before 1066 - * hotplug 1067 - */ 1061 + /* Update policy governor to the one used before hotplug. */ 1068 1062 gov = find_governor(policy->last_governor); 1069 1063 if (gov) { 1070 1064 pr_debug("Restoring governor %s for cpu %d\n", 1071 - policy->governor->name, policy->cpu); 1072 - } else { 1073 - if (!def_gov) 1074 - return -ENODATA; 1065 + policy->governor->name, policy->cpu); 1066 + } else if (def_gov) { 1075 1067 gov = def_gov; 1068 + } else { 1069 + return -ENODATA; 1076 1070 } 1077 - new_policy.governor = gov; 1078 1071 } else { 1079 1072 /* Use the default policy if there is no last_policy. */ 1080 1073 if (policy->last_policy) { 1081 - new_policy.policy = policy->last_policy; 1074 + pol = policy->last_policy; 1075 + } else if (def_gov) { 1076 + pol = cpufreq_parse_policy(def_gov->name); 1082 1077 } else { 1083 - if (!def_gov) 1084 - return -ENODATA; 1085 - cpufreq_parse_policy(def_gov->name, &new_policy); 1078 + return -ENODATA; 1086 1079 } 1087 1080 } 1088 1081 1089 - return cpufreq_set_policy(policy, &new_policy); 1082 + return cpufreq_set_policy(policy, gov, pol); 1090 1083 } 1091 1084 1092 1085 static int cpufreq_add_policy_cpu(struct cpufreq_policy *policy, unsigned int cpu) ··· 1107 1114 1108 1115 void refresh_frequency_limits(struct cpufreq_policy *policy) 1109 1116 { 1110 - struct cpufreq_policy new_policy; 1111 - 1112 1117 if (!policy_is_inactive(policy)) { 1113 - new_policy = *policy; 1114 1118 pr_debug("updating policy for CPU %u\n", policy->cpu); 1115 1119 1116 - cpufreq_set_policy(policy, &new_policy); 1120 + cpufreq_set_policy(policy, policy->governor, policy->policy); 1117 1121 } 1118 1122 } 1119 1123 EXPORT_SYMBOL(refresh_frequency_limits); ··· 2354 2364 /** 2355 2365 * cpufreq_set_policy - Modify cpufreq policy parameters. 2356 2366 * @policy: Policy object to modify. 2357 - * @new_policy: New policy data. 2367 + * @new_gov: Policy governor pointer. 2368 + * @new_pol: Policy value (for drivers with built-in governors). 2358 2369 * 2359 - * Pass @new_policy to the cpufreq driver's ->verify() callback. Next, copy the 2360 - * min and max parameters of @new_policy to @policy and either invoke the 2361 - * driver's ->setpolicy() callback (if present) or carry out a governor update 2362 - * for @policy. That is, run the current governor's ->limits() callback (if the 2363 - * governor field in @new_policy points to the same object as the one in 2364 - * @policy) or replace the governor for @policy with the new one stored in 2365 - * @new_policy. 2370 + * Invoke the cpufreq driver's ->verify() callback to sanity-check the frequency 2371 + * limits to be set for the policy, update @policy with the verified limits 2372 + * values and either invoke the driver's ->setpolicy() callback (if present) or 2373 + * carry out a governor update for @policy. That is, run the current governor's 2374 + * ->limits() callback (if @new_gov points to the same object as the one in 2375 + * @policy) or replace the governor for @policy with @new_gov. 2366 2376 * 2367 2377 * The cpuinfo part of @policy is not updated by this function. 2368 2378 */ 2369 - int cpufreq_set_policy(struct cpufreq_policy *policy, 2370 - struct cpufreq_policy *new_policy) 2379 + static int cpufreq_set_policy(struct cpufreq_policy *policy, 2380 + struct cpufreq_governor *new_gov, 2381 + unsigned int new_pol) 2371 2382 { 2383 + struct cpufreq_policy_data new_data; 2372 2384 struct cpufreq_governor *old_gov; 2373 2385 int ret; 2374 2386 2375 - pr_debug("setting new policy for CPU %u: %u - %u kHz\n", 2376 - new_policy->cpu, new_policy->min, new_policy->max); 2377 - 2378 - memcpy(&new_policy->cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo)); 2379 - 2387 + memcpy(&new_data.cpuinfo, &policy->cpuinfo, sizeof(policy->cpuinfo)); 2388 + new_data.freq_table = policy->freq_table; 2389 + new_data.cpu = policy->cpu; 2380 2390 /* 2381 2391 * PM QoS framework collects all the requests from users and provide us 2382 2392 * the final aggregated value here. 2383 2393 */ 2384 - new_policy->min = freq_qos_read_value(&policy->constraints, FREQ_QOS_MIN); 2385 - new_policy->max = freq_qos_read_value(&policy->constraints, FREQ_QOS_MAX); 2394 + new_data.min = freq_qos_read_value(&policy->constraints, FREQ_QOS_MIN); 2395 + new_data.max = freq_qos_read_value(&policy->constraints, FREQ_QOS_MAX); 2396 + 2397 + pr_debug("setting new policy for CPU %u: %u - %u kHz\n", 2398 + new_data.cpu, new_data.min, new_data.max); 2386 2399 2387 2400 /* 2388 2401 * Verify that the CPU speed can be set within these limits and make sure 2389 2402 * that min <= max. 2390 2403 */ 2391 - ret = cpufreq_driver->verify(new_policy); 2404 + ret = cpufreq_driver->verify(&new_data); 2392 2405 if (ret) 2393 2406 return ret; 2394 2407 2395 - policy->min = new_policy->min; 2396 - policy->max = new_policy->max; 2408 + policy->min = new_data.min; 2409 + policy->max = new_data.max; 2397 2410 trace_cpu_frequency_limits(policy); 2398 2411 2399 2412 policy->cached_target_freq = UINT_MAX; ··· 2405 2412 policy->min, policy->max); 2406 2413 2407 2414 if (cpufreq_driver->setpolicy) { 2408 - policy->policy = new_policy->policy; 2415 + policy->policy = new_pol; 2409 2416 pr_debug("setting range\n"); 2410 2417 return cpufreq_driver->setpolicy(policy); 2411 2418 } 2412 2419 2413 - if (new_policy->governor == policy->governor) { 2420 + if (new_gov == policy->governor) { 2414 2421 pr_debug("governor limits update\n"); 2415 2422 cpufreq_governor_limits(policy); 2416 2423 return 0; ··· 2427 2434 } 2428 2435 2429 2436 /* start new governor */ 2430 - policy->governor = new_policy->governor; 2437 + policy->governor = new_gov; 2431 2438 ret = cpufreq_init_governor(policy); 2432 2439 if (!ret) { 2433 2440 ret = cpufreq_start_governor(policy);
+2 -2
drivers/cpufreq/freq_table.c
··· 60 60 return 0; 61 61 } 62 62 63 - int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, 63 + int cpufreq_frequency_table_verify(struct cpufreq_policy_data *policy, 64 64 struct cpufreq_frequency_table *table) 65 65 { 66 66 struct cpufreq_frequency_table *pos; ··· 100 100 * Generic routine to verify policy & frequency table, requires driver to set 101 101 * policy->freq_table prior to it. 102 102 */ 103 - int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy) 103 + int cpufreq_generic_frequency_table_verify(struct cpufreq_policy_data *policy) 104 104 { 105 105 if (!policy->freq_table) 106 106 return -ENODEV;
+1 -1
drivers/cpufreq/gx-suspmod.c
··· 328 328 * for the hardware supported by the driver. 329 329 */ 330 330 331 - static int cpufreq_gx_verify(struct cpufreq_policy *policy) 331 + static int cpufreq_gx_verify(struct cpufreq_policy_data *policy) 332 332 { 333 333 unsigned int tmp_freq = 0; 334 334 u8 tmp1, tmp2;
+17 -21
drivers/cpufreq/intel_pstate.c
··· 2036 2036 cpu->pstate.max_freq : cpu->pstate.turbo_freq; 2037 2037 } 2038 2038 2039 - static void intel_pstate_update_perf_limits(struct cpufreq_policy *policy, 2040 - struct cpudata *cpu) 2039 + static void intel_pstate_update_perf_limits(struct cpudata *cpu, 2040 + unsigned int policy_min, 2041 + unsigned int policy_max) 2041 2042 { 2042 2043 int max_freq = intel_pstate_get_max_freq(cpu); 2043 2044 int32_t max_policy_perf, min_policy_perf; ··· 2057 2056 turbo_max = cpu->pstate.turbo_pstate; 2058 2057 } 2059 2058 2060 - max_policy_perf = max_state * policy->max / max_freq; 2061 - if (policy->max == policy->min) { 2059 + max_policy_perf = max_state * policy_max / max_freq; 2060 + if (policy_max == policy_min) { 2062 2061 min_policy_perf = max_policy_perf; 2063 2062 } else { 2064 - min_policy_perf = max_state * policy->min / max_freq; 2063 + min_policy_perf = max_state * policy_min / max_freq; 2065 2064 min_policy_perf = clamp_t(int32_t, min_policy_perf, 2066 2065 0, max_policy_perf); 2067 2066 } 2068 2067 2069 2068 pr_debug("cpu:%d max_state %d min_policy_perf:%d max_policy_perf:%d\n", 2070 - policy->cpu, max_state, 2071 - min_policy_perf, max_policy_perf); 2069 + cpu->cpu, max_state, min_policy_perf, max_policy_perf); 2072 2070 2073 2071 /* Normalize user input to [min_perf, max_perf] */ 2074 2072 if (per_cpu_limits) { ··· 2081 2081 global_min = DIV_ROUND_UP(turbo_max * global.min_perf_pct, 100); 2082 2082 global_min = clamp_t(int32_t, global_min, 0, global_max); 2083 2083 2084 - pr_debug("cpu:%d global_min:%d global_max:%d\n", policy->cpu, 2084 + pr_debug("cpu:%d global_min:%d global_max:%d\n", cpu->cpu, 2085 2085 global_min, global_max); 2086 2086 2087 2087 cpu->min_perf_ratio = max(min_policy_perf, global_min); ··· 2094 2094 cpu->max_perf_ratio); 2095 2095 2096 2096 } 2097 - pr_debug("cpu:%d max_perf_ratio:%d min_perf_ratio:%d\n", policy->cpu, 2097 + pr_debug("cpu:%d max_perf_ratio:%d min_perf_ratio:%d\n", cpu->cpu, 2098 2098 cpu->max_perf_ratio, 2099 2099 cpu->min_perf_ratio); 2100 2100 } ··· 2114 2114 2115 2115 mutex_lock(&intel_pstate_limits_lock); 2116 2116 2117 - intel_pstate_update_perf_limits(policy, cpu); 2117 + intel_pstate_update_perf_limits(cpu, policy->min, policy->max); 2118 2118 2119 2119 if (cpu->policy == CPUFREQ_POLICY_PERFORMANCE) { 2120 2120 /* ··· 2143 2143 return 0; 2144 2144 } 2145 2145 2146 - static void intel_pstate_adjust_policy_max(struct cpufreq_policy *policy, 2147 - struct cpudata *cpu) 2146 + static void intel_pstate_adjust_policy_max(struct cpudata *cpu, 2147 + struct cpufreq_policy_data *policy) 2148 2148 { 2149 2149 if (!hwp_active && 2150 2150 cpu->pstate.max_pstate_physical > cpu->pstate.max_pstate && ··· 2155 2155 } 2156 2156 } 2157 2157 2158 - static int intel_pstate_verify_policy(struct cpufreq_policy *policy) 2158 + static int intel_pstate_verify_policy(struct cpufreq_policy_data *policy) 2159 2159 { 2160 2160 struct cpudata *cpu = all_cpu_data[policy->cpu]; 2161 2161 ··· 2163 2163 cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, 2164 2164 intel_pstate_get_max_freq(cpu)); 2165 2165 2166 - if (policy->policy != CPUFREQ_POLICY_POWERSAVE && 2167 - policy->policy != CPUFREQ_POLICY_PERFORMANCE) 2168 - return -EINVAL; 2169 - 2170 - intel_pstate_adjust_policy_max(policy, cpu); 2166 + intel_pstate_adjust_policy_max(cpu, policy); 2171 2167 2172 2168 return 0; 2173 2169 } ··· 2264 2268 .name = "intel_pstate", 2265 2269 }; 2266 2270 2267 - static int intel_cpufreq_verify_policy(struct cpufreq_policy *policy) 2271 + static int intel_cpufreq_verify_policy(struct cpufreq_policy_data *policy) 2268 2272 { 2269 2273 struct cpudata *cpu = all_cpu_data[policy->cpu]; 2270 2274 ··· 2272 2276 cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, 2273 2277 intel_pstate_get_max_freq(cpu)); 2274 2278 2275 - intel_pstate_adjust_policy_max(policy, cpu); 2279 + intel_pstate_adjust_policy_max(cpu, policy); 2276 2280 2277 - intel_pstate_update_perf_limits(policy, cpu); 2281 + intel_pstate_update_perf_limits(cpu, policy->min, policy->max); 2278 2282 2279 2283 return 0; 2280 2284 }
+1 -5
drivers/cpufreq/longrun.c
··· 122 122 * Validates a new CPUFreq policy. This function has to be called with 123 123 * cpufreq_driver locked. 124 124 */ 125 - static int longrun_verify_policy(struct cpufreq_policy *policy) 125 + static int longrun_verify_policy(struct cpufreq_policy_data *policy) 126 126 { 127 127 if (!policy) 128 128 return -EINVAL; 129 129 130 130 policy->cpu = 0; 131 131 cpufreq_verify_within_cpu_limits(policy); 132 - 133 - if ((policy->policy != CPUFREQ_POLICY_POWERSAVE) && 134 - (policy->policy != CPUFREQ_POLICY_PERFORMANCE)) 135 - return -EINVAL; 136 132 137 133 return 0; 138 134 }
+1 -1
drivers/cpufreq/pcc-cpufreq.c
··· 109 109 110 110 static struct pcc_cpu __percpu *pcc_cpu_info; 111 111 112 - static int pcc_cpufreq_verify(struct cpufreq_policy *policy) 112 + static int pcc_cpufreq_verify(struct cpufreq_policy_data *policy) 113 113 { 114 114 cpufreq_verify_within_cpu_limits(policy); 115 115 return 0;
+1 -1
drivers/cpufreq/sh-cpufreq.c
··· 87 87 return work_on_cpu(policy->cpu, __sh_cpufreq_target, &data); 88 88 } 89 89 90 - static int sh_cpufreq_verify(struct cpufreq_policy *policy) 90 + static int sh_cpufreq_verify(struct cpufreq_policy_data *policy) 91 91 { 92 92 struct clk *cpuclk = &per_cpu(sh_cpuclk, policy->cpu); 93 93 struct cpufreq_frequency_table *freq_table;
+1 -1
drivers/cpufreq/unicore2-cpufreq.c
··· 22 22 /* make sure that only the "userspace" governor is run 23 23 * -- anything else wouldn't make sense on this platform, anyway. 24 24 */ 25 - static int ucv2_verify_speed(struct cpufreq_policy *policy) 25 + static int ucv2_verify_speed(struct cpufreq_policy_data *policy) 26 26 { 27 27 if (policy->cpu) 28 28 return -EINVAL;
+23 -9
include/linux/cpufreq.h
··· 148 148 struct notifier_block nb_max; 149 149 }; 150 150 151 + /* 152 + * Used for passing new cpufreq policy data to the cpufreq driver's ->verify() 153 + * callback for sanitization. That callback is only expected to modify the min 154 + * and max values, if necessary, and specifically it must not update the 155 + * frequency table. 156 + */ 157 + struct cpufreq_policy_data { 158 + struct cpufreq_cpuinfo cpuinfo; 159 + struct cpufreq_frequency_table *freq_table; 160 + unsigned int cpu; 161 + unsigned int min; /* in kHz */ 162 + unsigned int max; /* in kHz */ 163 + }; 164 + 151 165 struct cpufreq_freqs { 152 166 struct cpufreq_policy *policy; 153 167 unsigned int old; ··· 215 201 struct cpufreq_policy *cpufreq_cpu_acquire(unsigned int cpu); 216 202 void cpufreq_cpu_release(struct cpufreq_policy *policy); 217 203 int cpufreq_get_policy(struct cpufreq_policy *policy, unsigned int cpu); 218 - int cpufreq_set_policy(struct cpufreq_policy *policy, 219 - struct cpufreq_policy *new_policy); 220 204 void refresh_frequency_limits(struct cpufreq_policy *policy); 221 205 void cpufreq_update_policy(unsigned int cpu); 222 206 void cpufreq_update_limits(unsigned int cpu); ··· 296 284 297 285 /* needed by all drivers */ 298 286 int (*init)(struct cpufreq_policy *policy); 299 - int (*verify)(struct cpufreq_policy *policy); 287 + int (*verify)(struct cpufreq_policy_data *policy); 300 288 301 289 /* define one out of two */ 302 290 int (*setpolicy)(struct cpufreq_policy *policy); ··· 427 415 (drv->flags & CPUFREQ_IS_COOLING_DEV); 428 416 } 429 417 430 - static inline void cpufreq_verify_within_limits(struct cpufreq_policy *policy, 431 - unsigned int min, unsigned int max) 418 + static inline void cpufreq_verify_within_limits(struct cpufreq_policy_data *policy, 419 + unsigned int min, 420 + unsigned int max) 432 421 { 433 422 if (policy->min < min) 434 423 policy->min = min; ··· 445 432 } 446 433 447 434 static inline void 448 - cpufreq_verify_within_cpu_limits(struct cpufreq_policy *policy) 435 + cpufreq_verify_within_cpu_limits(struct cpufreq_policy_data *policy) 449 436 { 450 437 cpufreq_verify_within_limits(policy, policy->cpuinfo.min_freq, 451 - policy->cpuinfo.max_freq); 438 + policy->cpuinfo.max_freq); 452 439 } 453 440 454 441 #ifdef CONFIG_CPU_FREQ ··· 526 513 * CPUFREQ GOVERNORS * 527 514 *********************************************************************/ 528 515 516 + #define CPUFREQ_POLICY_UNKNOWN (0) 529 517 /* 530 518 * If (cpufreq_driver->target) exists, the ->governor decides what frequency 531 519 * within the limits is used. If (cpufreq_driver->setpolicy> exists, these ··· 698 684 int cpufreq_frequency_table_cpuinfo(struct cpufreq_policy *policy, 699 685 struct cpufreq_frequency_table *table); 700 686 701 - int cpufreq_frequency_table_verify(struct cpufreq_policy *policy, 687 + int cpufreq_frequency_table_verify(struct cpufreq_policy_data *policy, 702 688 struct cpufreq_frequency_table *table); 703 - int cpufreq_generic_frequency_table_verify(struct cpufreq_policy *policy); 689 + int cpufreq_generic_frequency_table_verify(struct cpufreq_policy_data *policy); 704 690 705 691 int cpufreq_table_index_unsorted(struct cpufreq_policy *policy, 706 692 unsigned int target_freq,
+69 -11
tools/power/cpupower/lib/cpufreq.c
··· 332 332 } 333 333 334 334 335 - struct cpufreq_frequencies 336 - *cpufreq_get_frequencies(const char *type, unsigned int cpu) 335 + struct cpufreq_available_frequencies 336 + *cpufreq_get_available_frequencies(unsigned int cpu) 337 337 { 338 - struct cpufreq_frequencies *first = NULL; 339 - struct cpufreq_frequencies *current = NULL; 338 + struct cpufreq_available_frequencies *first = NULL; 339 + struct cpufreq_available_frequencies *current = NULL; 340 340 char one_value[SYSFS_PATH_MAX]; 341 341 char linebuf[MAX_LINE_LEN]; 342 - char fname[MAX_LINE_LEN]; 343 342 unsigned int pos, i; 344 343 unsigned int len; 345 344 346 - snprintf(fname, MAX_LINE_LEN, "scaling_%s_frequencies", type); 347 - 348 - len = sysfs_cpufreq_read_file(cpu, fname, 349 - linebuf, sizeof(linebuf)); 345 + len = sysfs_cpufreq_read_file(cpu, "scaling_available_frequencies", 346 + linebuf, sizeof(linebuf)); 350 347 if (len == 0) 351 348 return NULL; 352 349 ··· 388 391 return NULL; 389 392 } 390 393 391 - void cpufreq_put_frequencies(struct cpufreq_frequencies *any) 394 + struct cpufreq_available_frequencies 395 + *cpufreq_get_boost_frequencies(unsigned int cpu) 392 396 { 393 - struct cpufreq_frequencies *tmp, *next; 397 + struct cpufreq_available_frequencies *first = NULL; 398 + struct cpufreq_available_frequencies *current = NULL; 399 + char one_value[SYSFS_PATH_MAX]; 400 + char linebuf[MAX_LINE_LEN]; 401 + unsigned int pos, i; 402 + unsigned int len; 403 + 404 + len = sysfs_cpufreq_read_file(cpu, "scaling_boost_frequencies", 405 + linebuf, sizeof(linebuf)); 406 + if (len == 0) 407 + return NULL; 408 + 409 + pos = 0; 410 + for (i = 0; i < len; i++) { 411 + if (linebuf[i] == ' ' || linebuf[i] == '\n') { 412 + if (i - pos < 2) 413 + continue; 414 + if (i - pos >= SYSFS_PATH_MAX) 415 + goto error_out; 416 + if (current) { 417 + current->next = malloc(sizeof(*current)); 418 + if (!current->next) 419 + goto error_out; 420 + current = current->next; 421 + } else { 422 + first = malloc(sizeof(*first)); 423 + if (!first) 424 + goto error_out; 425 + current = first; 426 + } 427 + current->first = first; 428 + current->next = NULL; 429 + 430 + memcpy(one_value, linebuf + pos, i - pos); 431 + one_value[i - pos] = '\0'; 432 + if (sscanf(one_value, "%lu", &current->frequency) != 1) 433 + goto error_out; 434 + 435 + pos = i + 1; 436 + } 437 + } 438 + 439 + return first; 440 + 441 + error_out: 442 + while (first) { 443 + current = first->next; 444 + free(first); 445 + first = current; 446 + } 447 + return NULL; 448 + } 449 + 450 + void cpufreq_put_available_frequencies(struct cpufreq_available_frequencies *any) 451 + { 452 + struct cpufreq_available_frequencies *tmp, *next; 394 453 395 454 if (!any) 396 455 return; ··· 457 404 free(tmp); 458 405 tmp = next; 459 406 } 407 + } 408 + 409 + void cpufreq_put_boost_frequencies(struct cpufreq_available_frequencies *any) 410 + { 411 + cpufreq_put_available_frequencies(any); 460 412 } 461 413 462 414 static struct cpufreq_affected_cpus *sysfs_get_cpu_list(unsigned int cpu,
+13 -7
tools/power/cpupower/lib/cpufreq.h
··· 20 20 struct cpufreq_available_governors *first; 21 21 }; 22 22 23 - struct cpufreq_frequencies { 23 + struct cpufreq_available_frequencies { 24 24 unsigned long frequency; 25 - struct cpufreq_frequencies *next; 26 - struct cpufreq_frequencies *first; 25 + struct cpufreq_available_frequencies *next; 26 + struct cpufreq_available_frequencies *first; 27 27 }; 28 28 29 29 ··· 124 124 * cpufreq_put_frequencies after use. 125 125 */ 126 126 127 - struct cpufreq_frequencies 128 - *cpufreq_get_frequencies(const char *type, unsigned int cpu); 127 + struct cpufreq_available_frequencies 128 + *cpufreq_get_available_frequencies(unsigned int cpu); 129 129 130 - void cpufreq_put_frequencies( 131 - struct cpufreq_frequencies *first); 130 + void cpufreq_put_available_frequencies( 131 + struct cpufreq_available_frequencies *first); 132 + 133 + struct cpufreq_available_frequencies 134 + *cpufreq_get_boost_frequencies(unsigned int cpu); 135 + 136 + void cpufreq_put_boost_frequencies( 137 + struct cpufreq_available_frequencies *first); 132 138 133 139 134 140 /* determine affected CPUs
+3 -3
tools/power/cpupower/man/cpupower.1
··· 62 62 Print the package name and version number. 63 63 64 64 .SH "SEE ALSO" 65 - cpupower-set(1), cpupower-info(1), cpupower-idle(1), 66 - cpupower-frequency-set(1), cpupower-frequency-info(1), cpupower-monitor(1), 67 - powertop(1) 65 + cpupower-set(1), cpupower-info(1), cpupower-idle-info(1), 66 + cpupower-idle-set(1), cpupower-frequency-set(1), cpupower-frequency-info(1), 67 + cpupower-monitor(1), powertop(1) 68 68 .PP 69 69 .SH AUTHORS 70 70 .nf
+6 -6
tools/power/cpupower/utils/cpufreq-info.c
··· 244 244 245 245 static int get_boost_mode(unsigned int cpu) 246 246 { 247 - struct cpufreq_frequencies *freqs; 247 + struct cpufreq_available_frequencies *freqs; 248 248 249 249 if (cpupower_cpu_info.vendor == X86_VENDOR_AMD || 250 250 cpupower_cpu_info.vendor == X86_VENDOR_HYGON || 251 251 cpupower_cpu_info.vendor == X86_VENDOR_INTEL) 252 252 return get_boost_mode_x86(cpu); 253 253 254 - freqs = cpufreq_get_frequencies("boost", cpu); 254 + freqs = cpufreq_get_boost_frequencies(cpu); 255 255 if (freqs) { 256 256 printf(_(" boost frequency steps: ")); 257 257 while (freqs->next) { ··· 261 261 } 262 262 print_speed(freqs->frequency); 263 263 printf("\n"); 264 - cpufreq_put_frequencies(freqs); 264 + cpufreq_put_available_frequencies(freqs); 265 265 } 266 266 267 267 return 0; ··· 475 475 476 476 static void debug_output_one(unsigned int cpu) 477 477 { 478 - struct cpufreq_frequencies *freqs; 478 + struct cpufreq_available_frequencies *freqs; 479 479 480 480 get_driver(cpu); 481 481 get_related_cpus(cpu); ··· 483 483 get_latency(cpu, 1); 484 484 get_hardware_limits(cpu, 1); 485 485 486 - freqs = cpufreq_get_frequencies("available", cpu); 486 + freqs = cpufreq_get_available_frequencies(cpu); 487 487 if (freqs) { 488 488 printf(_(" available frequency steps: ")); 489 489 while (freqs->next) { ··· 493 493 } 494 494 print_speed(freqs->frequency); 495 495 printf("\n"); 496 - cpufreq_put_frequencies(freqs); 496 + cpufreq_put_available_frequencies(freqs); 497 497 } 498 498 499 499 get_available_governors(cpu);
+18 -20
tools/power/x86/intel_pstate_tracer/intel_pstate_tracer.py
··· 11 11 and generates performance plots. 12 12 13 13 Prerequisites: 14 - Python version 2.7.x 14 + Python version 2.7.x or higher 15 15 gnuplot 5.0 or higher 16 - gnuplot-py 1.8 16 + gnuplot-py 1.8 or higher 17 17 (Most of the distributions have these required packages. They may be called 18 - gnuplot-py, phython-gnuplot. ) 18 + gnuplot-py, phython-gnuplot or phython3-gnuplot, gnuplot-nox, ... ) 19 19 20 20 HWP (Hardware P-States are disabled) 21 21 Kernel config for Linux trace is enabled ··· 104 104 if os.path.exists(file_name): 105 105 output_png = "cpu%03d_perf_busy_vs_samples.png" % cpu_index 106 106 g_plot = common_all_gnuplot_settings(output_png) 107 - g_plot('set yrange [0:40]') 107 + # autoscale this one, no set y1 range 108 108 g_plot('set y2range [0:200]') 109 109 g_plot('set y2tics 0, 10') 110 110 g_plot('set title "{} : cpu perf busy vs. sample : CPU {:0>3} : {:%F %H:%M}"'.format(testname, cpu_index, datetime.now())) ··· 125 125 if os.path.exists(file_name): 126 126 output_png = "cpu%03d_perf_busy.png" % cpu_index 127 127 g_plot = common_all_gnuplot_settings(output_png) 128 - g_plot('set yrange [0:40]') 128 + # autoscale this one, no set y1 range 129 129 g_plot('set y2range [0:200]') 130 130 g_plot('set y2tics 0, 10') 131 131 g_plot('set title "{} : perf busy : CPU {:0>3} : {:%F %H:%M}"'.format(testname, cpu_index, datetime.now())) ··· 144 144 if os.path.exists(file_name): 145 145 output_png = "cpu%03d_durations.png" % cpu_index 146 146 g_plot = common_all_gnuplot_settings(output_png) 147 - # Should autoscale be used here? Should seconds be used here? 148 - g_plot('set yrange [0:5000]') 149 - g_plot('set ytics 0, 500') 147 + # autoscale this one, no set y range 150 148 g_plot('set title "{} : durations : CPU {:0>3} : {:%F %H:%M}"'.format(testname, cpu_index, datetime.now())) 151 149 g_plot('set ylabel "Timer Duration (MilliSeconds)"') 152 150 # override common ··· 174 176 if os.path.exists('cpu.csv'): 175 177 output_png = 'all_cpu_pstates_vs_samples.png' 176 178 g_plot = common_all_gnuplot_settings(output_png) 177 - g_plot('set yrange [0:40]') 179 + # autoscale this one, no set y range 178 180 # override common 179 181 g_plot('set xlabel "Samples"') 180 182 g_plot('set ylabel "P-State"') 181 183 g_plot('set title "{} : cpu pstate vs. sample : {:%F %H:%M}"'.format(testname, datetime.now())) 182 - title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).replace('\n', ' ') 184 + title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).decode('utf-8').replace('\n', ' ') 183 185 plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_SAMPLE, C_TO) 184 186 g_plot('title_list = "{}"'.format(title_list)) 185 187 g_plot(plot_str) ··· 189 191 190 192 output_png = 'all_cpu_pstates.png' 191 193 g_plot = common_all_gnuplot_settings(output_png) 192 - g_plot('set yrange [0:40]') 194 + # autoscale this one, no set y range 193 195 g_plot('set ylabel "P-State"') 194 196 g_plot('set title "{} : cpu pstates : {:%F %H:%M}"'.format(testname, datetime.now())) 195 197 196 198 # the following command is really cool, but doesn't work with the CPU masking option because it aborts on the first missing file. 197 199 # plot_str = 'plot for [i=0:*] file=sprintf("cpu%03d.csv",i) title_s=sprintf("cpu%03d",i) file using 16:7 pt 7 ps 1 title title_s' 198 200 # 199 - title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).replace('\n', ' ') 201 + title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).decode('utf-8').replace('\n', ' ') 200 202 plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_TO) 201 203 g_plot('title_list = "{}"'.format(title_list)) 202 204 g_plot(plot_str) ··· 210 212 g_plot('set ylabel "CPU load (percent)"') 211 213 g_plot('set title "{} : cpu loads : {:%F %H:%M}"'.format(testname, datetime.now())) 212 214 213 - title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).replace('\n', ' ') 215 + title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).decode('utf-8').replace('\n', ' ') 214 216 plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_LOAD) 215 217 g_plot('title_list = "{}"'.format(title_list)) 216 218 g_plot(plot_str) ··· 220 222 221 223 output_png = 'all_cpu_frequencies.png' 222 224 g_plot = common_all_gnuplot_settings(output_png) 223 - g_plot('set yrange [0:4]') 225 + # autoscale this one, no set y range 224 226 g_plot('set ylabel "CPU Frequency (GHz)"') 225 227 g_plot('set title "{} : cpu frequencies : {:%F %H:%M}"'.format(testname, datetime.now())) 226 228 227 - title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).replace('\n', ' ') 229 + title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).decode('utf-8').replace('\n', ' ') 228 230 plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_FREQ) 229 231 g_plot('title_list = "{}"'.format(title_list)) 230 232 g_plot(plot_str) ··· 234 236 235 237 output_png = 'all_cpu_durations.png' 236 238 g_plot = common_all_gnuplot_settings(output_png) 237 - g_plot('set yrange [0:5000]') 239 + # autoscale this one, no set y range 238 240 g_plot('set ytics 0, 500') 239 241 g_plot('set ylabel "Timer Duration (MilliSeconds)"') 240 242 g_plot('set title "{} : cpu durations : {:%F %H:%M}"'.format(testname, datetime.now())) 241 243 242 - title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).replace('\n', ' ') 244 + title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).decode('utf-8').replace('\n', ' ') 243 245 plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_DURATION) 244 246 g_plot('title_list = "{}"'.format(title_list)) 245 247 g_plot(plot_str) ··· 253 255 g_plot('set ylabel "Scaled Busy (Unitless)"') 254 256 g_plot('set title "{} : cpu scaled busy : {:%F %H:%M}"'.format(testname, datetime.now())) 255 257 256 - title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).replace('\n', ' ') 258 + title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).decode('utf-8').replace('\n', ' ') 257 259 plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_SCALED) 258 260 g_plot('title_list = "{}"'.format(title_list)) 259 261 g_plot(plot_str) ··· 267 269 g_plot('set ylabel "CPU IO Boost (percent)"') 268 270 g_plot('set title "{} : cpu io boost : {:%F %H:%M}"'.format(testname, datetime.now())) 269 271 270 - title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).replace('\n', ' ') 272 + title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).decode('utf-8').replace('\n', ' ') 271 273 plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_BOOST) 272 274 g_plot('title_list = "{}"'.format(title_list)) 273 275 g_plot(plot_str) ··· 281 283 g_plot('set ylabel "TSC Frequency (GHz)"') 282 284 g_plot('set title "{} : cpu TSC Frequencies (Sanity check calculation) : {:%F %H:%M}"'.format(testname, datetime.now())) 283 285 284 - title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).replace('\n', ' ') 286 + title_list = subprocess.check_output('ls cpu???.csv | sed -e \'s/.csv//\'',shell=True).decode('utf-8').replace('\n', ' ') 285 287 plot_str = "plot for [i in title_list] i.'.csv' using {:d}:{:d} pt 7 ps 1 title i".format(C_ELAPSED, C_GHZ) 286 288 g_plot('title_list = "{}"'.format(title_list)) 287 289 g_plot(plot_str)