diff options
-rw-r--r-- | include/linux/sched.h | 2 | ||||
-rw-r--r-- | kernel/sched.c | 26 | ||||
-rw-r--r-- | kernel/sched_fair.c | 32 | ||||
-rw-r--r-- | kernel/sched_idletask.c | 2 | ||||
-rw-r--r-- | kernel/sched_rt.c | 19 |
5 files changed, 27 insertions, 54 deletions
diff --git a/include/linux/sched.h b/include/linux/sched.h index 24bce423f10d..513b81c60e87 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -870,7 +870,7 @@ struct sched_class { | |||
870 | struct rq *busiest, | 870 | struct rq *busiest, |
871 | unsigned long max_nr_move, unsigned long max_load_move, | 871 | unsigned long max_nr_move, unsigned long max_load_move, |
872 | struct sched_domain *sd, enum cpu_idle_type idle, | 872 | struct sched_domain *sd, enum cpu_idle_type idle, |
873 | int *all_pinned); | 873 | int *all_pinned, int *this_best_prio); |
874 | 874 | ||
875 | void (*set_curr_task) (struct rq *rq); | 875 | void (*set_curr_task) (struct rq *rq); |
876 | void (*task_tick) (struct rq *rq, struct task_struct *p); | 876 | void (*task_tick) (struct rq *rq, struct task_struct *p); |
diff --git a/kernel/sched.c b/kernel/sched.c index 85b93118d244..1fa07c14624e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -745,8 +745,7 @@ static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, | |||
745 | unsigned long max_nr_move, unsigned long max_load_move, | 745 | unsigned long max_nr_move, unsigned long max_load_move, |
746 | struct sched_domain *sd, enum cpu_idle_type idle, | 746 | struct sched_domain *sd, enum cpu_idle_type idle, |
747 | int *all_pinned, unsigned long *load_moved, | 747 | int *all_pinned, unsigned long *load_moved, |
748 | int this_best_prio, int best_prio, int best_prio_seen, | 748 | int *this_best_prio, struct rq_iterator *iterator); |
749 | struct rq_iterator *iterator); | ||
750 | 749 | ||
751 | #include "sched_stats.h" | 750 | #include "sched_stats.h" |
752 | #include "sched_rt.c" | 751 | #include "sched_rt.c" |
@@ -2165,8 +2164,7 @@ static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, | |||
2165 | unsigned long max_nr_move, unsigned long max_load_move, | 2164 | unsigned long max_nr_move, unsigned long max_load_move, |
2166 | struct sched_domain *sd, enum cpu_idle_type idle, | 2165 | struct sched_domain *sd, enum cpu_idle_type idle, |
2167 | int *all_pinned, unsigned long *load_moved, | 2166 | int *all_pinned, unsigned long *load_moved, |
2168 | int this_best_prio, int best_prio, int best_prio_seen, | 2167 | int *this_best_prio, struct rq_iterator *iterator) |
2169 | struct rq_iterator *iterator) | ||
2170 | { | 2168 | { |
2171 | int pulled = 0, pinned = 0, skip_for_load; | 2169 | int pulled = 0, pinned = 0, skip_for_load; |
2172 | struct task_struct *p; | 2170 | struct task_struct *p; |
@@ -2191,12 +2189,8 @@ next: | |||
2191 | */ | 2189 | */ |
2192 | skip_for_load = (p->se.load.weight >> 1) > rem_load_move + | 2190 | skip_for_load = (p->se.load.weight >> 1) > rem_load_move + |
2193 | SCHED_LOAD_SCALE_FUZZ; | 2191 | SCHED_LOAD_SCALE_FUZZ; |
2194 | if (skip_for_load && p->prio < this_best_prio) | 2192 | if ((skip_for_load && p->prio >= *this_best_prio) || |
2195 | skip_for_load = !best_prio_seen && p->prio == best_prio; | ||
2196 | if (skip_for_load || | ||
2197 | !can_migrate_task(p, busiest, this_cpu, sd, idle, &pinned)) { | 2193 | !can_migrate_task(p, busiest, this_cpu, sd, idle, &pinned)) { |
2198 | |||
2199 | best_prio_seen |= p->prio == best_prio; | ||
2200 | p = iterator->next(iterator->arg); | 2194 | p = iterator->next(iterator->arg); |
2201 | goto next; | 2195 | goto next; |
2202 | } | 2196 | } |
@@ -2210,8 +2204,8 @@ next: | |||
2210 | * and the prescribed amount of weighted load. | 2204 | * and the prescribed amount of weighted load. |
2211 | */ | 2205 | */ |
2212 | if (pulled < max_nr_move && rem_load_move > 0) { | 2206 | if (pulled < max_nr_move && rem_load_move > 0) { |
2213 | if (p->prio < this_best_prio) | 2207 | if (p->prio < *this_best_prio) |
2214 | this_best_prio = p->prio; | 2208 | *this_best_prio = p->prio; |
2215 | p = iterator->next(iterator->arg); | 2209 | p = iterator->next(iterator->arg); |
2216 | goto next; | 2210 | goto next; |
2217 | } | 2211 | } |
@@ -2243,12 +2237,13 @@ static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, | |||
2243 | { | 2237 | { |
2244 | struct sched_class *class = sched_class_highest; | 2238 | struct sched_class *class = sched_class_highest; |
2245 | unsigned long total_load_moved = 0; | 2239 | unsigned long total_load_moved = 0; |
2240 | int this_best_prio = this_rq->curr->prio; | ||
2246 | 2241 | ||
2247 | do { | 2242 | do { |
2248 | total_load_moved += | 2243 | total_load_moved += |
2249 | class->load_balance(this_rq, this_cpu, busiest, | 2244 | class->load_balance(this_rq, this_cpu, busiest, |
2250 | ULONG_MAX, max_load_move - total_load_moved, | 2245 | ULONG_MAX, max_load_move - total_load_moved, |
2251 | sd, idle, all_pinned); | 2246 | sd, idle, all_pinned, &this_best_prio); |
2252 | class = class->next; | 2247 | class = class->next; |
2253 | } while (class && max_load_move > total_load_moved); | 2248 | } while (class && max_load_move > total_load_moved); |
2254 | 2249 | ||
@@ -2266,10 +2261,12 @@ static int move_one_task(struct rq *this_rq, int this_cpu, struct rq *busiest, | |||
2266 | struct sched_domain *sd, enum cpu_idle_type idle) | 2261 | struct sched_domain *sd, enum cpu_idle_type idle) |
2267 | { | 2262 | { |
2268 | struct sched_class *class; | 2263 | struct sched_class *class; |
2264 | int this_best_prio = MAX_PRIO; | ||
2269 | 2265 | ||
2270 | for (class = sched_class_highest; class; class = class->next) | 2266 | for (class = sched_class_highest; class; class = class->next) |
2271 | if (class->load_balance(this_rq, this_cpu, busiest, | 2267 | if (class->load_balance(this_rq, this_cpu, busiest, |
2272 | 1, ULONG_MAX, sd, idle, NULL)) | 2268 | 1, ULONG_MAX, sd, idle, NULL, |
2269 | &this_best_prio)) | ||
2273 | return 1; | 2270 | return 1; |
2274 | 2271 | ||
2275 | return 0; | 2272 | return 0; |
@@ -3184,8 +3181,7 @@ static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, | |||
3184 | unsigned long max_nr_move, unsigned long max_load_move, | 3181 | unsigned long max_nr_move, unsigned long max_load_move, |
3185 | struct sched_domain *sd, enum cpu_idle_type idle, | 3182 | struct sched_domain *sd, enum cpu_idle_type idle, |
3186 | int *all_pinned, unsigned long *load_moved, | 3183 | int *all_pinned, unsigned long *load_moved, |
3187 | int this_best_prio, int best_prio, int best_prio_seen, | 3184 | int *this_best_prio, struct rq_iterator *iterator) |
3188 | struct rq_iterator *iterator) | ||
3189 | { | 3185 | { |
3190 | *load_moved = 0; | 3186 | *load_moved = 0; |
3191 | 3187 | ||
diff --git a/kernel/sched_fair.c b/kernel/sched_fair.c index 16511e9e5528..923bed0b0c42 100644 --- a/kernel/sched_fair.c +++ b/kernel/sched_fair.c | |||
@@ -929,6 +929,7 @@ static struct task_struct *load_balance_next_fair(void *arg) | |||
929 | return __load_balance_iterator(cfs_rq, cfs_rq->rb_load_balance_curr); | 929 | return __load_balance_iterator(cfs_rq, cfs_rq->rb_load_balance_curr); |
930 | } | 930 | } |
931 | 931 | ||
932 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
932 | static int cfs_rq_best_prio(struct cfs_rq *cfs_rq) | 933 | static int cfs_rq_best_prio(struct cfs_rq *cfs_rq) |
933 | { | 934 | { |
934 | struct sched_entity *curr; | 935 | struct sched_entity *curr; |
@@ -942,12 +943,13 @@ static int cfs_rq_best_prio(struct cfs_rq *cfs_rq) | |||
942 | 943 | ||
943 | return p->prio; | 944 | return p->prio; |
944 | } | 945 | } |
946 | #endif | ||
945 | 947 | ||
946 | static unsigned long | 948 | static unsigned long |
947 | load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, | 949 | load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, |
948 | unsigned long max_nr_move, unsigned long max_load_move, | 950 | unsigned long max_nr_move, unsigned long max_load_move, |
949 | struct sched_domain *sd, enum cpu_idle_type idle, | 951 | struct sched_domain *sd, enum cpu_idle_type idle, |
950 | int *all_pinned) | 952 | int *all_pinned, int *this_best_prio) |
951 | { | 953 | { |
952 | struct cfs_rq *busy_cfs_rq; | 954 | struct cfs_rq *busy_cfs_rq; |
953 | unsigned long load_moved, total_nr_moved = 0, nr_moved; | 955 | unsigned long load_moved, total_nr_moved = 0, nr_moved; |
@@ -958,10 +960,10 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, | |||
958 | cfs_rq_iterator.next = load_balance_next_fair; | 960 | cfs_rq_iterator.next = load_balance_next_fair; |
959 | 961 | ||
960 | for_each_leaf_cfs_rq(busiest, busy_cfs_rq) { | 962 | for_each_leaf_cfs_rq(busiest, busy_cfs_rq) { |
963 | #ifdef CONFIG_FAIR_GROUP_SCHED | ||
961 | struct cfs_rq *this_cfs_rq; | 964 | struct cfs_rq *this_cfs_rq; |
962 | long imbalance; | 965 | long imbalances; |
963 | unsigned long maxload; | 966 | unsigned long maxload; |
964 | int this_best_prio, best_prio, best_prio_seen = 0; | ||
965 | 967 | ||
966 | this_cfs_rq = cpu_cfs_rq(busy_cfs_rq, this_cpu); | 968 | this_cfs_rq = cpu_cfs_rq(busy_cfs_rq, this_cpu); |
967 | 969 | ||
@@ -975,27 +977,17 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest, | |||
975 | imbalance /= 2; | 977 | imbalance /= 2; |
976 | maxload = min(rem_load_move, imbalance); | 978 | maxload = min(rem_load_move, imbalance); |
977 | 979 | ||
978 | this_best_prio = cfs_rq_best_prio(this_cfs_rq); | 980 | *this_best_prio = cfs_rq_best_prio(this_cfs_rq); |
979 | best_prio = cfs_rq_best_prio(busy_cfs_rq); | 981 | #else |
980 | 982 | #define maxload rem_load_move | |
981 | /* | 983 | #endif |
982 | * Enable handling of the case where there is more than one task | ||
983 | * with the best priority. If the current running task is one | ||
984 | * of those with prio==best_prio we know it won't be moved | ||
985 | * and therefore it's safe to override the skip (based on load) | ||
986 | * of any task we find with that prio. | ||
987 | */ | ||
988 | if (cfs_rq_curr(busy_cfs_rq) == &busiest->curr->se) | ||
989 | best_prio_seen = 1; | ||
990 | |||
991 | /* pass busy_cfs_rq argument into | 984 | /* pass busy_cfs_rq argument into |
992 | * load_balance_[start|next]_fair iterators | 985 | * load_balance_[start|next]_fair iterators |
993 | */ | 986 | */ |
994 | cfs_rq_iterator.arg = busy_cfs_rq; | 987 | cfs_rq_iterator.arg = busy_cfs_rq; |
995 | nr_moved = balance_tasks(this_rq, this_cpu, busiest, | 988 | nr_moved = balance_tasks(this_rq, this_cpu, busiest, |
996 | max_nr_move, maxload, sd, idle, all_pinned, | 989 | max_nr_move, maxload, sd, idle, all_pinned, |
997 | &load_moved, this_best_prio, best_prio, | 990 | &load_moved, this_best_prio, &cfs_rq_iterator); |
998 | best_prio_seen, &cfs_rq_iterator); | ||
999 | 991 | ||
1000 | total_nr_moved += nr_moved; | 992 | total_nr_moved += nr_moved; |
1001 | max_nr_move -= nr_moved; | 993 | max_nr_move -= nr_moved; |
diff --git a/kernel/sched_idletask.c b/kernel/sched_idletask.c index 1d8d9e13d950..dc9e1068911f 100644 --- a/kernel/sched_idletask.c +++ b/kernel/sched_idletask.c | |||
@@ -41,7 +41,7 @@ static unsigned long | |||
41 | load_balance_idle(struct rq *this_rq, int this_cpu, struct rq *busiest, | 41 | load_balance_idle(struct rq *this_rq, int this_cpu, struct rq *busiest, |
42 | unsigned long max_nr_move, unsigned long max_load_move, | 42 | unsigned long max_nr_move, unsigned long max_load_move, |
43 | struct sched_domain *sd, enum cpu_idle_type idle, | 43 | struct sched_domain *sd, enum cpu_idle_type idle, |
44 | int *all_pinned) | 44 | int *all_pinned, int *this_best_prio) |
45 | { | 45 | { |
46 | return 0; | 46 | return 0; |
47 | } | 47 | } |
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c index 2b0626a43cb8..5b559e8c8aa6 100644 --- a/kernel/sched_rt.c +++ b/kernel/sched_rt.c | |||
@@ -176,26 +176,12 @@ static unsigned long | |||
176 | load_balance_rt(struct rq *this_rq, int this_cpu, struct rq *busiest, | 176 | load_balance_rt(struct rq *this_rq, int this_cpu, struct rq *busiest, |
177 | unsigned long max_nr_move, unsigned long max_load_move, | 177 | unsigned long max_nr_move, unsigned long max_load_move, |
178 | struct sched_domain *sd, enum cpu_idle_type idle, | 178 | struct sched_domain *sd, enum cpu_idle_type idle, |
179 | int *all_pinned) | 179 | int *all_pinned, int *this_best_prio) |
180 | { | 180 | { |
181 | int this_best_prio, best_prio, best_prio_seen = 0; | ||
182 | int nr_moved; | 181 | int nr_moved; |
183 | struct rq_iterator rt_rq_iterator; | 182 | struct rq_iterator rt_rq_iterator; |
184 | unsigned long load_moved; | 183 | unsigned long load_moved; |
185 | 184 | ||
186 | best_prio = sched_find_first_bit(busiest->rt.active.bitmap); | ||
187 | this_best_prio = sched_find_first_bit(this_rq->rt.active.bitmap); | ||
188 | |||
189 | /* | ||
190 | * Enable handling of the case where there is more than one task | ||
191 | * with the best priority. If the current running task is one | ||
192 | * of those with prio==best_prio we know it won't be moved | ||
193 | * and therefore it's safe to override the skip (based on load) | ||
194 | * of any task we find with that prio. | ||
195 | */ | ||
196 | if (busiest->curr->prio == best_prio) | ||
197 | best_prio_seen = 1; | ||
198 | |||
199 | rt_rq_iterator.start = load_balance_start_rt; | 185 | rt_rq_iterator.start = load_balance_start_rt; |
200 | rt_rq_iterator.next = load_balance_next_rt; | 186 | rt_rq_iterator.next = load_balance_next_rt; |
201 | /* pass 'busiest' rq argument into | 187 | /* pass 'busiest' rq argument into |
@@ -205,8 +191,7 @@ load_balance_rt(struct rq *this_rq, int this_cpu, struct rq *busiest, | |||
205 | 191 | ||
206 | nr_moved = balance_tasks(this_rq, this_cpu, busiest, max_nr_move, | 192 | nr_moved = balance_tasks(this_rq, this_cpu, busiest, max_nr_move, |
207 | max_load_move, sd, idle, all_pinned, &load_moved, | 193 | max_load_move, sd, idle, all_pinned, &load_moved, |
208 | this_best_prio, best_prio, best_prio_seen, | 194 | this_best_prio, &rt_rq_iterator); |
209 | &rt_rq_iterator); | ||
210 | 195 | ||
211 | return load_moved; | 196 | return load_moved; |
212 | } | 197 | } |