diff options
Diffstat (limited to 'kernel/sched/core.c')
-rw-r--r-- | kernel/sched/core.c | 75 |
1 files changed, 58 insertions, 17 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 3595403921bd..10a8faa1b0d4 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -621,18 +621,21 @@ int get_nohz_timer_target(void) | |||
621 | int i, cpu = smp_processor_id(); | 621 | int i, cpu = smp_processor_id(); |
622 | struct sched_domain *sd; | 622 | struct sched_domain *sd; |
623 | 623 | ||
624 | if (!idle_cpu(cpu)) | 624 | if (!idle_cpu(cpu) && is_housekeeping_cpu(cpu)) |
625 | return cpu; | 625 | return cpu; |
626 | 626 | ||
627 | rcu_read_lock(); | 627 | rcu_read_lock(); |
628 | for_each_domain(cpu, sd) { | 628 | for_each_domain(cpu, sd) { |
629 | for_each_cpu(i, sched_domain_span(sd)) { | 629 | for_each_cpu(i, sched_domain_span(sd)) { |
630 | if (!idle_cpu(i)) { | 630 | if (!idle_cpu(i) && is_housekeeping_cpu(cpu)) { |
631 | cpu = i; | 631 | cpu = i; |
632 | goto unlock; | 632 | goto unlock; |
633 | } | 633 | } |
634 | } | 634 | } |
635 | } | 635 | } |
636 | |||
637 | if (!is_housekeeping_cpu(cpu)) | ||
638 | cpu = housekeeping_any_cpu(); | ||
636 | unlock: | 639 | unlock: |
637 | rcu_read_unlock(); | 640 | rcu_read_unlock(); |
638 | return cpu; | 641 | return cpu; |
@@ -2514,11 +2517,11 @@ static struct rq *finish_task_switch(struct task_struct *prev) | |||
2514 | * If a task dies, then it sets TASK_DEAD in tsk->state and calls | 2517 | * If a task dies, then it sets TASK_DEAD in tsk->state and calls |
2515 | * schedule one last time. The schedule call will never return, and | 2518 | * schedule one last time. The schedule call will never return, and |
2516 | * the scheduled task must drop that reference. | 2519 | * the scheduled task must drop that reference. |
2517 | * The test for TASK_DEAD must occur while the runqueue locks are | 2520 | * |
2518 | * still held, otherwise prev could be scheduled on another cpu, die | 2521 | * We must observe prev->state before clearing prev->on_cpu (in |
2519 | * there before we look at prev->state, and then the reference would | 2522 | * finish_lock_switch), otherwise a concurrent wakeup can get prev |
2520 | * be dropped twice. | 2523 | * running on another CPU and we could rave with its RUNNING -> DEAD |
2521 | * Manfred Spraul <manfred@colorfullife.com> | 2524 | * transition, resulting in a double drop. |
2522 | */ | 2525 | */ |
2523 | prev_state = prev->state; | 2526 | prev_state = prev->state; |
2524 | vtime_task_switch(prev); | 2527 | vtime_task_switch(prev); |
@@ -2666,13 +2669,20 @@ unsigned long nr_running(void) | |||
2666 | 2669 | ||
2667 | /* | 2670 | /* |
2668 | * Check if only the current task is running on the cpu. | 2671 | * Check if only the current task is running on the cpu. |
2672 | * | ||
2673 | * Caution: this function does not check that the caller has disabled | ||
2674 | * preemption, thus the result might have a time-of-check-to-time-of-use | ||
2675 | * race. The caller is responsible to use it correctly, for example: | ||
2676 | * | ||
2677 | * - from a non-preemptable section (of course) | ||
2678 | * | ||
2679 | * - from a thread that is bound to a single CPU | ||
2680 | * | ||
2681 | * - in a loop with very short iterations (e.g. a polling loop) | ||
2669 | */ | 2682 | */ |
2670 | bool single_task_running(void) | 2683 | bool single_task_running(void) |
2671 | { | 2684 | { |
2672 | if (cpu_rq(smp_processor_id())->nr_running == 1) | 2685 | return raw_rq()->nr_running == 1; |
2673 | return true; | ||
2674 | else | ||
2675 | return false; | ||
2676 | } | 2686 | } |
2677 | EXPORT_SYMBOL(single_task_running); | 2687 | EXPORT_SYMBOL(single_task_running); |
2678 | 2688 | ||
@@ -4924,7 +4934,15 @@ void init_idle(struct task_struct *idle, int cpu) | |||
4924 | idle->state = TASK_RUNNING; | 4934 | idle->state = TASK_RUNNING; |
4925 | idle->se.exec_start = sched_clock(); | 4935 | idle->se.exec_start = sched_clock(); |
4926 | 4936 | ||
4927 | do_set_cpus_allowed(idle, cpumask_of(cpu)); | 4937 | #ifdef CONFIG_SMP |
4938 | /* | ||
4939 | * Its possible that init_idle() gets called multiple times on a task, | ||
4940 | * in that case do_set_cpus_allowed() will not do the right thing. | ||
4941 | * | ||
4942 | * And since this is boot we can forgo the serialization. | ||
4943 | */ | ||
4944 | set_cpus_allowed_common(idle, cpumask_of(cpu)); | ||
4945 | #endif | ||
4928 | /* | 4946 | /* |
4929 | * We're having a chicken and egg problem, even though we are | 4947 | * We're having a chicken and egg problem, even though we are |
4930 | * holding rq->lock, the cpu isn't yet set to this cpu so the | 4948 | * holding rq->lock, the cpu isn't yet set to this cpu so the |
@@ -4941,7 +4959,7 @@ void init_idle(struct task_struct *idle, int cpu) | |||
4941 | 4959 | ||
4942 | rq->curr = rq->idle = idle; | 4960 | rq->curr = rq->idle = idle; |
4943 | idle->on_rq = TASK_ON_RQ_QUEUED; | 4961 | idle->on_rq = TASK_ON_RQ_QUEUED; |
4944 | #if defined(CONFIG_SMP) | 4962 | #ifdef CONFIG_SMP |
4945 | idle->on_cpu = 1; | 4963 | idle->on_cpu = 1; |
4946 | #endif | 4964 | #endif |
4947 | raw_spin_unlock(&rq->lock); | 4965 | raw_spin_unlock(&rq->lock); |
@@ -4956,7 +4974,7 @@ void init_idle(struct task_struct *idle, int cpu) | |||
4956 | idle->sched_class = &idle_sched_class; | 4974 | idle->sched_class = &idle_sched_class; |
4957 | ftrace_graph_init_idle_task(idle, cpu); | 4975 | ftrace_graph_init_idle_task(idle, cpu); |
4958 | vtime_init_idle(idle, cpu); | 4976 | vtime_init_idle(idle, cpu); |
4959 | #if defined(CONFIG_SMP) | 4977 | #ifdef CONFIG_SMP |
4960 | sprintf(idle->comm, "%s/%d", INIT_TASK_COMM, cpu); | 4978 | sprintf(idle->comm, "%s/%d", INIT_TASK_COMM, cpu); |
4961 | #endif | 4979 | #endif |
4962 | } | 4980 | } |
@@ -5178,24 +5196,47 @@ static void migrate_tasks(struct rq *dead_rq) | |||
5178 | break; | 5196 | break; |
5179 | 5197 | ||
5180 | /* | 5198 | /* |
5181 | * Ensure rq->lock covers the entire task selection | 5199 | * pick_next_task assumes pinned rq->lock. |
5182 | * until the migration. | ||
5183 | */ | 5200 | */ |
5184 | lockdep_pin_lock(&rq->lock); | 5201 | lockdep_pin_lock(&rq->lock); |
5185 | next = pick_next_task(rq, &fake_task); | 5202 | next = pick_next_task(rq, &fake_task); |
5186 | BUG_ON(!next); | 5203 | BUG_ON(!next); |
5187 | next->sched_class->put_prev_task(rq, next); | 5204 | next->sched_class->put_prev_task(rq, next); |
5188 | 5205 | ||
5206 | /* | ||
5207 | * Rules for changing task_struct::cpus_allowed are holding | ||
5208 | * both pi_lock and rq->lock, such that holding either | ||
5209 | * stabilizes the mask. | ||
5210 | * | ||
5211 | * Drop rq->lock is not quite as disastrous as it usually is | ||
5212 | * because !cpu_active at this point, which means load-balance | ||
5213 | * will not interfere. Also, stop-machine. | ||
5214 | */ | ||
5215 | lockdep_unpin_lock(&rq->lock); | ||
5216 | raw_spin_unlock(&rq->lock); | ||
5217 | raw_spin_lock(&next->pi_lock); | ||
5218 | raw_spin_lock(&rq->lock); | ||
5219 | |||
5220 | /* | ||
5221 | * Since we're inside stop-machine, _nothing_ should have | ||
5222 | * changed the task, WARN if weird stuff happened, because in | ||
5223 | * that case the above rq->lock drop is a fail too. | ||
5224 | */ | ||
5225 | if (WARN_ON(task_rq(next) != rq || !task_on_rq_queued(next))) { | ||
5226 | raw_spin_unlock(&next->pi_lock); | ||
5227 | continue; | ||
5228 | } | ||
5229 | |||
5189 | /* Find suitable destination for @next, with force if needed. */ | 5230 | /* Find suitable destination for @next, with force if needed. */ |
5190 | dest_cpu = select_fallback_rq(dead_rq->cpu, next); | 5231 | dest_cpu = select_fallback_rq(dead_rq->cpu, next); |
5191 | 5232 | ||
5192 | lockdep_unpin_lock(&rq->lock); | ||
5193 | rq = __migrate_task(rq, next, dest_cpu); | 5233 | rq = __migrate_task(rq, next, dest_cpu); |
5194 | if (rq != dead_rq) { | 5234 | if (rq != dead_rq) { |
5195 | raw_spin_unlock(&rq->lock); | 5235 | raw_spin_unlock(&rq->lock); |
5196 | rq = dead_rq; | 5236 | rq = dead_rq; |
5197 | raw_spin_lock(&rq->lock); | 5237 | raw_spin_lock(&rq->lock); |
5198 | } | 5238 | } |
5239 | raw_spin_unlock(&next->pi_lock); | ||
5199 | } | 5240 | } |
5200 | 5241 | ||
5201 | rq->stop = stop; | 5242 | rq->stop = stop; |