Port-atari archive

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

Re: wdc and DMA interrupt issue

This one works fine for me as well. I went through the full install, this time around trying AHDI partitioning to try to get around the bootloader issue but no luck with that.

David Ross

----- Original Message ----- From: "T. Makinen" <tjamaloo%gmail.com@localhost>
To: "Izumi Tsutsui" <tsutsui%ceres.dti.ne.jp@localhost>
Cc: <port-atari%netbsd.org@localhost>
Sent: Friday, January 02, 2009 5:10 PM
Subject: Re: wdc and DMA interrupt issue

On Fri, Jan 2, 2009 at 3:43 AM, Izumi Tsutsui <tsutsui%ceres.dti.ne.jp@localhost> wrote:
As I noted in this message
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)

Oh, thanks for extensive explanation about subject :)

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;
+                       s = splsoftnet();       /* XXX */
                       function(rock1, rock2);
+                       splx(s);
       } while (si);

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?

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...

Great! this patch works :) I copied some files between IDE and SCSI drives
and read all NetBSD installation sets from IDE; all worked well.

So it seems that IDE disk works well with this patch and there's no interrupt issues happening for IDE and SCSI disk. At least this workaround is improvement
for current situation and seems to work well according to my quick tests.

Thanks :)


Home | Main Index | Thread Index | Old Index