freezer: introduce freezer-friendly waiting macros
authorRafael J. Wysocki <rjw@sisk.pl>
Thu, 18 Oct 2007 10:04:45 +0000 (03:04 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Thu, 18 Oct 2007 21:37:19 +0000 (14:37 -0700)
Introduce freezer-friendly wrappers around wait_event_interruptible() and
wait_event_interruptible_timeout(), originally defined in <linux/wait.h>, to
be used in freezable kernel threads.  Make some of the freezable kernel
threads use them.

This is necessary for the freezer to stop sending signals to kernel threads,
which is implemented in the next patch.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Acked-by: Pavel Machek <pavel@ucw.cz>
Cc: Nigel Cunningham <nigel@nigel.suspend2.net>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/input/gameport/gameport.c
drivers/input/serio/serio.c
drivers/input/touchscreen/ucb1400_ts.c
drivers/media/dvb/dvb-core/dvb_frontend.c
drivers/usb/core/hub.c
drivers/usb/storage/usb.c
include/linux/freezer.h

index 20896d5..ec1b6cf 100644 (file)
@@ -448,9 +448,8 @@ static int gameport_thread(void *nothing)
        set_freezable();
        do {
                gameport_handle_event();
-               wait_event_interruptible(gameport_wait,
+               wait_event_freezable(gameport_wait,
                        kthread_should_stop() || !list_empty(&gameport_event_list));
-               try_to_freeze();
        } while (!kthread_should_stop());
 
        printk(KERN_DEBUG "gameport: kgameportd exiting\n");
index b3bc15a..7f52938 100644 (file)
@@ -387,9 +387,8 @@ static int serio_thread(void *nothing)
        set_freezable();
        do {
                serio_handle_event();
-               wait_event_interruptible(serio_wait,
+               wait_event_freezable(serio_wait,
                        kthread_should_stop() || !list_empty(&serio_event_list));
-               try_to_freeze();
        } while (!kthread_should_stop());
 
        printk(KERN_DEBUG "serio: kseriod exiting\n");
index 86aed64..89373b0 100644 (file)
@@ -333,10 +333,9 @@ static int ucb1400_ts_thread(void *_ucb)
                        timeout = msecs_to_jiffies(10);
                }
 
-               wait_event_interruptible_timeout(ucb->ts_wait,
+               wait_event_freezable_timeout(ucb->ts_wait,
                        ucb->irq_pending || ucb->ts_restart || kthread_should_stop(),
                        timeout);
-               try_to_freeze();
        }
 
        /* Send the "pen off" if we are stopping with the pen still active */
index b203640..445f026 100644 (file)
@@ -527,7 +527,8 @@ static int dvb_frontend_thread(void *data)
                up(&fepriv->sem);           /* is locked when we enter the thread... */
 restart:
                timeout = wait_event_interruptible_timeout(fepriv->wait_queue,
-                       dvb_frontend_should_wakeup(fe) || kthread_should_stop(),
+                       dvb_frontend_should_wakeup(fe) || kthread_should_stop()
+                               || freezing(current),
                        fepriv->delay);
 
                if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) {
index 60a8f55..036c3de 100644 (file)
@@ -2870,10 +2870,9 @@ static int hub_thread(void *__unused)
        set_freezable();
        do {
                hub_events();
-               wait_event_interruptible(khubd_wait,
+               wait_event_freezable(khubd_wait,
                                !list_empty(&hub_event_list) ||
                                kthread_should_stop());
-               try_to_freeze();
        } while (!kthread_should_stop() || !list_empty(&hub_event_list));
 
        pr_debug("%s: khubd exiting\n", usbcore_name);
index 3451e8d..ac6114e 100644 (file)
@@ -907,12 +907,9 @@ static int usb_stor_scan_thread(void * __us)
        if (delay_use > 0) {
                printk(KERN_DEBUG "usb-storage: waiting for device "
                                "to settle before scanning\n");
-retry:
-               wait_event_interruptible_timeout(us->delay_wait,
+               wait_event_freezable_timeout(us->delay_wait,
                                test_bit(US_FLIDX_DISCONNECTING, &us->flags),
                                delay_use * HZ);
-               if (try_to_freeze())
-                       goto retry;
        }
 
        /* If the device is still connected, perform the scanning */
index efded00..0893499 100644 (file)
@@ -4,6 +4,7 @@
 #define FREEZER_H_INCLUDED
 
 #include <linux/sched.h>
+#include <linux/wait.h>
 
 #ifdef CONFIG_PM_SLEEP
 /*
@@ -126,6 +127,36 @@ static inline void set_freezable(void)
        current->flags &= ~PF_NOFREEZE;
 }
 
+/*
+ * Freezer-friendly wrappers around wait_event_interruptible() and
+ * wait_event_interruptible_timeout(), originally defined in <linux/wait.h>
+ */
+
+#define wait_event_freezable(wq, condition)                            \
+({                                                                     \
+       int __retval;                                                   \
+       do {                                                            \
+               __retval = wait_event_interruptible(wq,                 \
+                               (condition) || freezing(current));      \
+               if (__retval && !freezing(current))                     \
+                       break;                                          \
+               else if (!(condition))                                  \
+                       __retval = -ERESTARTSYS;                        \
+       } while (try_to_freeze());                                      \
+       __retval;                                                       \
+})
+
+
+#define wait_event_freezable_timeout(wq, condition, timeout)           \
+({                                                                     \
+       long __retval = timeout;                                        \
+       do {                                                            \
+               __retval = wait_event_interruptible_timeout(wq,         \
+                               (condition) || freezing(current),       \
+                               __retval);                              \
+       } while (try_to_freeze());                                      \
+       __retval;                                                       \
+})
 #else /* !CONFIG_PM_SLEEP */
 static inline int frozen(struct task_struct *p) { return 0; }
 static inline int freezing(struct task_struct *p) { return 0; }
@@ -143,6 +174,13 @@ static inline void freezer_do_not_count(void) {}
 static inline void freezer_count(void) {}
 static inline int freezer_should_skip(struct task_struct *p) { return 0; }
 static inline void set_freezable(void) {}
+
+#define wait_event_freezable(wq, condition)                            \
+               wait_event_interruptible(wq, condition)
+
+#define wait_event_freezable_timeout(wq, condition, timeout)           \
+               wait_event_interruptible_timeout(wq, condition, timeout)
+
 #endif /* !CONFIG_PM_SLEEP */
 
 #endif /* FREEZER_H_INCLUDED */