diff options
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 146 |
1 files changed, 0 insertions, 146 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index b56d1505d058..60400a22401f 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -2269,152 +2269,6 @@ void kick_process(struct task_struct *p) | |||
2269 | preempt_enable(); | 2269 | preempt_enable(); |
2270 | } | 2270 | } |
2271 | EXPORT_SYMBOL_GPL(kick_process); | 2271 | EXPORT_SYMBOL_GPL(kick_process); |
2272 | |||
2273 | /* | ||
2274 | * find_idlest_group finds and returns the least busy CPU group within the | ||
2275 | * domain. | ||
2276 | */ | ||
2277 | static struct sched_group * | ||
2278 | find_idlest_group(struct sched_domain *sd, struct task_struct *p, int this_cpu) | ||
2279 | { | ||
2280 | struct sched_group *idlest = NULL, *this = NULL, *group = sd->groups; | ||
2281 | unsigned long min_load = ULONG_MAX, this_load = 0; | ||
2282 | int load_idx = sd->forkexec_idx; | ||
2283 | int imbalance = 100 + (sd->imbalance_pct-100)/2; | ||
2284 | |||
2285 | do { | ||
2286 | unsigned long load, avg_load; | ||
2287 | int local_group; | ||
2288 | int i; | ||
2289 | |||
2290 | /* Skip over this group if it has no CPUs allowed */ | ||
2291 | if (!cpumask_intersects(sched_group_cpus(group), | ||
2292 | &p->cpus_allowed)) | ||
2293 | continue; | ||
2294 | |||
2295 | local_group = cpumask_test_cpu(this_cpu, | ||
2296 | sched_group_cpus(group)); | ||
2297 | |||
2298 | /* Tally up the load of all CPUs in the group */ | ||
2299 | avg_load = 0; | ||
2300 | |||
2301 | for_each_cpu(i, sched_group_cpus(group)) { | ||
2302 | /* Bias balancing toward cpus of our domain */ | ||
2303 | if (local_group) | ||
2304 | load = source_load(i, load_idx); | ||
2305 | else | ||
2306 | load = target_load(i, load_idx); | ||
2307 | |||
2308 | avg_load += load; | ||
2309 | } | ||
2310 | |||
2311 | /* Adjust by relative CPU power of the group */ | ||
2312 | avg_load = (avg_load * SCHED_LOAD_SCALE) / group->cpu_power; | ||
2313 | |||
2314 | if (local_group) { | ||
2315 | this_load = avg_load; | ||
2316 | this = group; | ||
2317 | } else if (avg_load < min_load) { | ||
2318 | min_load = avg_load; | ||
2319 | idlest = group; | ||
2320 | } | ||
2321 | } while (group = group->next, group != sd->groups); | ||
2322 | |||
2323 | if (!idlest || 100*this_load < imbalance*min_load) | ||
2324 | return NULL; | ||
2325 | return idlest; | ||
2326 | } | ||
2327 | |||
2328 | /* | ||
2329 | * find_idlest_cpu - find the idlest cpu among the cpus in group. | ||
2330 | */ | ||
2331 | static int | ||
2332 | find_idlest_cpu(struct sched_group *group, struct task_struct *p, int this_cpu) | ||
2333 | { | ||
2334 | unsigned long load, min_load = ULONG_MAX; | ||
2335 | int idlest = -1; | ||
2336 | int i; | ||
2337 | |||
2338 | /* Traverse only the allowed CPUs */ | ||
2339 | for_each_cpu_and(i, sched_group_cpus(group), &p->cpus_allowed) { | ||
2340 | load = weighted_cpuload(i); | ||
2341 | |||
2342 | if (load < min_load || (load == min_load && i == this_cpu)) { | ||
2343 | min_load = load; | ||
2344 | idlest = i; | ||
2345 | } | ||
2346 | } | ||
2347 | |||
2348 | return idlest; | ||
2349 | } | ||
2350 | |||
2351 | /* | ||
2352 | * sched_balance_self: balance the current task (running on cpu) in domains | ||
2353 | * that have the 'flag' flag set. In practice, this is SD_BALANCE_FORK and | ||
2354 | * SD_BALANCE_EXEC. | ||
2355 | * | ||
2356 | * Balance, ie. select the least loaded group. | ||
2357 | * | ||
2358 | * Returns the target CPU number, or the same CPU if no balancing is needed. | ||
2359 | * | ||
2360 | * preempt must be disabled. | ||
2361 | */ | ||
2362 | static int sched_balance_self(int cpu, int flag) | ||
2363 | { | ||
2364 | struct task_struct *t = current; | ||
2365 | struct sched_domain *tmp, *sd = NULL; | ||
2366 | |||
2367 | for_each_domain(cpu, tmp) { | ||
2368 | /* | ||
2369 | * If power savings logic is enabled for a domain, stop there. | ||
2370 | */ | ||
2371 | if (tmp->flags & SD_POWERSAVINGS_BALANCE) | ||
2372 | break; | ||
2373 | if (tmp->flags & flag) | ||
2374 | sd = tmp; | ||
2375 | } | ||
2376 | |||
2377 | if (sd) | ||
2378 | update_shares(sd); | ||
2379 | |||
2380 | while (sd) { | ||
2381 | struct sched_group *group; | ||
2382 | int new_cpu, weight; | ||
2383 | |||
2384 | if (!(sd->flags & flag)) { | ||
2385 | sd = sd->child; | ||
2386 | continue; | ||
2387 | } | ||
2388 | |||
2389 | group = find_idlest_group(sd, t, cpu); | ||
2390 | if (!group) { | ||
2391 | sd = sd->child; | ||
2392 | continue; | ||
2393 | } | ||
2394 | |||
2395 | new_cpu = find_idlest_cpu(group, t, cpu); | ||
2396 | if (new_cpu == -1 || new_cpu == cpu) { | ||
2397 | /* Now try balancing at a lower domain level of cpu */ | ||
2398 | sd = sd->child; | ||
2399 | continue; | ||
2400 | } | ||
2401 | |||
2402 | /* Now try balancing at a lower domain level of new_cpu */ | ||
2403 | cpu = new_cpu; | ||
2404 | weight = cpumask_weight(sched_domain_span(sd)); | ||
2405 | sd = NULL; | ||
2406 | for_each_domain(cpu, tmp) { | ||
2407 | if (weight <= cpumask_weight(sched_domain_span(tmp))) | ||
2408 | break; | ||
2409 | if (tmp->flags & flag) | ||
2410 | sd = tmp; | ||
2411 | } | ||
2412 | /* while loop will break here if sd == NULL */ | ||
2413 | } | ||
2414 | |||
2415 | return cpu; | ||
2416 | } | ||
2417 | |||
2418 | #endif /* CONFIG_SMP */ | 2272 | #endif /* CONFIG_SMP */ |
2419 | 2273 | ||
2420 | /** | 2274 | /** |