• Mark Rutland's avatar
    lockdep: report broken irq restoration · 997acaf6
    Mark Rutland authored
    We generally expect local_irq_save() and local_irq_restore() to be
    paired and sanely nested, and so local_irq_restore() expects to be
    called with irqs disabled. Thus, within local_irq_restore() we only
    trace irq flag changes when unmasking irqs.
    
    This means that a sequence such as:
    
    | local_irq_disable();
    | local_irq_save(flags);
    | local_irq_enable();
    | local_irq_restore(flags);
    
    ... is liable to break things, as the local_irq_restore() would mask
    irqs without tracing this change. Similar problems may exist for
    architectures whose arch_irq_restore() function depends on being called
    with irqs disabled.
    
    We don't consider such sequences to be a good idea, so let's define
    those as forbidden, and add tooling to detect such broken cases.
    
    This patch adds debug code to WARN() when raw_local_irq_restore() is
    called with irqs enabled. As raw_local_irq_restore() is expected to pair
    with raw_local_irq_save(), it should never be called with irqs enabled.
    
    To avoid the possibility of circular header dependencies between
    irqflags.h and bug.h, the warning is handled in a separate C file.
    
    The new code is all conditional on a new CONFIG_DEBUG_IRQFLAGS symbol
    which is independent of CONFIG_TRACE_IRQFLAGS. As noted above such cases
    will confuse lockdep, so CONFIG_DEBUG_LOCKDEP now selects
    CONFIG_DEBUG_IRQFLAGS.
    Signed-off-by: default avatarMark Rutland <mark.rutland@arm.com>
    Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    Link: https://lkml.kernel.org/r/20210111153707.10071-1-mark.rutland@arm.com
    997acaf6
Kconfig.debug 81.8 KB