diff options
| author | Peter Williams <pwil3058@bigpond.net.au> | 2009-09-24 02:47:10 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-10-05 07:42:20 -0400 |
| commit | f83f9ac2632732bd1678150b5a03d152f912fe72 (patch) | |
| tree | cbf8600bf31cec0cb7d22c02cdcd27d992ba5c84 | |
| parent | 374576a8b6f865022c0fd1ca62396889b23d66dd (diff) | |
sched: Set correct normal_prio and prio values in sched_fork()
normal_prio should be updated if policy changes from RT to
SCHED_MORMAL or if static_prio/nice is changed.
Some paths through sched_fork() ignore this requirement and may
result in normal_prio having an invalid value.
Fixing this issue allows the call to effective_prio() in
wake_up_new_task() to be removed.
Signed-off-by: Peter Williams <pwil3058@bigpond.net.au>
Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Mike Galbraith <efault@gmx.de>
LKML-Reference: <f8f46736fd4e7f090ac0.1253774830@mudlark.pw.nest>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
| -rw-r--r-- | kernel/sched.c | 20 |
1 files changed, 9 insertions, 11 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 1535f3884b88..76c0e9691fc0 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
| @@ -2515,22 +2515,17 @@ void sched_fork(struct task_struct *p, int clone_flags) | |||
| 2515 | __sched_fork(p); | 2515 | __sched_fork(p); |
| 2516 | 2516 | ||
| 2517 | /* | 2517 | /* |
| 2518 | * Make sure we do not leak PI boosting priority to the child. | ||
| 2519 | */ | ||
| 2520 | p->prio = current->normal_prio; | ||
| 2521 | |||
| 2522 | /* | ||
| 2523 | * Revert to default priority/policy on fork if requested. | 2518 | * Revert to default priority/policy on fork if requested. |
| 2524 | */ | 2519 | */ |
| 2525 | if (unlikely(p->sched_reset_on_fork)) { | 2520 | if (unlikely(p->sched_reset_on_fork)) { |
| 2526 | if (p->policy == SCHED_FIFO || p->policy == SCHED_RR) | 2521 | if (p->policy == SCHED_FIFO || p->policy == SCHED_RR) { |
| 2527 | p->policy = SCHED_NORMAL; | 2522 | p->policy = SCHED_NORMAL; |
| 2528 | 2523 | p->normal_prio = p->static_prio; | |
| 2529 | if (p->normal_prio < DEFAULT_PRIO) | 2524 | } |
| 2530 | p->prio = DEFAULT_PRIO; | ||
| 2531 | 2525 | ||
| 2532 | if (PRIO_TO_NICE(p->static_prio) < 0) { | 2526 | if (PRIO_TO_NICE(p->static_prio) < 0) { |
| 2533 | p->static_prio = NICE_TO_PRIO(0); | 2527 | p->static_prio = NICE_TO_PRIO(0); |
| 2528 | p->normal_prio = p->static_prio; | ||
| 2534 | set_load_weight(p); | 2529 | set_load_weight(p); |
| 2535 | } | 2530 | } |
| 2536 | 2531 | ||
| @@ -2541,6 +2536,11 @@ void sched_fork(struct task_struct *p, int clone_flags) | |||
| 2541 | p->sched_reset_on_fork = 0; | 2536 | p->sched_reset_on_fork = 0; |
| 2542 | } | 2537 | } |
| 2543 | 2538 | ||
| 2539 | /* | ||
| 2540 | * Make sure we do not leak PI boosting priority to the child. | ||
| 2541 | */ | ||
| 2542 | p->prio = current->normal_prio; | ||
| 2543 | |||
| 2544 | if (!rt_prio(p->prio)) | 2544 | if (!rt_prio(p->prio)) |
| 2545 | p->sched_class = &fair_sched_class; | 2545 | p->sched_class = &fair_sched_class; |
| 2546 | 2546 | ||
| @@ -2581,8 +2581,6 @@ void wake_up_new_task(struct task_struct *p, unsigned long clone_flags) | |||
| 2581 | BUG_ON(p->state != TASK_RUNNING); | 2581 | BUG_ON(p->state != TASK_RUNNING); |
| 2582 | update_rq_clock(rq); | 2582 | update_rq_clock(rq); |
| 2583 | 2583 | ||
| 2584 | p->prio = effective_prio(p); | ||
| 2585 | |||
| 2586 | if (!p->sched_class->task_new || !current->se.on_rq) { | 2584 | if (!p->sched_class->task_new || !current->se.on_rq) { |
| 2587 | activate_task(rq, p, 0); | 2585 | activate_task(rq, p, 0); |
| 2588 | } else { | 2586 | } else { |
