aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <tj@kernel.org>2009-12-01 22:56:46 -0500
committerIngo Molnar <mingo@elte.hu>2009-12-02 03:55:33 -0500
commit8592e6486a177a02f048567cb928bc3a1f9a86c3 (patch)
treeb33fda329271835bb879b6395efa5179b62a1b7b
parentb7b20df91d43d5e59578b8fc16e895c0c8cbd9b5 (diff)
sched: Revert 498657a478c60be092208422fefa9c7b248729c2
498657a478c60be092208422fefa9c7b248729c2 incorrectly assumed that preempt wasn't disabled around context_switch() and thus was fixing imaginary problem. It also broke KVM because it depended on ->sched_in() to be called with irq enabled so that it can do smp calls from there. Revert the incorrect commit and add comment describing different contexts under with the two callbacks are invoked. Avi: spotted transposed in/out in the added comment. Signed-off-by: Tejun Heo <tj@kernel.org> Acked-by: Avi Kivity <avi@redhat.com> Cc: peterz@infradead.org Cc: efault@gmx.de Cc: rusty@rustcorp.com.au LKML-Reference: <1259726212-30259-2-git-send-email-tj@kernel.org> Signed-off-by: Ingo Molnar <mingo@elte.hu>
-rw-r--r--include/linux/preempt.h5
-rw-r--r--kernel/sched.c2
2 files changed, 6 insertions, 1 deletions
diff --git a/include/linux/preempt.h b/include/linux/preempt.h
index 72b1a10a59b6..2e681d9555bd 100644
--- a/include/linux/preempt.h
+++ b/include/linux/preempt.h
@@ -105,6 +105,11 @@ struct preempt_notifier;
105 * @sched_out: we've just been preempted 105 * @sched_out: we've just been preempted
106 * notifier: struct preempt_notifier for the task being preempted 106 * notifier: struct preempt_notifier for the task being preempted
107 * next: the task that's kicking us out 107 * next: the task that's kicking us out
108 *
109 * Please note that sched_in and out are called under different
110 * contexts. sched_out is called with rq lock held and irq disabled
111 * while sched_in is called without rq lock and irq enabled. This
112 * difference is intentional and depended upon by its users.
108 */ 113 */
109struct preempt_ops { 114struct preempt_ops {
110 void (*sched_in)(struct preempt_notifier *notifier, int cpu); 115 void (*sched_in)(struct preempt_notifier *notifier, int cpu);
diff --git a/kernel/sched.c b/kernel/sched.c
index b3d4e2be95aa..1031cae39c4c 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -2768,9 +2768,9 @@ static void finish_task_switch(struct rq *rq, struct task_struct *prev)
2768 prev_state = prev->state; 2768 prev_state = prev->state;
2769 finish_arch_switch(prev); 2769 finish_arch_switch(prev);
2770 perf_event_task_sched_in(current, cpu_of(rq)); 2770 perf_event_task_sched_in(current, cpu_of(rq));
2771 fire_sched_in_preempt_notifiers(current);
2772 finish_lock_switch(rq, prev); 2771 finish_lock_switch(rq, prev);
2773 2772
2773 fire_sched_in_preempt_notifiers(current);
2774 if (mm) 2774 if (mm)
2775 mmdrop(mm); 2775 mmdrop(mm);
2776 if (unlikely(prev_state == TASK_DEAD)) { 2776 if (unlikely(prev_state == TASK_DEAD)) {