Subject: port-macppc/12989: interrupt handling loses soft interrupts when posted inside handlers
To: None <gnats-bugs@gnats.netbsd.org>
From: None <donlee_ppc@icompute.com>
List: netbsd-bugs
Date: 05/20/2001 00:08:33
>Number:         12989
>Category:       port-macppc
>Synopsis:       interrupt handling loses soft interrupts when posted inside handlers
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    port-macppc-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat May 19 22:08:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Donald Lee
>Release:        NetBSD 1.5 MacPPC
>Organization:
icompute.com
>Environment:
	any macppc NetBSD 1.5 machine.
System: NetBSD mercy 1.5 NetBSD 1.5 (try1) #21: Thu Jan 11 23:29:03 CST 2001 donlee@charm:/usr/src/sys/arch/macppc/compile/try1 macppc


>Description:
	There is a condition in the interrupt handler where soft interrupts
can be lost if they are posted during another soft interrupt handler.
This is because the code clears the bits in the mask *after*
handling the interrupts rather than before handling them.

The symptoms of this problem include long latencies on ppp network
traffic.  Others have not been seen by me, but I suspect strongly that
they exist.

>How-To-Repeat:
Because serial is not working well on macppc, it's hard to see the
problem.  I have some networking code that allows ppp to be run
"remotely" via ptys that can show the problem.  If you have a cyclades
card (and my patches to its driver) you can also demo the problem.
>Fix:

The following code has been running on my production server since
January 14th 2001.

sys/arch/macppc/macppc/extintr.c

*** extintr.c.nogo      Wed Jan  3 23:18:05 2001
--- extintr.c.ok        Sat Feb 24 17:58:16 2001
***************
*** 618,623 ****
--- 618,624 ----
        int irq;
        int pcpl;
        int hwpend;
+       int softpend;
        int emsr, dmsr;
        static int processing;

***************
*** 630,636 ****
--- 631,639 ----
        asm volatile("mtmsr %0" :: "r"(dmsr));

        pcpl = splhigh();               /* Turn off all */
+       softpend = ipending & ~pcpl;    /* pending "softies" */
        hwpend = ipending & ~pcpl;      /* Do now unmasked pendings */
+       ipending &= pcpl;               /* Clear ints we're about to do */
        if (!have_openpic) {
                imen &= ~hwpend;
                enable_irq(~imen);
***************
*** 652,673 ****

        /*out32rb(INT_ENABLE_REG, ~imen);*/

!       if ((ipending & ~pcpl) & (1 << SIR_SERIAL)) {
!               ipending &= ~(1 << SIR_SERIAL);
!               softserial();
!               intrcnt[CNT_SOFTSERIAL]++;
!       }
!       if ((ipending & ~pcpl) & (1 << SIR_CLOCK)) {
                ipending &= ~(1 << SIR_CLOCK);
                softclock();
                intrcnt[CNT_SOFTCLOCK]++;
        }
!       if ((ipending & ~pcpl) & (1 << SIR_NET)) {
                ipending &= ~(1 << SIR_NET);
                softnet();
                intrcnt[CNT_SOFTNET]++;
        }
!       ipending &= pcpl;
        cpl = pcpl;     /* Don't use splx... we are here already! */
        asm volatile("mtmsr %0" :: "r"(emsr));
        processing = 0;
--- 655,676 ----

        /*out32rb(INT_ENABLE_REG, ~imen);*/

!       if (softpend & (1 << SIR_CLOCK)) {
                ipending &= ~(1 << SIR_CLOCK);
                softclock();
                intrcnt[CNT_SOFTCLOCK]++;
        }
!       if (softpend & (1 << SIR_NET)) {
                ipending &= ~(1 << SIR_NET);
                softnet();
                intrcnt[CNT_SOFTNET]++;
        }
!       if (softpend & (1 << SIR_SERIAL)) {
!               ipending &= ~(1 << SIR_SERIAL);
!               softserial();
!               intrcnt[CNT_SOFTSERIAL]++;
!       }
!
        cpl = pcpl;     /* Don't use splx... we are here already! */
        asm volatile("mtmsr %0" :: "r"(emsr));
        processing = 0;

>Release-Note:
>Audit-Trail:
>Unformatted: