]> git.hungrycats.org Git - linux/commitdiff
[PATCH] sh: preempt fixes
authorAndrew Morton <akpm@osdl.org>
Fri, 13 Feb 2004 07:45:47 +0000 (23:45 -0800)
committerLinus Torvalds <torvalds@home.osdl.org>
Fri, 13 Feb 2004 07:45:47 +0000 (23:45 -0800)
From: Paul Mundt <lethal@linux-sh.org>

This fixes up a number of other outstanding preemption issues in the sh
backend (in addition to the ones already fixed in previous patches).

Patch from Kaz Kojima.

arch/sh/kernel/entry.S
arch/sh/kernel/irq.c

index 19094650d69a624031faf208255dd6d12b9914a8..e64c5fbfe45ff42344a989d527af7727a412170a 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.33 2003/11/22 15:39:51 lethal Exp $
+/* $Id: entry.S,v 1.34 2004/01/13 05:52:11 kkojima Exp $
  *
  *  linux/arch/sh/entry.S
  *
@@ -351,18 +351,22 @@ ret_from_irq:
         GET_THREAD_INFO(r8)
 
 #ifdef CONFIG_PREEMPT
+       bra     resume_userspace
+        nop
 ENTRY(resume_kernel)
        mov.l   @(TI_PRE_COUNT,r8), r0  ! current_thread_info->preempt_count
        tst     r0, r0
-       bf      restore_all
+       bf      noresched
 need_resched:
        mov.l   @(TI_FLAGS,r8), r0      ! current_thread_info->flags
        tst     #_TIF_NEED_RESCHED, r0  ! need_resched set?
-       bt      restore_all
+       bt      noresched
 
-       stc     sr, r0                  ! interrupts disabled?
-       tst     #0xf0, r0
-       bf      restore_all
+       mov     #OFF_SR, r0
+       mov.l   @(r0,r15), r0           ! get status register
+       and     #0xf0, r0               ! interrupts off (exception path)?
+       cmp/eq  #0xf0, r0
+       bt      noresched
 
        mov.l   1f, r0
        mov.l   r0, @(TI_PRE_COUNT,r8)
@@ -375,7 +379,10 @@ need_resched:
        mov.l   r0, @(TI_PRE_COUNT,r8)
        CLI()
 
-       bra need_resched
+       bra     need_resched
+        nop
+noresched:
+       bra     restore_all
         nop
 
        .align 2
@@ -525,7 +532,7 @@ ENTRY(system_call)
        ! Is the trap argument >= 0x20? (TRA will be >= 0x80)
        mov     #0x7f, r9
        cmp/hi  r9, r8
-       bt/s    debug_trap
+       bt/s    0f
         mov    #OFF_TRA, r9
        add     r15, r9
        !
@@ -543,6 +550,10 @@ syscall_badsys:                    ! Bad syscall number
        bra     resume_userspace
         mov.l  r0, @(OFF_R0,r15)       ! Return value
        !
+0:
+       bra     debug_trap
+        nop
+       !
 good_system_call:              ! Good syscall number
        mov.l   @(TI_FLAGS,r8), r8
        mov     #_TIF_SYSCALL_TRACE, r10
@@ -632,12 +643,8 @@ skip_restore:
        !
        ! Calculate new SR value
        mov     k3, k2                  ! original SR value
-       mov.l   8f, k1
-       stc     sr, k0
-       and     k1, k0                  ! Get current FD-bit
        mov.l   9f, k1
        and     k1, k2                  ! Mask orignal SR value
-       or      k0, k2                  ! Inherit current FD-bit
        !
        mov     k3, k0                  ! Calculate IMASK-bits
        shlr2   k0
@@ -668,8 +675,7 @@ skip_restore:
 4:     .long   do_syscall_trace
 5:     .long   0x00001000      ! DSP
 7:     .long   0x30000000
-8:     .long   0x00008000      ! FD
-9:     .long   0xffff7f0f      ! ~(IMASK+FD)
+9:
 __INV_IMASK:
        .long   0xffffff0f      ! ~(IMASK)
 
@@ -838,7 +844,7 @@ skip_save:
 
        .align  2
 1:     .long   0x00001000      ! DSP=1
-2:     .long   0x000000f0      ! FD=0, IMASK=15
+2:     .long   0x000080f0      ! FD=1, IMASK=15
 3:     .long   0xcfffffff      ! RB=0, BL=0
 4:     .long   exception_handling_table
 
index 5365a7d63ef474e17bab1e8a1b6a02cf1e9730b7..a37e2d1cffcee150c3d611edb88b454c1f10ee0e 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: irq.c,v 1.19 2004/01/10 01:25:32 lethal Exp $
+/* $Id: irq.c,v 1.20 2004/01/13 05:52:11 kkojima Exp $
  *
  * linux/arch/sh/kernel/irq.c
  *
@@ -318,6 +318,16 @@ asmlinkage int do_IRQ(unsigned long r4, unsigned long r5,
 
        irq_enter();
 
+#ifdef CONFIG_PREEMPT
+       /*
+        * At this point we're now about to actually call handlers,
+        * and interrupts might get reenabled during them... bump
+        * preempt_count to prevent any preemption while the handler
+        * called here is pending...
+        */
+       preempt_disable();
+#endif
+
        /* Get IRQ number */
        asm volatile("stc       r2_bank, %0\n\t"
                     "shlr2     %0\n\t"
@@ -393,6 +403,15 @@ out:
 
        irq_exit();
 
+#ifdef CONFIG_PREEMPT
+       /*
+        * We're done with the handlers, interrupts should be
+        * currently disabled; decrement preempt_count now so
+        * as we return preemption may be allowed...
+        */
+       preempt_enable_no_resched();
+#endif
+
        return 1;
 }