aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sched.c
diff options
context:
space:
mode:
authorGlenn Elliott <gelliott@cs.unc.edu>2012-09-17 09:57:37 -0400
committerGlenn Elliott <gelliott@cs.unc.edu>2012-09-17 09:57:37 -0400
commit0fb745065f08796fe4f17acb9b9edacc1e374842 (patch)
tree76655b91a3395cc2211041f93b31472bdc13371d /kernel/sched.c
parentb53c479a0f44b8990ce106622412a3bf54809944 (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.
Diffstat (limited to 'kernel/sched.c')
-rw-r--r--kernel/sched.c14
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)
3163asmlinkage void schedule_tail(struct task_struct *prev) 3163asmlinkage 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();