aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched.c')
-rw-r--r--kernel/sched.c99
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
841static 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, 842static unsigned long
843 struct sched_domain *sd, enum cpu_idle_type idle, 843balance_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
848static int
849iter_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
853static inline unsigned long
854balance_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
862static inline int
863iter_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
2227static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest, 2251static unsigned long
2228 unsigned long max_nr_move, unsigned long max_load_move, 2252balance_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 }
2276out: 2300out:
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
2341static int
2342iter_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 */
3271static 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
3284DEFINE_PER_CPU(struct kernel_stat, kstat); 3319DEFINE_PER_CPU(struct kernel_stat, kstat);