Message ID | 20230712004705.316157-3-axboe@kernel.dk (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Add io_uring futex/futexv support | expand |
On Tue, Jul 11, 2023 at 06:47:00PM -0600, Jens Axboe wrote: > 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. Urgh... so if I understand things right, you're going to replace this with a custom wake function that does *NOT* put the task on the wake_q. The wake_q will thus be empty and the task does not get woken up. I'm presuming someone gets a notification instead somewhere somehow. I might've been nice to mention some of this somewhere ... > Signed-off-by: Jens Axboe <axboe@kernel.dk> > --- > kernel/futex/futex.h | 4 ++++ > kernel/futex/requeue.c | 3 ++- > kernel/futex/waitwake.c | 6 +++--- > 3 files changed, 9 insertions(+), 4 deletions(-) > > diff --git a/kernel/futex/futex.h b/kernel/futex/futex.h > index d2949fca37d1..8eaf1a5ce967 100644 > --- a/kernel/futex/futex.h > +++ b/kernel/futex/futex.h > @@ -69,6 +69,9 @@ struct futex_pi_state { > union futex_key key; > } __randomize_layout; > > +struct futex_q; > +typedef void (futex_wake_fn)(struct wake_q_head *wake_q, struct futex_q *q); > + > /** > * struct futex_q - The hashed futex queue entry, one per waiting task > * @list: priority-sorted list of tasks waiting on this futex > @@ -98,6 +101,7 @@ struct futex_q { > > struct task_struct *task; > spinlock_t *lock_ptr; > + futex_wake_fn *wake; > union futex_key key; > struct futex_pi_state *pi_state; > struct rt_mutex_waiter *rt_waiter;
On 7/12/23 2:58?AM, Peter Zijlstra wrote: > On Tue, Jul 11, 2023 at 06:47:00PM -0600, Jens Axboe wrote: >> 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. > > Urgh... so if I understand things right, you're going to replace this > with a custom wake function that does *NOT* put the task on the wake_q. > > The wake_q will thus be empty and the task does not get woken up. I'm > presuming someone gets a notification instead somewhere somehow. Right. The custom wake function is responsible for waking the task, if that is what needs to happen. On the io_uring side, the callback would queue work for the original task to post a completion event, which would then also wake it up obviously. > I might've been nice to mention some of this somewhere ... I'll expand the commit message a bit, it is a bit light.
diff --git a/kernel/futex/futex.h b/kernel/futex/futex.h index d2949fca37d1..8eaf1a5ce967 100644 --- a/kernel/futex/futex.h +++ b/kernel/futex/futex.h @@ -69,6 +69,9 @@ struct futex_pi_state { union futex_key key; } __randomize_layout; +struct futex_q; +typedef void (futex_wake_fn)(struct wake_q_head *wake_q, struct futex_q *q); + /** * struct futex_q - The hashed futex queue entry, one per waiting task * @list: priority-sorted list of tasks waiting on this futex @@ -98,6 +101,7 @@ struct futex_q { struct task_struct *task; spinlock_t *lock_ptr; + futex_wake_fn *wake; union futex_key key; struct futex_pi_state *pi_state; struct rt_mutex_waiter *rt_waiter; diff --git a/kernel/futex/requeue.c b/kernel/futex/requeue.c index cba8b1a6a4cc..e892bc6c41d8 100644 --- a/kernel/futex/requeue.c +++ b/kernel/futex/requeue.c @@ -58,6 +58,7 @@ enum { const struct futex_q futex_q_init = { /* list gets initialized in futex_queue()*/ + .wake = futex_wake_mark, .key = FUTEX_KEY_INIT, .bitset = FUTEX_BITSET_MATCH_ANY, .requeue_state = ATOMIC_INIT(Q_REQUEUE_PI_NONE), @@ -591,7 +592,7 @@ int futex_requeue(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2, /* Plain futexes just wake or requeue and are done */ if (!requeue_pi) { if (++task_count <= nr_wake) - futex_wake_mark(&wake_q, this); + this->wake(&wake_q, this); else requeue_futex(this, hb1, hb2, &key2); continue; diff --git a/kernel/futex/waitwake.c b/kernel/futex/waitwake.c index ba01b9408203..3471af87cb7d 100644 --- a/kernel/futex/waitwake.c +++ b/kernel/futex/waitwake.c @@ -174,7 +174,7 @@ int futex_wake(u32 __user *uaddr, unsigned int flags, int nr_wake, u32 bitset) if (!(this->bitset & bitset)) continue; - futex_wake_mark(&wake_q, this); + this->wake(&wake_q, this); if (++ret >= nr_wake) break; } @@ -289,7 +289,7 @@ int futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2, ret = -EINVAL; goto out_unlock; } - futex_wake_mark(&wake_q, this); + this->wake(&wake_q, this); if (++ret >= nr_wake) break; } @@ -303,7 +303,7 @@ int futex_wake_op(u32 __user *uaddr1, unsigned int flags, u32 __user *uaddr2, ret = -EINVAL; goto out_unlock; } - futex_wake_mark(&wake_q, this); + this->wake(&wake_q, this); if (++op_ret >= nr_wake2) break; }
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. Signed-off-by: Jens Axboe <axboe@kernel.dk> --- kernel/futex/futex.h | 4 ++++ kernel/futex/requeue.c | 3 ++- kernel/futex/waitwake.c | 6 +++--- 3 files changed, 9 insertions(+), 4 deletions(-)