mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 08:44:21 +08:00
a750036f35
With the write lock path simply subtracting RW_LOCK_BIAS there is, on large systems, the theoretical possibility of overflowing the 32-bit value that was used so far (namely if 128 or more CPUs manage to do the subtraction, but don't get to do the inverse addition in the failure path quickly enough). A first measure is to modify RW_LOCK_BIAS itself - with the new value chosen, it is good for up to 2048 CPUs each allowed to nest over 2048 times on the read path without causing an issue. Quite possibly it would even be sufficient to adjust the bias a little further, assuming that allowing for significantly less nesting would suffice. However, as the original value chosen allowed for even more nesting levels, to support more than 2048 CPUs (possible currently only for 64-bit kernels) the lock itself gets widened to 64 bits. Signed-off-by: Jan Beulich <jbeulich@novell.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Link: http://lkml.kernel.org/r/4E258E0D020000780004E3F0@nat28.tlf.novell.com Signed-off-by: Ingo Molnar <mingo@elte.hu>
50 lines
1.0 KiB
C
50 lines
1.0 KiB
C
#ifndef _ASM_X86_RWLOCK_H
|
|
#define _ASM_X86_RWLOCK_H
|
|
|
|
#include <asm/asm.h>
|
|
|
|
#if CONFIG_NR_CPUS <= 2048
|
|
|
|
#ifndef __ASSEMBLY__
|
|
typedef union {
|
|
s32 lock;
|
|
s32 write;
|
|
} arch_rwlock_t;
|
|
#endif
|
|
|
|
#define RW_LOCK_BIAS 0x00100000
|
|
#define READ_LOCK_SIZE(insn) __ASM_FORM(insn##l)
|
|
#define READ_LOCK_ATOMIC(n) atomic_##n
|
|
#define WRITE_LOCK_ADD(n) __ASM_FORM_COMMA(addl n)
|
|
#define WRITE_LOCK_SUB(n) __ASM_FORM_COMMA(subl n)
|
|
#define WRITE_LOCK_CMP RW_LOCK_BIAS
|
|
|
|
#else /* CONFIG_NR_CPUS > 2048 */
|
|
|
|
#include <linux/const.h>
|
|
|
|
#ifndef __ASSEMBLY__
|
|
typedef union {
|
|
s64 lock;
|
|
struct {
|
|
u32 read;
|
|
s32 write;
|
|
};
|
|
} arch_rwlock_t;
|
|
#endif
|
|
|
|
#define RW_LOCK_BIAS (_AC(1,L) << 32)
|
|
#define READ_LOCK_SIZE(insn) __ASM_FORM(insn##q)
|
|
#define READ_LOCK_ATOMIC(n) atomic64_##n
|
|
#define WRITE_LOCK_ADD(n) __ASM_FORM(incl)
|
|
#define WRITE_LOCK_SUB(n) __ASM_FORM(decl)
|
|
#define WRITE_LOCK_CMP 1
|
|
|
|
#endif /* CONFIG_NR_CPUS */
|
|
|
|
#define __ARCH_RW_LOCK_UNLOCKED { RW_LOCK_BIAS }
|
|
|
|
/* Actual code is in asm/spinlock.h or in arch/x86/lib/rwlock.S */
|
|
|
|
#endif /* _ASM_X86_RWLOCK_H */
|