diff options
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 99 |
1 files changed, 67 insertions, 32 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index cc9cd5b710a6..8607795fad69 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -838,11 +838,35 @@ struct rq_iterator { | |||
838 | struct task_struct *(*next)(void *); | 838 | struct task_struct *(*next)(void *); |
839 | }; | 839 | }; |
840 | 840 | ||
841 | static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, | 841 | #ifdef CONFIG_SMP |
842 | unsigned long max_nr_move, unsigned long max_load_move, | 842 | static unsigned long |
843 | struct sched_domain *sd, enum cpu_idle_type idle, | 843 | balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, |
844 | int *all_pinned, unsigned long *load_moved, | 844 | unsigned long max_load_move, struct sched_domain *sd, |
845 | int *this_best_prio, struct rq_iterator *iterator); | 845 | enum cpu_idle_type idle, int *all_pinned, |
846 | int *this_best_prio, struct rq_iterator *iterator); | ||
847 | |||
848 | static int | ||
849 | iter_move_one_task(struct rq *this_rq, int this_cpu, struct rq *busiest, | ||
850 | struct sched_domain *sd, enum cpu_idle_type idle, | ||
851 | struct rq_iterator *iterator); | ||
852 | #else | ||
853 | static inline unsigned long | ||
854 | balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, | ||
855 | unsigned long max_load_move, struct sched_domain *sd, | ||
856 | enum cpu_idle_type idle, int *all_pinned, | ||
857 | int *this_best_prio, struct rq_iterator *iterator) | ||
858 | { | ||
859 | return 0; | ||
860 | } | ||
861 | |||
862 | static inline int | ||
863 | iter_move_one_task(struct rq *this_rq, int this_cpu, struct rq *busiest, | ||
864 | struct sched_domain *sd, enum cpu_idle_type idle, | ||
865 | struct rq_iterator *iterator) | ||
866 | { | ||
867 | return 0; | ||
868 | } | ||
869 | #endif | ||
846 | 870 | ||
847 | #include "sched_stats.h" | 871 | #include "sched_stats.h" |
848 | #include "sched_idletask.c" | 872 | #include "sched_idletask.c" |
@@ -2224,17 +2248,17 @@ int can_migrate_task(struct task_struct *p, struct rq *rq, int this_cpu, | |||
2224 | return 1; | 2248 | return 1; |
2225 | } | 2249 | } |
2226 | 2250 | ||
2227 | static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, | 2251 | static unsigned long |
2228 | unsigned long max_nr_move, unsigned long max_load_move, | 2252 | balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, |
2229 | struct sched_domain *sd, enum cpu_idle_type idle, | 2253 | unsigned long max_load_move, struct sched_domain *sd, |
2230 | int *all_pinned, unsigned long *load_moved, | 2254 | enum cpu_idle_type idle, int *all_pinned, |
2231 | int *this_best_prio, struct rq_iterator *iterator) | 2255 | int *this_best_prio, struct rq_iterator *iterator) |
2232 | { | 2256 | { |
2233 | int pulled = 0, pinned = 0, skip_for_load; | 2257 | int pulled = 0, pinned = 0, skip_for_load; |
2234 | struct task_struct *p; | 2258 | struct task_struct *p; |
2235 | long rem_load_move = max_load_move; | 2259 | long rem_load_move = max_load_move; |
2236 | 2260 | ||
2237 | if (max_nr_move == 0 || max_load_move == 0) | 2261 | if (max_load_move == 0) |
2238 | goto out; | 2262 | goto out; |
2239 | 2263 | ||
2240 | pinned = 1; | 2264 | pinned = 1; |
@@ -2267,7 +2291,7 @@ next: | |||
2267 | * We only want to steal up to the prescribed number of tasks | 2291 | * We only want to steal up to the prescribed number of tasks |
2268 | * and the prescribed amount of weighted load. | 2292 | * and the prescribed amount of weighted load. |
2269 | */ | 2293 | */ |
2270 | if (pulled < max_nr_move && rem_load_move > 0) { | 2294 | if (rem_load_move > 0) { |
2271 | if (p->prio < *this_best_prio) | 2295 | if (p->prio < *this_best_prio) |
2272 | *this_best_prio = p->prio; | 2296 | *this_best_prio = p->prio; |
2273 | p = iterator->next(iterator->arg); | 2297 | p = iterator->next(iterator->arg); |
@@ -2275,7 +2299,7 @@ next: | |||
2275 | } | 2299 | } |
2276 | out: | 2300 | out: |
2277 | /* | 2301 | /* |
2278 | * Right now, this is the only place pull_task() is called, | 2302 | * Right now, this is one of only two places pull_task() is called, |
2279 | * so we can safely collect pull_task() stats here rather than | 2303 | * so we can safely collect pull_task() stats here rather than |
2280 | * inside pull_task(). | 2304 | * inside pull_task(). |
2281 | */ | 2305 | */ |
@@ -2283,8 +2307,8 @@ out: | |||
2283 | 2307 | ||
2284 | if (all_pinned) | 2308 | if (all_pinned) |
2285 | *all_pinned = pinned; | 2309 | *all_pinned = pinned; |
2286 | *load_moved = max_load_move - rem_load_move; | 2310 | |
2287 | return pulled; | 2311 | return max_load_move - rem_load_move; |
2288 | } | 2312 | } |
2289 | 2313 | ||
2290 | /* | 2314 | /* |
@@ -2306,7 +2330,7 @@ static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, | |||
2306 | do { | 2330 | do { |
2307 | total_load_moved += | 2331 | total_load_moved += |
2308 | class->load_balance(this_rq, this_cpu, busiest, | 2332 | class->load_balance(this_rq, this_cpu, busiest, |
2309 | ULONG_MAX, max_load_move - total_load_moved, | 2333 | max_load_move - total_load_moved, |
2310 | sd, idle, all_pinned, &this_best_prio); | 2334 | sd, idle, all_pinned, &this_best_prio); |
2311 | class = class->next; | 2335 | class = class->next; |
2312 | } while (class && max_load_move > total_load_moved); | 2336 | } while (class && max_load_move > total_load_moved); |
@@ -2314,6 +2338,32 @@ static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, | |||
2314 | return total_load_moved > 0; | 2338 | return total_load_moved > 0; |
2315 | } | 2339 | } |
2316 | 2340 | ||
2341 | static int | ||
2342 | iter_move_one_task(struct rq *this_rq, int this_cpu, struct rq *busiest, | ||
2343 | struct sched_domain *sd, enum cpu_idle_type idle, | ||
2344 | struct rq_iterator *iterator) | ||
2345 | { | ||
2346 | struct task_struct *p = iterator->start(iterator->arg); | ||
2347 | int pinned = 0; | ||
2348 | |||
2349 | while (p) { | ||
2350 | if (can_migrate_task(p, busiest, this_cpu, sd, idle, &pinned)) { | ||
2351 | pull_task(busiest, p, this_rq, this_cpu); | ||
2352 | /* | ||
2353 | * Right now, this is only the second place pull_task() | ||
2354 | * is called, so we can safely collect pull_task() | ||
2355 | * stats here rather than inside pull_task(). | ||
2356 | */ | ||
2357 | schedstat_inc(sd, lb_gained[idle]); | ||
2358 | |||
2359 | return 1; | ||
2360 | } | ||
2361 | p = iterator->next(iterator->arg); | ||
2362 | } | ||
2363 | |||
2364 | return 0; | ||
2365 | } | ||
2366 | |||
2317 | /* | 2367 | /* |
2318 | * move_one_task tries to move exactly one task from busiest to this_rq, as | 2368 | * move_one_task tries to move exactly one task from busiest to this_rq, as |
2319 | * part of active balancing operations within "domain". | 2369 | * part of active balancing operations within "domain". |
@@ -2325,12 +2375,9 @@ static int move_one_task(struct rq *this_rq, int this_cpu, struct rq *busiest, | |||
2325 | struct sched_domain *sd, enum cpu_idle_type idle) | 2375 | struct sched_domain *sd, enum cpu_idle_type idle) |
2326 | { | 2376 | { |
2327 | const struct sched_class *class; | 2377 | const struct sched_class *class; |
2328 | int this_best_prio = MAX_PRIO; | ||
2329 | 2378 | ||
2330 | for (class = sched_class_highest; class; class = class->next) | 2379 | for (class = sched_class_highest; class; class = class->next) |
2331 | if (class->load_balance(this_rq, this_cpu, busiest, | 2380 | if (class->move_one_task(this_rq, this_cpu, busiest, sd, idle)) |
2332 | 1, ULONG_MAX, sd, idle, NULL, | ||
2333 | &this_best_prio)) | ||
2334 | return 1; | 2381 | return 1; |
2335 | 2382 | ||
2336 | return 0; | 2383 | return 0; |
@@ -3267,18 +3314,6 @@ static inline void idle_balance(int cpu, struct rq *rq) | |||
3267 | { | 3314 | { |
3268 | } | 3315 | } |
3269 | 3316 | ||
3270 | /* Avoid "used but not defined" warning on UP */ | ||
3271 | static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, | ||
3272 | unsigned long max_nr_move, unsigned long max_load_move, | ||
3273 | struct sched_domain *sd, enum cpu_idle_type idle, | ||
3274 | int *all_pinned, unsigned long *load_moved, | ||
3275 | int *this_best_prio, struct rq_iterator *iterator) | ||
3276 | { | ||
3277 | *load_moved = 0; | ||
3278 | |||
3279 | return 0; | ||
3280 | } | ||
3281 | |||
3282 | #endif | 3317 | #endif |
3283 | 3318 | ||
3284 | DEFINE_PER_CPU(struct kernel_stat, kstat); | 3319 | DEFINE_PER_CPU(struct kernel_stat, kstat); |