diff options
author | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-10-01 04:57:57 -0400 |
---|---|---|
committer | Martin Schwidefsky <schwidefsky@de.ibm.com> | 2014-10-09 03:14:03 -0400 |
commit | b5f87f15e20092c060f465b283b07a76af7f2e5f (patch) | |
tree | f6a7b227a09ce5fd47e28113e0f48208654dd82c /arch/s390 | |
parent | fe0f49768d807a8fe6336b097feb8c4441951710 (diff) |
s390/idle: consolidate idle functions and definitions
Move the C functions and definitions related to the idle state handling
to arch/s390/include/asm/idle.h and arch/s390/kernel/idle.c. The function
s390_get_idle_time is renamed to arch_cpu_idle_time and vtime_stop_cpu to
enabled_wait.
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/include/asm/cputime.h | 18 | ||||
-rw-r--r-- | arch/s390/include/asm/idle.h | 26 | ||||
-rw-r--r-- | arch/s390/include/asm/processor.h | 7 | ||||
-rw-r--r-- | arch/s390/include/asm/vtimer.h | 2 | ||||
-rw-r--r-- | arch/s390/kernel/Makefile | 2 | ||||
-rw-r--r-- | arch/s390/kernel/asm-offsets.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/entry.h | 2 | ||||
-rw-r--r-- | arch/s390/kernel/idle.c | 124 | ||||
-rw-r--r-- | arch/s390/kernel/process.c | 24 | ||||
-rw-r--r-- | arch/s390/kernel/smp.c | 39 | ||||
-rw-r--r-- | arch/s390/kernel/vtime.c | 60 | ||||
-rw-r--r-- | arch/s390/lib/delay.c | 4 |
12 files changed, 166 insertions, 144 deletions
diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h index 01887b1fade5..1c016a5fa97e 100644 --- a/arch/s390/include/asm/cputime.h +++ b/arch/s390/include/asm/cputime.h | |||
@@ -8,8 +8,6 @@ | |||
8 | #define _S390_CPUTIME_H | 8 | #define _S390_CPUTIME_H |
9 | 9 | ||
10 | #include <linux/types.h> | 10 | #include <linux/types.h> |
11 | #include <linux/percpu.h> | ||
12 | #include <linux/spinlock.h> | ||
13 | #include <asm/div64.h> | 11 | #include <asm/div64.h> |
14 | 12 | ||
15 | 13 | ||
@@ -165,20 +163,8 @@ static inline clock_t cputime64_to_clock_t(cputime64_t cputime) | |||
165 | return clock; | 163 | return clock; |
166 | } | 164 | } |
167 | 165 | ||
168 | struct s390_idle_data { | 166 | cputime64_t arch_cpu_idle_time(int cpu); |
169 | unsigned int sequence; | ||
170 | unsigned long long idle_count; | ||
171 | unsigned long long idle_time; | ||
172 | unsigned long long clock_idle_enter; | ||
173 | unsigned long long clock_idle_exit; | ||
174 | unsigned long long timer_idle_enter; | ||
175 | unsigned long long timer_idle_exit; | ||
176 | }; | ||
177 | 167 | ||
178 | DECLARE_PER_CPU(struct s390_idle_data, s390_idle); | 168 | #define arch_idle_time(cpu) arch_cpu_idle_time(cpu) |
179 | |||
180 | cputime64_t s390_get_idle_time(int cpu); | ||
181 | |||
182 | #define arch_idle_time(cpu) s390_get_idle_time(cpu) | ||
183 | 169 | ||
184 | #endif /* _S390_CPUTIME_H */ | 170 | #endif /* _S390_CPUTIME_H */ |
diff --git a/arch/s390/include/asm/idle.h b/arch/s390/include/asm/idle.h new file mode 100644 index 000000000000..6af037f574b8 --- /dev/null +++ b/arch/s390/include/asm/idle.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* | ||
2 | * Copyright IBM Corp. 2014 | ||
3 | * | ||
4 | * Author: Martin Schwidefsky <schwidefsky@de.ibm.com> | ||
5 | */ | ||
6 | |||
7 | #ifndef _S390_IDLE_H | ||
8 | #define _S390_IDLE_H | ||
9 | |||
10 | #include <linux/types.h> | ||
11 | #include <linux/device.h> | ||
12 | |||
13 | struct s390_idle_data { | ||
14 | unsigned int sequence; | ||
15 | unsigned long long idle_count; | ||
16 | unsigned long long idle_time; | ||
17 | unsigned long long clock_idle_enter; | ||
18 | unsigned long long clock_idle_exit; | ||
19 | unsigned long long timer_idle_enter; | ||
20 | unsigned long long timer_idle_exit; | ||
21 | }; | ||
22 | |||
23 | extern struct device_attribute dev_attr_idle_count; | ||
24 | extern struct device_attribute dev_attr_idle_time_us; | ||
25 | |||
26 | #endif /* _S390_IDLE_H */ | ||
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h index bc796d73129b..3d0871058306 100644 --- a/arch/s390/include/asm/processor.h +++ b/arch/s390/include/asm/processor.h | |||
@@ -289,7 +289,12 @@ static inline unsigned long __rewind_psw(psw_t psw, unsigned long ilc) | |||
289 | return (psw.addr - ilc) & mask; | 289 | return (psw.addr - ilc) & mask; |
290 | #endif | 290 | #endif |
291 | } | 291 | } |
292 | 292 | ||
293 | /* | ||
294 | * Function to stop a processor until the next interrupt occurs | ||
295 | */ | ||
296 | void enabled_wait(void); | ||
297 | |||
293 | /* | 298 | /* |
294 | * Function to drop a processor into disabled wait state | 299 | * Function to drop a processor into disabled wait state |
295 | */ | 300 | */ |
diff --git a/arch/s390/include/asm/vtimer.h b/arch/s390/include/asm/vtimer.h index bfe25d513ad2..10a179af62d8 100644 --- a/arch/s390/include/asm/vtimer.h +++ b/arch/s390/include/asm/vtimer.h | |||
@@ -28,6 +28,4 @@ extern int del_virt_timer(struct vtimer_list *timer); | |||
28 | extern void init_cpu_vtimer(void); | 28 | extern void init_cpu_vtimer(void); |
29 | extern void vtime_init(void); | 29 | extern void vtime_init(void); |
30 | 30 | ||
31 | extern void vtime_stop_cpu(void); | ||
32 | |||
33 | #endif /* _ASM_S390_TIMER_H */ | 31 | #endif /* _ASM_S390_TIMER_H */ |
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile index 3249e1f36d55..c249785669f3 100644 --- a/arch/s390/kernel/Makefile +++ b/arch/s390/kernel/Makefile | |||
@@ -28,7 +28,7 @@ CFLAGS_ptrace.o += -DUTS_MACHINE='"$(UTS_MACHINE)"' | |||
28 | 28 | ||
29 | CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w | 29 | CFLAGS_sysinfo.o += -Iinclude/math-emu -Iarch/s390/math-emu -w |
30 | 30 | ||
31 | obj-y := traps.o time.o process.o base.o early.o setup.o vtime.o | 31 | obj-y := traps.o time.o process.o base.o early.o setup.o idle.o vtime.o |
32 | obj-y += processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o | 32 | obj-y += processor.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o nmi.o |
33 | obj-y += debug.o irq.o ipl.o dis.o diag.o sclp.o vdso.o | 33 | obj-y += debug.o irq.o ipl.o dis.o diag.o sclp.o vdso.o |
34 | obj-y += sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o | 34 | obj-y += sysinfo.o jump_label.o lgr.o os_info.o machine_kexec.o pgm_check.o |
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index 3e9e479d9b49..ef279a136801 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c | |||
@@ -9,7 +9,7 @@ | |||
9 | #include <linux/kbuild.h> | 9 | #include <linux/kbuild.h> |
10 | #include <linux/kvm_host.h> | 10 | #include <linux/kvm_host.h> |
11 | #include <linux/sched.h> | 11 | #include <linux/sched.h> |
12 | #include <asm/cputime.h> | 12 | #include <asm/idle.h> |
13 | #include <asm/vdso.h> | 13 | #include <asm/vdso.h> |
14 | #include <asm/pgtable.h> | 14 | #include <asm/pgtable.h> |
15 | 15 | ||
diff --git a/arch/s390/kernel/entry.h b/arch/s390/kernel/entry.h index 58541633b8d6..cd68869f9504 100644 --- a/arch/s390/kernel/entry.h +++ b/arch/s390/kernel/entry.h | |||
@@ -4,7 +4,7 @@ | |||
4 | #include <linux/types.h> | 4 | #include <linux/types.h> |
5 | #include <linux/signal.h> | 5 | #include <linux/signal.h> |
6 | #include <asm/ptrace.h> | 6 | #include <asm/ptrace.h> |
7 | #include <asm/cputime.h> | 7 | #include <asm/idle.h> |
8 | 8 | ||
9 | extern void *restart_stack; | 9 | extern void *restart_stack; |
10 | extern unsigned long suspend_zero_pages; | 10 | extern unsigned long suspend_zero_pages; |
diff --git a/arch/s390/kernel/idle.c b/arch/s390/kernel/idle.c new file mode 100644 index 000000000000..c846aee7372f --- /dev/null +++ b/arch/s390/kernel/idle.c | |||
@@ -0,0 +1,124 @@ | |||
1 | /* | ||
2 | * Idle functions for s390. | ||
3 | * | ||
4 | * Copyright IBM Corp. 2014 | ||
5 | * | ||
6 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/kernel_stat.h> | ||
11 | #include <linux/kprobes.h> | ||
12 | #include <linux/notifier.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/cpu.h> | ||
15 | #include <asm/cputime.h> | ||
16 | #include <asm/nmi.h> | ||
17 | #include <asm/smp.h> | ||
18 | #include "entry.h" | ||
19 | |||
20 | static DEFINE_PER_CPU(struct s390_idle_data, s390_idle); | ||
21 | |||
22 | void __kprobes enabled_wait(void) | ||
23 | { | ||
24 | struct s390_idle_data *idle = &__get_cpu_var(s390_idle); | ||
25 | unsigned long long idle_time; | ||
26 | unsigned long psw_mask; | ||
27 | |||
28 | trace_hardirqs_on(); | ||
29 | |||
30 | /* Wait for external, I/O or machine check interrupt. */ | ||
31 | psw_mask = PSW_KERNEL_BITS | PSW_MASK_WAIT | PSW_MASK_DAT | | ||
32 | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; | ||
33 | clear_cpu_flag(CIF_NOHZ_DELAY); | ||
34 | |||
35 | /* Call the assembler magic in entry.S */ | ||
36 | psw_idle(idle, psw_mask); | ||
37 | |||
38 | /* Account time spent with enabled wait psw loaded as idle time. */ | ||
39 | idle->sequence++; | ||
40 | smp_wmb(); | ||
41 | idle_time = idle->clock_idle_exit - idle->clock_idle_enter; | ||
42 | idle->clock_idle_enter = idle->clock_idle_exit = 0ULL; | ||
43 | idle->idle_time += idle_time; | ||
44 | idle->idle_count++; | ||
45 | account_idle_time(idle_time); | ||
46 | smp_wmb(); | ||
47 | idle->sequence++; | ||
48 | } | ||
49 | |||
50 | static ssize_t show_idle_count(struct device *dev, | ||
51 | struct device_attribute *attr, char *buf) | ||
52 | { | ||
53 | struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id); | ||
54 | unsigned long long idle_count; | ||
55 | unsigned int sequence; | ||
56 | |||
57 | do { | ||
58 | sequence = ACCESS_ONCE(idle->sequence); | ||
59 | idle_count = ACCESS_ONCE(idle->idle_count); | ||
60 | if (ACCESS_ONCE(idle->clock_idle_enter)) | ||
61 | idle_count++; | ||
62 | } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence)); | ||
63 | return sprintf(buf, "%llu\n", idle_count); | ||
64 | } | ||
65 | DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL); | ||
66 | |||
67 | static ssize_t show_idle_time(struct device *dev, | ||
68 | struct device_attribute *attr, char *buf) | ||
69 | { | ||
70 | struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id); | ||
71 | unsigned long long now, idle_time, idle_enter, idle_exit; | ||
72 | unsigned int sequence; | ||
73 | |||
74 | do { | ||
75 | now = get_tod_clock(); | ||
76 | sequence = ACCESS_ONCE(idle->sequence); | ||
77 | idle_time = ACCESS_ONCE(idle->idle_time); | ||
78 | idle_enter = ACCESS_ONCE(idle->clock_idle_enter); | ||
79 | idle_exit = ACCESS_ONCE(idle->clock_idle_exit); | ||
80 | } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence)); | ||
81 | idle_time += idle_enter ? ((idle_exit ? : now) - idle_enter) : 0; | ||
82 | return sprintf(buf, "%llu\n", idle_time >> 12); | ||
83 | } | ||
84 | DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL); | ||
85 | |||
86 | cputime64_t arch_cpu_idle_time(int cpu) | ||
87 | { | ||
88 | struct s390_idle_data *idle = &per_cpu(s390_idle, cpu); | ||
89 | unsigned long long now, idle_enter, idle_exit; | ||
90 | unsigned int sequence; | ||
91 | |||
92 | do { | ||
93 | now = get_tod_clock(); | ||
94 | sequence = ACCESS_ONCE(idle->sequence); | ||
95 | idle_enter = ACCESS_ONCE(idle->clock_idle_enter); | ||
96 | idle_exit = ACCESS_ONCE(idle->clock_idle_exit); | ||
97 | } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence)); | ||
98 | return idle_enter ? ((idle_exit ?: now) - idle_enter) : 0; | ||
99 | } | ||
100 | |||
101 | void arch_cpu_idle_enter(void) | ||
102 | { | ||
103 | local_mcck_disable(); | ||
104 | } | ||
105 | |||
106 | void arch_cpu_idle(void) | ||
107 | { | ||
108 | if (!test_cpu_flag(CIF_MCCK_PENDING)) | ||
109 | /* Halt the cpu and keep track of cpu time accounting. */ | ||
110 | enabled_wait(); | ||
111 | local_irq_enable(); | ||
112 | } | ||
113 | |||
114 | void arch_cpu_idle_exit(void) | ||
115 | { | ||
116 | local_mcck_enable(); | ||
117 | if (test_cpu_flag(CIF_MCCK_PENDING)) | ||
118 | s390_handle_mcck(); | ||
119 | } | ||
120 | |||
121 | void arch_cpu_idle_dead(void) | ||
122 | { | ||
123 | cpu_die(); | ||
124 | } | ||
diff --git a/arch/s390/kernel/process.c b/arch/s390/kernel/process.c index 93b9ca42e5c0..ed84cc224899 100644 --- a/arch/s390/kernel/process.c +++ b/arch/s390/kernel/process.c | |||
@@ -61,30 +61,6 @@ unsigned long thread_saved_pc(struct task_struct *tsk) | |||
61 | return sf->gprs[8]; | 61 | return sf->gprs[8]; |
62 | } | 62 | } |
63 | 63 | ||
64 | void arch_cpu_idle(void) | ||
65 | { | ||
66 | local_mcck_disable(); | ||
67 | if (test_cpu_flag(CIF_MCCK_PENDING)) { | ||
68 | local_mcck_enable(); | ||
69 | local_irq_enable(); | ||
70 | return; | ||
71 | } | ||
72 | /* Halt the cpu and keep track of cpu time accounting. */ | ||
73 | vtime_stop_cpu(); | ||
74 | local_irq_enable(); | ||
75 | } | ||
76 | |||
77 | void arch_cpu_idle_exit(void) | ||
78 | { | ||
79 | if (test_cpu_flag(CIF_MCCK_PENDING)) | ||
80 | s390_handle_mcck(); | ||
81 | } | ||
82 | |||
83 | void arch_cpu_idle_dead(void) | ||
84 | { | ||
85 | cpu_die(); | ||
86 | } | ||
87 | |||
88 | extern void __kprobes kernel_thread_starter(void); | 64 | extern void __kprobes kernel_thread_starter(void); |
89 | 65 | ||
90 | /* | 66 | /* |
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c index 46317d6951c4..bba0e2469254 100644 --- a/arch/s390/kernel/smp.c +++ b/arch/s390/kernel/smp.c | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <asm/debug.h> | 45 | #include <asm/debug.h> |
46 | #include <asm/os_info.h> | 46 | #include <asm/os_info.h> |
47 | #include <asm/sigp.h> | 47 | #include <asm/sigp.h> |
48 | #include <asm/idle.h> | ||
48 | #include "entry.h" | 49 | #include "entry.h" |
49 | 50 | ||
50 | enum { | 51 | enum { |
@@ -661,7 +662,7 @@ static void smp_start_secondary(void *cpuvoid) | |||
661 | cpu_init(); | 662 | cpu_init(); |
662 | preempt_disable(); | 663 | preempt_disable(); |
663 | init_cpu_timer(); | 664 | init_cpu_timer(); |
664 | init_cpu_vtimer(); | 665 | vtime_init(); |
665 | pfault_init(); | 666 | pfault_init(); |
666 | notify_cpu_starting(smp_processor_id()); | 667 | notify_cpu_starting(smp_processor_id()); |
667 | set_cpu_online(smp_processor_id(), true); | 668 | set_cpu_online(smp_processor_id(), true); |
@@ -893,42 +894,6 @@ static struct attribute_group cpu_common_attr_group = { | |||
893 | .attrs = cpu_common_attrs, | 894 | .attrs = cpu_common_attrs, |
894 | }; | 895 | }; |
895 | 896 | ||
896 | static ssize_t show_idle_count(struct device *dev, | ||
897 | struct device_attribute *attr, char *buf) | ||
898 | { | ||
899 | struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id); | ||
900 | unsigned long long idle_count; | ||
901 | unsigned int sequence; | ||
902 | |||
903 | do { | ||
904 | sequence = ACCESS_ONCE(idle->sequence); | ||
905 | idle_count = ACCESS_ONCE(idle->idle_count); | ||
906 | if (ACCESS_ONCE(idle->clock_idle_enter)) | ||
907 | idle_count++; | ||
908 | } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence)); | ||
909 | return sprintf(buf, "%llu\n", idle_count); | ||
910 | } | ||
911 | static DEVICE_ATTR(idle_count, 0444, show_idle_count, NULL); | ||
912 | |||
913 | static ssize_t show_idle_time(struct device *dev, | ||
914 | struct device_attribute *attr, char *buf) | ||
915 | { | ||
916 | struct s390_idle_data *idle = &per_cpu(s390_idle, dev->id); | ||
917 | unsigned long long now, idle_time, idle_enter, idle_exit; | ||
918 | unsigned int sequence; | ||
919 | |||
920 | do { | ||
921 | now = get_tod_clock(); | ||
922 | sequence = ACCESS_ONCE(idle->sequence); | ||
923 | idle_time = ACCESS_ONCE(idle->idle_time); | ||
924 | idle_enter = ACCESS_ONCE(idle->clock_idle_enter); | ||
925 | idle_exit = ACCESS_ONCE(idle->clock_idle_exit); | ||
926 | } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence)); | ||
927 | idle_time += idle_enter ? ((idle_exit ? : now) - idle_enter) : 0; | ||
928 | return sprintf(buf, "%llu\n", idle_time >> 12); | ||
929 | } | ||
930 | static DEVICE_ATTR(idle_time_us, 0444, show_idle_time, NULL); | ||
931 | |||
932 | static struct attribute *cpu_online_attrs[] = { | 897 | static struct attribute *cpu_online_attrs[] = { |
933 | &dev_attr_idle_count.attr, | 898 | &dev_attr_idle_count.attr, |
934 | &dev_attr_idle_time_us.attr, | 899 | &dev_attr_idle_time_us.attr, |
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index 40709821abde..416f2a323ba5 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c | |||
@@ -6,27 +6,18 @@ | |||
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <linux/kernel_stat.h> | 8 | #include <linux/kernel_stat.h> |
9 | #include <linux/notifier.h> | ||
10 | #include <linux/kprobes.h> | ||
11 | #include <linux/export.h> | 9 | #include <linux/export.h> |
12 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
13 | #include <linux/timex.h> | 11 | #include <linux/timex.h> |
14 | #include <linux/types.h> | 12 | #include <linux/types.h> |
15 | #include <linux/time.h> | 13 | #include <linux/time.h> |
16 | #include <linux/cpu.h> | ||
17 | #include <linux/smp.h> | ||
18 | 14 | ||
19 | #include <asm/irq_regs.h> | ||
20 | #include <asm/cputime.h> | 15 | #include <asm/cputime.h> |
21 | #include <asm/vtimer.h> | 16 | #include <asm/vtimer.h> |
22 | #include <asm/vtime.h> | 17 | #include <asm/vtime.h> |
23 | #include <asm/irq.h> | ||
24 | #include "entry.h" | ||
25 | 18 | ||
26 | static void virt_timer_expire(void); | 19 | static void virt_timer_expire(void); |
27 | 20 | ||
28 | DEFINE_PER_CPU(struct s390_idle_data, s390_idle); | ||
29 | |||
30 | static LIST_HEAD(virt_timer_list); | 21 | static LIST_HEAD(virt_timer_list); |
31 | static DEFINE_SPINLOCK(virt_timer_lock); | 22 | static DEFINE_SPINLOCK(virt_timer_lock); |
32 | static atomic64_t virt_timer_current; | 23 | static atomic64_t virt_timer_current; |
@@ -152,49 +143,6 @@ void vtime_account_system(struct task_struct *tsk) | |||
152 | __attribute__((alias("vtime_account_irq_enter"))); | 143 | __attribute__((alias("vtime_account_irq_enter"))); |
153 | EXPORT_SYMBOL_GPL(vtime_account_system); | 144 | EXPORT_SYMBOL_GPL(vtime_account_system); |
154 | 145 | ||
155 | void __kprobes vtime_stop_cpu(void) | ||
156 | { | ||
157 | struct s390_idle_data *idle = &__get_cpu_var(s390_idle); | ||
158 | unsigned long long idle_time; | ||
159 | unsigned long psw_mask; | ||
160 | |||
161 | trace_hardirqs_on(); | ||
162 | |||
163 | /* Wait for external, I/O or machine check interrupt. */ | ||
164 | psw_mask = PSW_KERNEL_BITS | PSW_MASK_WAIT | PSW_MASK_DAT | | ||
165 | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK; | ||
166 | clear_cpu_flag(CIF_NOHZ_DELAY); | ||
167 | |||
168 | /* Call the assembler magic in entry.S */ | ||
169 | psw_idle(idle, psw_mask); | ||
170 | |||
171 | /* Account time spent with enabled wait psw loaded as idle time. */ | ||
172 | idle->sequence++; | ||
173 | smp_wmb(); | ||
174 | idle_time = idle->clock_idle_exit - idle->clock_idle_enter; | ||
175 | idle->clock_idle_enter = idle->clock_idle_exit = 0ULL; | ||
176 | idle->idle_time += idle_time; | ||
177 | idle->idle_count++; | ||
178 | account_idle_time(idle_time); | ||
179 | smp_wmb(); | ||
180 | idle->sequence++; | ||
181 | } | ||
182 | |||
183 | cputime64_t s390_get_idle_time(int cpu) | ||
184 | { | ||
185 | struct s390_idle_data *idle = &per_cpu(s390_idle, cpu); | ||
186 | unsigned long long now, idle_enter, idle_exit; | ||
187 | unsigned int sequence; | ||
188 | |||
189 | do { | ||
190 | now = get_tod_clock(); | ||
191 | sequence = ACCESS_ONCE(idle->sequence); | ||
192 | idle_enter = ACCESS_ONCE(idle->clock_idle_enter); | ||
193 | idle_exit = ACCESS_ONCE(idle->clock_idle_exit); | ||
194 | } while ((sequence & 1) || (ACCESS_ONCE(idle->sequence) != sequence)); | ||
195 | return idle_enter ? ((idle_exit ?: now) - idle_enter) : 0; | ||
196 | } | ||
197 | |||
198 | /* | 146 | /* |
199 | * Sorted add to a list. List is linear searched until first bigger | 147 | * Sorted add to a list. List is linear searched until first bigger |
200 | * element is found. | 148 | * element is found. |
@@ -372,14 +320,8 @@ EXPORT_SYMBOL(del_virt_timer); | |||
372 | /* | 320 | /* |
373 | * Start the virtual CPU timer on the current CPU. | 321 | * Start the virtual CPU timer on the current CPU. |
374 | */ | 322 | */ |
375 | void init_cpu_vtimer(void) | 323 | void vtime_init(void) |
376 | { | 324 | { |
377 | /* set initial cpu timer */ | 325 | /* set initial cpu timer */ |
378 | set_vtimer(VTIMER_MAX_SLICE); | 326 | set_vtimer(VTIMER_MAX_SLICE); |
379 | } | 327 | } |
380 | |||
381 | void __init vtime_init(void) | ||
382 | { | ||
383 | /* Enable cpu timer interrupts on the boot cpu. */ | ||
384 | init_cpu_vtimer(); | ||
385 | } | ||
diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c index a9f3d0042d58..16dc42d83f93 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c | |||
@@ -43,7 +43,7 @@ static void __udelay_disabled(unsigned long long usecs) | |||
43 | lockdep_off(); | 43 | lockdep_off(); |
44 | do { | 44 | do { |
45 | set_clock_comparator(end); | 45 | set_clock_comparator(end); |
46 | vtime_stop_cpu(); | 46 | enabled_wait(); |
47 | } while (get_tod_clock_fast() < end); | 47 | } while (get_tod_clock_fast() < end); |
48 | lockdep_on(); | 48 | lockdep_on(); |
49 | __ctl_load(cr0, 0, 0); | 49 | __ctl_load(cr0, 0, 0); |
@@ -62,7 +62,7 @@ static void __udelay_enabled(unsigned long long usecs) | |||
62 | clock_saved = local_tick_disable(); | 62 | clock_saved = local_tick_disable(); |
63 | set_clock_comparator(end); | 63 | set_clock_comparator(end); |
64 | } | 64 | } |
65 | vtime_stop_cpu(); | 65 | enabled_wait(); |
66 | if (clock_saved) | 66 | if (clock_saved) |
67 | local_tick_enable(clock_saved); | 67 | local_tick_enable(clock_saved); |
68 | } while (get_tod_clock_fast() < end); | 68 | } while (get_tod_clock_fast() < end); |