Commit 2688905e authored by Martin Schwidefsky's avatar Martin Schwidefsky

[S390] s390: Optimize user and work TIF check

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: default avatarMartin Schwidefsky <schwidefsky@de.ibm.com>
parent c0a18111
...@@ -279,8 +279,6 @@ sysc_do_restart: ...@@ -279,8 +279,6 @@ sysc_do_restart:
st %r2,SP_R2(%r15) # store return value (change R2 on stack) st %r2,SP_R2(%r15) # store return value (change R2 on stack)
sysc_return: sysc_return:
tm SP_PSW+1(%r15),0x01 # returning to user ?
bno BASED(sysc_restore)
tm __TI_flags+3(%r9),_TIF_WORK_SVC tm __TI_flags+3(%r9),_TIF_WORK_SVC
bnz BASED(sysc_work) # there is work to do (signals etc.) bnz BASED(sysc_work) # there is work to do (signals etc.)
sysc_restore: sysc_restore:
...@@ -312,6 +310,8 @@ sysc_work_loop: ...@@ -312,6 +310,8 @@ sysc_work_loop:
# One of the work bits is on. Find out which one. # One of the work bits is on. Find out which one.
# #
sysc_work: sysc_work:
tm SP_PSW+1(%r15),0x01 # returning to user ?
bno BASED(sysc_restore)
tm __TI_flags+3(%r9),_TIF_MCCK_PENDING tm __TI_flags+3(%r9),_TIF_MCCK_PENDING
bo BASED(sysc_mcck_pending) bo BASED(sysc_mcck_pending)
tm __TI_flags+3(%r9),_TIF_NEED_RESCHED tm __TI_flags+3(%r9),_TIF_NEED_RESCHED
...@@ -602,12 +602,6 @@ io_no_vtime: ...@@ -602,12 +602,6 @@ io_no_vtime:
la %r2,SP_PTREGS(%r15) # address of register-save area la %r2,SP_PTREGS(%r15) # address of register-save area
basr %r14,%r1 # branch to standard irq handler basr %r14,%r1 # branch to standard irq handler
io_return: 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 tm __TI_flags+3(%r9),_TIF_WORK_INT
bnz BASED(io_work) # there is work to do (signals etc.) bnz BASED(io_work) # there is work to do (signals etc.)
io_restore: io_restore:
...@@ -629,10 +623,18 @@ io_restore_trace_psw: ...@@ -629,10 +623,18 @@ io_restore_trace_psw:
.long 0, io_restore_trace + 0x80000000 .long 0, io_restore_trace + 0x80000000
#endif #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) icm %r0,15,__TI_precount(%r9)
bnz BASED(io_restore) bnz BASED(io_restore) # preemption disabled
l %r1,SP_R15(%r15) l %r1,SP_R15(%r15)
s %r1,BASED(.Lc_spsize) s %r1,BASED(.Lc_spsize)
mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
...@@ -646,10 +648,7 @@ io_resume_loop: ...@@ -646,10 +648,7 @@ io_resume_loop:
br %r1 # call schedule br %r1 # call schedule
#endif #endif
# io_work_user:
# switch to kernel stack, then check the TIF bits
#
io_work:
l %r1,__LC_KERNEL_STACK l %r1,__LC_KERNEL_STACK
s %r1,BASED(.Lc_spsize) s %r1,BASED(.Lc_spsize)
mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
......
...@@ -271,8 +271,6 @@ sysc_noemu: ...@@ -271,8 +271,6 @@ sysc_noemu:
stg %r2,SP_R2(%r15) # store return value (change R2 on stack) stg %r2,SP_R2(%r15) # store return value (change R2 on stack)
sysc_return: sysc_return:
tm SP_PSW+1(%r15),0x01 # returning to user ?
jno sysc_restore
tm __TI_flags+7(%r9),_TIF_WORK_SVC tm __TI_flags+7(%r9),_TIF_WORK_SVC
jnz sysc_work # there is work to do (signals etc.) jnz sysc_work # there is work to do (signals etc.)
sysc_restore: sysc_restore:
...@@ -304,6 +302,8 @@ sysc_work_loop: ...@@ -304,6 +302,8 @@ sysc_work_loop:
# One of the work bits is on. Find out which one. # One of the work bits is on. Find out which one.
# #
sysc_work: sysc_work:
tm SP_PSW+1(%r15),0x01 # returning to user ?
jno sysc_restore
tm __TI_flags+7(%r9),_TIF_MCCK_PENDING tm __TI_flags+7(%r9),_TIF_MCCK_PENDING
jo sysc_mcck_pending jo sysc_mcck_pending
tm __TI_flags+7(%r9),_TIF_NEED_RESCHED tm __TI_flags+7(%r9),_TIF_NEED_RESCHED
...@@ -585,12 +585,6 @@ io_no_vtime: ...@@ -585,12 +585,6 @@ io_no_vtime:
la %r2,SP_PTREGS(%r15) # address of register-save area la %r2,SP_PTREGS(%r15) # address of register-save area
brasl %r14,do_IRQ # call standard irq handler brasl %r14,do_IRQ # call standard irq handler
io_return: 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 tm __TI_flags+7(%r9),_TIF_WORK_INT
jnz io_work # there is work to do (signals etc.) jnz io_work # there is work to do (signals etc.)
io_restore: io_restore:
...@@ -612,10 +606,18 @@ io_restore_trace_psw: ...@@ -612,10 +606,18 @@ io_restore_trace_psw:
.quad 0, io_restore_trace .quad 0, io_restore_trace
#endif #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) icm %r0,15,__TI_precount(%r9)
jnz io_restore jnz io_restore # preemption is disabled
# switch to kernel stack # switch to kernel stack
lg %r1,SP_R15(%r15) lg %r1,SP_R15(%r15)
aghi %r1,-SP_SIZE aghi %r1,-SP_SIZE
...@@ -629,10 +631,7 @@ io_resume_loop: ...@@ -629,10 +631,7 @@ io_resume_loop:
jg preempt_schedule_irq jg preempt_schedule_irq
#endif #endif
# io_work_user:
# switch to kernel stack, then check TIF bits
#
io_work:
lg %r1,__LC_KERNEL_STACK lg %r1,__LC_KERNEL_STACK
aghi %r1,-SP_SIZE aghi %r1,-SP_SIZE
mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15) mvc SP_PTREGS(__PT_SIZE,%r1),SP_PTREGS(%r15)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment