diff options
author | Glenn Elliott <gelliott@cs.unc.edu> | 2012-09-17 09:57:37 -0400 |
---|---|---|
committer | Bjoern Brandenburg <bbb@mpi-sws.org> | 2012-09-21 12:21:05 -0400 |
commit | 9434d607f4ddaf2374dafd86c20ed4336230ecfa (patch) | |
tree | 0839634ea400e0069b42ee75e1d52a5753018431 | |
parent | 3c3683a9e8891f1da6dabf1d1fc8087d85d056a4 (diff) |
Do processor state transitions in schedule_tail().
Fixes a bug in Litmus where processor scheduling states
could become corrupted. Corruption can occur when a
just-forked thread is externally forced to be scheduled
by SCHED_LITMUS before this just-forked thread can complete
post-fork processing. Specifically, before schedule_tail()
has completed.
-rw-r--r-- | kernel/sched.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index 2229d0deec4b..65aba7ec564d 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -3163,16 +3163,26 @@ static inline void post_schedule(struct rq *rq) | |||
3163 | asmlinkage void schedule_tail(struct task_struct *prev) | 3163 | asmlinkage void schedule_tail(struct task_struct *prev) |
3164 | __releases(rq->lock) | 3164 | __releases(rq->lock) |
3165 | { | 3165 | { |
3166 | struct rq *rq = this_rq(); | 3166 | struct rq *rq; |
3167 | 3167 | ||
3168 | preempt_disable(); | ||
3169 | |||
3170 | rq = this_rq(); | ||
3168 | finish_task_switch(rq, prev); | 3171 | finish_task_switch(rq, prev); |
3169 | 3172 | ||
3173 | sched_trace_task_switch_to(current); | ||
3174 | |||
3170 | /* | 3175 | /* |
3171 | * FIXME: do we need to worry about rq being invalidated by the | 3176 | * FIXME: do we need to worry about rq being invalidated by the |
3172 | * task_switch? | 3177 | * task_switch? |
3173 | */ | 3178 | */ |
3174 | post_schedule(rq); | 3179 | post_schedule(rq); |
3175 | 3180 | ||
3181 | if (sched_state_validate_switch()) | ||
3182 | litmus_reschedule_local(); | ||
3183 | |||
3184 | preempt_enable(); | ||
3185 | |||
3176 | #ifdef __ARCH_WANT_UNLOCKED_CTXSW | 3186 | #ifdef __ARCH_WANT_UNLOCKED_CTXSW |
3177 | /* In this case, finish_task_switch does not reenable preemption */ | 3187 | /* In this case, finish_task_switch does not reenable preemption */ |
3178 | preempt_enable(); | 3188 | preempt_enable(); |