diff options
author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-12-30 09:58:21 -0500 |
---|---|---|
committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2016-12-31 15:48:44 -0500 |
commit | 111b8b3fe4fae35d4a85e9f524b077f5c4951e65 (patch) | |
tree | 52ea31f9e01001b99bcfed20fa659084373bd67f | |
parent | cad30467963267509d5b0d7d3c9bd1af3b91e720 (diff) |
cpufreq: intel_pstate: Always keep all limits settings in sync
Make intel_pstate update per-logical-CPU limits when the global
settings are changed to ensure that they are always in sync and
users will not see confusing values in per-logical-CPU sysfs
attributes.
This also fixes the problem that setting the "no_turbo" global
attribute to 1 in the "passive" mode (ie. when intel_pstate acts
as a regular cpufreq driver) when scaling_governor is set to
"performance" has no effect.
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
-rw-r--r-- | drivers/cpufreq/intel_pstate.c | 30 |
1 files changed, 14 insertions, 16 deletions
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index f8e514d7fbc4..e261438cd690 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
@@ -803,13 +803,13 @@ static struct freq_attr *hwp_cpufreq_attrs[] = { | |||
803 | NULL, | 803 | NULL, |
804 | }; | 804 | }; |
805 | 805 | ||
806 | static void intel_pstate_hwp_set(const struct cpumask *cpumask) | 806 | static void intel_pstate_hwp_set(struct cpufreq_policy *policy) |
807 | { | 807 | { |
808 | int min, hw_min, max, hw_max, cpu, range, adj_range; | 808 | int min, hw_min, max, hw_max, cpu, range, adj_range; |
809 | struct perf_limits *perf_limits = limits; | 809 | struct perf_limits *perf_limits = limits; |
810 | u64 value, cap; | 810 | u64 value, cap; |
811 | 811 | ||
812 | for_each_cpu(cpu, cpumask) { | 812 | for_each_cpu(cpu, policy->cpus) { |
813 | int max_perf_pct, min_perf_pct; | 813 | int max_perf_pct, min_perf_pct; |
814 | struct cpudata *cpu_data = all_cpu_data[cpu]; | 814 | struct cpudata *cpu_data = all_cpu_data[cpu]; |
815 | s16 epp; | 815 | s16 epp; |
@@ -895,7 +895,7 @@ skip_epp: | |||
895 | static int intel_pstate_hwp_set_policy(struct cpufreq_policy *policy) | 895 | static int intel_pstate_hwp_set_policy(struct cpufreq_policy *policy) |
896 | { | 896 | { |
897 | if (hwp_active) | 897 | if (hwp_active) |
898 | intel_pstate_hwp_set(policy->cpus); | 898 | intel_pstate_hwp_set(policy); |
899 | 899 | ||
900 | return 0; | 900 | return 0; |
901 | } | 901 | } |
@@ -930,11 +930,12 @@ static int intel_pstate_resume(struct cpufreq_policy *policy) | |||
930 | return ret; | 930 | return ret; |
931 | } | 931 | } |
932 | 932 | ||
933 | static void intel_pstate_hwp_set_online_cpus(void) | 933 | static void intel_pstate_update_policies(void) |
934 | { | 934 | { |
935 | get_online_cpus(); | 935 | int cpu; |
936 | intel_pstate_hwp_set(cpu_online_mask); | 936 | |
937 | put_online_cpus(); | 937 | for_each_possible_cpu(cpu) |
938 | cpufreq_update_policy(cpu); | ||
938 | } | 939 | } |
939 | 940 | ||
940 | /************************** debugfs begin ************************/ | 941 | /************************** debugfs begin ************************/ |
@@ -1055,11 +1056,10 @@ static ssize_t store_no_turbo(struct kobject *a, struct attribute *b, | |||
1055 | 1056 | ||
1056 | limits->no_turbo = clamp_t(int, input, 0, 1); | 1057 | limits->no_turbo = clamp_t(int, input, 0, 1); |
1057 | 1058 | ||
1058 | if (hwp_active) | ||
1059 | intel_pstate_hwp_set_online_cpus(); | ||
1060 | |||
1061 | mutex_unlock(&intel_pstate_limits_lock); | 1059 | mutex_unlock(&intel_pstate_limits_lock); |
1062 | 1060 | ||
1061 | intel_pstate_update_policies(); | ||
1062 | |||
1063 | return count; | 1063 | return count; |
1064 | } | 1064 | } |
1065 | 1065 | ||
@@ -1084,11 +1084,10 @@ static ssize_t store_max_perf_pct(struct kobject *a, struct attribute *b, | |||
1084 | limits->max_perf_pct); | 1084 | limits->max_perf_pct); |
1085 | limits->max_perf = div_ext_fp(limits->max_perf_pct, 100); | 1085 | limits->max_perf = div_ext_fp(limits->max_perf_pct, 100); |
1086 | 1086 | ||
1087 | if (hwp_active) | ||
1088 | intel_pstate_hwp_set_online_cpus(); | ||
1089 | |||
1090 | mutex_unlock(&intel_pstate_limits_lock); | 1087 | mutex_unlock(&intel_pstate_limits_lock); |
1091 | 1088 | ||
1089 | intel_pstate_update_policies(); | ||
1090 | |||
1092 | return count; | 1091 | return count; |
1093 | } | 1092 | } |
1094 | 1093 | ||
@@ -1113,11 +1112,10 @@ static ssize_t store_min_perf_pct(struct kobject *a, struct attribute *b, | |||
1113 | limits->min_perf_pct); | 1112 | limits->min_perf_pct); |
1114 | limits->min_perf = div_ext_fp(limits->min_perf_pct, 100); | 1113 | limits->min_perf = div_ext_fp(limits->min_perf_pct, 100); |
1115 | 1114 | ||
1116 | if (hwp_active) | ||
1117 | intel_pstate_hwp_set_online_cpus(); | ||
1118 | |||
1119 | mutex_unlock(&intel_pstate_limits_lock); | 1115 | mutex_unlock(&intel_pstate_limits_lock); |
1120 | 1116 | ||
1117 | intel_pstate_update_policies(); | ||
1118 | |||
1121 | return count; | 1119 | return count; |
1122 | } | 1120 | } |
1123 | 1121 | ||