diff options
-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 |