diff options
Diffstat (limited to 'drivers/cpufreq/intel_pstate.c')
-rw-r--r-- | drivers/cpufreq/intel_pstate.c | 105 |
1 files changed, 56 insertions, 49 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index dd66decf2087..002f5169d4eb 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c @@ -50,6 +50,8 @@ #define int_tofp(X) ((int64_t)(X) << FRAC_BITS) #define fp_toint(X) ((X) >> FRAC_BITS) +#define ONE_EIGHTH_FP ((int64_t)1 << (FRAC_BITS - 3)) + #define EXT_BITS 6 #define EXT_FRAC_BITS (EXT_BITS + FRAC_BITS) #define fp_ext_toint(X) ((X) >> EXT_FRAC_BITS) @@ -895,7 +897,7 @@ static void intel_pstate_update_policies(void) /************************** sysfs begin ************************/ #define show_one(file_name, object) \ static ssize_t show_##file_name \ - (struct kobject *kobj, struct attribute *attr, char *buf) \ + (struct kobject *kobj, struct kobj_attribute *attr, char *buf) \ { \ return sprintf(buf, "%u\n", global.object); \ } @@ -904,7 +906,7 @@ static ssize_t intel_pstate_show_status(char *buf); static int intel_pstate_update_status(const char *buf, size_t size); static ssize_t show_status(struct kobject *kobj, - struct attribute *attr, char *buf) + struct kobj_attribute *attr, char *buf) { ssize_t ret; @@ -915,7 +917,7 @@ static ssize_t show_status(struct kobject *kobj, return ret; } -static ssize_t store_status(struct kobject *a, struct attribute *b, +static ssize_t store_status(struct kobject *a, struct kobj_attribute *b, const char *buf, size_t count) { char *p = memchr(buf, '\n', count); @@ -929,7 +931,7 @@ static ssize_t store_status(struct kobject *a, struct attribute *b, } static ssize_t show_turbo_pct(struct kobject *kobj, - struct attribute *attr, char *buf) + struct kobj_attribute *attr, char *buf) { struct cpudata *cpu; int total, no_turbo, turbo_pct; @@ -955,7 +957,7 @@ static ssize_t show_turbo_pct(struct kobject *kobj, } static ssize_t show_num_pstates(struct kobject *kobj, - struct attribute *attr, char *buf) + struct kobj_attribute *attr, char *buf) { struct cpudata *cpu; int total; @@ -976,7 +978,7 @@ static ssize_t show_num_pstates(struct kobject *kobj, } static ssize_t show_no_turbo(struct kobject *kobj, - struct attribute *attr, char *buf) + struct kobj_attribute *attr, char *buf) { ssize_t ret; @@ -998,7 +1000,7 @@ static ssize_t show_no_turbo(struct kobject *kobj, return ret; } -static ssize_t store_no_turbo(struct kobject *a, struct attribute *b, +static ssize_t store_no_turbo(struct kobject *a, struct kobj_attribute *b, const char *buf, size_t count) { unsigned int input; @@ -1045,7 +1047,7 @@ static ssize_t store_no_turbo(struct kobject *a, struct attribute *b, return count; } -static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b, +static ssize_t store_max_perf_pct(struct kobject *a, struct kobj_attribute *b, const char *buf, size_t count) { unsigned int input; @@ -1075,7 +1077,7 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b, return count; } -static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b, +static ssize_t store_min_perf_pct(struct kobject *a, struct kobj_attribute *b, const char *buf, size_t count) { unsigned int input; @@ -1107,12 +1109,13 @@ static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b, } static ssize_t show_hwp_dynamic_boost(struct kobject *kobj, - struct attribute *attr, char *buf) + struct kobj_attribute *attr, char *buf) { return sprintf(buf, "%u\n", hwp_boost); } -static ssize_t store_hwp_dynamic_boost(struct kobject *a, struct attribute *b, +static ssize_t store_hwp_dynamic_boost(struct kobject *a, + struct kobj_attribute *b, const char *buf, size_t count) { unsigned int input; @@ -1444,12 +1447,6 @@ static int knl_get_turbo_pstate(void) return ret; } -static int intel_pstate_get_base_pstate(struct cpudata *cpu) -{ - return global.no_turbo || global.turbo_disabled ? - cpu->pstate.max_pstate : cpu->pstate.turbo_pstate; -} - static void intel_pstate_set_pstate(struct cpudata *cpu, int pstate) { trace_cpu_frequency(pstate * cpu->pstate.scaling, cpu->cpu); @@ -1470,11 +1467,9 @@ static void intel_pstate_set_min_pstate(struct cpudata *cpu) static void intel_pstate_max_within_limits(struct cpudata *cpu) { - int pstate; + int pstate = max(cpu->pstate.min_pstate, cpu->max_perf_ratio); update_turbo_state(); - pstate = intel_pstate_get_base_pstate(cpu); - pstate = max(cpu->pstate.min_pstate, cpu->max_perf_ratio); intel_pstate_set_pstate(cpu, pstate); } @@ -1678,17 +1673,14 @@ static inline int32_t get_avg_pstate(struct cpudata *cpu) static inline int32_t get_target_pstate(struct cpudata *cpu) { struct sample *sample = &cpu->sample; - int32_t busy_frac, boost; + int32_t busy_frac; int target, avg_pstate; busy_frac = div_fp(sample->mperf << cpu->aperf_mperf_shift, sample->tsc); - boost = cpu->iowait_boost; - cpu->iowait_boost >>= 1; - - if (busy_frac < boost) - busy_frac = boost; + if (busy_frac < cpu->iowait_boost) + busy_frac = cpu->iowait_boost; sample->busy_scaled = busy_frac * 100; @@ -1715,11 +1707,9 @@ static inline int32_t get_target_pstate(struct cpudata *cpu) static int intel_pstate_prepare_request(struct cpudata *cpu, int pstate) { - int max_pstate = intel_pstate_get_base_pstate(cpu); - int min_pstate; + int min_pstate = max(cpu->pstate.min_pstate, cpu->min_perf_ratio); + int max_pstate = max(min_pstate, cpu->max_perf_ratio); - min_pstate = max(cpu->pstate.min_pstate, cpu->min_perf_ratio); - max_pstate = max(min_pstate, cpu->max_perf_ratio); return clamp_t(int, pstate, min_pstate, max_pstate); } @@ -1767,29 +1757,30 @@ static void intel_pstate_update_util(struct update_util_data *data, u64 time, if (smp_processor_id() != cpu->cpu) return; + delta_ns = time - cpu->last_update; if (flags & SCHED_CPUFREQ_IOWAIT) { - cpu->iowait_boost = int_tofp(1); - cpu->last_update = time; - /* - * The last time the busy was 100% so P-state was max anyway - * so avoid overhead of computation. - */ - if (fp_toint(cpu->sample.busy_scaled) == 100) - return; - - goto set_pstate; + /* Start over if the CPU may have been idle. */ + if (delta_ns > TICK_NSEC) { + cpu->iowait_boost = ONE_EIGHTH_FP; + } else if (cpu->iowait_boost) { + cpu->iowait_boost <<= 1; + if (cpu->iowait_boost > int_tofp(1)) + cpu->iowait_boost = int_tofp(1); + } else { + cpu->iowait_boost = ONE_EIGHTH_FP; + } } else if (cpu->iowait_boost) { /* Clear iowait_boost if the CPU may have been idle. */ - delta_ns = time - cpu->last_update; if (delta_ns > TICK_NSEC) cpu->iowait_boost = 0; + else + cpu->iowait_boost >>= 1; } cpu->last_update = time; delta_ns = time - cpu->sample.time; if ((s64)delta_ns < INTEL_PSTATE_SAMPLING_INTERVAL) return; -set_pstate: if (intel_pstate_sample(cpu, time)) intel_pstate_adjust_pstate(cpu); } @@ -1976,7 +1967,8 @@ static void intel_pstate_update_perf_limits(struct cpufreq_policy *policy, if (hwp_active) { intel_pstate_get_hwp_max(cpu->cpu, &turbo_max, &max_state); } else { - max_state = intel_pstate_get_base_pstate(cpu); + max_state = global.no_turbo || global.turbo_disabled ? + cpu->pstate.max_pstate : cpu->pstate.turbo_pstate; turbo_max = cpu->pstate.turbo_pstate; } @@ -2475,6 +2467,7 @@ static bool __init intel_pstate_no_acpi_pss(void) kfree(pss); } + pr_debug("ACPI _PSS not found\n"); return true; } @@ -2485,9 +2478,14 @@ static bool __init intel_pstate_no_acpi_pcch(void) status = acpi_get_handle(NULL, "\\_SB", &handle); if (ACPI_FAILURE(status)) - return true; + goto not_found; + + if (acpi_has_method(handle, "PCCH")) + return false; - return !acpi_has_method(handle, "PCCH"); +not_found: + pr_debug("ACPI PCCH not found\n"); + return true; } static bool __init intel_pstate_has_acpi_ppc(void) @@ -2502,6 +2500,7 @@ static bool __init intel_pstate_has_acpi_ppc(void) if (acpi_has_method(pr->handle, "_PPC")) return true; } + pr_debug("ACPI _PPC not found\n"); return false; } @@ -2539,8 +2538,10 @@ static bool __init intel_pstate_platform_pwr_mgmt_exists(void) id = x86_match_cpu(intel_pstate_cpu_oob_ids); if (id) { rdmsrl(MSR_MISC_PWR_MGMT, misc_pwr); - if ( misc_pwr & (1 << 8)) + if (misc_pwr & (1 << 8)) { + pr_debug("Bit 8 in the MISC_PWR_MGMT MSR set\n"); return true; + } } idx = acpi_match_platform_list(plat_info); @@ -2606,22 +2607,28 @@ static int __init intel_pstate_init(void) } } else { id = x86_match_cpu(intel_pstate_cpu_ids); - if (!id) + if (!id) { + pr_info("CPU ID not supported\n"); return -ENODEV; + } copy_cpu_funcs((struct pstate_funcs *)id->driver_data); } - if (intel_pstate_msrs_not_valid()) + if (intel_pstate_msrs_not_valid()) { + pr_info("Invalid MSRs\n"); return -ENODEV; + } hwp_cpu_matched: /* * The Intel pstate driver will be ignored if the platform * firmware has its own power management modes. */ - if (intel_pstate_platform_pwr_mgmt_exists()) + if (intel_pstate_platform_pwr_mgmt_exists()) { + pr_info("P-states controlled by the platform\n"); return -ENODEV; + } if (!hwp_active && hwp_only) return -ENOTSUPP; |