Port-arm archive

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

pic/arm lost blocked irqs



Hi! all,


My Overo board happen hangup.  This reason is lost blocked irqs
in pic/arm/pic.c:pic_deliver_irqs().

                blocked_irqs = pending_irqs;
                do {

                :
                        if (is != NULL) {
                                cpsie(I32_bit);
                                pic_dispatch(is, frame);
                                cpsid(I32_bit);
                        } else {
                :
                        pending_irqs = pic_find_pending_irqs_by_ipl(pic,
                            irq_base, *ipending, ipl);
                } while (pending_irqs);
                if (blocked_irqs) {
                        atomic_or_32(iblocked, blocked_irqs);
                        atomic_or_32(&pic_blocked_pics, __BIT(pic->pic_id));
                }

arm/pic accepts other interrupt while executing pic_dispatch() and
interrupt-handler.
And, the interrupt newly generated is masked, and remarked ipending.

The interrupt of same ipl that ipending is done is processed by this
loop.  However, because blocked_irqs is not changed in the loop.
Therefor some masked interrupts forgot unmask.


Index: pic.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/pic/pic.c,v
retrieving revision 1.4
diff -u -r1.4 pic.c
--- pic.c       30 Dec 2008 05:43:14 -0000      1.4
+++ pic.c       29 Aug 2010 14:30:39 -0000
@@ -229,7 +229,7 @@
 #endif
                }
                progress = true;
-               blocked_irqs = pending_irqs;
+               blocked_irqs = 0;
                do {
                        irq = ffs(pending_irqs) - 1;
                        KASSERT(irq >= 0);
@@ -240,9 +240,9 @@
                                cpsie(I32_bit);
                                pic_dispatch(is, frame);
                                cpsid(I32_bit);
+                               blocked_irqs |= __BIT(irq);
                        } else {
                                KASSERT(0);
-                               blocked_irqs &= ~__BIT(irq);
                        }
                        pending_irqs = pic_find_pending_irqs_by_ipl(pic,
                            irq_base, *ipending, ipl);


Is my understanding wrong?
Thanks,
--
kiyohara


Home | Main Index | Thread Index | Old Index