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.

locking/osq_lock: Clarify osq_wait_next() calling convention

osq_wait_next() is passed 'prev' from osq_lock() and NULL from
osq_unlock() but only needs the 'cpu' value to write to lock->tail.

Just pass prev->cpu or OSQ_UNLOCKED_VAL instead.

Should have no effect on the generated code since gcc manages to assume
that 'prev != NULL' due to an earlier dereference.

Signed-off-by: David Laight <david.laight@aculab.com>
[ Changed 'old' to 'old_cpu' by request from Waiman Long - Linus ]
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

David Laight and committed by
Linus Torvalds
563adbfc 7c223098

+9 -12
+9 -12
kernel/locking/osq_lock.c
··· 44 44 /* 45 45 * Get a stable @node->next pointer, either for unlock() or unqueue() purposes. 46 46 * Can return NULL in case we were the last queued and we updated @lock instead. 47 + * 48 + * If osq_lock() is being cancelled there must be a previous node 49 + * and 'old_cpu' is its CPU #. 50 + * For osq_unlock() there is never a previous node and old_cpu is 51 + * set to OSQ_UNLOCKED_VAL. 47 52 */ 48 53 static inline struct optimistic_spin_node * 49 54 osq_wait_next(struct optimistic_spin_queue *lock, 50 55 struct optimistic_spin_node *node, 51 - struct optimistic_spin_node *prev) 56 + int old_cpu) 52 57 { 53 58 struct optimistic_spin_node *next = NULL; 54 59 int curr = encode_cpu(smp_processor_id()); 55 - int old; 56 - 57 - /* 58 - * If there is a prev node in queue, then the 'old' value will be 59 - * the prev node's CPU #, else it's set to OSQ_UNLOCKED_VAL since if 60 - * we're currently last in queue, then the queue will then become empty. 61 - */ 62 - old = prev ? prev->cpu : OSQ_UNLOCKED_VAL; 63 60 64 61 for (;;) { 65 62 if (atomic_read(&lock->tail) == curr && 66 - atomic_cmpxchg_acquire(&lock->tail, curr, old) == curr) { 63 + atomic_cmpxchg_acquire(&lock->tail, curr, old_cpu) == curr) { 67 64 /* 68 65 * We were the last queued, we moved @lock back. @prev 69 66 * will now observe @lock and will complete its ··· 190 193 * back to @prev. 191 194 */ 192 195 193 - next = osq_wait_next(lock, node, prev); 196 + next = osq_wait_next(lock, node, prev->cpu); 194 197 if (!next) 195 198 return false; 196 199 ··· 230 233 return; 231 234 } 232 235 233 - next = osq_wait_next(lock, node, NULL); 236 + next = osq_wait_next(lock, node, OSQ_UNLOCKED_VAL); 234 237 if (next) 235 238 WRITE_ONCE(next->locked, 1); 236 239 }