diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-27 22:37:00 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-04-27 22:37:00 -0400 |
| commit | daae677f56187e83ddc81cf8e45bbcc236e0e661 (patch) | |
| tree | ed4dbd2383c4096f6ef00f57fd4635f5b045a6b1 /kernel | |
| parent | 06fc5d3d248bdae213aed9efe3a262acf10acd94 (diff) | |
| parent | fb2cf2c660971bea0ad86a9a5c19ad39eab61344 (diff) | |
Merge branch 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull scheduler fixes from Ingo Molnar.
* 'sched-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
sched: Fix OOPS when build_sched_domains() percpu allocation fails
sched: Fix more load-balancing fallout
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/sched/core.c | 22 | ||||
| -rw-r--r-- | kernel/sched/fair.c | 18 | ||||
| -rw-r--r-- | kernel/sched/features.h | 1 |
3 files changed, 27 insertions, 14 deletions
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 4603b9d8f30a..0533a688ce22 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
| @@ -6405,16 +6405,26 @@ static void __sdt_free(const struct cpumask *cpu_map) | |||
| 6405 | struct sd_data *sdd = &tl->data; | 6405 | struct sd_data *sdd = &tl->data; |
| 6406 | 6406 | ||
| 6407 | for_each_cpu(j, cpu_map) { | 6407 | for_each_cpu(j, cpu_map) { |
| 6408 | struct sched_domain *sd = *per_cpu_ptr(sdd->sd, j); | 6408 | struct sched_domain *sd; |
| 6409 | if (sd && (sd->flags & SD_OVERLAP)) | 6409 | |
| 6410 | free_sched_groups(sd->groups, 0); | 6410 | if (sdd->sd) { |
| 6411 | kfree(*per_cpu_ptr(sdd->sd, j)); | 6411 | sd = *per_cpu_ptr(sdd->sd, j); |
| 6412 | kfree(*per_cpu_ptr(sdd->sg, j)); | 6412 | if (sd && (sd->flags & SD_OVERLAP)) |
| 6413 | kfree(*per_cpu_ptr(sdd->sgp, j)); | 6413 | free_sched_groups(sd->groups, 0); |
| 6414 | kfree(*per_cpu_ptr(sdd->sd, j)); | ||
| 6415 | } | ||
| 6416 | |||
| 6417 | if (sdd->sg) | ||
| 6418 | kfree(*per_cpu_ptr(sdd->sg, j)); | ||
| 6419 | if (sdd->sgp) | ||
| 6420 | kfree(*per_cpu_ptr(sdd->sgp, j)); | ||
| 6414 | } | 6421 | } |
| 6415 | free_percpu(sdd->sd); | 6422 | free_percpu(sdd->sd); |
| 6423 | sdd->sd = NULL; | ||
| 6416 | free_percpu(sdd->sg); | 6424 | free_percpu(sdd->sg); |
| 6425 | sdd->sg = NULL; | ||
| 6417 | free_percpu(sdd->sgp); | 6426 | free_percpu(sdd->sgp); |
| 6427 | sdd->sgp = NULL; | ||
| 6418 | } | 6428 | } |
| 6419 | } | 6429 | } |
| 6420 | 6430 | ||
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 0d97ebdc58f0..e9553640c1c3 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
| @@ -784,7 +784,7 @@ account_entity_enqueue(struct cfs_rq *cfs_rq, struct sched_entity *se) | |||
| 784 | update_load_add(&rq_of(cfs_rq)->load, se->load.weight); | 784 | update_load_add(&rq_of(cfs_rq)->load, se->load.weight); |
| 785 | #ifdef CONFIG_SMP | 785 | #ifdef CONFIG_SMP |
| 786 | if (entity_is_task(se)) | 786 | if (entity_is_task(se)) |
| 787 | list_add_tail(&se->group_node, &rq_of(cfs_rq)->cfs_tasks); | 787 | list_add(&se->group_node, &rq_of(cfs_rq)->cfs_tasks); |
| 788 | #endif | 788 | #endif |
| 789 | cfs_rq->nr_running++; | 789 | cfs_rq->nr_running++; |
| 790 | } | 790 | } |
| @@ -3215,6 +3215,8 @@ static int move_one_task(struct lb_env *env) | |||
| 3215 | 3215 | ||
| 3216 | static unsigned long task_h_load(struct task_struct *p); | 3216 | static unsigned long task_h_load(struct task_struct *p); |
| 3217 | 3217 | ||
| 3218 | static const unsigned int sched_nr_migrate_break = 32; | ||
| 3219 | |||
| 3218 | /* | 3220 | /* |
| 3219 | * move_tasks tries to move up to load_move weighted load from busiest to | 3221 | * move_tasks tries to move up to load_move weighted load from busiest to |
| 3220 | * this_rq, as part of a balancing operation within domain "sd". | 3222 | * this_rq, as part of a balancing operation within domain "sd". |
| @@ -3242,7 +3244,7 @@ static int move_tasks(struct lb_env *env) | |||
| 3242 | 3244 | ||
| 3243 | /* take a breather every nr_migrate tasks */ | 3245 | /* take a breather every nr_migrate tasks */ |
| 3244 | if (env->loop > env->loop_break) { | 3246 | if (env->loop > env->loop_break) { |
| 3245 | env->loop_break += sysctl_sched_nr_migrate; | 3247 | env->loop_break += sched_nr_migrate_break; |
| 3246 | env->flags |= LBF_NEED_BREAK; | 3248 | env->flags |= LBF_NEED_BREAK; |
| 3247 | break; | 3249 | break; |
| 3248 | } | 3250 | } |
| @@ -3252,7 +3254,7 @@ static int move_tasks(struct lb_env *env) | |||
| 3252 | 3254 | ||
| 3253 | load = task_h_load(p); | 3255 | load = task_h_load(p); |
| 3254 | 3256 | ||
| 3255 | if (load < 16 && !env->sd->nr_balance_failed) | 3257 | if (sched_feat(LB_MIN) && load < 16 && !env->sd->nr_balance_failed) |
| 3256 | goto next; | 3258 | goto next; |
| 3257 | 3259 | ||
| 3258 | if ((load / 2) > env->load_move) | 3260 | if ((load / 2) > env->load_move) |
| @@ -4407,7 +4409,7 @@ static int load_balance(int this_cpu, struct rq *this_rq, | |||
| 4407 | .dst_cpu = this_cpu, | 4409 | .dst_cpu = this_cpu, |
| 4408 | .dst_rq = this_rq, | 4410 | .dst_rq = this_rq, |
| 4409 | .idle = idle, | 4411 | .idle = idle, |
| 4410 | .loop_break = sysctl_sched_nr_migrate, | 4412 | .loop_break = sched_nr_migrate_break, |
| 4411 | }; | 4413 | }; |
| 4412 | 4414 | ||
| 4413 | cpumask_copy(cpus, cpu_active_mask); | 4415 | cpumask_copy(cpus, cpu_active_mask); |
| @@ -4445,10 +4447,10 @@ redo: | |||
| 4445 | * correctly treated as an imbalance. | 4447 | * correctly treated as an imbalance. |
| 4446 | */ | 4448 | */ |
| 4447 | env.flags |= LBF_ALL_PINNED; | 4449 | env.flags |= LBF_ALL_PINNED; |
| 4448 | env.load_move = imbalance; | 4450 | env.load_move = imbalance; |
| 4449 | env.src_cpu = busiest->cpu; | 4451 | env.src_cpu = busiest->cpu; |
| 4450 | env.src_rq = busiest; | 4452 | env.src_rq = busiest; |
| 4451 | env.loop_max = busiest->nr_running; | 4453 | env.loop_max = min_t(unsigned long, sysctl_sched_nr_migrate, busiest->nr_running); |
| 4452 | 4454 | ||
| 4453 | more_balance: | 4455 | more_balance: |
| 4454 | local_irq_save(flags); | 4456 | local_irq_save(flags); |
diff --git a/kernel/sched/features.h b/kernel/sched/features.h index e61fd73913d0..de00a486c5c6 100644 --- a/kernel/sched/features.h +++ b/kernel/sched/features.h | |||
| @@ -68,3 +68,4 @@ SCHED_FEAT(TTWU_QUEUE, true) | |||
| 68 | 68 | ||
| 69 | SCHED_FEAT(FORCE_SD_OVERLAP, false) | 69 | SCHED_FEAT(FORCE_SD_OVERLAP, false) |
| 70 | SCHED_FEAT(RT_RUNTIME_SHARE, true) | 70 | SCHED_FEAT(RT_RUNTIME_SHARE, true) |
| 71 | SCHED_FEAT(LB_MIN, false) | ||
