Port-powerpc archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: powerpc/pic/intr.c IPL_HIGH vs IPL_NONE



KIYOHARA Takashi wrote:

>> Can you compile the kernel with PIC_DEBUG, to get some more
>> information about the irqs, virqs and masks in your system?
>
> The attached ipl.log is after r1.23:
>
>   ih->ih_ipl = ipl;
>
> And attached maxipl.log is before r1.22:
>
>   ih->ih_ipl = maxipl;

You probably mean "is->is_ipl = maxipl"? I'm sure this assignment is
correct.

The interrupt handler (ih) will receive the IPL priority, which was passed
into the intr_establish() call. But the interrupt source (is), which can
have multiple handlers at different IPLs, must hold the highest IPL of all
handlers. Otherwise the same interrupt could occur again, breaking a
handler with a higher IPL.


> And pic_handle_intr() is called the interrupt 26.  However imask[0..7]
> is not masked virq 1.

Indeed. But I think the is also correct. In intr_calculatemasks() you can
read this comment:
/*
 * IPL_NONE is used for hardware interrupts that are never blocked,
 * and do not block anything else.
 */

This is exactly what happens now. Your i8259 interrupt at BeBox-interrupt 26
should not be blocked and should not block anything else. So virq 1 does
not appear in any imask[].


> pic_handler_intr() ---
> 1st call
> ========
>   if ((imask[pcpl] & v_imen) != 0) {
>       :               <-- Don't reached.
>       pic->pic_disable_irq(pic, picirq);
>   } else {
>           :
>       splraise(is->is_ipl);       <-- splraise(IPL_HIGH)
>       mtmsr(msr | PSL_EE);        <-- interrupt enable!!
>                           And 2nd call
>       intr_deliver(is, virq);     <-- not reached...
>   }
>
>
> 2nd call
> ========
>   if ((imask[pcpl] & v_imen) != 0) {
>       :               <-- Oops, don't reached.
>       pic->pic_disable_irq(pic, picirq);
>   } else {
>           :
>       splraise(is->is_ipl);       <-- splraise(IPL_HIGH)
>       mtmsr(msr | PSL_EE);        <-- interrupt enable!!
>                           And 3rd call, 4th, 5th...
>       intr_deliver(is, virq);     <-- not reached...  X-<
>   }

Ok. I see the whole picture now. Thanks.

That your hwirq 42 is interrupted by another hwirq 42 seems normal to me.
You certainly want that com0 at IPL_HIGH interrupts wdc0 at IPL_VM. Both
are detected by the i8259, which signals the interrupt via hwirq 42 to the
BeBox PIC.

The problem here is that the i8259 obviously doesn't stop to signal new
interrupts. Otherwise one of these i8259 interrupts should make it into
pic_handle_intr() (this time with the i8259-irq) again.

Do you know which i8259 interrupt is causing this interrupt storm?


> Shall I change to call intr_establish() with IPL_HIGH in cpu_startup()?
> Or
>
>   ih->ih_ipl = (ipl != IPL_NONE) ? ipl : maxipl;

I didn't write the PIC code and perhaps I don't get the concept behind it,
but, as far as I understand, both solutions would have the effect that any
i8259 interrupt cannot be interrupted. All following interrupts will be
deferred until after the hwirq 42 is handled.

Maybe this was the way it worked before, but then it had been sub-optimal.
;)

-- 
Frank Wille



Home | Main Index | Thread Index | Old Index