diff options
-rw-r--r-- | kernel/sched/fair.c | 34 |
1 files changed, 29 insertions, 5 deletions
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 84adb2d66cbd..7c6414fc669d 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
@@ -4866,6 +4866,15 @@ static void nohz_balancer_kick(int cpu) | |||
4866 | return; | 4866 | return; |
4867 | } | 4867 | } |
4868 | 4868 | ||
4869 | static inline void clear_nohz_tick_stopped(int cpu) | ||
4870 | { | ||
4871 | if (unlikely(test_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)))) { | ||
4872 | cpumask_clear_cpu(cpu, nohz.idle_cpus_mask); | ||
4873 | atomic_dec(&nohz.nr_cpus); | ||
4874 | clear_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)); | ||
4875 | } | ||
4876 | } | ||
4877 | |||
4869 | static inline void set_cpu_sd_state_busy(void) | 4878 | static inline void set_cpu_sd_state_busy(void) |
4870 | { | 4879 | { |
4871 | struct sched_domain *sd; | 4880 | struct sched_domain *sd; |
@@ -4904,6 +4913,12 @@ void select_nohz_load_balancer(int stop_tick) | |||
4904 | { | 4913 | { |
4905 | int cpu = smp_processor_id(); | 4914 | int cpu = smp_processor_id(); |
4906 | 4915 | ||
4916 | /* | ||
4917 | * If this cpu is going down, then nothing needs to be done. | ||
4918 | */ | ||
4919 | if (!cpu_active(cpu)) | ||
4920 | return; | ||
4921 | |||
4907 | if (stop_tick) { | 4922 | if (stop_tick) { |
4908 | if (test_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu))) | 4923 | if (test_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu))) |
4909 | return; | 4924 | return; |
@@ -4914,6 +4929,18 @@ void select_nohz_load_balancer(int stop_tick) | |||
4914 | } | 4929 | } |
4915 | return; | 4930 | return; |
4916 | } | 4931 | } |
4932 | |||
4933 | static int __cpuinit sched_ilb_notifier(struct notifier_block *nfb, | ||
4934 | unsigned long action, void *hcpu) | ||
4935 | { | ||
4936 | switch (action & ~CPU_TASKS_FROZEN) { | ||
4937 | case CPU_DYING: | ||
4938 | clear_nohz_tick_stopped(smp_processor_id()); | ||
4939 | return NOTIFY_OK; | ||
4940 | default: | ||
4941 | return NOTIFY_DONE; | ||
4942 | } | ||
4943 | } | ||
4917 | #endif | 4944 | #endif |
4918 | 4945 | ||
4919 | static DEFINE_SPINLOCK(balancing); | 4946 | static DEFINE_SPINLOCK(balancing); |
@@ -5070,11 +5097,7 @@ static inline int nohz_kick_needed(struct rq *rq, int cpu) | |||
5070 | * busy tick after returning from idle, we will update the busy stats. | 5097 | * busy tick after returning from idle, we will update the busy stats. |
5071 | */ | 5098 | */ |
5072 | set_cpu_sd_state_busy(); | 5099 | set_cpu_sd_state_busy(); |
5073 | if (unlikely(test_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)))) { | 5100 | clear_nohz_tick_stopped(cpu); |
5074 | clear_bit(NOHZ_TICK_STOPPED, nohz_flags(cpu)); | ||
5075 | cpumask_clear_cpu(cpu, nohz.idle_cpus_mask); | ||
5076 | atomic_dec(&nohz.nr_cpus); | ||
5077 | } | ||
5078 | 5101 | ||
5079 | /* | 5102 | /* |
5080 | * None are in tickless mode and hence no need for NOHZ idle load | 5103 | * None are in tickless mode and hence no need for NOHZ idle load |
@@ -5590,6 +5613,7 @@ __init void init_sched_fair_class(void) | |||
5590 | 5613 | ||
5591 | #ifdef CONFIG_NO_HZ | 5614 | #ifdef CONFIG_NO_HZ |
5592 | zalloc_cpumask_var(&nohz.idle_cpus_mask, GFP_NOWAIT); | 5615 | zalloc_cpumask_var(&nohz.idle_cpus_mask, GFP_NOWAIT); |
5616 | cpu_notifier(sched_ilb_notifier, 0); | ||
5593 | #endif | 5617 | #endif |
5594 | #endif /* SMP */ | 5618 | #endif /* SMP */ |
5595 | 5619 | ||