diff options
Diffstat (limited to 'kernel/sched/fair.c')
| -rw-r--r-- | kernel/sched/fair.c | 37 |
1 files changed, 26 insertions, 11 deletions
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 */ |
