kernel BUG at kernel/posix-cpu-timers.c:1389!

Russell King - ARM Linux linux at arm.linux.org.uk
Thu Nov 5 12:29:54 EST 2009


On Thu, Nov 05, 2009 at 11:07:41AM -0600, E Robertson wrote:
> On Mon, Nov 2, 2009 at 10:54 AM, Russell King - ARM Linux
> <linux at arm.linux.org.uk> wrote:
> > On Mon, Nov 02, 2009 at 05:47:57PM +0100, Nicolas Ferre wrote:
> >> in arch/arm/mach-at91/at91sam926x_time.c +125
> >>  .flags = IRQF_SHARED | IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
> >>
> >> IRQF_DISABLED is positionned. But on the other hand, I saw in the kernel
> >> booting messages that:
> >> "IRQ 1/rtc0: IRQF_DISABLED is not guaranteed on shared IRQs"
> >>
> >> What does this mean ? what is the difference with former way of managing
> >> shared interrupts ?
> >
> > If the first IRQ action which is run was registered without IRQF_DISABLED
> > the entire set will be run without interrupts disabled.
> >
> >> And above all, what is the proper way to set an IRQ on a shared
> >> interrupt line ?
> >
> > The only real solution is to ensure that all requesters use IRQF_DISABLED.
> >
> 
> I don't see where this could be the cause of this problem. The bug
> happens after the system is running and I attempt to use the select
> method for polling (serial port & uevents).  Without this the bug [
> BUG_ON(!irqs_disabled()); ]  did not occur.  I added the flag to the
> requesters but that did not help, maybe I overlooked something.

Well, run_posix_cpu_timers() must be called with interrupts disabled.
This bug indicates that this has been violated.

Since we know that the timer stuff works on virtually every other
platform which makes use of the generic time infrastructure, I doubt
you've found a bug in it - so that tends to eliminate tick_handle_periodic()
and below in the call chain.  (Oh how I absolutely detest how genirq is
completely undocumented with respect to details like this, and people
are left to guess.)

So, the only thing that leaves is that tick_handle_periodic() was called
with IRQs enabled.

You could try putting a BUG_ON(!irqs_disabled()) in parent functions to
trace where interrupts are being re-enabled, but I think you'll find that
at91sam926x_pit_interrupt() was called with IRQs enabled.

Now, for any shared interrupt, where some handlers are registered with
IRQF_DISABLED and non-IRQF_DISABLED can lead to IRQF_DISABLED handlers
being called with IRQs enabled (hence the "IRQF_SHARED is not guaranteed
on shared IRQs" warning).  So... the solution is as I said above.

> [<c00da3a8>] (__bug+0x0/0x2c) from [<c0105444>] (run_posix_cpu_timers+0x34/0x88
> 4)
> [<c0105410>] (run_posix_cpu_timers+0x0/0x884) from [<c00f8a24>] (update_process
> _times+0x5c/0x60)
> [<c00f89c8>] (update_process_times+0x0/0x60) from [<c010dafc>] (tick_periodic+0
> xb8/0xdc)
>  r6:00000001 r5:c0345790 r4:00000000
> [<c010da44>] (tick_periodic+0x0/0xdc) from [<c010db40>] (tick_handle_periodic+0
> x20/0xd0)
>  r5:c032a954 r4:00000001
> [<c010db20>] (tick_handle_periodic+0x0/0xd0) from [<c00dfaf0>] (at91sam926x_pit
> _interrupt+0x60/0x90)
> [<c00dfa90>] (at91sam926x_pit_interrupt+0x0/0x90) from [<c0113ba8>] (handle_IRQ
> _event+0x44/0x10c)
>  r5:00000001 r4:c032a99c
> [<c0113b64>] (handle_IRQ_event+0x0/0x10c) from [<c011582c>] (handle_level_irq+0
> xc4/0x13c)
>  r8:00000000 r7:c032a99c r6:00000000 r5:00000001 r4:c032e034
> [<c0115768>] (handle_level_irq+0x0/0x13c) from [<c00d606c>] (asm_do_IRQ+0x6c/0x
> 9c)
>  r7:00000001 r6:00000000 r5:c0333e58 r4:00000001
> [<c00d6000>] (asm_do_IRQ+0x0/0x9c) from [<c00d6a5c>] (__irq_svc+0x3c/0x80)
> Exception stack(0xc1ce5f60 to 0xc1ce5fa8)
> 5f60: 00000006 beebaaa8 00000000 00000000 beebaaa0 beebaaa8 00000005 0000008e
> 5f80: c00d6fe4 c1ce4000 4004e108 00000000 00000000 c1ce5fa8 c00d6e40 c014bc68
> 5fa0: 80000013 ffffffff
>  r6:00000001 r5:fefff000 r4:ffffffff



More information about the linux-arm-kernel mailing list