aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched')
-rw-r--r--kernel/sched/core.c11
-rw-r--r--kernel/sched/cpufreq_schedutil.c19
-rw-r--r--kernel/sched/fair.c2
-rw-r--r--kernel/sched/features.h5
-rw-r--r--kernel/sched/wait.c39
5 files changed, 62 insertions, 14 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 956383844116..3b31fc05a0f1 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -3287,10 +3287,15 @@ pick_next_task(struct rq *rq, struct task_struct *prev, struct rq_flags *rf)
3287 struct task_struct *p; 3287 struct task_struct *p;
3288 3288
3289 /* 3289 /*
3290 * Optimization: we know that if all tasks are in 3290 * Optimization: we know that if all tasks are in the fair class we can
3291 * the fair class we can call that function directly: 3291 * call that function directly, but only if the @prev task wasn't of a
3292 * higher scheduling class, because otherwise those loose the
3293 * opportunity to pull in more work from other CPUs.
3292 */ 3294 */
3293 if (likely(rq->nr_running == rq->cfs.h_nr_running)) { 3295 if (likely((prev->sched_class == &idle_sched_class ||
3296 prev->sched_class == &fair_sched_class) &&
3297 rq->nr_running == rq->cfs.h_nr_running)) {
3298
3294 p = fair_sched_class.pick_next_task(rq, prev, rf); 3299 p = fair_sched_class.pick_next_task(rq, prev, rf);
3295 if (unlikely(p == RETRY_TASK)) 3300 if (unlikely(p == RETRY_TASK))
3296 goto again; 3301 goto again;
diff --git a/kernel/sched/cpufreq_schedutil.c b/kernel/sched/cpufreq_schedutil.c
index 8f8de3d4d6b7..cd7cd489f739 100644
--- a/kernel/sched/cpufreq_schedutil.c
+++ b/kernel/sched/cpufreq_schedutil.c
@@ -36,6 +36,7 @@ struct sugov_policy {
36 u64 last_freq_update_time; 36 u64 last_freq_update_time;
37 s64 freq_update_delay_ns; 37 s64 freq_update_delay_ns;
38 unsigned int next_freq; 38 unsigned int next_freq;
39 unsigned int cached_raw_freq;
39 40
40 /* The next fields are only needed if fast switch cannot be used. */ 41 /* The next fields are only needed if fast switch cannot be used. */
41 struct irq_work irq_work; 42 struct irq_work irq_work;
@@ -52,7 +53,6 @@ struct sugov_cpu {
52 struct update_util_data update_util; 53 struct update_util_data update_util;
53 struct sugov_policy *sg_policy; 54 struct sugov_policy *sg_policy;
54 55
55 unsigned int cached_raw_freq;
56 unsigned long iowait_boost; 56 unsigned long iowait_boost;
57 unsigned long iowait_boost_max; 57 unsigned long iowait_boost_max;
58 u64 last_update; 58 u64 last_update;
@@ -116,7 +116,7 @@ static void sugov_update_commit(struct sugov_policy *sg_policy, u64 time,
116 116
117/** 117/**
118 * get_next_freq - Compute a new frequency for a given cpufreq policy. 118 * get_next_freq - Compute a new frequency for a given cpufreq policy.
119 * @sg_cpu: schedutil cpu object to compute the new frequency for. 119 * @sg_policy: schedutil policy object to compute the new frequency for.
120 * @util: Current CPU utilization. 120 * @util: Current CPU utilization.
121 * @max: CPU capacity. 121 * @max: CPU capacity.
122 * 122 *
@@ -136,19 +136,18 @@ static void sugov_update_commit(struct sugov_policy *sg_policy, u64 time,
136 * next_freq (as calculated above) is returned, subject to policy min/max and 136 * next_freq (as calculated above) is returned, subject to policy min/max and
137 * cpufreq driver limitations. 137 * cpufreq driver limitations.
138 */ 138 */
139static unsigned int get_next_freq(struct sugov_cpu *sg_cpu, unsigned long util, 139static unsigned int get_next_freq(struct sugov_policy *sg_policy,
140 unsigned long max) 140 unsigned long util, unsigned long max)
141{ 141{
142 struct sugov_policy *sg_policy = sg_cpu->sg_policy;
143 struct cpufreq_policy *policy = sg_policy->policy; 142 struct cpufreq_policy *policy = sg_policy->policy;
144 unsigned int freq = arch_scale_freq_invariant() ? 143 unsigned int freq = arch_scale_freq_invariant() ?
145 policy->cpuinfo.max_freq : policy->cur; 144 policy->cpuinfo.max_freq : policy->cur;
146 145
147 freq = (freq + (freq >> 2)) * util / max; 146 freq = (freq + (freq >> 2)) * util / max;
148 147
149 if (freq == sg_cpu->cached_raw_freq && sg_policy->next_freq != UINT_MAX) 148 if (freq == sg_policy->cached_raw_freq && sg_policy->next_freq != UINT_MAX)
150 return sg_policy->next_freq; 149 return sg_policy->next_freq;
151 sg_cpu->cached_raw_freq = freq; 150 sg_policy->cached_raw_freq = freq;
152 return cpufreq_driver_resolve_freq(policy, freq); 151 return cpufreq_driver_resolve_freq(policy, freq);
153} 152}
154 153
@@ -213,7 +212,7 @@ static void sugov_update_single(struct update_util_data *hook, u64 time,
213 } else { 212 } else {
214 sugov_get_util(&util, &max); 213 sugov_get_util(&util, &max);
215 sugov_iowait_boost(sg_cpu, &util, &max); 214 sugov_iowait_boost(sg_cpu, &util, &max);
216 next_f = get_next_freq(sg_cpu, util, max); 215 next_f = get_next_freq(sg_policy, util, max);
217 } 216 }
218 sugov_update_commit(sg_policy, time, next_f); 217 sugov_update_commit(sg_policy, time, next_f);
219} 218}
@@ -267,7 +266,7 @@ static unsigned int sugov_next_freq_shared(struct sugov_cpu *sg_cpu,
267 sugov_iowait_boost(j_sg_cpu, &util, &max); 266 sugov_iowait_boost(j_sg_cpu, &util, &max);
268 } 267 }
269 268
270 return get_next_freq(sg_cpu, util, max); 269 return get_next_freq(sg_policy, util, max);
271} 270}
272 271
273static void sugov_update_shared(struct update_util_data *hook, u64 time, 272static void sugov_update_shared(struct update_util_data *hook, u64 time,
@@ -580,6 +579,7 @@ static int sugov_start(struct cpufreq_policy *policy)
580 sg_policy->next_freq = UINT_MAX; 579 sg_policy->next_freq = UINT_MAX;
581 sg_policy->work_in_progress = false; 580 sg_policy->work_in_progress = false;
582 sg_policy->need_freq_update = false; 581 sg_policy->need_freq_update = false;
582 sg_policy->cached_raw_freq = 0;
583 583
584 for_each_cpu(cpu, policy->cpus) { 584 for_each_cpu(cpu, policy->cpus) {
585 struct sugov_cpu *sg_cpu = &per_cpu(sugov_cpu, cpu); 585 struct sugov_cpu *sg_cpu = &per_cpu(sugov_cpu, cpu);
@@ -590,7 +590,6 @@ static int sugov_start(struct cpufreq_policy *policy)
590 sg_cpu->max = 0; 590 sg_cpu->max = 0;
591 sg_cpu->flags = SCHED_CPUFREQ_RT; 591 sg_cpu->flags = SCHED_CPUFREQ_RT;
592 sg_cpu->last_update = 0; 592 sg_cpu->last_update = 0;
593 sg_cpu->cached_raw_freq = 0;
594 sg_cpu->iowait_boost = 0; 593 sg_cpu->iowait_boost = 0;
595 sg_cpu->iowait_boost_max = policy->cpuinfo.max_freq; 594 sg_cpu->iowait_boost_max = policy->cpuinfo.max_freq;
596 cpufreq_add_update_util_hook(cpu, &sg_cpu->update_util, 595 cpufreq_add_update_util_hook(cpu, &sg_cpu->update_util,
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 3e88b35ac157..dea138964b91 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -5799,7 +5799,7 @@ static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int t
5799 * Due to large variance we need a large fuzz factor; hackbench in 5799 * Due to large variance we need a large fuzz factor; hackbench in
5800 * particularly is sensitive here. 5800 * particularly is sensitive here.
5801 */ 5801 */
5802 if ((avg_idle / 512) < avg_cost) 5802 if (sched_feat(SIS_AVG_CPU) && (avg_idle / 512) < avg_cost)
5803 return -1; 5803 return -1;
5804 5804
5805 time = local_clock(); 5805 time = local_clock();
diff --git a/kernel/sched/features.h b/kernel/sched/features.h
index 69631fa46c2f..1b3c8189b286 100644
--- a/kernel/sched/features.h
+++ b/kernel/sched/features.h
@@ -51,6 +51,11 @@ SCHED_FEAT(NONTASK_CAPACITY, true)
51 */ 51 */
52SCHED_FEAT(TTWU_QUEUE, true) 52SCHED_FEAT(TTWU_QUEUE, true)
53 53
54/*
55 * When doing wakeups, attempt to limit superfluous scans of the LLC domain.
56 */
57SCHED_FEAT(SIS_AVG_CPU, false)
58
54#ifdef HAVE_RT_PUSH_IPI 59#ifdef HAVE_RT_PUSH_IPI
55/* 60/*
56 * In order to avoid a thundering herd attack of CPUs that are 61 * In order to avoid a thundering herd attack of CPUs that are
diff --git a/kernel/sched/wait.c b/kernel/sched/wait.c
index 4d2ea6f25568..b8c84c6dee64 100644
--- a/kernel/sched/wait.c
+++ b/kernel/sched/wait.c
@@ -242,6 +242,45 @@ long prepare_to_wait_event(wait_queue_head_t *q, wait_queue_t *wait, int state)
242} 242}
243EXPORT_SYMBOL(prepare_to_wait_event); 243EXPORT_SYMBOL(prepare_to_wait_event);
244 244
245/*
246 * Note! These two wait functions are entered with the
247 * wait-queue lock held (and interrupts off in the _irq
248 * case), so there is no race with testing the wakeup
249 * condition in the caller before they add the wait
250 * entry to the wake queue.
251 */
252int do_wait_intr(wait_queue_head_t *wq, wait_queue_t *wait)
253{
254 if (likely(list_empty(&wait->task_list)))
255 __add_wait_queue_tail(wq, wait);
256
257 set_current_state(TASK_INTERRUPTIBLE);
258 if (signal_pending(current))
259 return -ERESTARTSYS;
260
261 spin_unlock(&wq->lock);
262 schedule();
263 spin_lock(&wq->lock);
264 return 0;
265}
266EXPORT_SYMBOL(do_wait_intr);
267
268int do_wait_intr_irq(wait_queue_head_t *wq, wait_queue_t *wait)
269{
270 if (likely(list_empty(&wait->task_list)))
271 __add_wait_queue_tail(wq, wait);
272
273 set_current_state(TASK_INTERRUPTIBLE);
274 if (signal_pending(current))
275 return -ERESTARTSYS;
276
277 spin_unlock_irq(&wq->lock);
278 schedule();
279 spin_lock_irq(&wq->lock);
280 return 0;
281}
282EXPORT_SYMBOL(do_wait_intr_irq);
283
245/** 284/**
246 * finish_wait - clean up after waiting in a queue 285 * finish_wait - clean up after waiting in a queue
247 * @q: waitqueue waited on 286 * @q: waitqueue waited on