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

Configure Feed

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

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

Pull power management fixes from Rafael Wysocki:
"Fixes for two recent regressions that may lead to degraded performance
(operating performance points framework, intel_pstate).

Specifics:

- Fix a recent regression in the intel_pstate driver that may lead to
degraded performance on some systems due to missing turbo state
entry in the table returned by the ACPI _PSS object (Srinivas
Pandruvada).

- Fix a recent regression in the OPP (operating performance points)
framework that may lead to degraded performance on some systems
where the OPP table is created too early (Viresh Kumar)"

* tag 'pm-4.7-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
PM / OPP: Add 'UNKNOWN' status for shared_opp in struct opp_table
cpufreq: intel_pstate: Adjust _PSS[0] freqeuency if needed

+26 -26
+9 -3
drivers/base/power/opp/cpu.c
··· 211 211 } 212 212 213 213 /* Mark opp-table as multiple CPUs are sharing it now */ 214 - opp_table->shared_opp = true; 214 + opp_table->shared_opp = OPP_TABLE_ACCESS_SHARED; 215 215 } 216 216 unlock: 217 217 mutex_unlock(&opp_table_lock); ··· 227 227 * 228 228 * This updates the @cpumask with CPUs that are sharing OPPs with @cpu_dev. 229 229 * 230 - * Returns -ENODEV if OPP table isn't already present. 230 + * Returns -ENODEV if OPP table isn't already present and -EINVAL if the OPP 231 + * table's status is access-unknown. 231 232 * 232 233 * Locking: The internal opp_table and opp structures are RCU protected. 233 234 * Hence this function internally uses RCU updater strategy with mutex locks ··· 250 249 goto unlock; 251 250 } 252 251 252 + if (opp_table->shared_opp == OPP_TABLE_ACCESS_UNKNOWN) { 253 + ret = -EINVAL; 254 + goto unlock; 255 + } 256 + 253 257 cpumask_clear(cpumask); 254 258 255 - if (opp_table->shared_opp) { 259 + if (opp_table->shared_opp == OPP_TABLE_ACCESS_SHARED) { 256 260 list_for_each_entry(opp_dev, &opp_table->dev_list, node) 257 261 cpumask_set_cpu(opp_dev->dev->id, cpumask); 258 262 } else {
+8 -2
drivers/base/power/opp/of.c
··· 34 34 * But the OPPs will be considered as shared only if the 35 35 * OPP table contains a "opp-shared" property. 36 36 */ 37 - return opp_table->shared_opp ? opp_table : NULL; 37 + if (opp_table->shared_opp == OPP_TABLE_ACCESS_SHARED) 38 + return opp_table; 39 + 40 + return NULL; 38 41 } 39 42 } 40 43 ··· 356 353 } 357 354 358 355 opp_table->np = opp_np; 359 - opp_table->shared_opp = of_property_read_bool(opp_np, "opp-shared"); 356 + if (of_property_read_bool(opp_np, "opp-shared")) 357 + opp_table->shared_opp = OPP_TABLE_ACCESS_SHARED; 358 + else 359 + opp_table->shared_opp = OPP_TABLE_ACCESS_EXCLUSIVE; 360 360 361 361 mutex_unlock(&opp_table_lock); 362 362
+7 -1
drivers/base/power/opp/opp.h
··· 119 119 #endif 120 120 }; 121 121 122 + enum opp_table_access { 123 + OPP_TABLE_ACCESS_UNKNOWN = 0, 124 + OPP_TABLE_ACCESS_EXCLUSIVE = 1, 125 + OPP_TABLE_ACCESS_SHARED = 2, 126 + }; 127 + 122 128 /** 123 129 * struct opp_table - Device opp structure 124 130 * @node: table node - contains the devices with OPPs that ··· 172 166 /* For backward compatibility with v1 bindings */ 173 167 unsigned int voltage_tolerance_v1; 174 168 175 - bool shared_opp; 169 + enum opp_table_access shared_opp; 176 170 struct dev_pm_opp *suspend_opp; 177 171 178 172 unsigned int *supported_hw;
+2 -20
drivers/cpufreq/intel_pstate.c
··· 372 372 return acpi_ppc; 373 373 } 374 374 375 - /* 376 - * The max target pstate ratio is a 8 bit value in both PLATFORM_INFO MSR and 377 - * in TURBO_RATIO_LIMIT MSR, which pstate driver stores in max_pstate and 378 - * max_turbo_pstate fields. The PERF_CTL MSR contains 16 bit value for P state 379 - * ratio, out of it only high 8 bits are used. For example 0x1700 is setting 380 - * target ratio 0x17. The _PSS control value stores in a format which can be 381 - * directly written to PERF_CTL MSR. But in intel_pstate driver this shift 382 - * occurs during write to PERF_CTL (E.g. for cores core_set_pstate()). 383 - * This function converts the _PSS control value to intel pstate driver format 384 - * for comparison and assignment. 385 - */ 386 - static int convert_to_native_pstate_format(struct cpudata *cpu, int index) 387 - { 388 - return cpu->acpi_perf_data.states[index].control >> 8; 389 - } 390 - 391 375 static void intel_pstate_init_acpi_perf_limits(struct cpufreq_policy *policy) 392 376 { 393 377 struct cpudata *cpu; 394 - int turbo_pss_ctl; 395 378 int ret; 396 379 int i; 397 380 ··· 424 441 * max frequency, which will cause a reduced performance as 425 442 * this driver uses real max turbo frequency as the max 426 443 * frequency. So correct this frequency in _PSS table to 427 - * correct max turbo frequency based on the turbo ratio. 444 + * correct max turbo frequency based on the turbo state. 428 445 * Also need to convert to MHz as _PSS freq is in MHz. 429 446 */ 430 - turbo_pss_ctl = convert_to_native_pstate_format(cpu, 0); 431 - if (turbo_pss_ctl > cpu->pstate.max_pstate) 447 + if (!limits->turbo_disabled) 432 448 cpu->acpi_perf_data.states[0].core_frequency = 433 449 policy->cpuinfo.max_freq / 1000; 434 450 cpu->valid_pss_table = true;