softirq: remove irqs_disabled warning from local_bh_enable
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>
This commit is contained in:
parent
4620b49f76
commit
0f476b6d91
|
@ -131,48 +131,11 @@ void _local_bh_enable(void)
|
||||||
|
|
||||||
EXPORT_SYMBOL(_local_bh_enable);
|
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
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
unsigned long flags;
|
local_irq_disable();
|
||||||
|
|
||||||
WARN_ON_ONCE(in_irq());
|
|
||||||
#endif
|
|
||||||
WARN_ON_ONCE(irqs_disabled());
|
|
||||||
|
|
||||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
|
||||||
local_irq_save(flags);
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
* Are softirqs going to be turned on now:
|
|
||||||
*/
|
|
||||||
if (softirq_count() == SOFTIRQ_OFFSET)
|
|
||||||
trace_softirqs_on((unsigned long)__builtin_return_address(0));
|
|
||||||
/*
|
|
||||||
* 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();
|
|
||||||
}
|
|
||||||
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
|
#endif
|
||||||
/*
|
/*
|
||||||
* Are softirqs going to be turned on now:
|
* Are softirqs going to be turned on now:
|
||||||
|
@ -190,10 +153,21 @@ void local_bh_enable_ip(unsigned long ip)
|
||||||
|
|
||||||
dec_preempt_count();
|
dec_preempt_count();
|
||||||
#ifdef CONFIG_TRACE_IRQFLAGS
|
#ifdef CONFIG_TRACE_IRQFLAGS
|
||||||
local_irq_restore(flags);
|
local_irq_enable();
|
||||||
#endif
|
#endif
|
||||||
preempt_check_resched();
|
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)
|
||||||
|
{
|
||||||
|
_local_bh_enable_ip(ip);
|
||||||
|
}
|
||||||
EXPORT_SYMBOL(local_bh_enable_ip);
|
EXPORT_SYMBOL(local_bh_enable_ip);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in New Issue