introduce wait_event_freezable_hrtimeout, an interruptible and freezable
version of wait_event_hrtimeout.

simplify handle_vsoc_cond_wait (drivers/staging/android/vsoc.c) using this
newly added helper and remove useless includes.

Signed-off-by: Hugo Lefeuvre <h...@owl.eu.com>
---
 drivers/staging/android/vsoc.c | 69 +++++-----------------------------
 include/linux/wait.h           | 25 ++++++++++--
 2 files changed, 31 insertions(+), 63 deletions(-)

diff --git a/drivers/staging/android/vsoc.c b/drivers/staging/android/vsoc.c
index 22571abcaa4e..7e620e69f39d 100644
--- a/drivers/staging/android/vsoc.c
+++ b/drivers/staging/android/vsoc.c
@@ -17,7 +17,6 @@
  */
 
 #include <linux/dma-mapping.h>
-#include <linux/freezer.h>
 #include <linux/futex.h>
 #include <linux/init.h>
 #include <linux/kernel.h>
@@ -29,7 +28,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 +399,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 +417,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;
 }
 
diff --git a/include/linux/wait.h b/include/linux/wait.h
index ed7c122cb31f..13a454884f8b 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

Attachment: signature.asc
Description: PGP signature

_______________________________________________
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

Reply via email to