wdc and DMA interrupt issue
Izumi Tsutsui <[email protected]>
| Newsgroups | gmane.os.netbsd.ports.atari |
|---|---|
| Message-ID | <[email protected]> |
I wrote: > > Also reading NetBSD 4 installation sets from IDE disk and copying files > > from IDE to SCSI work, so it seems that wdc_mb.c is not affected by gcc4. > > Then maybe the problem is in softint(9) changes. > I'll a possible patch later (in a new thread again). As I noted in this message http://mail-index.NetBSD.org/port-atari/2008/12/25/msg000159.html softint(9) is one of major changes in the HEAD since 4.0, and the DMA interrupt (which is shared with wdc) uses a callback function which is invoked via the softint(9). In 4.x kernel, software interrupts are checked and invoked as soon as a higher priority interrupt is returned from its handler, and callback functions are called at splsoft(). (see the "rei" fucntion in locore.s) In the HEAD, software interrupts are now handled in kernel threads, (as we can see it in sys/kern/kern_softint.c) so callback functions could have some latency (context switch is required) and it may run at lower interrupt priority level (though I have not confirmed it well). On the other hand, the DMA interrupt handler (cdmaint() in dma.c) uses BASEPRI() macro which is defined in atari/include/cpu.h, and it checks %SR register value at the time interrupt occurs. If the interrupt occurs during another interrupt is being processed, the queued DMA interrupt handler is scheduled to be executed later via add_sicallback() function. If the cdmaint() is not come from interrupt handlers, it calls the queued interrupt handler directly. In wdc case, the wdcintr() function will be called from cdmaint() or via the callback function since it's queued via st_dmagrab() in claim_hw() function. If -current softint(9) functions are no longer executed at splsoft() but at BASEPRI, wdcintr() could be called recursively if another wdc interrupt occurs during wdcintr() invoked from the callback is being processed. (I haven't tracked this closely though) One possible and simple workaround is to raise IPL to splsoft() before invoking callback functions as if old kernels did in locore.s: --- Index: atari/machdep.c =================================================================== RCS file: /cvsroot/src/sys/arch/atari/atari/machdep.c,v retrieving revision 1.154 diff -u -r1.154 machdep.c --- atari/machdep.c 30 Nov 2008 18:21:32 -0000 1.154 +++ atari/machdep.c 2 Jan 2009 01:14:27 -0000 @@ -810,7 +810,9 @@ si->next = si_free; si_free = si; splx(s); + s = splsoftnet(); /* XXX */ function(rock1, rock2); + splx(s); } } while (si); #ifdef DIAGNOSTIC --- so that BASEPRI() returns false even if nested DMA (or wdc) interrupt occurs and the next wdcintr() is scheduled to be invoked later (i.e. after current wdcintr() returns). Could you try this one? http://www.ceres.dti.ne.jp/~tsutsui/netbsd/netbsd-ATARITT-HEAD-20090102.gz http://www.ceres.dti.ne.jp/~tsutsui/netbsd/netbsd-BOOT-HEAD-20090102.gz http://www.ceres.dti.ne.jp/~tsutsui/netbsd/netbsd-FALCON-HEAD-20090102.gz I wonder if the right solution is to raise IPL to splbio() before calling wdcintr() (and maybe also ncr_dma_intr() and ncr_ctrl_intr() in ncr5380.c) from the callback function to block nested interrupts properly, though... IMO, all uses of the callback function (which is atari specific) should be rewritten to use the MI softint(9) directly, though it doesn't have capability to cancel scheduled handlers as machdep.c:rem_sicallback() does... --- Izumi Tsutsui