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-6.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm

Pull power management fixes from Rafael Wysocki:
"These fix a cpuidle menu governor issue and two issues in the cpupower
utility:

- Prevent the menu cpuidle governor from selecting idle states with
exit latency exceeding the current PM QoS limit after stopping the
scheduler tick (Rafael Wysocki)

- Make the set subcommand's -t option in the cpupower utility work as
documented and allow it to control the CPU boost feature of cpufreq
beyond x86 (Shinji Nomoto)"

* tag 'pm-6.17-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
cpuidle: governors: menu: Avoid selecting states with too much latency
cpupower: Allow control of boost feature on non-x86 based systems with boost support.
cpupower: Fix a bug where the -t option of the set subcommand was not working.

+95 -52
+12 -17
drivers/cpuidle/governors/menu.c
··· 287 287 return 0; 288 288 } 289 289 290 - if (tick_nohz_tick_stopped()) { 291 - /* 292 - * If the tick is already stopped, the cost of possible short 293 - * idle duration misprediction is much higher, because the CPU 294 - * may be stuck in a shallow idle state for a long time as a 295 - * result of it. In that case say we might mispredict and use 296 - * the known time till the closest timer event for the idle 297 - * state selection. 298 - */ 299 - if (predicted_ns < TICK_NSEC) 300 - predicted_ns = data->next_timer_ns; 301 - } else if (latency_req > predicted_ns) { 302 - latency_req = predicted_ns; 303 - } 290 + /* 291 + * If the tick is already stopped, the cost of possible short idle 292 + * duration misprediction is much higher, because the CPU may be stuck 293 + * in a shallow idle state for a long time as a result of it. In that 294 + * case, say we might mispredict and use the known time till the closest 295 + * timer event for the idle state selection. 296 + */ 297 + if (tick_nohz_tick_stopped() && predicted_ns < TICK_NSEC) 298 + predicted_ns = data->next_timer_ns; 304 299 305 300 /* 306 301 * Find the idle state with the lowest power while satisfying ··· 311 316 if (idx == -1) 312 317 idx = i; /* first enabled state */ 313 318 319 + if (s->exit_latency_ns > latency_req) 320 + break; 321 + 314 322 if (s->target_residency_ns > predicted_ns) { 315 323 /* 316 324 * Use a physical idle state, not busy polling, unless 317 325 * a timer is going to trigger soon enough. 318 326 */ 319 327 if ((drv->states[idx].flags & CPUIDLE_FLAG_POLLING) && 320 - s->exit_latency_ns <= latency_req && 321 328 s->target_residency_ns <= data->next_timer_ns) { 322 329 predicted_ns = s->target_residency_ns; 323 330 idx = i; ··· 351 354 352 355 return idx; 353 356 } 354 - if (s->exit_latency_ns > latency_req) 355 - break; 356 357 357 358 idx = i; 358 359 }
+4 -3
tools/power/cpupower/man/cpupower-set.1
··· 81 81 .RE 82 82 83 83 .PP 84 - \-\-turbo\-boost, \-t 84 + \-\-turbo\-boost, \-\-boost, \-t 85 85 .RS 4 86 - This option is used to enable or disable the turbo boost feature on 87 - supported Intel and AMD processors. 86 + This option is used to enable or disable the boost feature on 87 + supported Intel and AMD processors, and other boost supported systems. 88 + (The --boost option is an alias for the --turbo-boost option) 88 89 89 90 This option takes as parameter either \fB1\fP to enable, or \fB0\fP to disable the feature. 90 91
+15 -1
tools/power/cpupower/utils/cpufreq-info.c
··· 128 128 /* ToDo: Make this more global */ 129 129 unsigned long pstates[MAX_HW_PSTATES] = {0,}; 130 130 131 - ret = cpufreq_has_boost_support(cpu, &support, &active, &b_states); 131 + ret = cpufreq_has_x86_boost_support(cpu, &support, &active, &b_states); 132 132 if (ret) { 133 133 printf(_("Error while evaluating Boost Capabilities" 134 134 " on CPU %d -- are you root?\n"), cpu); ··· 204 204 return 0; 205 205 } 206 206 207 + static int get_boost_mode_generic(unsigned int cpu) 208 + { 209 + bool active; 210 + 211 + if (!cpufreq_has_generic_boost_support(&active)) { 212 + printf(_(" boost state support:\n")); 213 + printf(_(" Active: %s\n"), active ? _("yes") : _("no")); 214 + } 215 + 216 + return 0; 217 + } 218 + 207 219 /* --boost / -b */ 208 220 209 221 static int get_boost_mode(unsigned int cpu) ··· 226 214 cpupower_cpu_info.vendor == X86_VENDOR_HYGON || 227 215 cpupower_cpu_info.vendor == X86_VENDOR_INTEL) 228 216 return get_boost_mode_x86(cpu); 217 + else 218 + get_boost_mode_generic(cpu); 229 219 230 220 freqs = cpufreq_get_boost_frequencies(cpu); 231 221 if (freqs) {
+3 -2
tools/power/cpupower/utils/cpupower-set.c
··· 21 21 {"epp", required_argument, NULL, 'e'}, 22 22 {"amd-pstate-mode", required_argument, NULL, 'm'}, 23 23 {"turbo-boost", required_argument, NULL, 't'}, 24 + {"boost", required_argument, NULL, 't'}, 24 25 { }, 25 26 }; 26 27 ··· 63 62 64 63 params.params = 0; 65 64 /* parameter parsing */ 66 - while ((ret = getopt_long(argc, argv, "b:e:m:", 67 - set_opts, NULL)) != -1) { 65 + while ((ret = getopt_long(argc, argv, "b:e:m:t:", 66 + set_opts, NULL)) != -1) { 68 67 switch (ret) { 69 68 case 'b': 70 69 if (params.perf_bias)
+7 -7
tools/power/cpupower/utils/helpers/helpers.h
··· 103 103 104 104 /* cpuid and cpuinfo helpers **************************/ 105 105 106 + int cpufreq_has_generic_boost_support(bool *active); 107 + int cpupower_set_turbo_boost(int turbo_boost); 108 + 106 109 /* X86 ONLY ****************************************/ 107 110 #if defined(__i386__) || defined(__x86_64__) 108 111 ··· 121 118 122 119 extern int cpupower_set_epp(unsigned int cpu, char *epp); 123 120 extern int cpupower_set_amd_pstate_mode(char *mode); 124 - extern int cpupower_set_turbo_boost(int turbo_boost); 125 121 126 122 /* Read/Write msr ****************************/ 127 123 ··· 141 139 142 140 /* AMD HW pstate decoding **************************/ 143 141 144 - extern int cpufreq_has_boost_support(unsigned int cpu, int *support, 145 - int *active, int * states); 142 + int cpufreq_has_x86_boost_support(unsigned int cpu, int *support, 143 + int *active, int *states); 146 144 147 145 /* AMD P-State stuff **************************/ 148 146 bool cpupower_amd_pstate_enabled(void); ··· 183 181 { return -1; }; 184 182 static inline int cpupower_set_amd_pstate_mode(char *mode) 185 183 { return -1; }; 186 - static inline int cpupower_set_turbo_boost(int turbo_boost) 187 - { return -1; }; 188 184 189 185 /* Read/Write msr ****************************/ 190 186 191 - static inline int cpufreq_has_boost_support(unsigned int cpu, int *support, 192 - int *active, int * states) 187 + static inline int cpufreq_has_x86_boost_support(unsigned int cpu, int *support, 188 + int *active, int *states) 193 189 { return -1; } 194 190 195 191 static inline bool cpupower_amd_pstate_enabled(void)
+54 -22
tools/power/cpupower/utils/helpers/misc.c
··· 8 8 #include "helpers/helpers.h" 9 9 #include "helpers/sysfs.h" 10 10 #include "cpufreq.h" 11 + #include "cpupower_intern.h" 11 12 12 13 #if defined(__i386__) || defined(__x86_64__) 13 14 14 - #include "cpupower_intern.h" 15 - 16 15 #define MSR_AMD_HWCR 0xc0010015 17 16 18 - int cpufreq_has_boost_support(unsigned int cpu, int *support, int *active, 19 - int *states) 17 + int cpufreq_has_x86_boost_support(unsigned int cpu, int *support, int *active, 18 + int *states) 20 19 { 21 20 int ret; 22 21 unsigned long long val; ··· 123 124 return 0; 124 125 } 125 126 126 - int cpupower_set_turbo_boost(int turbo_boost) 127 - { 128 - char path[SYSFS_PATH_MAX]; 129 - char linebuf[2] = {}; 130 - 131 - snprintf(path, sizeof(path), PATH_TO_CPU "cpufreq/boost"); 132 - 133 - if (!is_valid_path(path)) 134 - return -1; 135 - 136 - snprintf(linebuf, sizeof(linebuf), "%d", turbo_boost); 137 - 138 - if (cpupower_write_sysfs(path, linebuf, 2) <= 0) 139 - return -1; 140 - 141 - return 0; 142 - } 143 - 144 127 bool cpupower_amd_pstate_enabled(void) 145 128 { 146 129 char *driver = cpufreq_get_driver(0); ··· 140 159 } 141 160 142 161 #endif /* #if defined(__i386__) || defined(__x86_64__) */ 162 + 163 + int cpufreq_has_generic_boost_support(bool *active) 164 + { 165 + char path[SYSFS_PATH_MAX]; 166 + char linebuf[2] = {}; 167 + unsigned long val; 168 + char *endp; 169 + 170 + snprintf(path, sizeof(path), PATH_TO_CPU "cpufreq/boost"); 171 + 172 + if (!is_valid_path(path)) 173 + return -EACCES; 174 + 175 + if (cpupower_read_sysfs(path, linebuf, 2) <= 0) 176 + return -EINVAL; 177 + 178 + val = strtoul(linebuf, &endp, 0); 179 + if (endp == linebuf || errno == ERANGE) 180 + return -EINVAL; 181 + 182 + switch (val) { 183 + case 0: 184 + *active = false; 185 + break; 186 + case 1: 187 + *active = true; 188 + break; 189 + default: 190 + return -EINVAL; 191 + } 192 + 193 + return 0; 194 + } 143 195 144 196 /* get_cpustate 145 197 * ··· 272 258 ((unsigned int)(speed % 1000) / 100)); 273 259 } 274 260 } 261 + } 262 + 263 + int cpupower_set_turbo_boost(int turbo_boost) 264 + { 265 + char path[SYSFS_PATH_MAX]; 266 + char linebuf[2] = {}; 267 + 268 + snprintf(path, sizeof(path), PATH_TO_CPU "cpufreq/boost"); 269 + 270 + if (!is_valid_path(path)) 271 + return -1; 272 + 273 + snprintf(linebuf, sizeof(linebuf), "%d", turbo_boost); 274 + 275 + if (cpupower_write_sysfs(path, linebuf, 2) <= 0) 276 + return -1; 277 + 278 + return 0; 275 279 }