s390/vtimer: rework virtual timer interface
The current virtual timer interface is inherently per-cpu and hard to use. The sole user of the interface is appldata which uses it to execute a function after a specific amount of cputime has been used over all cpus. Rework the virtual timer interface to hook into the cputime accounting. This makes the interface independent from the CPU timer interrupts, and makes the virtual timers global as opposed to per-cpu. Overall the code is greatly simplified. The downside is that the accuracy is not as good as the original implementation, but it is still good enough for appldata. Reviewed-by: Jan Glauber <jang@linux.vnet.ibm.com> Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
This commit is contained in:
@@ -616,17 +616,13 @@ ext_skip:
|
||||
* Load idle PSW. The second "half" of this function is in cleanup_idle.
|
||||
*/
|
||||
ENTRY(psw_idle)
|
||||
st %r4,__SF_EMPTY(%r15)
|
||||
st %r3,__SF_EMPTY(%r15)
|
||||
basr %r1,0
|
||||
la %r1,psw_idle_lpsw+4-.(%r1)
|
||||
st %r1,__SF_EMPTY+4(%r15)
|
||||
oi __SF_EMPTY+4(%r15),0x80
|
||||
la %r1,.Lvtimer_max-psw_idle_lpsw-4(%r1)
|
||||
stck __IDLE_ENTER(%r2)
|
||||
ltr %r5,%r5
|
||||
stpt __VQ_IDLE_ENTER(%r3)
|
||||
jz psw_idle_lpsw
|
||||
spt 0(%r1)
|
||||
stck __CLOCK_IDLE_ENTER(%r2)
|
||||
stpt __TIMER_IDLE_ENTER(%r2)
|
||||
psw_idle_lpsw:
|
||||
lpsw __SF_EMPTY(%r15)
|
||||
br %r14
|
||||
@@ -885,33 +881,28 @@ cleanup_io_restore_insn:
|
||||
|
||||
cleanup_idle:
|
||||
# copy interrupt clock & cpu timer
|
||||
mvc __IDLE_EXIT(8,%r2),__LC_INT_CLOCK
|
||||
mvc __VQ_IDLE_EXIT(8,%r3),__LC_ASYNC_ENTER_TIMER
|
||||
mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_INT_CLOCK
|
||||
mvc __TIMER_IDLE_EXIT(8,%r2),__LC_ASYNC_ENTER_TIMER
|
||||
chi %r11,__LC_SAVE_AREA_ASYNC
|
||||
je 0f
|
||||
mvc __IDLE_EXIT(8,%r2),__LC_MCCK_CLOCK
|
||||
mvc __VQ_IDLE_EXIT(8,%r3),__LC_MCCK_ENTER_TIMER
|
||||
mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_MCCK_CLOCK
|
||||
mvc __TIMER_IDLE_EXIT(8,%r2),__LC_MCCK_ENTER_TIMER
|
||||
0: # check if stck has been executed
|
||||
cl %r9,BASED(cleanup_idle_insn)
|
||||
jhe 1f
|
||||
mvc __IDLE_ENTER(8,%r2),__IDLE_EXIT(%r2)
|
||||
mvc __VQ_IDLE_ENTER(8,%r3),__VQ_IDLE_EXIT(%r3)
|
||||
j 2f
|
||||
1: # check if the cpu timer has been reprogrammed
|
||||
ltr %r5,%r5
|
||||
jz 2f
|
||||
spt __VQ_IDLE_ENTER(%r3)
|
||||
2: # account system time going idle
|
||||
mvc __CLOCK_IDLE_ENTER(8,%r2),__CLOCK_IDLE_EXIT(%r2)
|
||||
mvc __TIMER_IDLE_ENTER(8,%r2),__TIMER_IDLE_EXIT(%r3)
|
||||
1: # account system time going idle
|
||||
lm %r9,%r10,__LC_STEAL_TIMER
|
||||
ADD64 %r9,%r10,__IDLE_ENTER(%r2)
|
||||
ADD64 %r9,%r10,__CLOCK_IDLE_ENTER(%r2)
|
||||
SUB64 %r9,%r10,__LC_LAST_UPDATE_CLOCK
|
||||
stm %r9,%r10,__LC_STEAL_TIMER
|
||||
mvc __LC_LAST_UPDATE_CLOCK(8),__IDLE_EXIT(%r2)
|
||||
mvc __LC_LAST_UPDATE_CLOCK(8),__CLOCK_IDLE_EXIT(%r2)
|
||||
lm %r9,%r10,__LC_SYSTEM_TIMER
|
||||
ADD64 %r9,%r10,__LC_LAST_UPDATE_TIMER
|
||||
SUB64 %r9,%r10,__VQ_IDLE_ENTER(%r3)
|
||||
SUB64 %r9,%r10,__TIMER_IDLE_ENTER(%r2)
|
||||
stm %r9,%r10,__LC_SYSTEM_TIMER
|
||||
mvc __LC_LAST_UPDATE_TIMER(8),__VQ_IDLE_EXIT(%r3)
|
||||
mvc __LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2)
|
||||
# prepare return psw
|
||||
n %r8,BASED(cleanup_idle_wait) # clear wait state bit
|
||||
l %r9,24(%r11) # return from psw_idle
|
||||
|
Reference in New Issue
Block a user