linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] sched/wait, staging/android: simplification of freeze related code
@ 2019-02-07 21:28 Hugo Lefeuvre
  2019-02-07 21:29 ` [PATCH v2 1/2] sched/wait: introduce wait_event_freezable_hrtimeout Hugo Lefeuvre
  2019-02-07 21:29 ` [PATCH v2 2/2] staging/android: simplify handle_vsoc_cond_wait Hugo Lefeuvre
  0 siblings, 2 replies; 4+ messages in thread
From: Hugo Lefeuvre @ 2019-02-07 21:28 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Greg Hartman, Alistair Strachan, Arve Hjønnevåg,
	Todd Kjos, Martijn Coenen, Christian Brauner, Ingo Molnar,
	Peter Zijlstra, devel, linux-kernel, Joel Fernandes

This patchset introduces a new wait_event_freezable_hrtimeout method
to the wait api.

wait_event_freezable_hrtimeout is then used to greatly simplify
handle_vsoc_cond_wait in the android vsoc driver, reducing the
size of the vsoc driver.

Changes since v1 [1]:

- Delete "[1/3] sched/wait: use freezable_schedule when possible",
  it was submitted separately.
- Patch 3/3 (now 2/2): Fix removal of a necessary linux/freezer.h
  include and improve commit message.

[1] v1: https://lkml.org/lkml/2019/2/1/19

Hugo Lefeuvre (2):
  sched/wait: introduce wait_event_freezable_hrtimeout
  staging/android: simplify handle_vsoc_cond_wait

 drivers/staging/android/vsoc.c | 68 +++++-----------------------------
 include/linux/wait.h           | 25 +++++++++++--
 2 files changed, 31 insertions(+), 62 deletions(-)

-- 
2.20.1

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2 1/2] sched/wait: introduce wait_event_freezable_hrtimeout
  2019-02-07 21:28 [PATCH v2 0/2] sched/wait, staging/android: simplification of freeze related code Hugo Lefeuvre
@ 2019-02-07 21:29 ` Hugo Lefeuvre
  2019-02-11  7:31   ` Ingo Molnar
  2019-02-07 21:29 ` [PATCH v2 2/2] staging/android: simplify handle_vsoc_cond_wait Hugo Lefeuvre
  1 sibling, 1 reply; 4+ messages in thread
From: Hugo Lefeuvre @ 2019-02-07 21:29 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Greg Hartman, Alistair Strachan, Arve Hjønnevåg,
	Todd Kjos, Martijn Coenen, Christian Brauner, Ingo Molnar,
	Peter Zijlstra, devel, linux-kernel, Joel Fernandes

introduce wait_event_freezable_hrtimeout, an interruptible and freezable
version of wait_event_hrtimeout.

This helper will allow for simplifications in staging/android/vsoc.c, among
others.

Signed-off-by: Hugo Lefeuvre <hle@owl.eu.com>
---
Changes in v2:
  - No change.

 include/linux/wait.h | 25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/include/linux/wait.h b/include/linux/wait.h
index 5f3efabc36f4..c4cf5113f58a 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -483,7 +483,7 @@ do {										\
 	__ret;									\
 })
 
-#define __wait_event_hrtimeout(wq_head, condition, timeout, state)		\
+#define __wait_event_hrtimeout(wq_head, condition, timeout, state, cmd)		\
 ({										\
 	int __ret = 0;								\
 	struct hrtimer_sleeper __t;						\
@@ -500,7 +500,7 @@ do {										\
 			__ret = -ETIME;						\
 			break;							\
 		}								\
-		schedule());							\
+		cmd);							        \
 										\
 	hrtimer_cancel(&__t.timer);						\
 	destroy_hrtimer_on_stack(&__t.timer);					\
@@ -529,7 +529,23 @@ do {										\
 	might_sleep();								\
 	if (!(condition))							\
 		__ret = __wait_event_hrtimeout(wq_head, condition, timeout,	\
-					       TASK_UNINTERRUPTIBLE);		\
+					       TASK_UNINTERRUPTIBLE,		\
+					       schedule());			\
+	__ret;									\
+})
+
+/*
+ * like wait_event_hrtimeout() -- except it uses TASK_INTERRUPTIBLE to avoid
+ * increasing load and is freezable.
+ */
+#define wait_event_freezable_hrtimeout(wq_head, condition, timeout)		\
+({										\
+	int __ret = 0;								\
+	might_sleep();								\
+	if (!(condition))							\
+		__ret = __wait_event_hrtimeout(wq_head, condition, timeout,	\
+					       TASK_INTERRUPTIBLE,		\
+					       freezable_schedule());		\
 	__ret;									\
 })
 
@@ -555,7 +571,8 @@ do {										\
 	might_sleep();								\
 	if (!(condition))							\
 		__ret = __wait_event_hrtimeout(wq, condition, timeout,		\
-					       TASK_INTERRUPTIBLE);		\
+					       TASK_INTERRUPTIBLE,		\
+					       schedule());			\
 	__ret;									\
 })
 
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 2/2] staging/android: simplify handle_vsoc_cond_wait
  2019-02-07 21:28 [PATCH v2 0/2] sched/wait, staging/android: simplification of freeze related code Hugo Lefeuvre
  2019-02-07 21:29 ` [PATCH v2 1/2] sched/wait: introduce wait_event_freezable_hrtimeout Hugo Lefeuvre
@ 2019-02-07 21:29 ` Hugo Lefeuvre
  1 sibling, 0 replies; 4+ messages in thread
From: Hugo Lefeuvre @ 2019-02-07 21:29 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Greg Hartman, Alistair Strachan, Arve Hjønnevåg,
	Todd Kjos, Martijn Coenen, Christian Brauner, Ingo Molnar,
	Peter Zijlstra, devel, linux-kernel, Joel Fernandes

simplify handle_vsoc_cond_wait (drivers/staging/android/vsoc.c) using newly
added wait_event_freezable_hrtimeout helper and remove duplicate include.

Signed-off-by: Hugo Lefeuvre <hle@owl.eu.com>
---
Changes in v2:
  - Fix removal of necessary linux/freezer.h include.
  - Make commit message more precise about the include removal.

 drivers/staging/android/vsoc.c | 68 +++++-----------------------------
 1 file changed, 10 insertions(+), 58 deletions(-)

diff --git a/drivers/staging/android/vsoc.c b/drivers/staging/android/vsoc.c
index 22571abcaa4e..f2bb18158e5b 100644
--- a/drivers/staging/android/vsoc.c
+++ b/drivers/staging/android/vsoc.c
@@ -29,7 +29,6 @@
 #include <linux/syscalls.h>
 #include <linux/uaccess.h>
 #include <linux/interrupt.h>
-#include <linux/mutex.h>
 #include <linux/cdev.h>
 #include <linux/file.h>
 #include "uapi/vsoc_shm.h"
@@ -401,7 +400,6 @@ static int handle_vsoc_cond_wait(struct file *filp, struct vsoc_cond_wait *arg)
 	DEFINE_WAIT(wait);
 	u32 region_number = iminor(file_inode(filp));
 	struct vsoc_region_data *data = vsoc_dev.regions_data + region_number;
-	struct hrtimer_sleeper timeout, *to = NULL;
 	int ret = 0;
 	struct vsoc_device_region *region_p = vsoc_region_from_filep(filp);
 	atomic_t *address = NULL;
@@ -420,69 +418,23 @@ static int handle_vsoc_cond_wait(struct file *filp, struct vsoc_cond_wait *arg)
 	/* Ensure that the type of wait is valid */
 	switch (arg->wait_type) {
 	case VSOC_WAIT_IF_EQUAL:
+		ret = wait_event_freezable(data->futex_wait_queue,
+					   arg->wakes++ &&
+					   atomic_read(address) != arg->value);
 		break;
 	case VSOC_WAIT_IF_EQUAL_TIMEOUT:
-		to = &timeout;
-		break;
-	default:
-		return -EINVAL;
-	}
-
-	if (to) {
-		/* Copy the user-supplied timesec into the kernel structure.
-		 * We do things this way to flatten differences between 32 bit
-		 * and 64 bit timespecs.
-		 */
 		if (arg->wake_time_nsec >= NSEC_PER_SEC)
 			return -EINVAL;
 		wake_time = ktime_set(arg->wake_time_sec, arg->wake_time_nsec);
-
-		hrtimer_init_on_stack(&to->timer, CLOCK_MONOTONIC,
-				      HRTIMER_MODE_ABS);
-		hrtimer_set_expires_range_ns(&to->timer, wake_time,
-					     current->timer_slack_ns);
-
-		hrtimer_init_sleeper(to, current);
+		ret = wait_event_freezable_hrtimeout(data->futex_wait_queue,
+						     arg->wakes++ &&
+						     atomic_read(address) != arg->value,
+						     wake_time);
+		break;
+	default:
+		return -EINVAL;
 	}
 
-	while (1) {
-		prepare_to_wait(&data->futex_wait_queue, &wait,
-				TASK_INTERRUPTIBLE);
-		/*
-		 * Check the sentinel value after prepare_to_wait. If the value
-		 * changes after this check the writer will call signal,
-		 * changing the task state from INTERRUPTIBLE to RUNNING. That
-		 * will ensure that schedule() will eventually schedule this
-		 * task.
-		 */
-		if (atomic_read(address) != arg->value) {
-			ret = 0;
-			break;
-		}
-		if (to) {
-			hrtimer_start_expires(&to->timer, HRTIMER_MODE_ABS);
-			if (likely(to->task))
-				freezable_schedule();
-			hrtimer_cancel(&to->timer);
-			if (!to->task) {
-				ret = -ETIMEDOUT;
-				break;
-			}
-		} else {
-			freezable_schedule();
-		}
-		/* Count the number of times that we woke up. This is useful
-		 * for unit testing.
-		 */
-		++arg->wakes;
-		if (signal_pending(current)) {
-			ret = -EINTR;
-			break;
-		}
-	}
-	finish_wait(&data->futex_wait_queue, &wait);
-	if (to)
-		destroy_hrtimer_on_stack(&to->timer);
 	return ret;
 }
 
-- 
2.20.1

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 1/2] sched/wait: introduce wait_event_freezable_hrtimeout
  2019-02-07 21:29 ` [PATCH v2 1/2] sched/wait: introduce wait_event_freezable_hrtimeout Hugo Lefeuvre
@ 2019-02-11  7:31   ` Ingo Molnar
  0 siblings, 0 replies; 4+ messages in thread
From: Ingo Molnar @ 2019-02-11  7:31 UTC (permalink / raw)
  To: Hugo Lefeuvre
  Cc: Greg Kroah-Hartman, Greg Hartman, Alistair Strachan,
	Arve Hjønnevåg, Todd Kjos, Martijn Coenen,
	Christian Brauner, Ingo Molnar, Peter Zijlstra, devel,
	linux-kernel, Joel Fernandes


* Hugo Lefeuvre <hle@owl.eu.com> wrote:

> introduce wait_event_freezable_hrtimeout, an interruptible and freezable
> version of wait_event_hrtimeout.
> 
> This helper will allow for simplifications in staging/android/vsoc.c, among
> others.
> 
> Signed-off-by: Hugo Lefeuvre <hle@owl.eu.com>
> ---
> Changes in v2:
>   - No change.
> 
>  include/linux/wait.h | 25 +++++++++++++++++++++----
>  1 file changed, 21 insertions(+), 4 deletions(-)
> 
> diff --git a/include/linux/wait.h b/include/linux/wait.h
> index 5f3efabc36f4..c4cf5113f58a 100644
> --- a/include/linux/wait.h
> +++ b/include/linux/wait.h
> @@ -483,7 +483,7 @@ do {										\
>  	__ret;									\
>  })
>  
> -#define __wait_event_hrtimeout(wq_head, condition, timeout, state)		\
> +#define __wait_event_hrtimeout(wq_head, condition, timeout, state, cmd)		\
>  ({										\
>  	int __ret = 0;								\
>  	struct hrtimer_sleeper __t;						\
> @@ -500,7 +500,7 @@ do {										\
>  			__ret = -ETIME;						\
>  			break;							\
>  		}								\
> -		schedule());							\
> +		cmd);							        \
>  										\
>  	hrtimer_cancel(&__t.timer);						\
>  	destroy_hrtimer_on_stack(&__t.timer);					\
> @@ -529,7 +529,23 @@ do {										\
>  	might_sleep();								\
>  	if (!(condition))							\
>  		__ret = __wait_event_hrtimeout(wq_head, condition, timeout,	\
> -					       TASK_UNINTERRUPTIBLE);		\
> +					       TASK_UNINTERRUPTIBLE,		\
> +					       schedule());			\
> +	__ret;									\
> +})
> +
> +/*
> + * like wait_event_hrtimeout() -- except it uses TASK_INTERRUPTIBLE to avoid
> + * increasing load and is freezable.
> + */
> +#define wait_event_freezable_hrtimeout(wq_head, condition, timeout)		\
> +({										\
> +	int __ret = 0;								\
> +	might_sleep();								\
> +	if (!(condition))							\
> +		__ret = __wait_event_hrtimeout(wq_head, condition, timeout,	\
> +					       TASK_INTERRUPTIBLE,		\
> +					       freezable_schedule());		\
>  	__ret;									\
>  })
>  
> @@ -555,7 +571,8 @@ do {										\
>  	might_sleep();								\
>  	if (!(condition))							\
>  		__ret = __wait_event_hrtimeout(wq, condition, timeout,		\
> -					       TASK_INTERRUPTIBLE);		\
> +					       TASK_INTERRUPTIBLE,		\
> +					       schedule());			\
>  	__ret;									\
>  })

Looks good to me - unless PeterZ objects I suspect this wants to go 
upstream via the driver tree, not the scheduler tree:

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

Thanks,

	Ingo

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-02-11  7:31 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-02-07 21:28 [PATCH v2 0/2] sched/wait, staging/android: simplification of freeze related code Hugo Lefeuvre
2019-02-07 21:29 ` [PATCH v2 1/2] sched/wait: introduce wait_event_freezable_hrtimeout Hugo Lefeuvre
2019-02-11  7:31   ` Ingo Molnar
2019-02-07 21:29 ` [PATCH v2 2/2] staging/android: simplify handle_vsoc_cond_wait Hugo Lefeuvre

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).