• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

linux-3.0.x for AP-SH4A-0A Board


Commit MetaInfo

Revisionc5d753a55ac92e09816d410cd17093813f1a904b (tree)
Time2011-07-21 02:50:11
AuthorPeter Zijlstra <a.p.zijlstra@chel...>
CommiterPaul E. McKenney

Log Message

sched: Add irq_{enter,exit}() to scheduler_ipi()

Ensure scheduler_ipi() calls irq_{enter,exit} when it does some actual
work. Traditionally we never did any actual work from the resched IPI
and all magic happened in the return from interrupt path.

Now that we do do some work, we need to ensure irq_{enter,exit} are
called so that we don't confuse things.

This affects things like timekeeping, NO_HZ and RCU, basically
everything with a hook in irq_enter/exit.

Explicit examples of things going wrong are:

sched_clock_cpu() -- has a callback when leaving NO_HZ state to take
a new reading from GTOD and TSC. Without this
callback, time is stuck in the past.
RCU -- needs in_irq() to work in order to avoid some nasty deadlocks

Signed-off-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Signed-off-by: Paul E. McKenney <paulmck@linux.vnet.ibm.com>

Change Summary

Incremental Difference

--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -2544,13 +2544,9 @@ static int ttwu_remote(struct task_struct *p, int wake_flags)
25442544 }
25452545
25462546 #ifdef CONFIG_SMP
2547-static void sched_ttwu_pending(void)
2547+static void sched_ttwu_do_pending(struct task_struct *list)
25482548 {
25492549 struct rq *rq = this_rq();
2550- struct task_struct *list = xchg(&rq->wake_list, NULL);
2551-
2552- if (!list)
2553- return;
25542550
25552551 raw_spin_lock(&rq->lock);
25562552
@@ -2563,9 +2559,45 @@ static void sched_ttwu_pending(void)
25632559 raw_spin_unlock(&rq->lock);
25642560 }
25652561
2562+#ifdef CONFIG_HOTPLUG_CPU
2563+
2564+static void sched_ttwu_pending(void)
2565+{
2566+ struct rq *rq = this_rq();
2567+ struct task_struct *list = xchg(&rq->wake_list, NULL);
2568+
2569+ if (!list)
2570+ return;
2571+
2572+ sched_ttwu_do_pending(list);
2573+}
2574+
2575+#endif /* CONFIG_HOTPLUG_CPU */
2576+
25662577 void scheduler_ipi(void)
25672578 {
2568- sched_ttwu_pending();
2579+ struct rq *rq = this_rq();
2580+ struct task_struct *list = xchg(&rq->wake_list, NULL);
2581+
2582+ if (!list)
2583+ return;
2584+
2585+ /*
2586+ * Not all reschedule IPI handlers call irq_enter/irq_exit, since
2587+ * traditionally all their work was done from the interrupt return
2588+ * path. Now that we actually do some work, we need to make sure
2589+ * we do call them.
2590+ *
2591+ * Some archs already do call them, luckily irq_enter/exit nest
2592+ * properly.
2593+ *
2594+ * Arguably we should visit all archs and update all handlers,
2595+ * however a fair share of IPIs are still resched only so this would
2596+ * somewhat pessimize the simple resched case.
2597+ */
2598+ irq_enter();
2599+ sched_ttwu_do_pending(list);
2600+ irq_exit();
25692601 }
25702602
25712603 static void ttwu_queue_remote(struct task_struct *p, int cpu)