softirq: remove irqs_disabled warning from local_bh_enable
authorJohannes Berg <johannes@sipsolutions.net>
Wed, 18 Jun 2008 07:29:37 +0000 (09:29 +0200)
committerIngo Molnar <mingo@elte.hu>
Fri, 20 Jun 2008 13:45:29 +0000 (15:45 +0200)
There's no need to use local_irq_save() over local_irq_disable() in the
local_bh_enable code since it is a bug to call it with irqs disabled and
do_softirq will enable irqs if there is any pending work.

Consolidate the code from local_bh_enable and ..._ip to avoid having a
disconnect between them in the warnings they trigger that is currently
there.

Also always trigger the warning on in_irq(), not just in the
trace-irqflags case.

Signed-off-by: Johannes Berg <johannes@sipsolutions.net>
Cc: Michael Buesch <mb@bu3sch.de>
Cc: David Ellingsworth <david@identd.dyndns.org>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
kernel/softirq.c

index 8677534..2cf2502 100644 (file)
@@ -131,23 +131,17 @@ void _local_bh_enable(void)
 
 EXPORT_SYMBOL(_local_bh_enable);
 
-void local_bh_enable(void)
+static inline void _local_bh_enable_ip(unsigned long ip)
 {
+       WARN_ON_ONCE(in_irq() || irqs_disabled());
 #ifdef CONFIG_TRACE_IRQFLAGS
-       unsigned long flags;
-
-       WARN_ON_ONCE(in_irq());
-#endif
-       WARN_ON_ONCE(irqs_disabled());
-
-#ifdef CONFIG_TRACE_IRQFLAGS
-       local_irq_save(flags);
+       local_irq_disable();
 #endif
        /*
         * Are softirqs going to be turned on now:
         */
        if (softirq_count() == SOFTIRQ_OFFSET)
-               trace_softirqs_on((unsigned long)__builtin_return_address(0));
+               trace_softirqs_on(ip);
        /*
         * Keep preemption disabled until we are done with
         * softirq processing:
@@ -159,40 +153,20 @@ void local_bh_enable(void)
 
        dec_preempt_count();
 #ifdef CONFIG_TRACE_IRQFLAGS
-       local_irq_restore(flags);
+       local_irq_enable();
 #endif
        preempt_check_resched();
 }
+
+void local_bh_enable(void)
+{
+       _local_bh_enable_ip((unsigned long)__builtin_return_address(0));
+}
 EXPORT_SYMBOL(local_bh_enable);
 
 void local_bh_enable_ip(unsigned long ip)
 {
-#ifdef CONFIG_TRACE_IRQFLAGS
-       unsigned long flags;
-
-       WARN_ON_ONCE(in_irq());
-
-       local_irq_save(flags);
-#endif
-       /*
-        * Are softirqs going to be turned on now:
-        */
-       if (softirq_count() == SOFTIRQ_OFFSET)
-               trace_softirqs_on(ip);
-       /*
-        * Keep preemption disabled until we are done with
-        * softirq processing:
-        */
-       sub_preempt_count(SOFTIRQ_OFFSET - 1);
-
-       if (unlikely(!in_interrupt() && local_softirq_pending()))
-               do_softirq();
-
-       dec_preempt_count();
-#ifdef CONFIG_TRACE_IRQFLAGS
-       local_irq_restore(flags);
-#endif
-       preempt_check_resched();
+       _local_bh_enable_ip(ip);
 }
 EXPORT_SYMBOL(local_bh_enable_ip);