GIT cae272b7f0e0fec2777c26b9e4e41e96fb9756d9 git://git390.osdl.marist.edu/pub/scm/linux-2.6.git#for-andrew commit Author: Mathieu Desnoyers Date: Thu Feb 15 15:22:37 2007 +0100 [S390] add atomic64_xchg to s390 Signed-off-by: Mathieu Desnoyers Cc: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Martin Schwidefsky commit e1b18af80eb0814e84f7cca640c998ca8bc959e5 Author: Mathieu Desnoyers Date: Thu Feb 15 15:22:33 2007 +0100 [S390] local_t cleanup : use asm-generic/local.h. Signed-off-by: Mathieu Desnoyers Cc: Heiko Carstens Signed-off-by: Andrew Morton Signed-off-by: Martin Schwidefsky commit fd80a0ac8c1fd15db316f7425fd32ce8eb776898 Author: Jan Glauber Date: Thu Feb 15 15:22:27 2007 +0100 [S390] fix non-smp compile. Fix compile of sclp_quiesce for CONFIG_SMP=n. Signed-off-by: Jan Glauber Signed-off-by: Martin Schwidefsky commit 663c1f1018c57b7f4478a4b289cedeedbc691fc8 Author: Martin Schwidefsky Date: Thu Feb 15 15:22:20 2007 +0100 [S390] prevent softirqs if delay is called disabled The new delay implementation uses the clock comparator and an external interrupt even if it is called disabled for interrupts. To do this all external interrupt source except clock comparator are switched of before enabling external interrupts. The external interrupt at the end of the delay period may not execute softirqs or we can end up in a dead-lock. Signed-off-by: Martin Schwidefsky arch/s390/lib/delay.c | 7 +++++ drivers/s390/char/sclp_quiesce.c | 1 + include/asm-s390/atomic.h | 2 + include/asm-s390/local.h | 59 +------------------------------------- 4 files changed, 11 insertions(+), 58 deletions(-) diff --git a/arch/s390/lib/delay.c b/arch/s390/lib/delay.c index 0285444..70f2a86 100644 --- a/arch/s390/lib/delay.c +++ b/arch/s390/lib/delay.c @@ -15,6 +15,7 @@ #include #include #include #include +#include void __delay(unsigned long loops) { @@ -35,7 +36,11 @@ void __udelay(unsigned long usecs) { u64 end, time, jiffy_timer = 0; unsigned long flags, cr0, mask, dummy; + int irq_context; + irq_context = in_interrupt(); + if (!irq_context) + local_bh_disable(); local_irq_save(flags); if (raw_irqs_disabled_flags(flags)) { jiffy_timer = S390_lowcore.jiffy_timer; @@ -62,6 +67,8 @@ void __udelay(unsigned long usecs) __ctl_load(cr0, 0, 0); S390_lowcore.jiffy_timer = jiffy_timer; } + if (!irq_context) + _local_bh_enable(); set_clock_comparator(S390_lowcore.jiffy_timer); local_irq_restore(flags); } diff --git a/drivers/s390/char/sclp_quiesce.c b/drivers/s390/char/sclp_quiesce.c index ffa9282..baa8fe6 100644 --- a/drivers/s390/char/sclp_quiesce.c +++ b/drivers/s390/char/sclp_quiesce.c @@ -16,6 +16,7 @@ #include #include #include #include +#include #include "sclp.h" diff --git a/include/asm-s390/atomic.h b/include/asm-s390/atomic.h index af20c74..c17bdbf 100644 --- a/include/asm-s390/atomic.h +++ b/include/asm-s390/atomic.h @@ -215,6 +215,8 @@ static __inline__ void atomic64_set_mask __CSG_LOOP(v, mask, "ogr"); } +#define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) + static __inline__ long long atomic64_cmpxchg(atomic64_t *v, long long old, long long new) { diff --git a/include/asm-s390/local.h b/include/asm-s390/local.h index 86745a1..c11c530 100644 --- a/include/asm-s390/local.h +++ b/include/asm-s390/local.h @@ -1,58 +1 @@ -#ifndef _ASM_LOCAL_H -#define _ASM_LOCAL_H - -#include -#include - -#ifndef __s390x__ - -typedef atomic_t local_t; - -#define LOCAL_INIT(i) ATOMIC_INIT(i) -#define local_read(v) atomic_read(v) -#define local_set(v,i) atomic_set(v,i) - -#define local_inc(v) atomic_inc(v) -#define local_dec(v) atomic_dec(v) -#define local_add(i, v) atomic_add(i, v) -#define local_sub(i, v) atomic_sub(i, v) - -#else - -typedef atomic64_t local_t; - -#define LOCAL_INIT(i) ATOMIC64_INIT(i) -#define local_read(v) atomic64_read(v) -#define local_set(v,i) atomic64_set(v,i) - -#define local_inc(v) atomic64_inc(v) -#define local_dec(v) atomic64_dec(v) -#define local_add(i, v) atomic64_add(i, v) -#define local_sub(i, v) atomic64_sub(i, v) - -#endif - -#define __local_inc(v) ((v)->counter++) -#define __local_dec(v) ((v)->counter--) -#define __local_add(i,v) ((v)->counter+=(i)) -#define __local_sub(i,v) ((v)->counter-=(i)) - -/* - * Use these for per-cpu local_t variables: on some archs they are - * much more efficient than these naive implementations. Note they take - * a variable, not an address. - */ -#define cpu_local_read(v) local_read(&__get_cpu_var(v)) -#define cpu_local_set(v, i) local_set(&__get_cpu_var(v), (i)) - -#define cpu_local_inc(v) local_inc(&__get_cpu_var(v)) -#define cpu_local_dec(v) local_dec(&__get_cpu_var(v)) -#define cpu_local_add(i, v) local_add((i), &__get_cpu_var(v)) -#define cpu_local_sub(i, v) local_sub((i), &__get_cpu_var(v)) - -#define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v)) -#define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v)) -#define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v)) -#define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v)) - -#endif /* _ASM_LOCAL_H */ +#include