aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390/kernel/vtime.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2009-09-08 20:55:21 -0400
committerDan Williams <dan.j.williams@intel.com>2009-09-08 20:55:21 -0400
commitbbb20089a3275a19e475dbc21320c3742e3ca423 (patch)
tree216fdc1cbef450ca688135c5b8969169482d9a48 /arch/s390/kernel/vtime.c
parent3e48e656903e9fd8bc805c6a2c4264d7808d315b (diff)
parent657a77fa7284d8ae28dfa48f1dc5d919bf5b2843 (diff)
Merge branch 'dmaengine' into async-tx-next
Conflicts: crypto/async_tx/async_xor.c drivers/dma/ioat/dma_v2.h drivers/dma/ioat/pci.c drivers/md/raid5.c
Diffstat (limited to 'arch/s390/kernel/vtime.c')
-rw-r--r--arch/s390/kernel/vtime.c29
1 files changed, 17 insertions, 12 deletions
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index c87f59bd8246..c41bb0d416e1 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -23,15 +23,11 @@
23#include <asm/s390_ext.h> 23#include <asm/s390_ext.h>
24#include <asm/timer.h> 24#include <asm/timer.h>
25#include <asm/irq_regs.h> 25#include <asm/irq_regs.h>
26#include <asm/cpu.h> 26#include <asm/cputime.h>
27
28static ext_int_info_t ext_int_info_timer;
29 27
30static DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer); 28static DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer);
31 29
32DEFINE_PER_CPU(struct s390_idle_data, s390_idle) = { 30DEFINE_PER_CPU(struct s390_idle_data, s390_idle);
33 .lock = __SPIN_LOCK_UNLOCKED(s390_idle.lock)
34};
35 31
36static inline __u64 get_vtimer(void) 32static inline __u64 get_vtimer(void)
37{ 33{
@@ -153,11 +149,13 @@ void vtime_start_cpu(void)
153 vq->elapsed -= vq->idle - S390_lowcore.async_enter_timer; 149 vq->elapsed -= vq->idle - S390_lowcore.async_enter_timer;
154 } 150 }
155 151
156 spin_lock(&idle->lock); 152 idle->sequence++;
153 smp_wmb();
157 idle->idle_time += idle_time; 154 idle->idle_time += idle_time;
158 idle->idle_enter = 0ULL; 155 idle->idle_enter = 0ULL;
159 idle->idle_count++; 156 idle->idle_count++;
160 spin_unlock(&idle->lock); 157 smp_wmb();
158 idle->sequence++;
161} 159}
162 160
163void vtime_stop_cpu(void) 161void vtime_stop_cpu(void)
@@ -244,15 +242,23 @@ cputime64_t s390_get_idle_time(int cpu)
244{ 242{
245 struct s390_idle_data *idle; 243 struct s390_idle_data *idle;
246 unsigned long long now, idle_time, idle_enter; 244 unsigned long long now, idle_time, idle_enter;
245 unsigned int sequence;
247 246
248 idle = &per_cpu(s390_idle, cpu); 247 idle = &per_cpu(s390_idle, cpu);
249 spin_lock(&idle->lock); 248
250 now = get_clock(); 249 now = get_clock();
250repeat:
251 sequence = idle->sequence;
252 smp_rmb();
253 if (sequence & 1)
254 goto repeat;
251 idle_time = 0; 255 idle_time = 0;
252 idle_enter = idle->idle_enter; 256 idle_enter = idle->idle_enter;
253 if (idle_enter != 0ULL && idle_enter < now) 257 if (idle_enter != 0ULL && idle_enter < now)
254 idle_time = now - idle_enter; 258 idle_time = now - idle_enter;
255 spin_unlock(&idle->lock); 259 smp_rmb();
260 if (idle->sequence != sequence)
261 goto repeat;
256 return idle_time; 262 return idle_time;
257} 263}
258 264
@@ -557,8 +563,7 @@ void init_cpu_vtimer(void)
557void __init vtime_init(void) 563void __init vtime_init(void)
558{ 564{
559 /* request the cpu timer external interrupt */ 565 /* request the cpu timer external interrupt */
560 if (register_early_external_interrupt(0x1005, do_cpu_timer_interrupt, 566 if (register_external_interrupt(0x1005, do_cpu_timer_interrupt))
561 &ext_int_info_timer) != 0)
562 panic("Couldn't request external interrupt 0x1005"); 567 panic("Couldn't request external interrupt 0x1005");
563 568
564 /* Enable cpu timer interrupts on the boot cpu. */ 569 /* Enable cpu timer interrupts on the boot cpu. */