diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2012-07-20 05:15:08 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2012-07-20 05:15:08 -0400 |
commit | 27f6b416626a240e1b46f646d2e0c5266f4eac95 (patch) | |
tree | 4549855d7996ce9d18e1586e2f0bfb5fa5835718 /arch/s390/kernel/entry.S | |
parent | 921486b92bcb1b82ab6668dcbb36d05604966351 (diff) |
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>
Diffstat (limited to 'arch/s390/kernel/entry.S')
-rw-r--r-- | arch/s390/kernel/entry.S | 37 |
1 files changed, 14 insertions, 23 deletions
diff --git a/arch/s390/kernel/entry.S b/arch/s390/kernel/entry.S index 2c0eff488875..870bad6d56fc 100644 --- a/arch/s390/kernel/entry.S +++ b/arch/s390/kernel/entry.S | |||
@@ -616,17 +616,13 @@ ext_skip: | |||
616 | * Load idle PSW. The second "half" of this function is in cleanup_idle. | 616 | * Load idle PSW. The second "half" of this function is in cleanup_idle. |
617 | */ | 617 | */ |
618 | ENTRY(psw_idle) | 618 | ENTRY(psw_idle) |
619 | st %r4,__SF_EMPTY(%r15) | 619 | st %r3,__SF_EMPTY(%r15) |
620 | basr %r1,0 | 620 | basr %r1,0 |
621 | la %r1,psw_idle_lpsw+4-.(%r1) | 621 | la %r1,psw_idle_lpsw+4-.(%r1) |
622 | st %r1,__SF_EMPTY+4(%r15) | 622 | st %r1,__SF_EMPTY+4(%r15) |
623 | oi __SF_EMPTY+4(%r15),0x80 | 623 | oi __SF_EMPTY+4(%r15),0x80 |
624 | la %r1,.Lvtimer_max-psw_idle_lpsw-4(%r1) | 624 | stck __CLOCK_IDLE_ENTER(%r2) |
625 | stck __IDLE_ENTER(%r2) | 625 | stpt __TIMER_IDLE_ENTER(%r2) |
626 | ltr %r5,%r5 | ||
627 | stpt __VQ_IDLE_ENTER(%r3) | ||
628 | jz psw_idle_lpsw | ||
629 | spt 0(%r1) | ||
630 | psw_idle_lpsw: | 626 | psw_idle_lpsw: |
631 | lpsw __SF_EMPTY(%r15) | 627 | lpsw __SF_EMPTY(%r15) |
632 | br %r14 | 628 | br %r14 |
@@ -885,33 +881,28 @@ cleanup_io_restore_insn: | |||
885 | 881 | ||
886 | cleanup_idle: | 882 | cleanup_idle: |
887 | # copy interrupt clock & cpu timer | 883 | # copy interrupt clock & cpu timer |
888 | mvc __IDLE_EXIT(8,%r2),__LC_INT_CLOCK | 884 | mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_INT_CLOCK |
889 | mvc __VQ_IDLE_EXIT(8,%r3),__LC_ASYNC_ENTER_TIMER | 885 | mvc __TIMER_IDLE_EXIT(8,%r2),__LC_ASYNC_ENTER_TIMER |
890 | chi %r11,__LC_SAVE_AREA_ASYNC | 886 | chi %r11,__LC_SAVE_AREA_ASYNC |
891 | je 0f | 887 | je 0f |
892 | mvc __IDLE_EXIT(8,%r2),__LC_MCCK_CLOCK | 888 | mvc __CLOCK_IDLE_EXIT(8,%r2),__LC_MCCK_CLOCK |
893 | mvc __VQ_IDLE_EXIT(8,%r3),__LC_MCCK_ENTER_TIMER | 889 | mvc __TIMER_IDLE_EXIT(8,%r2),__LC_MCCK_ENTER_TIMER |
894 | 0: # check if stck has been executed | 890 | 0: # check if stck has been executed |
895 | cl %r9,BASED(cleanup_idle_insn) | 891 | cl %r9,BASED(cleanup_idle_insn) |
896 | jhe 1f | 892 | jhe 1f |
897 | mvc __IDLE_ENTER(8,%r2),__IDLE_EXIT(%r2) | 893 | mvc __CLOCK_IDLE_ENTER(8,%r2),__CLOCK_IDLE_EXIT(%r2) |
898 | mvc __VQ_IDLE_ENTER(8,%r3),__VQ_IDLE_EXIT(%r3) | 894 | mvc __TIMER_IDLE_ENTER(8,%r2),__TIMER_IDLE_EXIT(%r3) |
899 | j 2f | 895 | 1: # account system time going idle |
900 | 1: # check if the cpu timer has been reprogrammed | ||
901 | ltr %r5,%r5 | ||
902 | jz 2f | ||
903 | spt __VQ_IDLE_ENTER(%r3) | ||
904 | 2: # account system time going idle | ||
905 | lm %r9,%r10,__LC_STEAL_TIMER | 896 | lm %r9,%r10,__LC_STEAL_TIMER |
906 | ADD64 %r9,%r10,__IDLE_ENTER(%r2) | 897 | ADD64 %r9,%r10,__CLOCK_IDLE_ENTER(%r2) |
907 | SUB64 %r9,%r10,__LC_LAST_UPDATE_CLOCK | 898 | SUB64 %r9,%r10,__LC_LAST_UPDATE_CLOCK |
908 | stm %r9,%r10,__LC_STEAL_TIMER | 899 | stm %r9,%r10,__LC_STEAL_TIMER |
909 | mvc __LC_LAST_UPDATE_CLOCK(8),__IDLE_EXIT(%r2) | 900 | mvc __LC_LAST_UPDATE_CLOCK(8),__CLOCK_IDLE_EXIT(%r2) |
910 | lm %r9,%r10,__LC_SYSTEM_TIMER | 901 | lm %r9,%r10,__LC_SYSTEM_TIMER |
911 | ADD64 %r9,%r10,__LC_LAST_UPDATE_TIMER | 902 | ADD64 %r9,%r10,__LC_LAST_UPDATE_TIMER |
912 | SUB64 %r9,%r10,__VQ_IDLE_ENTER(%r3) | 903 | SUB64 %r9,%r10,__TIMER_IDLE_ENTER(%r2) |
913 | stm %r9,%r10,__LC_SYSTEM_TIMER | 904 | stm %r9,%r10,__LC_SYSTEM_TIMER |
914 | mvc __LC_LAST_UPDATE_TIMER(8),__VQ_IDLE_EXIT(%r3) | 905 | mvc __LC_LAST_UPDATE_TIMER(8),__TIMER_IDLE_EXIT(%r2) |
915 | # prepare return psw | 906 | # prepare return psw |
916 | n %r8,BASED(cleanup_idle_wait) # clear wait state bit | 907 | n %r8,BASED(cleanup_idle_wait) # clear wait state bit |
917 | l %r9,24(%r11) # return from psw_idle | 908 | l %r9,24(%r11) # return from psw_idle |