> > But but but...
> >
> > do_idle() # IRQs on
> > local_irq_disable(); # IRQs off
> > defaul_idle_call() # IRQs off
> lockdep_hardirqs_on(); # IRQs off, but lockdep things they're on
> > arch_cpu_idle() # IRQs off
> > enabled_wait() # IRQs off
> > raw_local_save() # still off
> > psw_idle() # very much off
> > ext_int_handler # get an interrupt ?!?!
> rcu_irq_enter() # lockdep thinks IRQs are on <- FAIL
>
> I can't much read s390 assembler, but ext_int_handler() has a
> TRACE_IRQS_OFF, which would be sufficient to re-align the lockdep state
> with the actual state, but there's some condition before it, what's that
> test and is that right?
After digging a bit into our asm code: no, it is not right, and only
for psw_idle() it is wrong.
What happens with the current code:
- default_idle_call() calls lockdep_hardirqs_on() before calling into
arch_cpu_idle()
- our arch_cpu_idle() calls psw_idle() which enables irqs. the irq
handler will call/use the SWITCH_ASYNC macro which clears the
interrupt enabled bits in the old program status word (_only_ for
psw_idle)
- this again causes the interrupt handler to _not_ call TRACE_IRQS_OFF
and therefore lockdep thinks interrupts are enabled within the
interrupt handler
So I guess my patch which I sent yesterday evening should fix all that
mess - plus an explicit trace_hardirqs_off() call in our udelay
implementation is required now.
I'll send a proper patch later.