diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/sched.c | 79 |
1 files changed, 46 insertions, 33 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index f87adbe999e0..109db122de50 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -3192,6 +3192,18 @@ static int move_one_task(struct rq *this_rq, int this_cpu, struct rq *busiest, | |||
| 3192 | /********** Helpers for find_busiest_group ************************/ | 3192 | /********** Helpers for find_busiest_group ************************/ |
| 3193 | 3193 | ||
| 3194 | /** | 3194 | /** |
| 3195 | * sg_lb_stats - stats of a sched_group required for load_balancing | ||
| 3196 | */ | ||
| 3197 | struct sg_lb_stats { | ||
| 3198 | unsigned long avg_load; /*Avg load across the CPUs of the group */ | ||
| 3199 | unsigned long group_load; /* Total load over the CPUs of the group */ | ||
| 3200 | unsigned long sum_nr_running; /* Nr tasks running in the group */ | ||
| 3201 | unsigned long sum_weighted_load; /* Weighted load of group's tasks */ | ||
| 3202 | unsigned long group_capacity; | ||
| 3203 | int group_imb; /* Is there an imbalance in the group ? */ | ||
| 3204 | }; | ||
| 3205 | |||
| 3206 | /** | ||
| 3195 | * group_first_cpu - Returns the first cpu in the cpumask of a sched_group. | 3207 | * group_first_cpu - Returns the first cpu in the cpumask of a sched_group. |
| 3196 | * @group: The group whose first cpu is to be returned. | 3208 | * @group: The group whose first cpu is to be returned. |
| 3197 | */ | 3209 | */ |
| @@ -3257,23 +3269,22 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, | |||
| 3257 | load_idx = get_sd_load_idx(sd, idle); | 3269 | load_idx = get_sd_load_idx(sd, idle); |
| 3258 | 3270 | ||
| 3259 | do { | 3271 | do { |
| 3260 | unsigned long load, group_capacity, max_cpu_load, min_cpu_load; | 3272 | struct sg_lb_stats sgs; |
| 3273 | unsigned long load, max_cpu_load, min_cpu_load; | ||
| 3261 | int local_group; | 3274 | int local_group; |
| 3262 | int i; | 3275 | int i; |
| 3263 | int __group_imb = 0; | ||
| 3264 | unsigned int balance_cpu = -1, first_idle_cpu = 0; | 3276 | unsigned int balance_cpu = -1, first_idle_cpu = 0; |
| 3265 | unsigned long sum_nr_running, sum_weighted_load; | ||
| 3266 | unsigned long sum_avg_load_per_task; | 3277 | unsigned long sum_avg_load_per_task; |
| 3267 | unsigned long avg_load_per_task; | 3278 | unsigned long avg_load_per_task; |
| 3268 | 3279 | ||
| 3269 | local_group = cpumask_test_cpu(this_cpu, | 3280 | local_group = cpumask_test_cpu(this_cpu, |
| 3270 | sched_group_cpus(group)); | 3281 | sched_group_cpus(group)); |
| 3282 | memset(&sgs, 0, sizeof(sgs)); | ||
| 3271 | 3283 | ||
| 3272 | if (local_group) | 3284 | if (local_group) |
| 3273 | balance_cpu = group_first_cpu(group); | 3285 | balance_cpu = group_first_cpu(group); |
| 3274 | 3286 | ||
| 3275 | /* Tally up the load of all CPUs in the group */ | 3287 | /* Tally up the load of all CPUs in the group */ |
| 3276 | sum_weighted_load = sum_nr_running = avg_load = 0; | ||
| 3277 | sum_avg_load_per_task = avg_load_per_task = 0; | 3288 | sum_avg_load_per_task = avg_load_per_task = 0; |
| 3278 | 3289 | ||
| 3279 | max_cpu_load = 0; | 3290 | max_cpu_load = 0; |
| @@ -3301,9 +3312,9 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, | |||
| 3301 | min_cpu_load = load; | 3312 | min_cpu_load = load; |
| 3302 | } | 3313 | } |
| 3303 | 3314 | ||
| 3304 | avg_load += load; | 3315 | sgs.group_load += load; |
| 3305 | sum_nr_running += rq->nr_running; | 3316 | sgs.sum_nr_running += rq->nr_running; |
| 3306 | sum_weighted_load += weighted_cpuload(i); | 3317 | sgs.sum_weighted_load += weighted_cpuload(i); |
| 3307 | 3318 | ||
| 3308 | sum_avg_load_per_task += cpu_avg_load_per_task(i); | 3319 | sum_avg_load_per_task += cpu_avg_load_per_task(i); |
| 3309 | } | 3320 | } |
| @@ -3320,12 +3331,12 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, | |||
| 3320 | goto ret; | 3331 | goto ret; |
| 3321 | } | 3332 | } |
| 3322 | 3333 | ||
| 3323 | total_load += avg_load; | 3334 | total_load += sgs.group_load; |
| 3324 | total_pwr += group->__cpu_power; | 3335 | total_pwr += group->__cpu_power; |
| 3325 | 3336 | ||
| 3326 | /* Adjust by relative CPU power of the group */ | 3337 | /* Adjust by relative CPU power of the group */ |
| 3327 | avg_load = sg_div_cpu_power(group, | 3338 | sgs.avg_load = sg_div_cpu_power(group, |
| 3328 | avg_load * SCHED_LOAD_SCALE); | 3339 | sgs.group_load * SCHED_LOAD_SCALE); |
| 3329 | 3340 | ||
| 3330 | 3341 | ||
| 3331 | /* | 3342 | /* |
| @@ -3341,22 +3352,23 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, | |||
| 3341 | sum_avg_load_per_task * SCHED_LOAD_SCALE); | 3352 | sum_avg_load_per_task * SCHED_LOAD_SCALE); |
| 3342 | 3353 | ||
| 3343 | if ((max_cpu_load - min_cpu_load) > 2*avg_load_per_task) | 3354 | if ((max_cpu_load - min_cpu_load) > 2*avg_load_per_task) |
| 3344 | __group_imb = 1; | 3355 | sgs.group_imb = 1; |
| 3345 | 3356 | ||
| 3346 | group_capacity = group->__cpu_power / SCHED_LOAD_SCALE; | 3357 | sgs.group_capacity = group->__cpu_power / SCHED_LOAD_SCALE; |
| 3347 | 3358 | ||
| 3348 | if (local_group) { | 3359 | if (local_group) { |
| 3349 | this_load = avg_load; | 3360 | this_load = sgs.avg_load; |
| 3350 | this = group; | 3361 | this = group; |
| 3351 | this_nr_running = sum_nr_running; | 3362 | this_nr_running = sgs.sum_nr_running; |
| 3352 | this_load_per_task = sum_weighted_load; | 3363 | this_load_per_task = sgs.sum_weighted_load; |
| 3353 | } else if (avg_load > max_load && | 3364 | } else if (sgs.avg_load > max_load && |
| 3354 | (sum_nr_running > group_capacity || __group_imb)) { | 3365 | (sgs.sum_nr_running > sgs.group_capacity || |
| 3355 | max_load = avg_load; | 3366 | sgs.group_imb)) { |
| 3367 | max_load = sgs.avg_load; | ||
| 3356 | busiest = group; | 3368 | busiest = group; |
| 3357 | busiest_nr_running = sum_nr_running; | 3369 | busiest_nr_running = sgs.sum_nr_running; |
| 3358 | busiest_load_per_task = sum_weighted_load; | 3370 | busiest_load_per_task = sgs.sum_weighted_load; |
| 3359 | group_imb = __group_imb; | 3371 | group_imb = sgs.group_imb; |
| 3360 | } | 3372 | } |
| 3361 | 3373 | ||
| 3362 | #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) | 3374 | #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) |
| @@ -3372,7 +3384,7 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, | |||
| 3372 | * If the local group is idle or completely loaded | 3384 | * If the local group is idle or completely loaded |
| 3373 | * no need to do power savings balance at this domain | 3385 | * no need to do power savings balance at this domain |
| 3374 | */ | 3386 | */ |
| 3375 | if (local_group && (this_nr_running >= group_capacity || | 3387 | if (local_group && (this_nr_running >= sgs.group_capacity || |
| 3376 | !this_nr_running)) | 3388 | !this_nr_running)) |
| 3377 | power_savings_balance = 0; | 3389 | power_savings_balance = 0; |
| 3378 | 3390 | ||
| @@ -3380,8 +3392,9 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, | |||
| 3380 | * If a group is already running at full capacity or idle, | 3392 | * If a group is already running at full capacity or idle, |
| 3381 | * don't include that group in power savings calculations | 3393 | * don't include that group in power savings calculations |
| 3382 | */ | 3394 | */ |
| 3383 | if (!power_savings_balance || sum_nr_running >= group_capacity | 3395 | if (!power_savings_balance || |
| 3384 | || !sum_nr_running) | 3396 | sgs.sum_nr_running >= sgs.group_capacity || |
| 3397 | !sgs.sum_nr_running) | ||
| 3385 | goto group_next; | 3398 | goto group_next; |
| 3386 | 3399 | ||
| 3387 | /* | 3400 | /* |
| @@ -3389,13 +3402,13 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, | |||
| 3389 | * This is the group from where we need to pick up the load | 3402 | * This is the group from where we need to pick up the load |
| 3390 | * for saving power | 3403 | * for saving power |
| 3391 | */ | 3404 | */ |
| 3392 | if ((sum_nr_running < min_nr_running) || | 3405 | if ((sgs.sum_nr_running < min_nr_running) || |
| 3393 | (sum_nr_running == min_nr_running && | 3406 | (sgs.sum_nr_running == min_nr_running && |
| 3394 | group_first_cpu(group) > group_first_cpu(group_min))) { | 3407 | group_first_cpu(group) > group_first_cpu(group_min))) { |
| 3395 | group_min = group; | 3408 | group_min = group; |
| 3396 | min_nr_running = sum_nr_running; | 3409 | min_nr_running = sgs.sum_nr_running; |
| 3397 | min_load_per_task = sum_weighted_load / | 3410 | min_load_per_task = sgs.sum_weighted_load / |
| 3398 | sum_nr_running; | 3411 | sgs.sum_nr_running; |
| 3399 | } | 3412 | } |
| 3400 | 3413 | ||
| 3401 | /* | 3414 | /* |
| @@ -3403,14 +3416,14 @@ find_busiest_group(struct sched_domain *sd, int this_cpu, | |||
| 3403 | * capacity but still has some space to pick up some load | 3416 | * capacity but still has some space to pick up some load |
| 3404 | * from other group and save more power | 3417 | * from other group and save more power |
| 3405 | */ | 3418 | */ |
| 3406 | if (sum_nr_running > group_capacity - 1) | 3419 | if (sgs.sum_nr_running > sgs.group_capacity - 1) |
| 3407 | goto group_next; | 3420 | goto group_next; |
| 3408 | 3421 | ||
| 3409 | if (sum_nr_running > leader_nr_running || | 3422 | if (sgs.sum_nr_running > leader_nr_running || |
| 3410 | (sum_nr_running == leader_nr_running && | 3423 | (sgs.sum_nr_running == leader_nr_running && |
| 3411 | group_first_cpu(group) < group_first_cpu(group_leader))) { | 3424 | group_first_cpu(group) < group_first_cpu(group_leader))) { |
| 3412 | group_leader = group; | 3425 | group_leader = group; |
| 3413 | leader_nr_running = sum_nr_running; | 3426 | leader_nr_running = sgs.sum_nr_running; |
| 3414 | } | 3427 | } |
| 3415 | group_next: | 3428 | group_next: |
| 3416 | #endif | 3429 | #endif |
