diff options
| author | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2017-09-03 18:05:22 -0400 |
|---|---|---|
| committer | Rafael J. Wysocki <rafael.j.wysocki@intel.com> | 2017-09-03 18:05:22 -0400 |
| commit | 08a10002bed151f6df201715adb80c1c5e7fe7ca (patch) | |
| tree | a9d53ec2b6f5b1921a614f2d4bd70fb6c3a0d42f | |
| parent | bd87c8fb9d2e420e5ddffad0cd1abcadfca75dbd (diff) | |
| parent | c49cbc19b31e069cb344921c7286d7549767d10e (diff) | |
Merge branch 'pm-cpufreq-sched'
* pm-cpufreq-sched:
cpufreq: schedutil: Always process remote callback with slow switching
cpufreq: schedutil: Don't restrict kthread to related_cpus unnecessarily
cpufreq: Return 0 from ->fast_switch() on errors
cpufreq: Simplify cpufreq_can_do_remote_dvfs()
cpufreq: Process remote callbacks from any CPU if the platform permits
sched: cpufreq: Allow remote cpufreq callbacks
cpufreq: schedutil: Use unsigned int for iowait boost
cpufreq: schedutil: Make iowait boost more energy efficient
| -rw-r--r-- | drivers/cpufreq/cpufreq-dt.c | 1 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq.c | 7 | ||||
| -rw-r--r-- | drivers/cpufreq/cpufreq_governor.c | 3 | ||||
| -rw-r--r-- | drivers/cpufreq/intel_pstate.c | 8 | ||||
| -rw-r--r-- | include/linux/cpufreq.h | 20 | ||||
| -rw-r--r-- | kernel/sched/cpufreq_schedutil.c | 86 | ||||
| -rw-r--r-- | kernel/sched/deadline.c | 2 | ||||
| -rw-r--r-- | kernel/sched/fair.c | 8 | ||||
| -rw-r--r-- | kernel/sched/rt.c | 2 | ||||
| -rw-r--r-- | kernel/sched/sched.h | 10 |
10 files changed, 116 insertions, 31 deletions
diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index fef3c2160691..d83ab94d041a 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c | |||
| @@ -274,6 +274,7 @@ static int cpufreq_init(struct cpufreq_policy *policy) | |||
| 274 | transition_latency = CPUFREQ_ETERNAL; | 274 | transition_latency = CPUFREQ_ETERNAL; |
| 275 | 275 | ||
| 276 | policy->cpuinfo.transition_latency = transition_latency; | 276 | policy->cpuinfo.transition_latency = transition_latency; |
| 277 | policy->dvfs_possible_from_any_cpu = true; | ||
| 277 | 278 | ||
| 278 | return 0; | 279 | return 0; |
| 279 | 280 | ||
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index c7ae67d6886d..ea43b147a7fe 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
| @@ -1843,9 +1843,10 @@ EXPORT_SYMBOL(cpufreq_unregister_notifier); | |||
| 1843 | * twice in parallel for the same policy and that it will never be called in | 1843 | * twice in parallel for the same policy and that it will never be called in |
| 1844 | * parallel with either ->target() or ->target_index() for the same policy. | 1844 | * parallel with either ->target() or ->target_index() for the same policy. |
| 1845 | * | 1845 | * |
| 1846 | * If CPUFREQ_ENTRY_INVALID is returned by the driver's ->fast_switch() | 1846 | * Returns the actual frequency set for the CPU. |
| 1847 | * callback to indicate an error condition, the hardware configuration must be | 1847 | * |
| 1848 | * preserved. | 1848 | * If 0 is returned by the driver's ->fast_switch() callback to indicate an |
| 1849 | * error condition, the hardware configuration must be preserved. | ||
| 1849 | */ | 1850 | */ |
| 1850 | unsigned int cpufreq_driver_fast_switch(struct cpufreq_policy *policy, | 1851 | unsigned int cpufreq_driver_fast_switch(struct cpufreq_policy *policy, |
| 1851 | unsigned int target_freq) | 1852 | unsigned int target_freq) |
diff --git a/drivers/cpufreq/cpufreq_governor.c b/drivers/cpufreq/cpufreq_governor.c index eed069ecfd5e..58d4f4e1ad6a 100644 --- a/drivers/cpufreq/cpufreq_governor.c +++ b/drivers/cpufreq/cpufreq_governor.c | |||
| @@ -272,6 +272,9 @@ static void dbs_update_util_handler(struct update_util_data *data, u64 time, | |||
| 272 | struct policy_dbs_info *policy_dbs = cdbs->policy_dbs; | 272 | struct policy_dbs_info *policy_dbs = cdbs->policy_dbs; |
| 273 | u64 delta_ns, lst; | 273 | u64 delta_ns, lst; |
| 274 | 274 | ||
| 275 | if (!cpufreq_can_do_remote_dvfs(policy_dbs->policy)) | ||
| 276 | return; | ||
| 277 | |||
| 275 | /* | 278 | /* |
| 276 | * The work may not be allowed to be queued up right now. | 279 | * The work may not be allowed to be queued up right now. |
| 277 | * Possible reasons: | 280 | * Possible reasons: |
diff --git a/drivers/cpufreq/intel_pstate.c b/drivers/cpufreq/intel_pstate.c index 04dd5f46803d..0c50637e6bda 100644 --- a/drivers/cpufreq/intel_pstate.c +++ b/drivers/cpufreq/intel_pstate.c | |||
| @@ -1746,6 +1746,10 @@ static void intel_pstate_update_util_pid(struct update_util_data *data, | |||
| 1746 | struct cpudata *cpu = container_of(data, struct cpudata, update_util); | 1746 | struct cpudata *cpu = container_of(data, struct cpudata, update_util); |
| 1747 | u64 delta_ns = time - cpu->sample.time; | 1747 | u64 delta_ns = time - cpu->sample.time; |
| 1748 | 1748 | ||
| 1749 | /* Don't allow remote callbacks */ | ||
| 1750 | if (smp_processor_id() != cpu->cpu) | ||
| 1751 | return; | ||
| 1752 | |||
| 1749 | if ((s64)delta_ns < pid_params.sample_rate_ns) | 1753 | if ((s64)delta_ns < pid_params.sample_rate_ns) |
| 1750 | return; | 1754 | return; |
| 1751 | 1755 | ||
| @@ -1763,6 +1767,10 @@ static void intel_pstate_update_util(struct update_util_data *data, u64 time, | |||
| 1763 | struct cpudata *cpu = container_of(data, struct cpudata, update_util); | 1767 | struct cpudata *cpu = container_of(data, struct cpudata, update_util); |
| 1764 | u64 delta_ns; | 1768 | u64 delta_ns; |
| 1765 | 1769 | ||
| 1770 | /* Don't allow remote callbacks */ | ||
| 1771 | if (smp_processor_id() != cpu->cpu) | ||
| 1772 | return; | ||
| 1773 | |||
| 1766 | if (flags & SCHED_CPUFREQ_IOWAIT) { | 1774 | if (flags & SCHED_CPUFREQ_IOWAIT) { |
| 1767 | cpu->iowait_boost = int_tofp(1); | 1775 | cpu->iowait_boost = int_tofp(1); |
| 1768 | } else if (cpu->iowait_boost) { | 1776 | } else if (cpu->iowait_boost) { |
diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 5f40522ec98c..537ff842ff73 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h | |||
| @@ -127,6 +127,15 @@ struct cpufreq_policy { | |||
| 127 | */ | 127 | */ |
| 128 | unsigned int transition_delay_us; | 128 | unsigned int transition_delay_us; |
| 129 | 129 | ||
| 130 | /* | ||
| 131 | * Remote DVFS flag (Not added to the driver structure as we don't want | ||
| 132 | * to access another structure from scheduler hotpath). | ||
| 133 | * | ||
| 134 | * Should be set if CPUs can do DVFS on behalf of other CPUs from | ||
| 135 | * different cpufreq policies. | ||
| 136 | */ | ||
| 137 | bool dvfs_possible_from_any_cpu; | ||
| 138 | |||
| 130 | /* Cached frequency lookup from cpufreq_driver_resolve_freq. */ | 139 | /* Cached frequency lookup from cpufreq_driver_resolve_freq. */ |
| 131 | unsigned int cached_target_freq; | 140 | unsigned int cached_target_freq; |
| 132 | int cached_resolved_idx; | 141 | int cached_resolved_idx; |
| @@ -562,6 +571,17 @@ struct governor_attr { | |||
| 562 | size_t count); | 571 | size_t count); |
| 563 | }; | 572 | }; |
| 564 | 573 | ||
| 574 | static inline bool cpufreq_can_do_remote_dvfs(struct cpufreq_policy *policy) | ||
| 575 | { | ||
| 576 | /* | ||
| 577 | * Allow remote callbacks if: | ||
| 578 | * - dvfs_possible_from_any_cpu flag is set | ||
| 579 | * - the local and remote CPUs share cpufreq policy | ||
| 580 | */ | ||
| 581 | return policy->dvfs_possible_from_any_cpu || | ||
| 582 | cpumask_test_cpu(smp_processor_id(), policy->cpus); | ||
| 583 | } | ||
| 584 | |||
| 565 | /********************************************************************* | 585 | /********************************************************************* |
| 566 | * FREQUENCY TABLE HELPERS * | 586 | * FREQUENCY TABLE HELPERS * |
| 567 | *********************************************************************/ | 587 | *********************************************************************/ |
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c index 45fcf21ad685..9209d83ecdcf 100644 --- a/kernel/sched/cpufreq_schedutil.c +++ b/kernel/sched/cpufreq_schedutil.c | |||
| @@ -52,9 +52,11 @@ struct sugov_policy { | |||
| 52 | struct sugov_cpu { | 52 | struct sugov_cpu { |
| 53 | struct update_util_data update_util; | 53 | struct update_util_data update_util; |
| 54 | struct sugov_policy *sg_policy; | 54 | struct sugov_policy *sg_policy; |
| 55 | unsigned int cpu; | ||
| 55 | 56 | ||
| 56 | unsigned long iowait_boost; | 57 | bool iowait_boost_pending; |
| 57 | unsigned long iowait_boost_max; | 58 | unsigned int iowait_boost; |
| 59 | unsigned int iowait_boost_max; | ||
| 58 | u64 last_update; | 60 | u64 last_update; |
| 59 | 61 | ||
| 60 | /* The fields below are only needed when sharing a policy. */ | 62 | /* The fields below are only needed when sharing a policy. */ |
| @@ -76,6 +78,26 @@ static bool sugov_should_update_freq(struct sugov_policy *sg_policy, u64 time) | |||
| 76 | { | 78 | { |
| 77 | s64 delta_ns; | 79 | s64 delta_ns; |
| 78 | 80 | ||
| 81 | /* | ||
| 82 | * Since cpufreq_update_util() is called with rq->lock held for | ||
| 83 | * the @target_cpu, our per-cpu data is fully serialized. | ||
| 84 | * | ||
| 85 | * However, drivers cannot in general deal with cross-cpu | ||
| 86 | * requests, so while get_next_freq() will work, our | ||
| 87 | * sugov_update_commit() call may not for the fast switching platforms. | ||
| 88 | * | ||
| 89 | * Hence stop here for remote requests if they aren't supported | ||
| 90 | * by the hardware, as calculating the frequency is pointless if | ||
| 91 | * we cannot in fact act on it. | ||
| 92 | * | ||
| 93 | * For the slow switching platforms, the kthread is always scheduled on | ||
| 94 | * the right set of CPUs and any CPU can find the next frequency and | ||
| 95 | * schedule the kthread. | ||
| 96 | */ | ||
| 97 | if (sg_policy->policy->fast_switch_enabled && | ||
| 98 | !cpufreq_can_do_remote_dvfs(sg_policy->policy)) | ||
| 99 | return false; | ||
| 100 | |||
| 79 | if (sg_policy->work_in_progress) | 101 | if (sg_policy->work_in_progress) |
| 80 | return false; | 102 | return false; |
| 81 | 103 | ||
| @@ -106,7 +128,7 @@ static void sugov_update_commit(struct sugov_policy *sg_policy, u64 time, | |||
| 106 | 128 | ||
| 107 | if (policy->fast_switch_enabled) { | 129 | if (policy->fast_switch_enabled) { |
| 108 | next_freq = cpufreq_driver_fast_switch(policy, next_freq); | 130 | next_freq = cpufreq_driver_fast_switch(policy, next_freq); |
| 109 | if (next_freq == CPUFREQ_ENTRY_INVALID) | 131 | if (!next_freq) |
| 110 | return; | 132 | return; |
| 111 | 133 | ||
| 112 | policy->cur = next_freq; | 134 | policy->cur = next_freq; |
| @@ -154,12 +176,12 @@ static unsigned int get_next_freq(struct sugov_policy *sg_policy, | |||
| 154 | return cpufreq_driver_resolve_freq(policy, freq); | 176 | return cpufreq_driver_resolve_freq(policy, freq); |
| 155 | } | 177 | } |
| 156 | 178 | ||
| 157 | static void sugov_get_util(unsigned long *util, unsigned long *max) | 179 | static void sugov_get_util(unsigned long *util, unsigned long *max, int cpu) |
| 158 | { | 180 | { |
| 159 | struct rq *rq = this_rq(); | 181 | struct rq *rq = cpu_rq(cpu); |
| 160 | unsigned long cfs_max; | 182 | unsigned long cfs_max; |
| 161 | 183 | ||
| 162 | cfs_max = arch_scale_cpu_capacity(NULL, smp_processor_id()); | 184 | cfs_max = arch_scale_cpu_capacity(NULL, cpu); |
| 163 | 185 | ||
| 164 | *util = min(rq->cfs.avg.util_avg, cfs_max); | 186 | *util = min(rq->cfs.avg.util_avg, cfs_max); |
| 165 | *max = cfs_max; | 187 | *max = cfs_max; |
| @@ -169,30 +191,54 @@ static void sugov_set_iowait_boost(struct sugov_cpu *sg_cpu, u64 time, | |||
| 169 | unsigned int flags) | 191 | unsigned int flags) |
| 170 | { | 192 | { |
| 171 | if (flags & SCHED_CPUFREQ_IOWAIT) { | 193 | if (flags & SCHED_CPUFREQ_IOWAIT) { |
| 172 | sg_cpu->iowait_boost = sg_cpu->iowait_boost_max; | 194 | if (sg_cpu->iowait_boost_pending) |
| 195 | return; | ||
| 196 | |||
| 197 | sg_cpu->iowait_boost_pending = true; | ||
| 198 | |||
| 199 | if (sg_cpu->iowait_boost) { | ||
| 200 | sg_cpu->iowait_boost <<= 1; | ||
| 201 | if (sg_cpu->iowait_boost > sg_cpu->iowait_boost_max) | ||
| 202 | sg_cpu->iowait_boost = sg_cpu->iowait_boost_max; | ||
| 203 | } else { | ||
| 204 | sg_cpu->iowait_boost = sg_cpu->sg_policy->policy->min; | ||
| 205 | } | ||
| 173 | } else if (sg_cpu->iowait_boost) { | 206 | } else if (sg_cpu->iowait_boost) { |
| 174 | s64 delta_ns = time - sg_cpu->last_update; | 207 | s64 delta_ns = time - sg_cpu->last_update; |
| 175 | 208 | ||
| 176 | /* Clear iowait_boost if the CPU apprears to have been idle. */ | 209 | /* Clear iowait_boost if the CPU apprears to have been idle. */ |
| 177 | if (delta_ns > TICK_NSEC) | 210 | if (delta_ns > TICK_NSEC) { |
| 178 | sg_cpu->iowait_boost = 0; | 211 | sg_cpu->iowait_boost = 0; |
| 212 | sg_cpu->iowait_boost_pending = false; | ||
| 213 | } | ||
| 179 | } | 214 | } |
| 180 | } | 215 | } |
| 181 | 216 | ||
| 182 | static void sugov_iowait_boost(struct sugov_cpu *sg_cpu, unsigned long *util, | 217 | static void sugov_iowait_boost(struct sugov_cpu *sg_cpu, unsigned long *util, |
| 183 | unsigned long *max) | 218 | unsigned long *max) |
| 184 | { | 219 | { |
| 185 | unsigned long boost_util = sg_cpu->iowait_boost; | 220 | unsigned int boost_util, boost_max; |
| 186 | unsigned long boost_max = sg_cpu->iowait_boost_max; | ||
| 187 | 221 | ||
| 188 | if (!boost_util) | 222 | if (!sg_cpu->iowait_boost) |
| 189 | return; | 223 | return; |
| 190 | 224 | ||
| 225 | if (sg_cpu->iowait_boost_pending) { | ||
| 226 | sg_cpu->iowait_boost_pending = false; | ||
| 227 | } else { | ||
| 228 | sg_cpu->iowait_boost >>= 1; | ||
| 229 | if (sg_cpu->iowait_boost < sg_cpu->sg_policy->policy->min) { | ||
| 230 | sg_cpu->iowait_boost = 0; | ||
| 231 | return; | ||
| 232 | } | ||
| 233 | } | ||
| 234 | |||
| 235 | boost_util = sg_cpu->iowait_boost; | ||
| 236 | boost_max = sg_cpu->iowait_boost_max; | ||
| 237 | |||
| 191 | if (*util * boost_max < *max * boost_util) { | 238 | if (*util * boost_max < *max * boost_util) { |
| 192 | *util = boost_util; | 239 | *util = boost_util; |
| 193 | *max = boost_max; | 240 | *max = boost_max; |
| 194 | } | 241 | } |
| 195 | sg_cpu->iowait_boost >>= 1; | ||
| 196 | } | 242 | } |
| 197 | 243 | ||
| 198 | #ifdef CONFIG_NO_HZ_COMMON | 244 | #ifdef CONFIG_NO_HZ_COMMON |
| @@ -229,7 +275,7 @@ static void sugov_update_single(struct update_util_data *hook, u64 time, | |||
| 229 | if (flags & SCHED_CPUFREQ_RT_DL) { | 275 | if (flags & SCHED_CPUFREQ_RT_DL) { |
| 230 | next_f = policy->cpuinfo.max_freq; | 276 | next_f = policy->cpuinfo.max_freq; |
| 231 | } else { | 277 | } else { |
| 232 | sugov_get_util(&util, &max); | 278 | sugov_get_util(&util, &max, sg_cpu->cpu); |
| 233 | sugov_iowait_boost(sg_cpu, &util, &max); | 279 | sugov_iowait_boost(sg_cpu, &util, &max); |
| 234 | next_f = get_next_freq(sg_policy, util, max); | 280 | next_f = get_next_freq(sg_policy, util, max); |
| 235 | /* | 281 | /* |
| @@ -264,6 +310,7 @@ static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu, u64 time) | |||
| 264 | delta_ns = time - j_sg_cpu->last_update; | 310 | delta_ns = time - j_sg_cpu->last_update; |
| 265 | if (delta_ns > TICK_NSEC) { | 311 | if (delta_ns > TICK_NSEC) { |
| 266 | j_sg_cpu->iowait_boost = 0; | 312 | j_sg_cpu->iowait_boost = 0; |
| 313 | j_sg_cpu->iowait_boost_pending = false; | ||
| 267 | continue; | 314 | continue; |
| 268 | } | 315 | } |
| 269 | if (j_sg_cpu->flags & SCHED_CPUFREQ_RT_DL) | 316 | if (j_sg_cpu->flags & SCHED_CPUFREQ_RT_DL) |
| @@ -290,7 +337,7 @@ static void sugov_update_shared(struct update_util_data *hook, u64 time, | |||
| 290 | unsigned long util, max; | 337 | unsigned long util, max; |
| 291 | unsigned int next_f; | 338 | unsigned int next_f; |
| 292 | 339 | ||
| 293 | sugov_get_util(&util, &max); | 340 | sugov_get_util(&util, &max, sg_cpu->cpu); |
| 294 | 341 | ||
| 295 | raw_spin_lock(&sg_policy->update_lock); | 342 | raw_spin_lock(&sg_policy->update_lock); |
| 296 | 343 | ||
| @@ -445,7 +492,11 @@ static int sugov_kthread_create(struct sugov_policy *sg_policy) | |||
| 445 | } | 492 | } |
| 446 | 493 | ||
| 447 | sg_policy->thread = thread; | 494 | sg_policy->thread = thread; |
| 448 | kthread_bind_mask(thread, policy->related_cpus); | 495 | |
| 496 | /* Kthread is bound to all CPUs by default */ | ||
| 497 | if (!policy->dvfs_possible_from_any_cpu) | ||
| 498 | kthread_bind_mask(thread, policy->related_cpus); | ||
| 499 | |||
| 449 | init_irq_work(&sg_policy->irq_work, sugov_irq_work); | 500 | init_irq_work(&sg_policy->irq_work, sugov_irq_work); |
| 450 | mutex_init(&sg_policy->work_lock); | 501 | mutex_init(&sg_policy->work_lock); |
| 451 | 502 | ||
| @@ -663,6 +714,11 @@ struct cpufreq_governor *cpufreq_default_governor(void) | |||
| 663 | 714 | ||
| 664 | static int __init sugov_register(void) | 715 | static int __init sugov_register(void) |
| 665 | { | 716 | { |
| 717 | int cpu; | ||
| 718 | |||
| 719 | for_each_possible_cpu(cpu) | ||
| 720 | per_cpu(sugov_cpu, cpu).cpu = cpu; | ||
| 721 | |||
| 666 | return cpufreq_register_governor(&schedutil_gov); | 722 | return cpufreq_register_governor(&schedutil_gov); |
| 667 | } | 723 | } |
| 668 | fs_initcall(sugov_register); | 724 | fs_initcall(sugov_register); |
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c index 755bd3f1a1a9..5c3bf4bd0327 100644 --- a/kernel/sched/deadline.c +++ b/kernel/sched/deadline.c | |||
| @@ -1136,7 +1136,7 @@ static void update_curr_dl(struct rq *rq) | |||
| 1136 | } | 1136 | } |
| 1137 | 1137 | ||
| 1138 | /* kick cpufreq (see the comment in kernel/sched/sched.h). */ | 1138 | /* kick cpufreq (see the comment in kernel/sched/sched.h). */ |
| 1139 | cpufreq_update_this_cpu(rq, SCHED_CPUFREQ_DL); | 1139 | cpufreq_update_util(rq, SCHED_CPUFREQ_DL); |
| 1140 | 1140 | ||
| 1141 | schedstat_set(curr->se.statistics.exec_max, | 1141 | schedstat_set(curr->se.statistics.exec_max, |
| 1142 | max(curr->se.statistics.exec_max, delta_exec)); | 1142 | max(curr->se.statistics.exec_max, delta_exec)); |
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index c95880e216f6..d378d02fdfcb 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
| @@ -3278,7 +3278,9 @@ static inline void set_tg_cfs_propagate(struct cfs_rq *cfs_rq) {} | |||
| 3278 | 3278 | ||
| 3279 | static inline void cfs_rq_util_change(struct cfs_rq *cfs_rq) | 3279 | static inline void cfs_rq_util_change(struct cfs_rq *cfs_rq) |
| 3280 | { | 3280 | { |
| 3281 | if (&this_rq()->cfs == cfs_rq) { | 3281 | struct rq *rq = rq_of(cfs_rq); |
| 3282 | |||
| 3283 | if (&rq->cfs == cfs_rq) { | ||
| 3282 | /* | 3284 | /* |
| 3283 | * There are a few boundary cases this might miss but it should | 3285 | * There are a few boundary cases this might miss but it should |
| 3284 | * get called often enough that that should (hopefully) not be | 3286 | * get called often enough that that should (hopefully) not be |
| @@ -3295,7 +3297,7 @@ static inline void cfs_rq_util_change(struct cfs_rq *cfs_rq) | |||
| 3295 | * | 3297 | * |
| 3296 | * See cpu_util(). | 3298 | * See cpu_util(). |
| 3297 | */ | 3299 | */ |
| 3298 | cpufreq_update_util(rq_of(cfs_rq), 0); | 3300 | cpufreq_update_util(rq, 0); |
| 3299 | } | 3301 | } |
| 3300 | } | 3302 | } |
| 3301 | 3303 | ||
| @@ -4875,7 +4877,7 @@ enqueue_task_fair(struct rq *rq, struct task_struct *p, int flags) | |||
| 4875 | * passed. | 4877 | * passed. |
| 4876 | */ | 4878 | */ |
| 4877 | if (p->in_iowait) | 4879 | if (p->in_iowait) |
| 4878 | cpufreq_update_this_cpu(rq, SCHED_CPUFREQ_IOWAIT); | 4880 | cpufreq_update_util(rq, SCHED_CPUFREQ_IOWAIT); |
| 4879 | 4881 | ||
| 4880 | for_each_sched_entity(se) { | 4882 | for_each_sched_entity(se) { |
| 4881 | if (se->on_rq) | 4883 | if (se->on_rq) |
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 45caf937ef90..0af5ca9e3e3f 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c | |||
| @@ -970,7 +970,7 @@ static void update_curr_rt(struct rq *rq) | |||
| 970 | return; | 970 | return; |
| 971 | 971 | ||
| 972 | /* Kick cpufreq (see the comment in kernel/sched/sched.h). */ | 972 | /* Kick cpufreq (see the comment in kernel/sched/sched.h). */ |
| 973 | cpufreq_update_this_cpu(rq, SCHED_CPUFREQ_RT); | 973 | cpufreq_update_util(rq, SCHED_CPUFREQ_RT); |
| 974 | 974 | ||
| 975 | schedstat_set(curr->se.statistics.exec_max, | 975 | schedstat_set(curr->se.statistics.exec_max, |
| 976 | max(curr->se.statistics.exec_max, delta_exec)); | 976 | max(curr->se.statistics.exec_max, delta_exec)); |
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index eeef1a3086d1..aa9d5b87b4f8 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h | |||
| @@ -2070,19 +2070,13 @@ static inline void cpufreq_update_util(struct rq *rq, unsigned int flags) | |||
| 2070 | { | 2070 | { |
| 2071 | struct update_util_data *data; | 2071 | struct update_util_data *data; |
| 2072 | 2072 | ||
| 2073 | data = rcu_dereference_sched(*this_cpu_ptr(&cpufreq_update_util_data)); | 2073 | data = rcu_dereference_sched(*per_cpu_ptr(&cpufreq_update_util_data, |
| 2074 | cpu_of(rq))); | ||
| 2074 | if (data) | 2075 | if (data) |
| 2075 | data->func(data, rq_clock(rq), flags); | 2076 | data->func(data, rq_clock(rq), flags); |
| 2076 | } | 2077 | } |
| 2077 | |||
| 2078 | static inline void cpufreq_update_this_cpu(struct rq *rq, unsigned int flags) | ||
| 2079 | { | ||
| 2080 | if (cpu_of(rq) == smp_processor_id()) | ||
| 2081 | cpufreq_update_util(rq, flags); | ||
| 2082 | } | ||
| 2083 | #else | 2078 | #else |
| 2084 | static inline void cpufreq_update_util(struct rq *rq, unsigned int flags) {} | 2079 | static inline void cpufreq_update_util(struct rq *rq, unsigned int flags) {} |
| 2085 | static inline void cpufreq_update_this_cpu(struct rq *rq, unsigned int flags) {} | ||
| 2086 | #endif /* CONFIG_CPU_FREQ */ | 2080 | #endif /* CONFIG_CPU_FREQ */ |
| 2087 | 2081 | ||
| 2088 | #ifdef arch_scale_freq_capacity | 2082 | #ifdef arch_scale_freq_capacity |
