diff mbox series

[v3,5/6] sched/wait: Add wait_event_state()

Message ID 20220822114648.989212021@infradead.org (mailing list archive)
State Handled Elsewhere, archived
Headers show
Series Freezer Rewrite | expand

Commit Message

Peter Zijlstra Aug. 22, 2022, 11:18 a.m. UTC
Allows waiting with a custom @state.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
---
 include/linux/wait.h |   28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

Comments

Ingo Molnar Sept. 4, 2022, 9:54 a.m. UTC | #1
* Peter Zijlstra <peterz@infradead.org> wrote:

> Allows waiting with a custom @state.
> 
> Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
> ---
>  include/linux/wait.h |   28 ++++++++++++++++++++++++++++
>  1 file changed, 28 insertions(+)
> 
> --- a/include/linux/wait.h
> +++ b/include/linux/wait.h
> @@ -931,6 +931,34 @@ extern int do_wait_intr_irq(wait_queue_h
>  	__ret;									\
>  })
>  
> +#define __wait_event_state(wq, condition, state)				\
> +	___wait_event(wq, condition, state, 0, 0, schedule())
> +
> +/**
> + * wait_event_state - sleep until a condition gets true
> + * @wq_head: the waitqueue to wait on
> + * @condition: a C expression for the event to wait for
> + * @state: state to sleep in
> + *
> + * The process is put to sleep (@state) until the @condition evaluates to true
> + * or a signal is received.  The @condition is checked each time the waitqueue
> + * @wq_head is woken up.

Documentation inconsistency nit: if TASK_INTERRUPTIBLE isn't in @state then 
we won't wake up when a signal is received. This probably got copy-pasted 
from a signal variant.

> + *
> + * wake_up() has to be called after changing any variable that could
> + * change the result of the wait condition.
> + *
> + * The function will return -ERESTARTSYS if it was interrupted by a
> + * signal and 0 if @condition evaluated to true.

That's not unconditionally true either if !TASK_INTERRUPTIBLE.

> +#define wait_event_state(wq_head, condition, state)				\
> +({										\
> +	int __ret = 0;								\
> +	might_sleep();								\

Very small style consistency nit, the above should have a newline after 
local variables:

> +#define wait_event_state(wq_head, condition, state)				\
> +({										\
> +	int __ret = 0;								\
> +                                                                             \
> +	might_sleep();								\

Like most (but not all ... :-/ ) of the existing primitives have.

Thanks,

	Ingo
Peter Zijlstra Sept. 6, 2022, 11:08 a.m. UTC | #2
On Sun, Sep 04, 2022 at 11:54:57AM +0200, Ingo Molnar wrote:
> > +/**
> > + * wait_event_state - sleep until a condition gets true
> > + * @wq_head: the waitqueue to wait on
> > + * @condition: a C expression for the event to wait for
> > + * @state: state to sleep in
> > + *
> > + * The process is put to sleep (@state) until the @condition evaluates to true
> > + * or a signal is received.  The @condition is checked each time the waitqueue
> > + * @wq_head is woken up.
> 
> Documentation inconsistency nit: if TASK_INTERRUPTIBLE isn't in @state then 
> we won't wake up when a signal is received. This probably got copy-pasted 
> from a signal variant.
> 
> > + *
> > + * wake_up() has to be called after changing any variable that could
> > + * change the result of the wait condition.
> > + *
> > + * The function will return -ERESTARTSYS if it was interrupted by a
> > + * signal and 0 if @condition evaluated to true.
> 
> That's not unconditionally true either if !TASK_INTERRUPTIBLE.


--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -942,14 +942,14 @@ extern int do_wait_intr_irq(wait_queue_h
  * @state: state to sleep in
  *
  * The process is put to sleep (@state) until the @condition evaluates to true
- * or a signal is received.  The @condition is checked each time the waitqueue
- * @wq_head is woken up.
+ * or a signal is received (when allowed by @state).  The @condition is checked
+ * each time the waitqueue @wq_head is woken up.
  *
  * wake_up() has to be called after changing any variable that could
  * change the result of the wait condition.
  *
- * The function will return -ERESTARTSYS if it was interrupted by a
- * signal and 0 if @condition evaluated to true.
+ * The function will return -ERESTARTSYS if it was interrupted by a signal
+ * (when allowed by @state) and 0 if @condition evaluated to true.
  */
 #define wait_event_state(wq_head, condition, state)				\
 ({										\


> > +#define wait_event_state(wq_head, condition, state)				\
> > +({										\
> > +	int __ret = 0;								\
> > +	might_sleep();								\
> 
> Very small style consistency nit, the above should have a newline after 
> local variables:
> 
> > +#define wait_event_state(wq_head, condition, state)				\
> > +({										\
> > +	int __ret = 0;								\
> > +                                                                             \
> > +	might_sleep();								\
> 
> Like most (but not all ... :-/ ) of the existing primitives have.

Yeah, I'm going to leave it as is.
Ingo Molnar Sept. 7, 2022, 7:26 a.m. UTC | #3
* Peter Zijlstra <peterz@infradead.org> wrote:

> On Sun, Sep 04, 2022 at 11:54:57AM +0200, Ingo Molnar wrote:
> > > +/**
> > > + * wait_event_state - sleep until a condition gets true
> > > + * @wq_head: the waitqueue to wait on
> > > + * @condition: a C expression for the event to wait for
> > > + * @state: state to sleep in
> > > + *
> > > + * The process is put to sleep (@state) until the @condition evaluates to true
> > > + * or a signal is received.  The @condition is checked each time the waitqueue
> > > + * @wq_head is woken up.
> > 
> > Documentation inconsistency nit: if TASK_INTERRUPTIBLE isn't in @state then 
> > we won't wake up when a signal is received. This probably got copy-pasted 
> > from a signal variant.
> > 
> > > + *
> > > + * wake_up() has to be called after changing any variable that could
> > > + * change the result of the wait condition.
> > > + *
> > > + * The function will return -ERESTARTSYS if it was interrupted by a
> > > + * signal and 0 if @condition evaluated to true.
> > 
> > That's not unconditionally true either if !TASK_INTERRUPTIBLE.
> 
> 
> --- a/include/linux/wait.h
> +++ b/include/linux/wait.h
> @@ -942,14 +942,14 @@ extern int do_wait_intr_irq(wait_queue_h
>   * @state: state to sleep in
>   *
>   * The process is put to sleep (@state) until the @condition evaluates to true
> - * or a signal is received.  The @condition is checked each time the waitqueue
> - * @wq_head is woken up.
> + * or a signal is received (when allowed by @state).  The @condition is checked
> + * each time the waitqueue @wq_head is woken up.
>   *
>   * wake_up() has to be called after changing any variable that could
>   * change the result of the wait condition.
>   *
> - * The function will return -ERESTARTSYS if it was interrupted by a
> - * signal and 0 if @condition evaluated to true.
> + * The function will return -ERESTARTSYS if it was interrupted by a signal
> + * (when allowed by @state) and 0 if @condition evaluated to true.
>   */

Reviewed-by: Ingo Molnar <mingo@kernel.org>

> > > +#define wait_event_state(wq_head, condition, state)				\
> > > +({										\
> > > +	int __ret = 0;								\
> > > +                                                                             \
> > > +	might_sleep();								\
> > 
> > Like most (but not all ... :-/ ) of the existing primitives have.
> 
> Yeah, I'm going to leave it as is.

Will queue up a cleanup patch, should I ever notice this detail again ... :-)

Thanks,

	Ingo
diff mbox series

Patch

--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -931,6 +931,34 @@  extern int do_wait_intr_irq(wait_queue_h
 	__ret;									\
 })
 
+#define __wait_event_state(wq, condition, state)				\
+	___wait_event(wq, condition, state, 0, 0, schedule())
+
+/**
+ * wait_event_state - sleep until a condition gets true
+ * @wq_head: the waitqueue to wait on
+ * @condition: a C expression for the event to wait for
+ * @state: state to sleep in
+ *
+ * The process is put to sleep (@state) until the @condition evaluates to true
+ * or a signal is received.  The @condition is checked each time the waitqueue
+ * @wq_head is woken up.
+ *
+ * wake_up() has to be called after changing any variable that could
+ * change the result of the wait condition.
+ *
+ * The function will return -ERESTARTSYS if it was interrupted by a
+ * signal and 0 if @condition evaluated to true.
+ */
+#define wait_event_state(wq_head, condition, state)				\
+({										\
+	int __ret = 0;								\
+	might_sleep();								\
+	if (!(condition))							\
+		__ret = __wait_event_state(wq_head, condition, state);		\
+	__ret;									\
+})
+
 #define __wait_event_killable_timeout(wq_head, condition, timeout)		\
 	___wait_event(wq_head, ___wait_cond_timeout(condition),			\
 		      TASK_KILLABLE, 0, timeout,				\