Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

s390/spinlock: optimize spinlock code sequence

Use lowcore constant to improve the code generated for spinlocks.

[ Martin Schwidefsky: patch breakdown and code beautification ]

Signed-off-by: Philipp Hachtmann <phacht@linux.vnet.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>

authored by

Philipp Hachtmann and committed by
Martin Schwidefsky
6c8cd5bb 5b3f683e

+21 -10
+3 -2
arch/s390/include/asm/lowcore.h
··· 139 139 __u32 percpu_offset; /* 0x02f0 */ 140 140 __u32 machine_flags; /* 0x02f4 */ 141 141 __u32 ftrace_func; /* 0x02f8 */ 142 - __u8 pad_0x02fc[0x0300-0x02fc]; /* 0x02fc */ 142 + __u32 spinlock_lockval; /* 0x02fc */ 143 143 144 144 /* Interrupt response block */ 145 145 __u8 irb[64]; /* 0x0300 */ ··· 285 285 __u64 machine_flags; /* 0x0388 */ 286 286 __u64 ftrace_func; /* 0x0390 */ 287 287 __u64 gmap; /* 0x0398 */ 288 - __u8 pad_0x03a0[0x0400-0x03a0]; /* 0x03a0 */ 288 + __u32 spinlock_lockval; /* 0x03a0 */ 289 + __u8 pad_0x03a0[0x0400-0x03a4]; /* 0x03a4 */ 289 290 290 291 /* Interrupt response block. */ 291 292 __u8 irb[64]; /* 0x0400 */
+9 -6
arch/s390/include/asm/spinlock.h
··· 11 11 12 12 #include <linux/smp.h> 13 13 14 + #define SPINLOCK_LOCKVAL (S390_lowcore.spinlock_lockval) 15 + 14 16 extern int spin_retry; 15 17 16 18 static inline int ··· 42 40 void arch_spin_relax(arch_spinlock_t *); 43 41 void arch_spin_lock_wait_flags(arch_spinlock_t *, unsigned long flags); 44 42 43 + static inline u32 arch_spin_lockval(int cpu) 44 + { 45 + return ~cpu; 46 + } 47 + 45 48 static inline int arch_spin_value_unlocked(arch_spinlock_t lock) 46 49 { 47 50 return lock.lock == 0; ··· 59 52 60 53 static inline int arch_spin_trylock_once(arch_spinlock_t *lp) 61 54 { 62 - unsigned int new = ~smp_processor_id(); 63 - 64 - return _raw_compare_and_swap(&lp->lock, 0, new); 55 + return _raw_compare_and_swap(&lp->lock, 0, SPINLOCK_LOCKVAL); 65 56 } 66 57 67 58 static inline int arch_spin_tryrelease_once(arch_spinlock_t *lp) 68 59 { 69 - unsigned int old = ~smp_processor_id(); 70 - 71 - return _raw_compare_and_swap(&lp->lock, old, 0); 60 + return _raw_compare_and_swap(&lp->lock, SPINLOCK_LOCKVAL, 0); 72 61 } 73 62 74 63 static inline void arch_spin_lock(arch_spinlock_t *lp)
+4
arch/s390/kernel/setup.c
··· 373 373 mem_assign_absolute(S390_lowcore.restart_source, lc->restart_source); 374 374 mem_assign_absolute(S390_lowcore.restart_psw, lc->restart_psw); 375 375 376 + #ifdef CONFIG_SMP 377 + lc->spinlock_lockval = arch_spin_lockval(0); 378 + #endif 379 + 376 380 set_prefix((u32)(unsigned long) lc); 377 381 lowcore_ptr[0] = lc; 378 382 }
+3
arch/s390/kernel/smp.c
··· 170 170 lc->panic_stack = pcpu->panic_stack + PAGE_SIZE 171 171 - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs); 172 172 lc->cpu_nr = cpu; 173 + lc->spinlock_lockval = arch_spin_lockval(cpu); 173 174 #ifndef CONFIG_64BIT 174 175 if (MACHINE_HAS_IEEE) { 175 176 lc->extended_save_area_addr = get_zeroed_page(GFP_KERNEL); ··· 227 226 cpumask_set_cpu(cpu, mm_cpumask(&init_mm)); 228 227 atomic_inc(&init_mm.context.attach_count); 229 228 lc->cpu_nr = cpu; 229 + lc->spinlock_lockval = arch_spin_lockval(cpu); 230 230 lc->percpu_offset = __per_cpu_offset[cpu]; 231 231 lc->kernel_asce = S390_lowcore.kernel_asce; 232 232 lc->machine_flags = S390_lowcore.machine_flags; ··· 811 809 void __init smp_setup_processor_id(void) 812 810 { 813 811 S390_lowcore.cpu_nr = 0; 812 + S390_lowcore.spinlock_lockval = arch_spin_lockval(0); 814 813 } 815 814 816 815 /*
+2 -2
arch/s390/lib/spinlock.c
··· 27 27 void arch_spin_lock_wait(arch_spinlock_t *lp) 28 28 { 29 29 int count = spin_retry; 30 - unsigned int cpu = ~smp_processor_id(); 30 + unsigned int cpu = SPINLOCK_LOCKVAL; 31 31 unsigned int owner; 32 32 33 33 while (1) { ··· 54 54 void arch_spin_lock_wait_flags(arch_spinlock_t *lp, unsigned long flags) 55 55 { 56 56 int count = spin_retry; 57 - unsigned int cpu = ~smp_processor_id(); 57 + unsigned int cpu = SPINLOCK_LOCKVAL; 58 58 unsigned int owner; 59 59 60 60 local_irq_restore(flags);