summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-03-05 18:10:04 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2013-03-05 18:10:04 -0800
commite3b59518c10e08eeb06215abf06f50e8f83b51dc (patch)
treea1e5933192ee123883112d771e27e9c972ccd733
parent6516ab6fdffbda656253d4e1231660c3f87f7889 (diff)
parent4cd5d1115c2f752ca94a0eb461b36d88fb37ed1e (diff)
downloadlinux-e3b59518c10e08eeb06215abf06f50e8f83b51dc.tar.bz2
Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull irq fixes and cleanups from Thomas Gleixner: "Commit e5ab012c3271 ("nohz: Make tick_nohz_irq_exit() irq safe") is the first commit in the series and the minimal necessary bugfix, which needs to go back into stable. The remanining commits enforce irq disabling in irq_exit(), sanitize the hardirq/softirq preempt count transition and remove a bunch of no longer necessary conditionals." I personally love getting rid of the very subtle and confusing IRQ_EXIT_OFFSET thing. Even apart from the whole "more lines removed than added" thing. * 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: irq: Don't re-enable interrupts at the end of irq_exit irq: Remove IRQ_EXIT_OFFSET workaround Revert "nohz: Make tick_nohz_irq_exit() irq safe" irq: Sanitize invoke_softirq irq: Ensure irq_exit() code runs with interrupts disabled nohz: Make tick_nohz_irq_exit() irq safe
-rw-r--r--include/linux/hardirq.h2
-rw-r--r--kernel/softirq.c21
2 files changed, 9 insertions, 14 deletions
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h
index 29eb805ea4a6..c1d6555d2567 100644
--- a/include/linux/hardirq.h
+++ b/include/linux/hardirq.h
@@ -118,10 +118,8 @@
#ifdef CONFIG_PREEMPT_COUNT
# define preemptible() (preempt_count() == 0 && !irqs_disabled())
-# define IRQ_EXIT_OFFSET (HARDIRQ_OFFSET-1)
#else
# define preemptible() 0
-# define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
#endif
#if defined(CONFIG_SMP) || defined(CONFIG_GENERIC_HARDIRQS)
diff --git a/kernel/softirq.c b/kernel/softirq.c
index b4d252fd195b..14d7758074aa 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -323,18 +323,10 @@ void irq_enter(void)
static inline void invoke_softirq(void)
{
- if (!force_irqthreads) {
-#ifdef __ARCH_IRQ_EXIT_IRQS_DISABLED
+ if (!force_irqthreads)
__do_softirq();
-#else
- do_softirq();
-#endif
- } else {
- __local_bh_disable((unsigned long)__builtin_return_address(0),
- SOFTIRQ_OFFSET);
+ else
wakeup_softirqd();
- __local_bh_enable(SOFTIRQ_OFFSET);
- }
}
/*
@@ -342,9 +334,15 @@ static inline void invoke_softirq(void)
*/
void irq_exit(void)
{
+#ifndef __ARCH_IRQ_EXIT_IRQS_DISABLED
+ local_irq_disable();
+#else
+ WARN_ON_ONCE(!irqs_disabled());
+#endif
+
account_irq_exit_time(current);
trace_hardirq_exit();
- sub_preempt_count(IRQ_EXIT_OFFSET);
+ sub_preempt_count(HARDIRQ_OFFSET);
if (!in_interrupt() && local_softirq_pending())
invoke_softirq();
@@ -354,7 +352,6 @@ void irq_exit(void)
tick_nohz_irq_exit();
#endif
rcu_irq_exit();
- sched_preempt_enable_no_resched();
}
/*