Port-arm archive

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

Re: pic/arm lost blocked irqs



Hi! Adam,


From: KIYOHARA Takashi <kiyohara%kk.iij4u.or.jp@localhost>
Date: Mon, 30 Aug 2010 21:25:31 +0900 (JST)

> From: Adam Hoka <adam.hoka%gmail.com@localhost>
> Date: Mon, 30 Aug 2010 13:48:10 +0200
> 
> > i saw hangups in interrupt handling too with the dm9000 driver
> > i have tried to port. maybe it wasnt my mistake then?
> 
> That patch of me fixes a bug.  However, I happen another bug, too.
> For instance, can you type your keyboard on tip(1)(or cu(1)) of Host
> toward the console of your devkit9000?
> 
> My smsh(4) works again with typing keyboard.


Maybe, it is this.  ;-)

arm/pic/pic.c:pic_deliver_irqs() --

        for (;;) {
                pending_irqs = pic_find_pending_irqs_by_ipl(pic, irq_base,
                    *ipending, ipl);
                :
                if (pending_irqs == 0) {
                        irq_count += 32;
                        if (__predict_true(irq_count >= pic->pic_maxsources))
                                break;
                        :
                }
                :
                do {
                        :
                        pending_irqs = pic_find_pending_irqs_by_ipl(pic,
                            irq_base, *ipending, ipl);
                } while (pending_irqs);
                :
         }
         :
        if (atomic_and_32_nv(&pic->pic_pending_ipls, ~ipl_mask) == 0)
                atomic_and_32(&pic_pending_pics, ~__BIT(pic->pic_id));


com uses intr-74 and gpio uses intr between 29 and 34, both IPL_HIGH
(IPL_SERIAL).  If gpio interrupts in comintr(intr 74), pic_pending_pics
is cleared, and ipending not cleared.


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       30 Aug 2010 13:29:23 -0000
@@ -196,7 +196,7 @@
 #endif
        uint32_t pending_irqs;
        uint32_t blocked_irqs;
-       int irq;
+       int irq, dispatched;
        bool progress = false;
        
        KASSERT(pic->pic_pending_ipls & ipl_mask);
@@ -206,6 +206,7 @@
        irq_count = 0;
 #endif
 
+       dispatched = 0;
        for (;;) {
                pending_irqs = pic_find_pending_irqs_by_ipl(pic, irq_base,
                    *ipending, ipl);
@@ -214,14 +215,19 @@
                if (pending_irqs == 0) {
 #if PIC_MAXSOURCES > 32
                        irq_count += 32;
-                       if (__predict_true(irq_count >= pic->pic_maxsources))
-                               break;
-                       irq_base += 32;
-                       ipending++;
-                       iblocked++;
-                       if (irq_base >= pic->pic_maxsources) {
+                       if (__predict_true(irq_count >= pic->pic_maxsources)) {
+                               if (!dispatched)
+                                       break;
+                               irq_base = 0;
+                               irq_count = 0;
+                               dispatched = 0;
                                ipending = pic->pic_pending_irqs;
                                iblocked = pic->pic_blocked_irqs;
+                       } else {
+                               irq_base += 32;
+                               ipending++;
+                               iblocked++;
+                               KASSERT(irq_base <= pic->pic_maxsources);
                        }
                        continue;
 #else
@@ -251,6 +257,7 @@
                        atomic_or_32(iblocked, blocked_irqs);
                        atomic_or_32(&pic_blocked_pics, __BIT(pic->pic_id));
                }
+               dispatched = 1;
        }
 
        KASSERT(progress);


In my case, this fix clear that problem.  ;-)

Thanks,
--
kiyohara


Home | Main Index | Thread Index | Old Index