aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched')
-rw-r--r--kernel/sched/core.c73
-rw-r--r--kernel/sched/fair.c37
-rw-r--r--kernel/sched/rt.c1
-rw-r--r--kernel/sched/sched.h1
4 files changed, 38 insertions, 74 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index fbf1fd098dc6..649c9f876cb1 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -5304,27 +5304,17 @@ void idle_task_exit(void)
5304} 5304}
5305 5305
5306/* 5306/*
5307 * While a dead CPU has no uninterruptible tasks queued at this point, 5307 * Since this CPU is going 'away' for a while, fold any nr_active delta
5308 * it might still have a nonzero ->nr_uninterruptible counter, because 5308 * we might have. Assumes we're called after migrate_tasks() so that the
5309 * for performance reasons the counter is not stricly tracking tasks to 5309 * nr_active count is stable.
5310 * their home CPUs. So we just add the counter to another CPU's counter, 5310 *
5311 * to keep the global sum constant after CPU-down: 5311 * Also see the comment "Global load-average calculations".
5312 */
5313static void migrate_nr_uninterruptible(struct rq *rq_src)
5314{
5315 struct rq *rq_dest = cpu_rq(cpumask_any(cpu_active_mask));
5316
5317 rq_dest->nr_uninterruptible += rq_src->nr_uninterruptible;
5318 rq_src->nr_uninterruptible = 0;
5319}
5320
5321/*
5322 * remove the tasks which were accounted by rq from calc_load_tasks.
5323 */ 5312 */
5324static void calc_global_load_remove(struct rq *rq) 5313static void calc_load_migrate(struct rq *rq)
5325{ 5314{
5326 atomic_long_sub(rq->calc_load_active, &calc_load_tasks); 5315 long delta = calc_load_fold_active(rq);
5327 rq->calc_load_active = 0; 5316 if (delta)
5317 atomic_long_add(delta, &calc_load_tasks);
5328} 5318}
5329 5319
5330/* 5320/*
@@ -5352,9 +5342,6 @@ static void migrate_tasks(unsigned int dead_cpu)
5352 */ 5342 */
5353 rq->stop = NULL; 5343 rq->stop = NULL;
5354 5344
5355 /* Ensure any throttled groups are reachable by pick_next_task */
5356 unthrottle_offline_cfs_rqs(rq);
5357
5358 for ( ; ; ) { 5345 for ( ; ; ) {
5359 /* 5346 /*
5360 * There's this thread running, bail when that's the only 5347 * There's this thread running, bail when that's the only
@@ -5618,8 +5605,7 @@ migration_call(struct notifier_block *nfb, unsigned long action, void *hcpu)
5618 BUG_ON(rq->nr_running != 1); /* the migration thread */ 5605 BUG_ON(rq->nr_running != 1); /* the migration thread */
5619 raw_spin_unlock_irqrestore(&rq->lock, flags); 5606 raw_spin_unlock_irqrestore(&rq->lock, flags);
5620 5607
5621 migrate_nr_uninterruptible(rq); 5608 calc_load_migrate(rq);
5622 calc_global_load_remove(rq);
5623 break; 5609 break;
5624#endif 5610#endif
5625 } 5611 }
@@ -6028,11 +6014,6 @@ static void destroy_sched_domains(struct sched_domain *sd, int cpu)
6028 * SD_SHARE_PKG_RESOURCE set (Last Level Cache Domain) for this 6014 * SD_SHARE_PKG_RESOURCE set (Last Level Cache Domain) for this
6029 * allows us to avoid some pointer chasing select_idle_sibling(). 6015 * allows us to avoid some pointer chasing select_idle_sibling().
6030 * 6016 *
6031 * Iterate domains and sched_groups downward, assigning CPUs to be
6032 * select_idle_sibling() hw buddy. Cross-wiring hw makes bouncing
6033 * due to random perturbation self canceling, ie sw buddies pull
6034 * their counterpart to their CPU's hw counterpart.
6035 *
6036 * Also keep a unique ID per domain (we use the first cpu number in 6017 * Also keep a unique ID per domain (we use the first cpu number in
6037 * the cpumask of the domain), this allows us to quickly tell if 6018 * the cpumask of the domain), this allows us to quickly tell if
6038 * two cpus are in the same cache domain, see cpus_share_cache(). 6019 * two cpus are in the same cache domain, see cpus_share_cache().
@@ -6046,40 +6027,8 @@ static void update_top_cache_domain(int cpu)
6046 int id = cpu; 6027 int id = cpu;
6047 6028
6048 sd = highest_flag_domain(cpu, SD_SHARE_PKG_RESOURCES); 6029 sd = highest_flag_domain(cpu, SD_SHARE_PKG_RESOURCES);
6049 if (sd) { 6030 if (sd)
6050 struct sched_domain *tmp = sd;
6051 struct sched_group *sg, *prev;
6052 bool right;
6053
6054 /*
6055 * Traverse to first CPU in group, and count hops
6056 * to cpu from there, switching direction on each
6057 * hop, never ever pointing the last CPU rightward.
6058 */
6059 do {
6060 id = cpumask_first(sched_domain_span(tmp));
6061 prev = sg = tmp->groups;
6062 right = 1;
6063
6064 while (cpumask_first(sched_group_cpus(sg)) != id)
6065 sg = sg->next;
6066
6067 while (!cpumask_test_cpu(cpu, sched_group_cpus(sg))) {
6068 prev = sg;
6069 sg = sg->next;
6070 right = !right;
6071 }
6072
6073 /* A CPU went down, never point back to domain start. */
6074 if (right && cpumask_first(sched_group_cpus(sg->next)) == id)
6075 right = false;
6076
6077 sg = right ? sg->next : prev;
6078 tmp->idle_buddy = cpumask_first(sched_group_cpus(sg));
6079 } while ((tmp = tmp->child));
6080
6081 id = cpumask_first(sched_domain_span(sd)); 6031 id = cpumask_first(sched_domain_span(sd));
6082 }
6083 6032
6084 rcu_assign_pointer(per_cpu(sd_llc, cpu), sd); 6033 rcu_assign_pointer(per_cpu(sd_llc, cpu), sd);
6085 per_cpu(sd_llc_id, cpu) = id; 6034 per_cpu(sd_llc_id, cpu) = id;
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index c219bf8d704c..96e2b18b6283 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -2052,7 +2052,7 @@ static void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b)
2052 hrtimer_cancel(&cfs_b->slack_timer); 2052 hrtimer_cancel(&cfs_b->slack_timer);
2053} 2053}
2054 2054
2055void unthrottle_offline_cfs_rqs(struct rq *rq) 2055static void unthrottle_offline_cfs_rqs(struct rq *rq)
2056{ 2056{
2057 struct cfs_rq *cfs_rq; 2057 struct cfs_rq *cfs_rq;
2058 2058
@@ -2106,7 +2106,7 @@ static inline struct cfs_bandwidth *tg_cfs_bandwidth(struct task_group *tg)
2106 return NULL; 2106 return NULL;
2107} 2107}
2108static inline void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b) {} 2108static inline void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b) {}
2109void unthrottle_offline_cfs_rqs(struct rq *rq) {} 2109static inline void unthrottle_offline_cfs_rqs(struct rq *rq) {}
2110 2110
2111#endif /* CONFIG_CFS_BANDWIDTH */ 2111#endif /* CONFIG_CFS_BANDWIDTH */
2112 2112
@@ -2637,6 +2637,8 @@ static int select_idle_sibling(struct task_struct *p, int target)
2637 int cpu = smp_processor_id(); 2637 int cpu = smp_processor_id();
2638 int prev_cpu = task_cpu(p); 2638 int prev_cpu = task_cpu(p);
2639 struct sched_domain *sd; 2639 struct sched_domain *sd;
2640 struct sched_group *sg;
2641 int i;
2640 2642
2641 /* 2643 /*
2642 * If the task is going to be woken-up on this cpu and if it is 2644 * If the task is going to be woken-up on this cpu and if it is
@@ -2653,17 +2655,29 @@ static int select_idle_sibling(struct task_struct *p, int target)
2653 return prev_cpu; 2655 return prev_cpu;
2654 2656
2655 /* 2657 /*
2656 * Otherwise, check assigned siblings to find an elegible idle cpu. 2658 * Otherwise, iterate the domains and find an elegible idle cpu.
2657 */ 2659 */
2658 sd = rcu_dereference(per_cpu(sd_llc, target)); 2660 sd = rcu_dereference(per_cpu(sd_llc, target));
2659
2660 for_each_lower_domain(sd) { 2661 for_each_lower_domain(sd) {
2661 if (!cpumask_test_cpu(sd->idle_buddy, tsk_cpus_allowed(p))) 2662 sg = sd->groups;
2662 continue; 2663 do {
2663 if (idle_cpu(sd->idle_buddy)) 2664 if (!cpumask_intersects(sched_group_cpus(sg),
2664 return sd->idle_buddy; 2665 tsk_cpus_allowed(p)))
2665 } 2666 goto next;
2666 2667
2668 for_each_cpu(i, sched_group_cpus(sg)) {
2669 if (!idle_cpu(i))
2670 goto next;
2671 }
2672
2673 target = cpumask_first_and(sched_group_cpus(sg),
2674 tsk_cpus_allowed(p));
2675 goto done;
2676next:
2677 sg = sg->next;
2678 } while (sg != sd->groups);
2679 }
2680done:
2667 return target; 2681 return target;
2668} 2682}
2669 2683
@@ -3658,7 +3672,6 @@ fix_small_capacity(struct sched_domain *sd, struct sched_group *group)
3658 * @group: sched_group whose statistics are to be updated. 3672 * @group: sched_group whose statistics are to be updated.
3659 * @load_idx: Load index of sched_domain of this_cpu for load calc. 3673 * @load_idx: Load index of sched_domain of this_cpu for load calc.
3660 * @local_group: Does group contain this_cpu. 3674 * @local_group: Does group contain this_cpu.
3661 * @cpus: Set of cpus considered for load balancing.
3662 * @balance: Should we balance. 3675 * @balance: Should we balance.
3663 * @sgs: variable to hold the statistics for this group. 3676 * @sgs: variable to hold the statistics for this group.
3664 */ 3677 */
@@ -3805,7 +3818,6 @@ static bool update_sd_pick_busiest(struct lb_env *env,
3805/** 3818/**
3806 * update_sd_lb_stats - Update sched_domain's statistics for load balancing. 3819 * update_sd_lb_stats - Update sched_domain's statistics for load balancing.
3807 * @env: The load balancing environment. 3820 * @env: The load balancing environment.
3808 * @cpus: Set of cpus considered for load balancing.
3809 * @balance: Should we balance. 3821 * @balance: Should we balance.
3810 * @sds: variable to hold the statistics for this sched_domain. 3822 * @sds: variable to hold the statistics for this sched_domain.
3811 */ 3823 */
@@ -4956,6 +4968,9 @@ static void rq_online_fair(struct rq *rq)
4956static void rq_offline_fair(struct rq *rq) 4968static void rq_offline_fair(struct rq *rq)
4957{ 4969{
4958 update_sysctl(); 4970 update_sysctl();
4971
4972 /* Ensure any throttled groups are reachable by pick_next_task */
4973 unthrottle_offline_cfs_rqs(rq);
4959} 4974}
4960 4975
4961#endif /* CONFIG_SMP */ 4976#endif /* CONFIG_SMP */
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index 944cb68420e9..e0b7ba9c040f 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -691,6 +691,7 @@ balanced:
691 * runtime - in which case borrowing doesn't make sense. 691 * runtime - in which case borrowing doesn't make sense.
692 */ 692 */
693 rt_rq->rt_runtime = RUNTIME_INF; 693 rt_rq->rt_runtime = RUNTIME_INF;
694 rt_rq->rt_throttled = 0;
694 raw_spin_unlock(&rt_rq->rt_runtime_lock); 695 raw_spin_unlock(&rt_rq->rt_runtime_lock);
695 raw_spin_unlock(&rt_b->rt_runtime_lock); 696 raw_spin_unlock(&rt_b->rt_runtime_lock);
696 } 697 }
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index f6714d009e77..0848fa36c383 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1144,7 +1144,6 @@ extern void print_rt_stats(struct seq_file *m, int cpu);
1144 1144
1145extern void init_cfs_rq(struct cfs_rq *cfs_rq); 1145extern void init_cfs_rq(struct cfs_rq *cfs_rq);
1146extern void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq); 1146extern void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq);
1147extern void unthrottle_offline_cfs_rqs(struct rq *rq);
1148 1147
1149extern void account_cfs_bandwidth_used(int enabled, int was_enabled); 1148extern void account_cfs_bandwidth_used(int enabled, int was_enabled);
1150 1149