aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched')
-rw-r--r--kernel/sched/core.c62
-rw-r--r--kernel/sched/fair.c10
-rw-r--r--kernel/sched/sched.h15
3 files changed, 69 insertions, 18 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index c70a8814a767..e94842d4400c 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -544,7 +544,7 @@ void resched_cpu(int cpu)
544 raw_spin_unlock_irqrestore(&rq->lock, flags); 544 raw_spin_unlock_irqrestore(&rq->lock, flags);
545} 545}
546 546
547#ifdef CONFIG_NO_HZ 547#ifdef CONFIG_NO_HZ_COMMON
548/* 548/*
549 * In the semi idle case, use the nearest busy cpu for migrating timers 549 * In the semi idle case, use the nearest busy cpu for migrating timers
550 * from an idle cpu. This is good for power-savings. 550 * from an idle cpu. This is good for power-savings.
@@ -582,7 +582,7 @@ unlock:
582 * account when the CPU goes back to idle and evaluates the timer 582 * account when the CPU goes back to idle and evaluates the timer
583 * wheel for the next timer event. 583 * wheel for the next timer event.
584 */ 584 */
585void wake_up_idle_cpu(int cpu) 585static void wake_up_idle_cpu(int cpu)
586{ 586{
587 struct rq *rq = cpu_rq(cpu); 587 struct rq *rq = cpu_rq(cpu);
588 588
@@ -612,20 +612,56 @@ void wake_up_idle_cpu(int cpu)
612 smp_send_reschedule(cpu); 612 smp_send_reschedule(cpu);
613} 613}
614 614
615static bool wake_up_full_nohz_cpu(int cpu)
616{
617 if (tick_nohz_full_cpu(cpu)) {
618 if (cpu != smp_processor_id() ||
619 tick_nohz_tick_stopped())
620 smp_send_reschedule(cpu);
621 return true;
622 }
623
624 return false;
625}
626
627void wake_up_nohz_cpu(int cpu)
628{
629 if (!wake_up_full_nohz_cpu(cpu))
630 wake_up_idle_cpu(cpu);
631}
632
615static inline bool got_nohz_idle_kick(void) 633static inline bool got_nohz_idle_kick(void)
616{ 634{
617 int cpu = smp_processor_id(); 635 int cpu = smp_processor_id();
618 return idle_cpu(cpu) && test_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu)); 636 return idle_cpu(cpu) && test_bit(NOHZ_BALANCE_KICK, nohz_flags(cpu));
619} 637}
620 638
621#else /* CONFIG_NO_HZ */ 639#else /* CONFIG_NO_HZ_COMMON */
622 640
623static inline bool got_nohz_idle_kick(void) 641static inline bool got_nohz_idle_kick(void)
624{ 642{
625 return false; 643 return false;
626} 644}
627 645
628#endif /* CONFIG_NO_HZ */ 646#endif /* CONFIG_NO_HZ_COMMON */
647
648#ifdef CONFIG_NO_HZ_FULL
649bool sched_can_stop_tick(void)
650{
651 struct rq *rq;
652
653 rq = this_rq();
654
655 /* Make sure rq->nr_running update is visible after the IPI */
656 smp_rmb();
657
658 /* More than one running task need preemption */
659 if (rq->nr_running > 1)
660 return false;
661
662 return true;
663}
664#endif /* CONFIG_NO_HZ_FULL */
629 665
630void sched_avg_update(struct rq *rq) 666void sched_avg_update(struct rq *rq)
631{ 667{
@@ -1357,7 +1393,8 @@ static void sched_ttwu_pending(void)
1357 1393
1358void scheduler_ipi(void) 1394void scheduler_ipi(void)
1359{ 1395{
1360 if (llist_empty(&this_rq()->wake_list) && !got_nohz_idle_kick()) 1396 if (llist_empty(&this_rq()->wake_list) && !got_nohz_idle_kick()
1397 && !tick_nohz_full_cpu(smp_processor_id()))
1361 return; 1398 return;
1362 1399
1363 /* 1400 /*
@@ -1374,6 +1411,7 @@ void scheduler_ipi(void)
1374 * somewhat pessimize the simple resched case. 1411 * somewhat pessimize the simple resched case.
1375 */ 1412 */
1376 irq_enter(); 1413 irq_enter();
1414 tick_nohz_full_check();
1377 sched_ttwu_pending(); 1415 sched_ttwu_pending();
1378 1416
1379 /* 1417 /*
@@ -1855,6 +1893,8 @@ static void finish_task_switch(struct rq *rq, struct task_struct *prev)
1855 kprobe_flush_task(prev); 1893 kprobe_flush_task(prev);
1856 put_task_struct(prev); 1894 put_task_struct(prev);
1857 } 1895 }
1896
1897 tick_nohz_task_switch(current);
1858} 1898}
1859 1899
1860#ifdef CONFIG_SMP 1900#ifdef CONFIG_SMP
@@ -2118,7 +2158,7 @@ calc_load(unsigned long load, unsigned long exp, unsigned long active)
2118 return load >> FSHIFT; 2158 return load >> FSHIFT;
2119} 2159}
2120 2160
2121#ifdef CONFIG_NO_HZ 2161#ifdef CONFIG_NO_HZ_COMMON
2122/* 2162/*
2123 * Handle NO_HZ for the global load-average. 2163 * Handle NO_HZ for the global load-average.
2124 * 2164 *
@@ -2344,12 +2384,12 @@ static void calc_global_nohz(void)
2344 smp_wmb(); 2384 smp_wmb();
2345 calc_load_idx++; 2385 calc_load_idx++;
2346} 2386}
2347#else /* !CONFIG_NO_HZ */ 2387#else /* !CONFIG_NO_HZ_COMMON */
2348 2388
2349static inline long calc_load_fold_idle(void) { return 0; } 2389static inline long calc_load_fold_idle(void) { return 0; }
2350static inline void calc_global_nohz(void) { } 2390static inline void calc_global_nohz(void) { }
2351 2391
2352#endif /* CONFIG_NO_HZ */ 2392#endif /* CONFIG_NO_HZ_COMMON */
2353 2393
2354/* 2394/*
2355 * calc_load - update the avenrun load estimates 10 ticks after the 2395 * calc_load - update the avenrun load estimates 10 ticks after the
@@ -2509,7 +2549,7 @@ static void __update_cpu_load(struct rq *this_rq, unsigned long this_load,
2509 sched_avg_update(this_rq); 2549 sched_avg_update(this_rq);
2510} 2550}
2511 2551
2512#ifdef CONFIG_NO_HZ 2552#ifdef CONFIG_NO_HZ_COMMON
2513/* 2553/*
2514 * There is no sane way to deal with nohz on smp when using jiffies because the 2554 * There is no sane way to deal with nohz on smp when using jiffies because the
2515 * cpu doing the jiffies update might drift wrt the cpu doing the jiffy reading 2555 * cpu doing the jiffies update might drift wrt the cpu doing the jiffy reading
@@ -2569,7 +2609,7 @@ void update_cpu_load_nohz(void)
2569 } 2609 }
2570 raw_spin_unlock(&this_rq->lock); 2610 raw_spin_unlock(&this_rq->lock);
2571} 2611}
2572#endif /* CONFIG_NO_HZ */ 2612#endif /* CONFIG_NO_HZ_COMMON */
2573 2613
2574/* 2614/*
2575 * Called from scheduler_tick() 2615 * Called from scheduler_tick()
@@ -6950,7 +6990,7 @@ void __init sched_init(void)
6950 INIT_LIST_HEAD(&rq->cfs_tasks); 6990 INIT_LIST_HEAD(&rq->cfs_tasks);
6951 6991
6952 rq_attach_root(rq, &def_root_domain); 6992 rq_attach_root(rq, &def_root_domain);
6953#ifdef CONFIG_NO_HZ 6993#ifdef CONFIG_NO_HZ_COMMON
6954 rq->nohz_flags = 0; 6994 rq->nohz_flags = 0;
6955#endif 6995#endif
6956#endif 6996#endif
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 8bf7081b1ec5..c61a614465c8 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -5355,7 +5355,7 @@ out_unlock:
5355 return 0; 5355 return 0;
5356} 5356}
5357 5357
5358#ifdef CONFIG_NO_HZ 5358#ifdef CONFIG_NO_HZ_COMMON
5359/* 5359/*
5360 * idle load balancing details 5360 * idle load balancing details
5361 * - When one of the busy CPUs notice that there may be an idle rebalancing 5361 * - When one of the busy CPUs notice that there may be an idle rebalancing
@@ -5572,9 +5572,9 @@ out:
5572 rq->next_balance = next_balance; 5572 rq->next_balance = next_balance;
5573} 5573}
5574 5574
5575#ifdef CONFIG_NO_HZ 5575#ifdef CONFIG_NO_HZ_COMMON
5576/* 5576/*
5577 * In CONFIG_NO_HZ case, the idle balance kickee will do the 5577 * In CONFIG_NO_HZ_COMMON case, the idle balance kickee will do the
5578 * rebalancing for all the cpus for whom scheduler ticks are stopped. 5578 * rebalancing for all the cpus for whom scheduler ticks are stopped.
5579 */ 5579 */
5580static void nohz_idle_balance(int this_cpu, enum cpu_idle_type idle) 5580static void nohz_idle_balance(int this_cpu, enum cpu_idle_type idle)
@@ -5717,7 +5717,7 @@ void trigger_load_balance(struct rq *rq, int cpu)
5717 if (time_after_eq(jiffies, rq->next_balance) && 5717 if (time_after_eq(jiffies, rq->next_balance) &&
5718 likely(!on_null_domain(cpu))) 5718 likely(!on_null_domain(cpu)))
5719 raise_softirq(SCHED_SOFTIRQ); 5719 raise_softirq(SCHED_SOFTIRQ);
5720#ifdef CONFIG_NO_HZ 5720#ifdef CONFIG_NO_HZ_COMMON
5721 if (nohz_kick_needed(rq, cpu) && likely(!on_null_domain(cpu))) 5721 if (nohz_kick_needed(rq, cpu) && likely(!on_null_domain(cpu)))
5722 nohz_balancer_kick(cpu); 5722 nohz_balancer_kick(cpu);
5723#endif 5723#endif
@@ -6187,7 +6187,7 @@ __init void init_sched_fair_class(void)
6187#ifdef CONFIG_SMP 6187#ifdef CONFIG_SMP
6188 open_softirq(SCHED_SOFTIRQ, run_rebalance_domains); 6188 open_softirq(SCHED_SOFTIRQ, run_rebalance_domains);
6189 6189
6190#ifdef CONFIG_NO_HZ 6190#ifdef CONFIG_NO_HZ_COMMON
6191 nohz.next_balance = jiffies; 6191 nohz.next_balance = jiffies;
6192 zalloc_cpumask_var(&nohz.idle_cpus_mask, GFP_NOWAIT); 6192 zalloc_cpumask_var(&nohz.idle_cpus_mask, GFP_NOWAIT);
6193 cpu_notifier(sched_ilb_notifier, 0); 6193 cpu_notifier(sched_ilb_notifier, 0);
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index 4c225c4c7111..24dc29897749 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -5,6 +5,7 @@
5#include <linux/mutex.h> 5#include <linux/mutex.h>
6#include <linux/spinlock.h> 6#include <linux/spinlock.h>
7#include <linux/stop_machine.h> 7#include <linux/stop_machine.h>
8#include <linux/tick.h>
8 9
9#include "cpupri.h" 10#include "cpupri.h"
10#include "cpuacct.h" 11#include "cpuacct.h"
@@ -405,7 +406,7 @@ struct rq {
405 #define CPU_LOAD_IDX_MAX 5 406 #define CPU_LOAD_IDX_MAX 5
406 unsigned long cpu_load[CPU_LOAD_IDX_MAX]; 407 unsigned long cpu_load[CPU_LOAD_IDX_MAX];
407 unsigned long last_load_update_tick; 408 unsigned long last_load_update_tick;
408#ifdef CONFIG_NO_HZ 409#ifdef CONFIG_NO_HZ_COMMON
409 u64 nohz_stamp; 410 u64 nohz_stamp;
410 unsigned long nohz_flags; 411 unsigned long nohz_flags;
411#endif 412#endif
@@ -1072,6 +1073,16 @@ static inline u64 steal_ticks(u64 steal)
1072static inline void inc_nr_running(struct rq *rq) 1073static inline void inc_nr_running(struct rq *rq)
1073{ 1074{
1074 rq->nr_running++; 1075 rq->nr_running++;
1076
1077#ifdef CONFIG_NO_HZ_FULL
1078 if (rq->nr_running == 2) {
1079 if (tick_nohz_full_cpu(rq->cpu)) {
1080 /* Order rq->nr_running write against the IPI */
1081 smp_wmb();
1082 smp_send_reschedule(rq->cpu);
1083 }
1084 }
1085#endif
1075} 1086}
1076 1087
1077static inline void dec_nr_running(struct rq *rq) 1088static inline void dec_nr_running(struct rq *rq)
@@ -1299,7 +1310,7 @@ extern void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq);
1299 1310
1300extern void account_cfs_bandwidth_used(int enabled, int was_enabled); 1311extern void account_cfs_bandwidth_used(int enabled, int was_enabled);
1301 1312
1302#ifdef CONFIG_NO_HZ 1313#ifdef CONFIG_NO_HZ_COMMON
1303enum rq_nohz_flag_bits { 1314enum rq_nohz_flag_bits {
1304 NOHZ_TICK_STOPPED, 1315 NOHZ_TICK_STOPPED,
1305 NOHZ_BALANCE_KICK, 1316 NOHZ_BALANCE_KICK,