bug-hurd
[Top][All Lists]
Advanced

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

[PATCH] soft interrupts


From: Daniel Wagner
Subject: [PATCH] soft interrupts
Date: Tue, 28 Jan 2003 22:24:05 +0100
User-agent: Gnus/5.090008 (Oort Gnus v0.08) Emacs/21.2 (i386-debian-linux-gnu)

Hello

At the moment the softint handler is called from softclock handler.
This leads to a panic which I have reported here [1].  

The main idea of this patch is that the softint handler should be
called directly from spl0 and splx_cli.  The invariant is that only
after all outstanding hardware interrupts are handled and no other
softint frame is suppended a new call to the softint handler is
allowed.  This is exactly how the OSKit handles the softints.

I've tested the patch and the kernel is quite stable and didn't see
any panic under have net last (ping -f). 

daniel

ps: I have decided to fix this before going into the serial stuff
again. 

[1]: http://mail.gnu.org/archive/html/bug-hurd/2002-11/msg00187.html


2003-01-28  Daniel Wagner  <wagi@gmx.ch>

        * i386/i386/spl.S (SOFTINT): New marco.
        (spl0): Removed old Linux soft interrupt invokation code.  Call the 
        soft interrupt handler from here.
        (splx_cli): Likewise.
        * oskit/pc/osenv_timer.c (softclock_oskit): Don't call oskit_softint
        from here.
        * oskit/osenv_softirq.c (softint_disabled):  New variable.
        

Index: osenv_softirq.c
===================================================================
RCS file: /cvsroot/hurd/gnumach/oskit/osenv_softirq.c,v
retrieving revision 1.2
diff -u -p -r1.2 osenv_softirq.c
--- osenv_softirq.c     27 May 2002 23:01:57 -0000      1.2
+++ osenv_softirq.c     28 Jan 2003 21:10:37 -0000
@@ -39,6 +39,10 @@ struct softint_handler {
   int    flags;
 };
 
+/* Prevent oskit_softint being called while another oskit_softint frame is
+   suspended.  */
+int softint_disabled = 0;
+
 /* Array of pointers to lists of interrupt handlers.  */
 static struct softint_handler *softint_handlers[SOFT_IRQ_COUNT];
 

Index: pc/osenv_timer.c
===================================================================
RCS file: /cvsroot/hurd/gnumach/oskit/pc/osenv_timer.c,v
retrieving revision 1.2
diff -u -p -r1.2 osenv_timer.c
--- pc/osenv_timer.c    27 May 2002 23:01:57 -0000      1.2
+++ pc/osenv_timer.c    28 Jan 2003 21:06:41 -0000
@@ -54,8 +54,6 @@ softclock_oskit (void)
        for (th = timer_head; th; th = th->next)
                (*th->func)();
        osenv_intr_enable();
-
-       oskit_softint();
 }
 
 /*


Index: spl.S
===================================================================
RCS file: /cvsroot/hurd/gnumach/i386/i386/spl.S,v
retrieving revision 1.2
diff -u -p -r1.2 spl.S
--- spl.S       27 May 2002 23:01:50 -0000      1.2
+++ spl.S       28 Jan 2003 20:43:16 -0000
@@ -52,33 +52,33 @@
        outb    %al,$(SLAVES_OCW);              \
 9:
 
+/*
+ * Call the soft interrupt handler if there is no hardware interrupt
+ * pending/worked on or another softint frame suspended.
+ */
+#define SOFTINT()                              \
+       cmpl    $0, EXT(nested_pic_mask);       \
+       jne     1f;                             \
+       cmpl    $0, EXT(softint_disabled);      \
+       jne     1f;                             \
+       movl    $1, EXT(softint_disabled);      \
+       call    EXT(spl1);                      \
+       call    EXT(oskit_softint);             \
+       cli     ;                               \
+       movl    $0, EXT(softint_disabled);      \
+1:     
+
 ENTRY(spl0)
        movl    EXT(curr_ipl),%eax      /* save current ipl */
        pushl   %eax
        cli                             /* disable interrupts */
-#ifdef LINUX_DEV
-       movl    EXT(bh_active),%eax
-                                       /* get pending mask */
-       andl    EXT(bh_mask),%eax       /* any pending unmasked interrupts? */
-       jz      1f                      /* no, skip */
-       call    EXT(spl1)               /* block further interrupts */
-       incl    EXT(intr_count)         /* set interrupt flag */
-       call    EXT(linux_soft_intr)    /* go handle interrupt */
-       decl    EXT(intr_count)         /* decrement interrupt flag */
-       cli                             /* disable interrupts */
-1:
-#endif
+
+       SOFTINT()                       /* handle pending soft interrupts */
+       
        cmpl    $0,softclkpending       /* softclock pending? */
        je      1f                      /* no, skip */
        movl    $0,softclkpending       /* clear flag */
        call    EXT(spl1)               /* block further interrupts */
-#ifdef LINUX_DEV
-       incl    EXT(intr_count)         /* set interrupt flag */
-#endif
        call    EXT(softclock)          /* go handle interrupt */
-#ifdef LINUX_DEV
-       decl    EXT(intr_count)         /* decrement interrupt flag */
-#endif
        cli                             /* disable interrupts */
 1:
        cmpl    $(SPL0),EXT(curr_ipl)   /* are we at spl0? */
@@ -147,29 +147,14 @@ splx_cli:
        cli                             /* disable interrupts */
        testl   %edx,%edx               /* spl0? */
        jnz     2f                      /* no, skip */
-#ifdef LINUX_DEV
-       movl    EXT(bh_active),%eax
-                                       /* get pending mask */
-       andl    EXT(bh_mask),%eax       /* any pending unmasked interrupts? */
-       jz      1f                      /* no, skip */
-       call    EXT(spl1)               /* block further interrupts */
-       incl    EXT(intr_count)         /* set interrupt flag */
-       call    EXT(linux_soft_intr)    /* go handle interrupt */
-       decl    EXT(intr_count)         /* decrement interrupt flag */
-       cli                             /* disable interrupts */
-1:
-#endif
+
+       SOFTINT()                       /* handle pending soft interrupts */
+                       
        cmpl    $0,softclkpending       /* softclock pending? */
        je      1f                      /* no, skip */
        movl    $0,softclkpending       /* clear flag */
        call    EXT(spl1)               /* block further interrupts */
-#ifdef LINUX_DEV
-       incl    EXT(intr_count)         /* set interrupt flag */
-#endif
        call    EXT(softclock)          /* go handle interrupt */
-#ifdef LINUX_DEV
-       decl    EXT(intr_count)         /* decrement interrupt flag */
-#endif
        cli                             /* disable interrupts */
 1:
        xorl    %edx,%edx               /* edx = ipl 0 */




reply via email to

[Prev in Thread] Current Thread [Next in Thread]