diff options
Diffstat (limited to 'kernel/sched')
| -rw-r--r-- | kernel/sched/core.c | 73 | ||||
| -rw-r--r-- | kernel/sched/fair.c | 37 | ||||
| -rw-r--r-- | kernel/sched/rt.c | 1 | ||||
| -rw-r--r-- | kernel/sched/sched.h | 1 |
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 | */ | ||
| 5313 | static 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 | */ |
| 5324 | static void calc_global_load_remove(struct rq *rq) | 5313 | static 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 | ||
| 2055 | void unthrottle_offline_cfs_rqs(struct rq *rq) | 2055 | static 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 | } |
| 2108 | static inline void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b) {} | 2108 | static inline void destroy_cfs_bandwidth(struct cfs_bandwidth *cfs_b) {} |
| 2109 | void unthrottle_offline_cfs_rqs(struct rq *rq) {} | 2109 | static 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; | ||
| 2676 | next: | ||
| 2677 | sg = sg->next; | ||
| 2678 | } while (sg != sd->groups); | ||
| 2679 | } | ||
| 2680 | done: | ||
| 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) | |||
| 4956 | static void rq_offline_fair(struct rq *rq) | 4968 | static 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 | ||
| 1145 | extern void init_cfs_rq(struct cfs_rq *cfs_rq); | 1145 | extern void init_cfs_rq(struct cfs_rq *cfs_rq); |
| 1146 | extern void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq); | 1146 | extern void init_rt_rq(struct rt_rq *rt_rq, struct rq *rq); |
| 1147 | extern void unthrottle_offline_cfs_rqs(struct rq *rq); | ||
| 1148 | 1147 | ||
| 1149 | extern void account_cfs_bandwidth_used(int enabled, int was_enabled); | 1148 | extern void account_cfs_bandwidth_used(int enabled, int was_enabled); |
| 1150 | 1149 | ||
