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.

futex: Convert to compiler context analysis

Convert the sparse annotations over to the new compiler context
analysis stuff.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260121111213.950376128@infradead.org

+35 -6
+2
kernel/futex/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 3 + CONTEXT_ANALYSIS := y 4 + 3 5 obj-y += core.o syscalls.o pi.o requeue.o waitwake.o
+6 -3
kernel/futex/core.c
··· 864 864 865 865 /* The key must be already stored in q->key. */ 866 866 void futex_q_lock(struct futex_q *q, struct futex_hash_bucket *hb) 867 - __acquires(&hb->lock) 868 867 { 869 868 /* 870 869 * Increment the counter before taking the lock so that ··· 878 879 q->lock_ptr = &hb->lock; 879 880 880 881 spin_lock(&hb->lock); 882 + __acquire(q->lock_ptr); 881 883 } 882 884 883 885 void futex_q_unlock(struct futex_hash_bucket *hb) 884 - __releases(&hb->lock) 885 886 { 886 887 futex_hb_waiters_dec(hb); 887 888 spin_unlock(&hb->lock); ··· 1442 1443 void futex_exit_recursive(struct task_struct *tsk) 1443 1444 { 1444 1445 /* If the state is FUTEX_STATE_EXITING then futex_exit_mutex is held */ 1445 - if (tsk->futex_state == FUTEX_STATE_EXITING) 1446 + if (tsk->futex_state == FUTEX_STATE_EXITING) { 1447 + __assume_ctx_lock(&tsk->futex_exit_mutex); 1446 1448 mutex_unlock(&tsk->futex_exit_mutex); 1449 + } 1447 1450 tsk->futex_state = FUTEX_STATE_DEAD; 1448 1451 } 1449 1452 1450 1453 static void futex_cleanup_begin(struct task_struct *tsk) 1454 + __acquires(&tsk->futex_exit_mutex) 1451 1455 { 1452 1456 /* 1453 1457 * Prevent various race issues against a concurrent incoming waiter ··· 1477 1475 } 1478 1476 1479 1477 static void futex_cleanup_end(struct task_struct *tsk, int state) 1478 + __releases(&tsk->futex_exit_mutex) 1480 1479 { 1481 1480 /* 1482 1481 * Lockless store. The only side effect is that an observer might
+14 -3
kernel/futex/futex.h
··· 217 217 218 218 extern int get_futex_key(u32 __user *uaddr, unsigned int flags, union futex_key *key, 219 219 enum futex_access rw); 220 - extern void futex_q_lockptr_lock(struct futex_q *q); 220 + extern void futex_q_lockptr_lock(struct futex_q *q) __acquires(q->lock_ptr); 221 221 extern struct hrtimer_sleeper * 222 222 futex_setup_timer(ktime_t *time, struct hrtimer_sleeper *timeout, 223 223 int flags, u64 range_ns); ··· 311 311 static inline void futex_queue(struct futex_q *q, struct futex_hash_bucket *hb, 312 312 struct task_struct *task) 313 313 __releases(&hb->lock) 314 + __releases(q->lock_ptr) 314 315 { 315 316 __futex_queue(q, hb, task); 316 317 spin_unlock(&hb->lock); 318 + __release(q->lock_ptr); 317 319 } 318 320 319 321 extern void futex_unqueue_pi(struct futex_q *q); ··· 360 358 #endif 361 359 } 362 360 363 - extern void futex_q_lock(struct futex_q *q, struct futex_hash_bucket *hb); 364 - extern void futex_q_unlock(struct futex_hash_bucket *hb); 361 + extern void futex_q_lock(struct futex_q *q, struct futex_hash_bucket *hb) 362 + __acquires(&hb->lock) 363 + __acquires(q->lock_ptr); 365 364 365 + extern void futex_q_unlock(struct futex_hash_bucket *hb) 366 + __releases(&hb->lock); 366 367 367 368 extern int futex_lock_pi_atomic(u32 __user *uaddr, struct futex_hash_bucket *hb, 368 369 union futex_key *key, ··· 384 379 */ 385 380 static inline void 386 381 double_lock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2) 382 + __acquires(&hb1->lock) 383 + __acquires(&hb2->lock) 384 + __no_context_analysis 387 385 { 388 386 if (hb1 > hb2) 389 387 swap(hb1, hb2); ··· 398 390 399 391 static inline void 400 392 double_unlock_hb(struct futex_hash_bucket *hb1, struct futex_hash_bucket *hb2) 393 + __releases(&hb1->lock) 394 + __releases(&hb2->lock) 395 + __no_context_analysis 401 396 { 402 397 spin_unlock(&hb1->lock); 403 398 if (hb1 != hb2)
+9
kernel/futex/pi.c
··· 389 389 * Initialize the pi_mutex in locked state and make @p 390 390 * the owner of it: 391 391 */ 392 + __assume_ctx_lock(&pi_state->pi_mutex.wait_lock); 392 393 rt_mutex_init_proxy_locked(&pi_state->pi_mutex, p); 393 394 394 395 /* Store the key for possible exit cleanups: */ ··· 615 614 static int wake_futex_pi(u32 __user *uaddr, u32 uval, 616 615 struct futex_pi_state *pi_state, 617 616 struct rt_mutex_waiter *top_waiter) 617 + __must_hold(&pi_state->pi_mutex.wait_lock) 618 + __releases(&pi_state->pi_mutex.wait_lock) 618 619 { 619 620 struct task_struct *new_owner; 620 621 bool postunlock = false; ··· 673 670 674 671 static int __fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q, 675 672 struct task_struct *argowner) 673 + __must_hold(&q->pi_state->pi_mutex.wait_lock) 674 + __must_hold(q->lock_ptr) 676 675 { 677 676 struct futex_pi_state *pi_state = q->pi_state; 678 677 struct task_struct *oldowner, *newowner; ··· 971 966 * - EAGAIN: The user space value changed. 972 967 */ 973 968 futex_q_unlock(hb); 969 + __release(q.lock_ptr); 974 970 /* 975 971 * Handle the case where the owner is in the middle of 976 972 * exiting. Wait for the exit to complete otherwise ··· 1096 1090 if (res) 1097 1091 ret = (res < 0) ? res : 0; 1098 1092 1093 + __release(&hb->lock); 1099 1094 futex_unqueue_pi(&q); 1100 1095 spin_unlock(q.lock_ptr); 1101 1096 if (q.drop_hb_ref) { ··· 1108 1101 1109 1102 out_unlock_put_key: 1110 1103 futex_q_unlock(hb); 1104 + __release(q.lock_ptr); 1111 1105 goto out; 1112 1106 1113 1107 uaddr_faulted: 1114 1108 futex_q_unlock(hb); 1109 + __release(q.lock_ptr); 1115 1110 1116 1111 ret = fault_in_user_writeable(uaddr); 1117 1112 if (ret)
+4
kernel/futex/waitwake.c
··· 462 462 } 463 463 464 464 futex_q_unlock(hb); 465 + __release(q->lock_ptr); 465 466 } 466 467 __set_current_state(TASK_RUNNING); 467 468 ··· 629 628 630 629 if (ret) { 631 630 futex_q_unlock(hb); 631 + __release(q->lock_ptr); 632 632 633 633 ret = get_user(uval, uaddr); 634 634 if (ret) ··· 643 641 644 642 if (uval != val) { 645 643 futex_q_unlock(hb); 644 + __release(q->lock_ptr); 646 645 return -EWOULDBLOCK; 647 646 } 648 647 649 648 if (key2 && futex_match(&q->key, key2)) { 650 649 futex_q_unlock(hb); 650 + __release(q->lock_ptr); 651 651 return -EINVAL; 652 652 } 653 653