Skip to content

Commit 12a4be5

Browse files
committed
futex: factor out the futex wake handling
In preparation for having another waker that isn't futex_wake_mark(), add a wake handler in futex_q. No extra data is associated with the handler outside of struct futex_q itself. futex_wake_mark() is defined as the standard wakeup helper, now set through futex_q_init like other defaults. Normal sync futex waiting relies on wake_q holding tasks that should be woken up. This is what futex_wake_mark() does, it'll unqueue the futex and add the associated task to the wake queue. For async usage of futex waiting, rather than having tasks sleeping on the futex, we'll need to deal with a futex wake differently. For the planned io_uring case, that means posting a completion event for the task in question. Having a definable wake handler can help support that use case. Acked-by: Peter Zijlstra (Intel) <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 3b07815 commit 12a4be5

File tree

3 files changed

+10
-4
lines changed

3 files changed

+10
-4
lines changed

kernel/futex/futex.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,11 +139,15 @@ struct futex_pi_state {
139139
union futex_key key;
140140
} __randomize_layout;
141141

142+
struct futex_q;
143+
typedef void (futex_wake_fn)(struct wake_q_head *wake_q, struct futex_q *q);
144+
142145
/**
143146
* struct futex_q - The hashed futex queue entry, one per waiting task
144147
* @list: priority-sorted list of tasks waiting on this futex
145148
* @task: the task waiting on the futex
146149
* @lock_ptr: the hash bucket lock
150+
* @wake: the wake handler for this queue
147151
* @key: the key the futex is hashed on
148152
* @pi_state: optional priority inheritance state
149153
* @rt_waiter: rt_waiter storage for use with requeue_pi
@@ -168,6 +172,7 @@ struct futex_q {
168172

169173
struct task_struct *task;
170174
spinlock_t *lock_ptr;
175+
futex_wake_fn *wake;
171176
union futex_key key;
172177
struct futex_pi_state *pi_state;
173178
struct rt_mutex_waiter *rt_waiter;

kernel/futex/requeue.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ enum {
5858

5959
const struct futex_q futex_q_init = {
6060
/* list gets initialized in futex_queue()*/
61+
.wake = futex_wake_mark,
6162
.key = FUTEX_KEY_INIT,
6263
.bitset = FUTEX_BITSET_MATCH_ANY,
6364
.requeue_state = ATOMIC_INIT(Q_REQUEUE_PI_NONE),
@@ -593,7 +594,7 @@ int futex_requeue(u32 __user *uaddr1, unsigned int flags1,
593594
/* Plain futexes just wake or requeue and are done */
594595
if (!requeue_pi) {
595596
if (++task_count <= nr_wake)
596-
futex_wake_mark(&wake_q, this);
597+
this->wake(&wake_q, this);
597598
else
598599
requeue_futex(this, hb1, hb2, &key2);
599600
continue;

kernel/futex/waitwake.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ int futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset)
177177
if (!(this->bitset & bitset))
178178
continue;
179179

180-
futex_wake_mark(&wake_q, this);
180+
this->wake(&wake_q, this);
181181
if (++ret >= nr_wake)
182182
break;
183183
}
@@ -292,7 +292,7 @@ int futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2,
292292
ret = -EINVAL;
293293
goto out_unlock;
294294
}
295-
futex_wake_mark(&wake_q, this);
295+
this->wake(&wake_q, this);
296296
if (++ret >= nr_wake)
297297
break;
298298
}
@@ -306,7 +306,7 @@ int futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2,
306306
ret = -EINVAL;
307307
goto out_unlock;
308308
}
309-
futex_wake_mark(&wake_q, this);
309+
this->wake(&wake_q, this);
310310
if (++op_ret >= nr_wake2)
311311
break;
312312
}

0 commit comments

Comments
 (0)