diff options
author | Mike Galbraith <efault@gmx.de> | 2011-07-27 11:14:55 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2011-08-14 06:00:43 -0400 |
commit | c350a04efd1c89cd256b2abc8f07a21d0d53ff24 (patch) | |
tree | 81b7ad7cd7e86c21aeb81fcfe68bb38892e1ddbb /kernel | |
parent | 2c2efaed9bc973e3aeab1385c618017b56c8f6d7 (diff) |
sched: fix broken SCHED_RESET_ON_FORK handling
Setting child->prio = current->normal_prio _after_ SCHED_RESET_ON_FORK has
been handled for an RT parent gives birth to a deranged mutant child with
non-RT policy, but RT prio and sched_class.
Move PI leakage protection up, always set priorities and weight, and if the
child is leaving RT class, reset rt_priority to the proper value.
Signed-off-by: Mike Galbraith <efault@gmx.de>
Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1311779695.8691.2.camel@marge.simson.net
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sched.c | 25 |
1 files changed, 12 insertions, 13 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index b1e8f0eca1f9..cf427bb2b65e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -2844,19 +2844,23 @@ void sched_fork(struct task_struct *p) | |||
2844 | p->state = TASK_RUNNING; | 2844 | p->state = TASK_RUNNING; |
2845 | 2845 | ||
2846 | /* | 2846 | /* |
2847 | * Make sure we do not leak PI boosting priority to the child. | ||
2848 | */ | ||
2849 | p->prio = current->normal_prio; | ||
2850 | |||
2851 | /* | ||
2847 | * Revert to default priority/policy on fork if requested. | 2852 | * Revert to default priority/policy on fork if requested. |
2848 | */ | 2853 | */ |
2849 | if (unlikely(p->sched_reset_on_fork)) { | 2854 | if (unlikely(p->sched_reset_on_fork)) { |
2850 | if (p->policy == SCHED_FIFO || p->policy == SCHED_RR) { | 2855 | if (task_has_rt_policy(p)) { |
2851 | p->policy = SCHED_NORMAL; | 2856 | p->policy = SCHED_NORMAL; |
2852 | p->normal_prio = p->static_prio; | ||
2853 | } | ||
2854 | |||
2855 | if (PRIO_TO_NICE(p->static_prio) < 0) { | ||
2856 | p->static_prio = NICE_TO_PRIO(0); | 2857 | p->static_prio = NICE_TO_PRIO(0); |
2857 | p->normal_prio = p->static_prio; | 2858 | p->rt_priority = 0; |
2858 | set_load_weight(p); | 2859 | } else if (PRIO_TO_NICE(p->static_prio) < 0) |
2859 | } | 2860 | p->static_prio = NICE_TO_PRIO(0); |
2861 | |||
2862 | p->prio = p->normal_prio = __normal_prio(p); | ||
2863 | set_load_weight(p); | ||
2860 | 2864 | ||
2861 | /* | 2865 | /* |
2862 | * We don't need the reset flag anymore after the fork. It has | 2866 | * We don't need the reset flag anymore after the fork. It has |
@@ -2865,11 +2869,6 @@ void sched_fork(struct task_struct *p) | |||
2865 | p->sched_reset_on_fork = 0; | 2869 | p->sched_reset_on_fork = 0; |
2866 | } | 2870 | } |
2867 | 2871 | ||
2868 | /* | ||
2869 | * Make sure we do not leak PI boosting priority to the child. | ||
2870 | */ | ||
2871 | p->prio = current->normal_prio; | ||
2872 | |||
2873 | if (!rt_prio(p->prio)) | 2872 | if (!rt_prio(p->prio)) |
2874 | p->sched_class = &fair_sched_class; | 2873 | p->sched_class = &fair_sched_class; |
2875 | 2874 | ||