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: Create futex_hash() get/put class

This gets us:

hb = futex_hash(key) /* gets hb and inc users */
futex_hash_get(hb) /* inc users */
futex_hash_put(hb) /* dec users */

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/r/20250416162921.513656-7-bigeasy@linutronix.de

+30 -24
+3 -3
kernel/futex/core.c
··· 122 122 return &futex_queues[hash & futex_hashmask]; 123 123 } 124 124 125 + void futex_hash_get(struct futex_hash_bucket *hb) { } 126 + void futex_hash_put(struct futex_hash_bucket *hb) { } 125 127 126 128 /** 127 129 * futex_setup_timer - set up the sleeping hrtimer. ··· 959 957 pi_state = list_entry(next, struct futex_pi_state, list); 960 958 key = pi_state->key; 961 959 if (1) { 962 - struct futex_hash_bucket *hb; 963 - 964 - hb = futex_hash(&key); 960 + CLASS(hb, hb)(&key); 965 961 966 962 /* 967 963 * We can race against put_pi_state() removing itself from the
+7
kernel/futex/futex.h
··· 7 7 #include <linux/sched/wake_q.h> 8 8 #include <linux/compat.h> 9 9 #include <linux/uaccess.h> 10 + #include <linux/cleanup.h> 10 11 11 12 #ifdef CONFIG_PREEMPT_RT 12 13 #include <linux/rcuwait.h> ··· 203 202 int flags, u64 range_ns); 204 203 205 204 extern struct futex_hash_bucket *futex_hash(union futex_key *key); 205 + extern void futex_hash_get(struct futex_hash_bucket *hb); 206 + extern void futex_hash_put(struct futex_hash_bucket *hb); 207 + 208 + DEFINE_CLASS(hb, struct futex_hash_bucket *, 209 + if (_T) futex_hash_put(_T), 210 + futex_hash(key), union futex_key *key); 206 211 207 212 /** 208 213 * futex_match - Check whether two futex keys are equal
+12 -4
kernel/futex/pi.c
··· 939 939 940 940 retry_private: 941 941 if (1) { 942 - struct futex_hash_bucket *hb; 942 + CLASS(hb, hb)(&q.key); 943 943 944 - hb = futex_hash(&q.key); 945 944 futex_q_lock(&q, hb); 946 945 947 946 ret = futex_lock_pi_atomic(uaddr, hb, &q.key, &q.pi_state, current, ··· 993 994 goto no_block; 994 995 } 995 996 997 + /* 998 + * Caution; releasing @hb in-scope. The hb->lock is still locked 999 + * while the reference is dropped. The reference can not be dropped 1000 + * after the unlock because if a user initiated resize is in progress 1001 + * then we might need to wake him. This can not be done after the 1002 + * rt_mutex_pre_schedule() invocation. The hb will remain valid because 1003 + * the thread, performing resize, will block on hb->lock during 1004 + * the requeue. 1005 + */ 1006 + futex_hash_put(no_free_ptr(hb)); 996 1007 /* 997 1008 * Must be done before we enqueue the waiter, here is unfortunately 998 1009 * under the hb lock, but that *should* work because it does nothing. ··· 1128 1119 { 1129 1120 u32 curval, uval, vpid = task_pid_vnr(current); 1130 1121 union futex_key key = FUTEX_KEY_INIT; 1131 - struct futex_hash_bucket *hb; 1132 1122 struct futex_q *top_waiter; 1133 1123 int ret; 1134 1124 ··· 1147 1139 if (ret) 1148 1140 return ret; 1149 1141 1150 - hb = futex_hash(&key); 1142 + CLASS(hb, hb)(&key); 1151 1143 spin_lock(&hb->lock); 1152 1144 retry_hb: 1153 1145
+3 -7
kernel/futex/requeue.c
··· 444 444 445 445 retry_private: 446 446 if (1) { 447 - struct futex_hash_bucket *hb1, *hb2; 448 - 449 - hb1 = futex_hash(&key1); 450 - hb2 = futex_hash(&key2); 447 + CLASS(hb, hb1)(&key1); 448 + CLASS(hb, hb2)(&key2); 451 449 452 450 futex_hb_waiters_inc(hb2); 453 451 double_lock_hb(hb1, hb2); ··· 815 817 switch (futex_requeue_pi_wakeup_sync(&q)) { 816 818 case Q_REQUEUE_PI_IGNORE: 817 819 { 818 - struct futex_hash_bucket *hb; 819 - 820 - hb = futex_hash(&q.key); 820 + CLASS(hb, hb)(&q.key); 821 821 /* The waiter is still on uaddr1 */ 822 822 spin_lock(&hb->lock); 823 823 ret = handle_early_requeue_pi_wakeup(hb, &q, to);
+5 -10
kernel/futex/waitwake.c
··· 154 154 */ 155 155 int futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset) 156 156 { 157 - struct futex_hash_bucket *hb; 158 157 struct futex_q *this, *next; 159 158 union futex_key key = FUTEX_KEY_INIT; 160 159 DEFINE_WAKE_Q(wake_q); ··· 169 170 if ((flags & FLAGS_STRICT) && !nr_wake) 170 171 return 0; 171 172 172 - hb = futex_hash(&key); 173 + CLASS(hb, hb)(&key); 173 174 174 175 /* Make sure we really have tasks to wakeup */ 175 176 if (!futex_hb_waiters_pending(hb)) ··· 266 267 267 268 retry_private: 268 269 if (1) { 269 - struct futex_hash_bucket *hb1, *hb2; 270 - 271 - hb1 = futex_hash(&key1); 272 - hb2 = futex_hash(&key2); 270 + CLASS(hb, hb1)(&key1); 271 + CLASS(hb, hb2)(&key2); 273 272 274 273 double_lock_hb(hb1, hb2); 275 274 op_ret = futex_atomic_op_inuser(op, uaddr2); ··· 441 444 u32 val = vs[i].w.val; 442 445 443 446 if (1) { 444 - struct futex_hash_bucket *hb; 447 + CLASS(hb, hb)(&q->key); 445 448 446 - hb = futex_hash(&q->key); 447 449 futex_q_lock(q, hb); 448 450 ret = futex_get_value_locked(&uval, uaddr); 449 451 ··· 614 618 615 619 retry_private: 616 620 if (1) { 617 - struct futex_hash_bucket *hb; 621 + CLASS(hb, hb)(&q->key); 618 622 619 - hb = futex_hash(&q->key); 620 623 futex_q_lock(q, hb); 621 624 622 625 ret = futex_get_value_locked(&uval, uaddr);