diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-22 12:51:28 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-22 12:51:28 -0700 |
commit | a9b011f5ac57cbaedb32a8149f3d39d7b2c1f0e0 (patch) | |
tree | 89c850cc9e2ed949f5fc3b99180cd6cb70db6160 /arch/s390/kernel/vtime.c | |
parent | b5bdd43876e475724c662f99206f0349c67e33e6 (diff) | |
parent | da6330fccc251db73945ee3eb6248985cf2574de (diff) |
Merge branch 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6
* 'for-linus' of git://git390.marist.edu/pub/scm/linux-2.6: (22 commits)
[S390] Update default configuration.
[S390] kprobes: defer setting of ctlblk state
[S390] Enable tick based perf_counter on s390.
[S390] dasd: fix refcounting in dasd_change_state
[S390] lockless idle time accounting
[S390] driver_data access
[S390] pm: fix build error for !SMP
[S390] dasd_pm: fix stop flag handling
[S390] ap/zcrypt: Suspend/Resume ap bus and zcrypt
[S390] qdio: Sanitize do_QDIO sanity checks
[S390] qdio: leave inbound SBALs primed
[S390] qdio: merge AI tasklet into interrupt handler
[S390] qdio: extract all primed SBALs at once
[S390] qdio: fix check for running under z/VM
[S390] qdio: move adapter interrupt tasklet code
[S390] Use del_timer instead of del_timer_sync
[S390] s390: remove DEBUG_MALLOC
[S390] vt220 console: convert from bootmem to slab
[S390] sclp console: convert from bootmem to slab
[S390] 3270 console: convert from bootmem to slab
...
Diffstat (limited to 'arch/s390/kernel/vtime.c')
-rw-r--r-- | arch/s390/kernel/vtime.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c index c8eb7255332..c41bb0d416e 100644 --- a/arch/s390/kernel/vtime.c +++ b/arch/s390/kernel/vtime.c @@ -25,13 +25,9 @@ #include <asm/irq_regs.h> #include <asm/cputime.h> -static ext_int_info_t ext_int_info_timer; - static DEFINE_PER_CPU(struct vtimer_queue, virt_cpu_timer); -DEFINE_PER_CPU(struct s390_idle_data, s390_idle) = { - .lock = __SPIN_LOCK_UNLOCKED(s390_idle.lock) -}; +DEFINE_PER_CPU(struct s390_idle_data, s390_idle); static inline __u64 get_vtimer(void) { @@ -153,11 +149,13 @@ void vtime_start_cpu(void) vq->elapsed -= vq->idle - S390_lowcore.async_enter_timer; } - spin_lock(&idle->lock); + idle->sequence++; + smp_wmb(); idle->idle_time += idle_time; idle->idle_enter = 0ULL; idle->idle_count++; - spin_unlock(&idle->lock); + smp_wmb(); + idle->sequence++; } void vtime_stop_cpu(void) @@ -244,15 +242,23 @@ cputime64_t s390_get_idle_time(int cpu) { struct s390_idle_data *idle; unsigned long long now, idle_time, idle_enter; + unsigned int sequence; idle = &per_cpu(s390_idle, cpu); - spin_lock(&idle->lock); + now = get_clock(); +repeat: + sequence = idle->sequence; + smp_rmb(); + if (sequence & 1) + goto repeat; idle_time = 0; idle_enter = idle->idle_enter; if (idle_enter != 0ULL && idle_enter < now) idle_time = now - idle_enter; - spin_unlock(&idle->lock); + smp_rmb(); + if (idle->sequence != sequence) + goto repeat; return idle_time; } @@ -557,8 +563,7 @@ void init_cpu_vtimer(void) void __init vtime_init(void) { /* request the cpu timer external interrupt */ - if (register_early_external_interrupt(0x1005, do_cpu_timer_interrupt, - &ext_int_info_timer) != 0) + if (register_external_interrupt(0x1005, do_cpu_timer_interrupt)) panic("Couldn't request external interrupt 0x1005"); /* Enable cpu timer interrupts on the boot cpu. */ |