diff options
Diffstat (limited to 'kernel/sched')
-rw-r--r-- | kernel/sched/core.c | 19 | ||||
-rw-r--r-- | kernel/sched/fair.c | 34 | ||||
-rw-r--r-- | kernel/sched/rt.c | 5 |
3 files changed, 41 insertions, 17 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index df00cb09263e..5255c9d2e053 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -74,6 +74,7 @@ | |||
74 | 74 | ||
75 | #include <asm/tlb.h> | 75 | #include <asm/tlb.h> |
76 | #include <asm/irq_regs.h> | 76 | #include <asm/irq_regs.h> |
77 | #include <asm/mutex.h> | ||
77 | #ifdef CONFIG_PARAVIRT | 78 | #ifdef CONFIG_PARAVIRT |
78 | #include <asm/paravirt.h> | 79 | #include <asm/paravirt.h> |
79 | #endif | 80 | #endif |
@@ -723,9 +724,6 @@ static void dequeue_task(struct rq *rq, struct task_struct *p, int flags) | |||
723 | p->sched_class->dequeue_task(rq, p, flags); | 724 | p->sched_class->dequeue_task(rq, p, flags); |
724 | } | 725 | } |
725 | 726 | ||
726 | /* | ||
727 | * activate_task - move a task to the runqueue. | ||
728 | */ | ||
729 | void activate_task(struct rq *rq, struct task_struct *p, int flags) | 727 | void activate_task(struct rq *rq, struct task_struct *p, int flags) |
730 | { | 728 | { |
731 | if (task_contributes_to_load(p)) | 729 | if (task_contributes_to_load(p)) |
@@ -734,9 +732,6 @@ void activate_task(struct rq *rq, struct task_struct *p, int flags) | |||
734 | enqueue_task(rq, p, flags); | 732 | enqueue_task(rq, p, flags); |
735 | } | 733 | } |
736 | 734 | ||
737 | /* | ||
738 | * deactivate_task - remove a task from the runqueue. | ||
739 | */ | ||
740 | void deactivate_task(struct rq *rq, struct task_struct *p, int flags) | 735 | void deactivate_task(struct rq *rq, struct task_struct *p, int flags) |
741 | { | 736 | { |
742 | if (task_contributes_to_load(p)) | 737 | if (task_contributes_to_load(p)) |
@@ -4134,7 +4129,7 @@ recheck: | |||
4134 | on_rq = p->on_rq; | 4129 | on_rq = p->on_rq; |
4135 | running = task_current(rq, p); | 4130 | running = task_current(rq, p); |
4136 | if (on_rq) | 4131 | if (on_rq) |
4137 | deactivate_task(rq, p, 0); | 4132 | dequeue_task(rq, p, 0); |
4138 | if (running) | 4133 | if (running) |
4139 | p->sched_class->put_prev_task(rq, p); | 4134 | p->sched_class->put_prev_task(rq, p); |
4140 | 4135 | ||
@@ -4147,7 +4142,7 @@ recheck: | |||
4147 | if (running) | 4142 | if (running) |
4148 | p->sched_class->set_curr_task(rq); | 4143 | p->sched_class->set_curr_task(rq); |
4149 | if (on_rq) | 4144 | if (on_rq) |
4150 | activate_task(rq, p, 0); | 4145 | enqueue_task(rq, p, 0); |
4151 | 4146 | ||
4152 | check_class_changed(rq, p, prev_class, oldprio); | 4147 | check_class_changed(rq, p, prev_class, oldprio); |
4153 | task_rq_unlock(rq, p, &flags); | 4148 | task_rq_unlock(rq, p, &flags); |
@@ -4998,9 +4993,9 @@ static int __migrate_task(struct task_struct *p, int src_cpu, int dest_cpu) | |||
4998 | * placed properly. | 4993 | * placed properly. |
4999 | */ | 4994 | */ |
5000 | if (p->on_rq) { | 4995 | if (p->on_rq) { |
5001 | deactivate_task(rq_src, p, 0); | 4996 | dequeue_task(rq_src, p, 0); |
5002 | set_task_cpu(p, dest_cpu); | 4997 | set_task_cpu(p, dest_cpu); |
5003 | activate_task(rq_dest, p, 0); | 4998 | enqueue_task(rq_dest, p, 0); |
5004 | check_preempt_curr(rq_dest, p, 0); | 4999 | check_preempt_curr(rq_dest, p, 0); |
5005 | } | 5000 | } |
5006 | done: | 5001 | done: |
@@ -7032,10 +7027,10 @@ static void normalize_task(struct rq *rq, struct task_struct *p) | |||
7032 | 7027 | ||
7033 | on_rq = p->on_rq; | 7028 | on_rq = p->on_rq; |
7034 | if (on_rq) | 7029 | if (on_rq) |
7035 | deactivate_task(rq, p, 0); | 7030 | dequeue_task(rq, p, 0); |
7036 | __setscheduler(rq, p, SCHED_NORMAL, 0); | 7031 | __setscheduler(rq, p, SCHED_NORMAL, 0); |
7037 | if (on_rq) { | 7032 | if (on_rq) { |
7038 | activate_task(rq, p, 0); | 7033 | enqueue_task(rq, p, 0); |
7039 | resched_task(rq->curr); | 7034 | resched_task(rq->curr); |
7040 | } | 7035 | } |
7041 | 7036 | ||
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 | ||
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 3640ebbb466b..f42ae7fb5ec5 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c | |||
@@ -1587,6 +1587,11 @@ static int push_rt_task(struct rq *rq) | |||
1587 | if (!next_task) | 1587 | if (!next_task) |
1588 | return 0; | 1588 | return 0; |
1589 | 1589 | ||
1590 | #ifdef __ARCH_WANT_INTERRUPTS_ON_CTXSW | ||
1591 | if (unlikely(task_running(rq, next_task))) | ||
1592 | return 0; | ||
1593 | #endif | ||
1594 | |||
1590 | retry: | 1595 | retry: |
1591 | if (unlikely(next_task == rq->curr)) { | 1596 | if (unlikely(next_task == rq->curr)) { |
1592 | WARN_ON(1); | 1597 | WARN_ON(1); |