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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull locking fixes from Thomas Gleixner:
"The locking department delivers:

- A rather large and intrusive bundle of fixes to address serious
performance regressions introduced by the new rwsem / mcs
technology. Simpler solutions have been discussed, but they would
have been ugly bandaids with more risk than doing the right thing.

- Make the rwsem spin on owner technology opt-in for architectures
and enable it only on the known to work ones.

- A few fixes to the lockdep userspace library"

* 'locking-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
locking/rwsem: Add CONFIG_RWSEM_SPIN_ON_OWNER
locking/mutex: Disable optimistic spinning on some architectures
locking/rwsem: Reduce the size of struct rw_semaphore
locking/rwsem: Rename 'activity' to 'count'
locking/spinlocks/mcs: Micro-optimize osq_unlock()
locking/spinlocks/mcs: Introduce and use init macro and function for osq locks
locking/spinlocks/mcs: Convert osq lock to atomic_t to reduce overhead
locking/spinlocks/mcs: Rename optimistic_spin_queue() to optimistic_spin_node()
locking/rwsem: Allow conservative optimistic spinning when readers have lock
tools/liblockdep: Account for bitfield changes in lockdeps lock_acquire
tools/liblockdep: Remove debug print left over from development
tools/liblockdep: Fix comparison of a boolean value with a value of 2

+154 -86
+1
arch/arm/Kconfig
··· 6 6 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST 7 7 select ARCH_HAVE_CUSTOM_GPIO_H 8 8 select ARCH_MIGHT_HAVE_PC_PARPORT 9 + select ARCH_SUPPORTS_ATOMIC_RMW 9 10 select ARCH_USE_BUILTIN_BSWAP 10 11 select ARCH_USE_CMPXCHG_LOCKREF 11 12 select ARCH_WANT_IPC_PARSE_VERSION
+1
arch/arm64/Kconfig
··· 4 4 select ARCH_HAS_OPP 5 5 select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST 6 6 select ARCH_USE_CMPXCHG_LOCKREF 7 + select ARCH_SUPPORTS_ATOMIC_RMW 7 8 select ARCH_WANT_OPTIONAL_GPIOLIB 8 9 select ARCH_WANT_COMPAT_IPC_PARSE_VERSION 9 10 select ARCH_WANT_FRAME_POINTERS
+1
arch/powerpc/Kconfig
··· 145 145 select HAVE_IRQ_EXIT_ON_IRQ_STACK 146 146 select ARCH_USE_CMPXCHG_LOCKREF if PPC64 147 147 select HAVE_ARCH_AUDITSYSCALL 148 + select ARCH_SUPPORTS_ATOMIC_RMW 148 149 149 150 config GENERIC_CSUM 150 151 def_bool CPU_LITTLE_ENDIAN
+1
arch/sparc/Kconfig
··· 78 78 select HAVE_C_RECORDMCOUNT 79 79 select NO_BOOTMEM 80 80 select HAVE_ARCH_AUDITSYSCALL 81 + select ARCH_SUPPORTS_ATOMIC_RMW 81 82 82 83 config ARCH_DEFCONFIG 83 84 string
+1
arch/x86/Kconfig
··· 131 131 select HAVE_CC_STACKPROTECTOR 132 132 select GENERIC_CPU_AUTOPROBE 133 133 select HAVE_ARCH_AUDITSYSCALL 134 + select ARCH_SUPPORTS_ATOMIC_RMW 134 135 135 136 config INSTRUCTION_DECODER 136 137 def_bool y
+2 -2
include/linux/mutex.h
··· 17 17 #include <linux/lockdep.h> 18 18 #include <linux/atomic.h> 19 19 #include <asm/processor.h> 20 + #include <linux/osq_lock.h> 20 21 21 22 /* 22 23 * Simple, straightforward mutexes with strict semantics: ··· 47 46 * - detects multi-task circular deadlocks and prints out all affected 48 47 * locks and tasks (and only those tasks) 49 48 */ 50 - struct optimistic_spin_queue; 51 49 struct mutex { 52 50 /* 1: unlocked, 0: locked, negative: locked, possible waiters */ 53 51 atomic_t count; ··· 56 56 struct task_struct *owner; 57 57 #endif 58 58 #ifdef CONFIG_MUTEX_SPIN_ON_OWNER 59 - struct optimistic_spin_queue *osq; /* Spinner MCS lock */ 59 + struct optimistic_spin_queue osq; /* Spinner MCS lock */ 60 60 #endif 61 61 #ifdef CONFIG_DEBUG_MUTEXES 62 62 const char *name;
+27
include/linux/osq_lock.h
··· 1 + #ifndef __LINUX_OSQ_LOCK_H 2 + #define __LINUX_OSQ_LOCK_H 3 + 4 + /* 5 + * An MCS like lock especially tailored for optimistic spinning for sleeping 6 + * lock implementations (mutex, rwsem, etc). 7 + */ 8 + 9 + #define OSQ_UNLOCKED_VAL (0) 10 + 11 + struct optimistic_spin_queue { 12 + /* 13 + * Stores an encoded value of the CPU # of the tail node in the queue. 14 + * If the queue is empty, then it's set to OSQ_UNLOCKED_VAL. 15 + */ 16 + atomic_t tail; 17 + }; 18 + 19 + /* Init macro and function. */ 20 + #define OSQ_LOCK_UNLOCKED { ATOMIC_INIT(OSQ_UNLOCKED_VAL) } 21 + 22 + static inline void osq_lock_init(struct optimistic_spin_queue *lock) 23 + { 24 + atomic_set(&lock->tail, OSQ_UNLOCKED_VAL); 25 + } 26 + 27 + #endif
+4 -4
include/linux/rwsem-spinlock.h
··· 15 15 #ifdef __KERNEL__ 16 16 /* 17 17 * the rw-semaphore definition 18 - * - if activity is 0 then there are no active readers or writers 19 - * - if activity is +ve then that is the number of active readers 20 - * - if activity is -1 then there is one active writer 18 + * - if count is 0 then there are no active readers or writers 19 + * - if count is +ve then that is the number of active readers 20 + * - if count is -1 then there is one active writer 21 21 * - if wait_list is not empty, then there are processes waiting for the semaphore 22 22 */ 23 23 struct rw_semaphore { 24 - __s32 activity; 24 + __s32 count; 25 25 raw_spinlock_t wait_lock; 26 26 struct list_head wait_list; 27 27 #ifdef CONFIG_DEBUG_LOCK_ALLOC
+16 -18
include/linux/rwsem.h
··· 13 13 #include <linux/kernel.h> 14 14 #include <linux/list.h> 15 15 #include <linux/spinlock.h> 16 - 17 16 #include <linux/atomic.h> 17 + #ifdef CONFIG_RWSEM_SPIN_ON_OWNER 18 + #include <linux/osq_lock.h> 19 + #endif 18 20 19 - struct optimistic_spin_queue; 20 21 struct rw_semaphore; 21 22 22 23 #ifdef CONFIG_RWSEM_GENERIC_SPINLOCK ··· 26 25 /* All arch specific implementations share the same struct */ 27 26 struct rw_semaphore { 28 27 long count; 29 - raw_spinlock_t wait_lock; 30 28 struct list_head wait_list; 31 - #ifdef CONFIG_SMP 29 + raw_spinlock_t wait_lock; 30 + #ifdef CONFIG_RWSEM_SPIN_ON_OWNER 31 + struct optimistic_spin_queue osq; /* spinner MCS lock */ 32 32 /* 33 33 * Write owner. Used as a speculative check to see 34 34 * if the owner is running on the cpu. 35 35 */ 36 36 struct task_struct *owner; 37 - struct optimistic_spin_queue *osq; /* spinner MCS lock */ 38 37 #endif 39 38 #ifdef CONFIG_DEBUG_LOCK_ALLOC 40 39 struct lockdep_map dep_map; ··· 65 64 # define __RWSEM_DEP_MAP_INIT(lockname) 66 65 #endif 67 66 68 - #if defined(CONFIG_SMP) && !defined(CONFIG_RWSEM_GENERIC_SPINLOCK) 69 - #define __RWSEM_INITIALIZER(name) \ 70 - { RWSEM_UNLOCKED_VALUE, \ 71 - __RAW_SPIN_LOCK_UNLOCKED(name.wait_lock), \ 72 - LIST_HEAD_INIT((name).wait_list), \ 73 - NULL, /* owner */ \ 74 - NULL /* mcs lock */ \ 75 - __RWSEM_DEP_MAP_INIT(name) } 67 + #ifdef CONFIG_RWSEM_SPIN_ON_OWNER 68 + #define __RWSEM_OPT_INIT(lockname) , .osq = OSQ_LOCK_UNLOCKED, .owner = NULL 76 69 #else 77 - #define __RWSEM_INITIALIZER(name) \ 78 - { RWSEM_UNLOCKED_VALUE, \ 79 - __RAW_SPIN_LOCK_UNLOCKED(name.wait_lock), \ 80 - LIST_HEAD_INIT((name).wait_list) \ 81 - __RWSEM_DEP_MAP_INIT(name) } 70 + #define __RWSEM_OPT_INIT(lockname) 82 71 #endif 72 + 73 + #define __RWSEM_INITIALIZER(name) \ 74 + { .count = RWSEM_UNLOCKED_VALUE, \ 75 + .wait_list = LIST_HEAD_INIT((name).wait_list), \ 76 + .wait_lock = __RAW_SPIN_LOCK_UNLOCKED(name.wait_lock) \ 77 + __RWSEM_OPT_INIT(name) \ 78 + __RWSEM_DEP_MAP_INIT(name) } 83 79 84 80 #define DECLARE_RWSEM(name) \ 85 81 struct rw_semaphore name = __RWSEM_INITIALIZER(name)
+8 -1
kernel/Kconfig.locks
··· 220 220 221 221 endif 222 222 223 + config ARCH_SUPPORTS_ATOMIC_RMW 224 + bool 225 + 223 226 config MUTEX_SPIN_ON_OWNER 224 227 def_bool y 225 - depends on SMP && !DEBUG_MUTEXES 228 + depends on SMP && !DEBUG_MUTEXES && ARCH_SUPPORTS_ATOMIC_RMW 229 + 230 + config RWSEM_SPIN_ON_OWNER 231 + def_bool y 232 + depends on SMP && RWSEM_XCHGADD_ALGORITHM && ARCH_SUPPORTS_ATOMIC_RMW 226 233 227 234 config ARCH_USE_QUEUE_RWLOCK 228 235 bool
+48 -16
kernel/locking/mcs_spinlock.c
··· 14 14 * called from interrupt context and we have preemption disabled while 15 15 * spinning. 16 16 */ 17 - static DEFINE_PER_CPU_SHARED_ALIGNED(struct optimistic_spin_queue, osq_node); 17 + static DEFINE_PER_CPU_SHARED_ALIGNED(struct optimistic_spin_node, osq_node); 18 + 19 + /* 20 + * We use the value 0 to represent "no CPU", thus the encoded value 21 + * will be the CPU number incremented by 1. 22 + */ 23 + static inline int encode_cpu(int cpu_nr) 24 + { 25 + return cpu_nr + 1; 26 + } 27 + 28 + static inline struct optimistic_spin_node *decode_cpu(int encoded_cpu_val) 29 + { 30 + int cpu_nr = encoded_cpu_val - 1; 31 + 32 + return per_cpu_ptr(&osq_node, cpu_nr); 33 + } 18 34 19 35 /* 20 36 * Get a stable @node->next pointer, either for unlock() or unqueue() purposes. 21 37 * Can return NULL in case we were the last queued and we updated @lock instead. 22 38 */ 23 - static inline struct optimistic_spin_queue * 24 - osq_wait_next(struct optimistic_spin_queue **lock, 25 - struct optimistic_spin_queue *node, 26 - struct optimistic_spin_queue *prev) 39 + static inline struct optimistic_spin_node * 40 + osq_wait_next(struct optimistic_spin_queue *lock, 41 + struct optimistic_spin_node *node, 42 + struct optimistic_spin_node *prev) 27 43 { 28 - struct optimistic_spin_queue *next = NULL; 44 + struct optimistic_spin_node *next = NULL; 45 + int curr = encode_cpu(smp_processor_id()); 46 + int old; 47 + 48 + /* 49 + * If there is a prev node in queue, then the 'old' value will be 50 + * the prev node's CPU #, else it's set to OSQ_UNLOCKED_VAL since if 51 + * we're currently last in queue, then the queue will then become empty. 52 + */ 53 + old = prev ? prev->cpu : OSQ_UNLOCKED_VAL; 29 54 30 55 for (;;) { 31 - if (*lock == node && cmpxchg(lock, node, prev) == node) { 56 + if (atomic_read(&lock->tail) == curr && 57 + atomic_cmpxchg(&lock->tail, curr, old) == curr) { 32 58 /* 33 59 * We were the last queued, we moved @lock back. @prev 34 60 * will now observe @lock and will complete its ··· 85 59 return next; 86 60 } 87 61 88 - bool osq_lock(struct optimistic_spin_queue **lock) 62 + bool osq_lock(struct optimistic_spin_queue *lock) 89 63 { 90 - struct optimistic_spin_queue *node = this_cpu_ptr(&osq_node); 91 - struct optimistic_spin_queue *prev, *next; 64 + struct optimistic_spin_node *node = this_cpu_ptr(&osq_node); 65 + struct optimistic_spin_node *prev, *next; 66 + int curr = encode_cpu(smp_processor_id()); 67 + int old; 92 68 93 69 node->locked = 0; 94 70 node->next = NULL; 71 + node->cpu = curr; 95 72 96 - node->prev = prev = xchg(lock, node); 97 - if (likely(prev == NULL)) 73 + old = atomic_xchg(&lock->tail, curr); 74 + if (old == OSQ_UNLOCKED_VAL) 98 75 return true; 99 76 77 + prev = decode_cpu(old); 78 + node->prev = prev; 100 79 ACCESS_ONCE(prev->next) = node; 101 80 102 81 /* ··· 180 149 return false; 181 150 } 182 151 183 - void osq_unlock(struct optimistic_spin_queue **lock) 152 + void osq_unlock(struct optimistic_spin_queue *lock) 184 153 { 185 - struct optimistic_spin_queue *node = this_cpu_ptr(&osq_node); 186 - struct optimistic_spin_queue *next; 154 + struct optimistic_spin_node *node, *next; 155 + int curr = encode_cpu(smp_processor_id()); 187 156 188 157 /* 189 158 * Fast path for the uncontended case. 190 159 */ 191 - if (likely(cmpxchg(lock, node, NULL) == node)) 160 + if (likely(atomic_cmpxchg(&lock->tail, curr, OSQ_UNLOCKED_VAL) == curr)) 192 161 return; 193 162 194 163 /* 195 164 * Second most likely case. 196 165 */ 166 + node = this_cpu_ptr(&osq_node); 197 167 next = xchg(&node->next, NULL); 198 168 if (next) { 199 169 ACCESS_ONCE(next->locked) = 1;
+5 -4
kernel/locking/mcs_spinlock.h
··· 118 118 * mutex_lock()/rwsem_down_{read,write}() etc. 119 119 */ 120 120 121 - struct optimistic_spin_queue { 122 - struct optimistic_spin_queue *next, *prev; 121 + struct optimistic_spin_node { 122 + struct optimistic_spin_node *next, *prev; 123 123 int locked; /* 1 if lock acquired */ 124 + int cpu; /* encoded CPU # value */ 124 125 }; 125 126 126 - extern bool osq_lock(struct optimistic_spin_queue **lock); 127 - extern void osq_unlock(struct optimistic_spin_queue **lock); 127 + extern bool osq_lock(struct optimistic_spin_queue *lock); 128 + extern void osq_unlock(struct optimistic_spin_queue *lock); 128 129 129 130 #endif /* __LINUX_MCS_SPINLOCK_H */
+1 -1
kernel/locking/mutex.c
··· 60 60 INIT_LIST_HEAD(&lock->wait_list); 61 61 mutex_clear_owner(lock); 62 62 #ifdef CONFIG_MUTEX_SPIN_ON_OWNER 63 - lock->osq = NULL; 63 + osq_lock_init(&lock->osq); 64 64 #endif 65 65 66 66 debug_mutex_init(lock, name, key);
+14 -14
kernel/locking/rwsem-spinlock.c
··· 26 26 unsigned long flags; 27 27 28 28 if (raw_spin_trylock_irqsave(&sem->wait_lock, flags)) { 29 - ret = (sem->activity != 0); 29 + ret = (sem->count != 0); 30 30 raw_spin_unlock_irqrestore(&sem->wait_lock, flags); 31 31 } 32 32 return ret; ··· 46 46 debug_check_no_locks_freed((void *)sem, sizeof(*sem)); 47 47 lockdep_init_map(&sem->dep_map, name, key, 0); 48 48 #endif 49 - sem->activity = 0; 49 + sem->count = 0; 50 50 raw_spin_lock_init(&sem->wait_lock); 51 51 INIT_LIST_HEAD(&sem->wait_list); 52 52 } ··· 95 95 waiter = list_entry(next, struct rwsem_waiter, list); 96 96 } while (waiter->type != RWSEM_WAITING_FOR_WRITE); 97 97 98 - sem->activity += woken; 98 + sem->count += woken; 99 99 100 100 out: 101 101 return sem; ··· 126 126 127 127 raw_spin_lock_irqsave(&sem->wait_lock, flags); 128 128 129 - if (sem->activity >= 0 && list_empty(&sem->wait_list)) { 129 + if (sem->count >= 0 && list_empty(&sem->wait_list)) { 130 130 /* granted */ 131 - sem->activity++; 131 + sem->count++; 132 132 raw_spin_unlock_irqrestore(&sem->wait_lock, flags); 133 133 goto out; 134 134 } ··· 170 170 171 171 raw_spin_lock_irqsave(&sem->wait_lock, flags); 172 172 173 - if (sem->activity >= 0 && list_empty(&sem->wait_list)) { 173 + if (sem->count >= 0 && list_empty(&sem->wait_list)) { 174 174 /* granted */ 175 - sem->activity++; 175 + sem->count++; 176 176 ret = 1; 177 177 } 178 178 ··· 206 206 * itself into sleep and waiting for system woke it or someone 207 207 * else in the head of the wait list up. 208 208 */ 209 - if (sem->activity == 0) 209 + if (sem->count == 0) 210 210 break; 211 211 set_task_state(tsk, TASK_UNINTERRUPTIBLE); 212 212 raw_spin_unlock_irqrestore(&sem->wait_lock, flags); ··· 214 214 raw_spin_lock_irqsave(&sem->wait_lock, flags); 215 215 } 216 216 /* got the lock */ 217 - sem->activity = -1; 217 + sem->count = -1; 218 218 list_del(&waiter.list); 219 219 220 220 raw_spin_unlock_irqrestore(&sem->wait_lock, flags); ··· 235 235 236 236 raw_spin_lock_irqsave(&sem->wait_lock, flags); 237 237 238 - if (sem->activity == 0) { 238 + if (sem->count == 0) { 239 239 /* got the lock */ 240 - sem->activity = -1; 240 + sem->count = -1; 241 241 ret = 1; 242 242 } 243 243 ··· 255 255 256 256 raw_spin_lock_irqsave(&sem->wait_lock, flags); 257 257 258 - if (--sem->activity == 0 && !list_empty(&sem->wait_list)) 258 + if (--sem->count == 0 && !list_empty(&sem->wait_list)) 259 259 sem = __rwsem_wake_one_writer(sem); 260 260 261 261 raw_spin_unlock_irqrestore(&sem->wait_lock, flags); ··· 270 270 271 271 raw_spin_lock_irqsave(&sem->wait_lock, flags); 272 272 273 - sem->activity = 0; 273 + sem->count = 0; 274 274 if (!list_empty(&sem->wait_list)) 275 275 sem = __rwsem_do_wake(sem, 1); 276 276 ··· 287 287 288 288 raw_spin_lock_irqsave(&sem->wait_lock, flags); 289 289 290 - sem->activity = 1; 290 + sem->count = 1; 291 291 if (!list_empty(&sem->wait_list)) 292 292 sem = __rwsem_do_wake(sem, 0); 293 293
+8 -8
kernel/locking/rwsem-xadd.c
··· 82 82 sem->count = RWSEM_UNLOCKED_VALUE; 83 83 raw_spin_lock_init(&sem->wait_lock); 84 84 INIT_LIST_HEAD(&sem->wait_list); 85 - #ifdef CONFIG_SMP 85 + #ifdef CONFIG_RWSEM_SPIN_ON_OWNER 86 86 sem->owner = NULL; 87 - sem->osq = NULL; 87 + osq_lock_init(&sem->osq); 88 88 #endif 89 89 } 90 90 ··· 262 262 return false; 263 263 } 264 264 265 - #ifdef CONFIG_SMP 265 + #ifdef CONFIG_RWSEM_SPIN_ON_OWNER 266 266 /* 267 267 * Try to acquire write lock before the writer has been put on wait queue. 268 268 */ ··· 285 285 static inline bool rwsem_can_spin_on_owner(struct rw_semaphore *sem) 286 286 { 287 287 struct task_struct *owner; 288 - bool on_cpu = true; 288 + bool on_cpu = false; 289 289 290 290 if (need_resched()) 291 - return 0; 291 + return false; 292 292 293 293 rcu_read_lock(); 294 294 owner = ACCESS_ONCE(sem->owner); ··· 297 297 rcu_read_unlock(); 298 298 299 299 /* 300 - * If sem->owner is not set, the rwsem owner may have 301 - * just acquired it and not set the owner yet or the rwsem 302 - * has been released. 300 + * If sem->owner is not set, yet we have just recently entered the 301 + * slowpath, then there is a possibility reader(s) may have the lock. 302 + * To be safe, avoid spinning in these situations. 303 303 */ 304 304 return on_cpu; 305 305 }
+1 -1
kernel/locking/rwsem.c
··· 12 12 13 13 #include <linux/atomic.h> 14 14 15 - #if defined(CONFIG_SMP) && defined(CONFIG_RWSEM_XCHGADD_ALGORITHM) 15 + #ifdef CONFIG_RWSEM_SPIN_ON_OWNER 16 16 static inline void rwsem_set_owner(struct rw_semaphore *sem) 17 17 { 18 18 sem->owner = current;
+2 -2
tools/lib/lockdep/include/liblockdep/mutex.h
··· 35 35 36 36 static inline int liblockdep_pthread_mutex_lock(liblockdep_pthread_mutex_t *lock) 37 37 { 38 - lock_acquire(&lock->dep_map, 0, 0, 0, 2, NULL, (unsigned long)_RET_IP_); 38 + lock_acquire(&lock->dep_map, 0, 0, 0, 1, NULL, (unsigned long)_RET_IP_); 39 39 return pthread_mutex_lock(&lock->mutex); 40 40 } 41 41 ··· 47 47 48 48 static inline int liblockdep_pthread_mutex_trylock(liblockdep_pthread_mutex_t *lock) 49 49 { 50 - lock_acquire(&lock->dep_map, 0, 1, 0, 2, NULL, (unsigned long)_RET_IP_); 50 + lock_acquire(&lock->dep_map, 0, 1, 0, 1, NULL, (unsigned long)_RET_IP_); 51 51 return pthread_mutex_trylock(&lock->mutex) == 0 ? 1 : 0; 52 52 } 53 53
+4 -4
tools/lib/lockdep/include/liblockdep/rwlock.h
··· 36 36 37 37 static inline int liblockdep_pthread_rwlock_rdlock(liblockdep_pthread_rwlock_t *lock) 38 38 { 39 - lock_acquire(&lock->dep_map, 0, 0, 2, 2, NULL, (unsigned long)_RET_IP_); 39 + lock_acquire(&lock->dep_map, 0, 0, 2, 1, NULL, (unsigned long)_RET_IP_); 40 40 return pthread_rwlock_rdlock(&lock->rwlock); 41 41 42 42 } ··· 49 49 50 50 static inline int liblockdep_pthread_rwlock_wrlock(liblockdep_pthread_rwlock_t *lock) 51 51 { 52 - lock_acquire(&lock->dep_map, 0, 0, 0, 2, NULL, (unsigned long)_RET_IP_); 52 + lock_acquire(&lock->dep_map, 0, 0, 0, 1, NULL, (unsigned long)_RET_IP_); 53 53 return pthread_rwlock_wrlock(&lock->rwlock); 54 54 } 55 55 56 56 static inline int liblockdep_pthread_rwlock_tryrdlock(liblockdep_pthread_rwlock_t *lock) 57 57 { 58 - lock_acquire(&lock->dep_map, 0, 1, 2, 2, NULL, (unsigned long)_RET_IP_); 58 + lock_acquire(&lock->dep_map, 0, 1, 2, 1, NULL, (unsigned long)_RET_IP_); 59 59 return pthread_rwlock_tryrdlock(&lock->rwlock) == 0 ? 1 : 0; 60 60 } 61 61 62 62 static inline int liblockdep_pthread_rwlock_trywlock(liblockdep_pthread_rwlock_t *lock) 63 63 { 64 - lock_acquire(&lock->dep_map, 0, 1, 0, 2, NULL, (unsigned long)_RET_IP_); 64 + lock_acquire(&lock->dep_map, 0, 1, 0, 1, NULL, (unsigned long)_RET_IP_); 65 65 return pthread_rwlock_trywlock(&lock->rwlock) == 0 ? 1 : 0; 66 66 } 67 67
+9 -11
tools/lib/lockdep/preload.c
··· 92 92 static void init_preload(void); 93 93 static void try_init_preload(void) 94 94 { 95 - if (!__init_state != done) 95 + if (__init_state != done) 96 96 init_preload(); 97 97 } 98 98 ··· 252 252 253 253 try_init_preload(); 254 254 255 - lock_acquire(&__get_lock(mutex)->dep_map, 0, 0, 0, 2, NULL, 255 + lock_acquire(&__get_lock(mutex)->dep_map, 0, 0, 0, 1, NULL, 256 256 (unsigned long)_RET_IP_); 257 257 /* 258 258 * Here's the thing with pthread mutexes: unlike the kernel variant, ··· 281 281 282 282 try_init_preload(); 283 283 284 - lock_acquire(&__get_lock(mutex)->dep_map, 0, 1, 0, 2, NULL, (unsigned long)_RET_IP_); 284 + lock_acquire(&__get_lock(mutex)->dep_map, 0, 1, 0, 1, NULL, (unsigned long)_RET_IP_); 285 285 r = ll_pthread_mutex_trylock(mutex); 286 286 if (r) 287 287 lock_release(&__get_lock(mutex)->dep_map, 0, (unsigned long)_RET_IP_); ··· 303 303 */ 304 304 r = ll_pthread_mutex_unlock(mutex); 305 305 if (r) 306 - lock_acquire(&__get_lock(mutex)->dep_map, 0, 0, 0, 2, NULL, (unsigned long)_RET_IP_); 306 + lock_acquire(&__get_lock(mutex)->dep_map, 0, 0, 0, 1, NULL, (unsigned long)_RET_IP_); 307 307 308 308 return r; 309 309 } ··· 352 352 353 353 init_preload(); 354 354 355 - lock_acquire(&__get_lock(rwlock)->dep_map, 0, 0, 2, 2, NULL, (unsigned long)_RET_IP_); 355 + lock_acquire(&__get_lock(rwlock)->dep_map, 0, 0, 2, 1, NULL, (unsigned long)_RET_IP_); 356 356 r = ll_pthread_rwlock_rdlock(rwlock); 357 357 if (r) 358 358 lock_release(&__get_lock(rwlock)->dep_map, 0, (unsigned long)_RET_IP_); ··· 366 366 367 367 init_preload(); 368 368 369 - lock_acquire(&__get_lock(rwlock)->dep_map, 0, 1, 2, 2, NULL, (unsigned long)_RET_IP_); 369 + lock_acquire(&__get_lock(rwlock)->dep_map, 0, 1, 2, 1, NULL, (unsigned long)_RET_IP_); 370 370 r = ll_pthread_rwlock_tryrdlock(rwlock); 371 371 if (r) 372 372 lock_release(&__get_lock(rwlock)->dep_map, 0, (unsigned long)_RET_IP_); ··· 380 380 381 381 init_preload(); 382 382 383 - lock_acquire(&__get_lock(rwlock)->dep_map, 0, 1, 0, 2, NULL, (unsigned long)_RET_IP_); 383 + lock_acquire(&__get_lock(rwlock)->dep_map, 0, 1, 0, 1, NULL, (unsigned long)_RET_IP_); 384 384 r = ll_pthread_rwlock_trywrlock(rwlock); 385 385 if (r) 386 386 lock_release(&__get_lock(rwlock)->dep_map, 0, (unsigned long)_RET_IP_); ··· 394 394 395 395 init_preload(); 396 396 397 - lock_acquire(&__get_lock(rwlock)->dep_map, 0, 0, 0, 2, NULL, (unsigned long)_RET_IP_); 397 + lock_acquire(&__get_lock(rwlock)->dep_map, 0, 0, 0, 1, NULL, (unsigned long)_RET_IP_); 398 398 r = ll_pthread_rwlock_wrlock(rwlock); 399 399 if (r) 400 400 lock_release(&__get_lock(rwlock)->dep_map, 0, (unsigned long)_RET_IP_); ··· 411 411 lock_release(&__get_lock(rwlock)->dep_map, 0, (unsigned long)_RET_IP_); 412 412 r = ll_pthread_rwlock_unlock(rwlock); 413 413 if (r) 414 - lock_acquire(&__get_lock(rwlock)->dep_map, 0, 0, 0, 2, NULL, (unsigned long)_RET_IP_); 414 + lock_acquire(&__get_lock(rwlock)->dep_map, 0, 0, 0, 1, NULL, (unsigned long)_RET_IP_); 415 415 416 416 return r; 417 417 } ··· 438 438 ll_pthread_rwlock_trywrlock = dlsym(RTLD_NEXT, "pthread_rwlock_trywrlock"); 439 439 ll_pthread_rwlock_unlock = dlsym(RTLD_NEXT, "pthread_rwlock_unlock"); 440 440 #endif 441 - 442 - printf("%p\n", ll_pthread_mutex_trylock);fflush(stdout); 443 441 444 442 lockdep_init(); 445 443