OSDN Git Service

[S390] s390: Optimize user and work TIF check
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Wed, 7 May 2008 07:22:52 +0000 (09:22 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Wed, 7 May 2008 07:23:00 +0000 (09:23 +0200)
On return from syscall or interrupt, we have to check if we return to
userspace (likely) and if there is work todo (less likely) to decide
if we handle the work. We can optimize this check: we first check for
the less likely work case and then check for userspace.

This patch is also a preparation for an additional patch, that fixes a bug
in KVM dealing with cpu bound guests.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
arch/s390/kernel/entry.S
arch/s390/kernel/entry64.S

index bdbb3bc..708cf9c 100644 (file)
@@ -279,8 +279,6 @@ sysc_do_restart:
        st      %r2,SP_R2(%r15)   # store return value (change R2 on stack)
 
 sysc_return:
-       tm      SP_PSW+1(%r15),0x01     # returning to user ?
-       bno     BASED(sysc_restore)
        tm      __TI_flags+3(%r9),_TIF_WORK_SVC
        bnz     BASED(sysc_work)  # there is work to do (signals etc.)
 sysc_restore:
@@ -312,6 +310,8 @@ sysc_work_loop:
 # One of the work bits is on. Find out which one.
 #
 sysc_work:
+       tm      SP_PSW+1(%r15),0x01     # returning to user ?
+       bno     BASED(sysc_restore)
        tm      __TI_flags+3(%r9),_TIF_MCCK_PENDING
        bo      BASED(sysc_mcck_pending)
        tm      __TI_flags+3(%r9),_TIF_NEED_RESCHED
@@ -602,12 +602,6 @@ io_no_vtime:
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
        basr    %r14,%r1                # branch to standard irq handler
 io_return:
-       tm      SP_PSW+1(%r15),0x01     # returning to user ?
-#ifdef CONFIG_PREEMPT
-       bno     BASED(io_preempt)       # no -> check for preemptive scheduling
-#else
-       bno     BASED(io_restore)       # no-> skip resched & signal
-#endif
        tm      __TI_flags+3(%r9),_TIF_WORK_INT
        bnz     BASED(io_work)          # there is work to do (signals etc.)
 io_restore:
@@ -629,10 +623,18 @@ io_restore_trace_psw:
        .long   0, io_restore_trace + 0x80000000
 #endif
 
-#ifdef CONFIG_PREEMPT
-io_preempt:
+#
+# switch to kernel stack, then check the TIF bits
+#
+io_work:
+       tm      SP_PSW+1(%r15),0x01     # returning to user ?
+#ifndef CONFIG_PREEMPT
+       bno     BASED(io_restore)       # no-> skip resched & signal
+#else
+       bnz     BASED(io_work_user)     # no -> check for preemptive scheduling
+       # check for preemptive scheduling
        icm     %r0,15,__TI_precount(%r9)
-       bnz     BASED(io_restore)
+       bnz     BASED(io_restore)       # preemption disabled
        l       %r1,SP_R15(%r15)
        s       %r1,BASED(.Lc_spsize)
        mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
@@ -646,10 +648,7 @@ io_resume_loop:
        br      %r1                     # call schedule
 #endif
 
-#
-# switch to kernel stack, then check the TIF bits
-#
-io_work:
+io_work_user:
        l       %r1,__LC_KERNEL_STACK
        s       %r1,BASED(.Lc_spsize)
        mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
index 5a4a7bc..a57909d 100644 (file)
@@ -271,8 +271,6 @@ sysc_noemu:
        stg     %r2,SP_R2(%r15) # store return value (change R2 on stack)
 
 sysc_return:
-       tm      SP_PSW+1(%r15),0x01     # returning to user ?
-       jno     sysc_restore
        tm      __TI_flags+7(%r9),_TIF_WORK_SVC
        jnz     sysc_work       # there is work to do (signals etc.)
 sysc_restore:
@@ -304,6 +302,8 @@ sysc_work_loop:
 # One of the work bits is on. Find out which one.
 #
 sysc_work:
+       tm      SP_PSW+1(%r15),0x01     # returning to user ?
+       jno     sysc_restore
        tm      __TI_flags+7(%r9),_TIF_MCCK_PENDING
        jo      sysc_mcck_pending
        tm      __TI_flags+7(%r9),_TIF_NEED_RESCHED
@@ -585,12 +585,6 @@ io_no_vtime:
        la      %r2,SP_PTREGS(%r15)     # address of register-save area
        brasl   %r14,do_IRQ             # call standard irq handler
 io_return:
-       tm      SP_PSW+1(%r15),0x01     # returning to user ?
-#ifdef CONFIG_PREEMPT
-       jno     io_preempt              # no -> check for preemptive scheduling
-#else
-       jno     io_restore              # no-> skip resched & signal
-#endif
        tm      __TI_flags+7(%r9),_TIF_WORK_INT
        jnz     io_work                 # there is work to do (signals etc.)
 io_restore:
@@ -612,10 +606,18 @@ io_restore_trace_psw:
        .quad   0, io_restore_trace
 #endif
 
-#ifdef CONFIG_PREEMPT
-io_preempt:
+#
+# switch to kernel stack, then check TIF bits
+#
+io_work:
+       tm      SP_PSW+1(%r15),0x01     # returning to user ?
+#ifndef CONFIG_PREEMPT
+       jno     io_restore              # no-> skip resched & signal
+#else
+       jnz     io_work_user            # yes -> do resched & signal
+       # check for preemptive scheduling
        icm     %r0,15,__TI_precount(%r9)
-       jnz     io_restore
+       jnz     io_restore              # preemption is disabled
        # switch to kernel stack
        lg      %r1,SP_R15(%r15)
        aghi    %r1,-SP_SIZE
@@ -629,10 +631,7 @@ io_resume_loop:
        jg      preempt_schedule_irq
 #endif
 
-#
-# switch to kernel stack, then check TIF bits
-#
-io_work:
+io_work_user:
        lg      %r1,__LC_KERNEL_STACK
        aghi    %r1,-SP_SIZE
        mvc     SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)