From 4ab75f217f7fc28ff0f43c0b898f1bceec697fa0 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 18 Oct 2007 03:04:45 -0700 Subject: [PATCH] freezer: introduce freezer-friendly waiting macros Introduce freezer-friendly wrappers around wait_event_interruptible() and wait_event_interruptible_timeout(), originally defined in , 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 Acked-by: Pavel Machek Cc: Nigel Cunningham Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- drivers/input/gameport/gameport.c | 3 +- drivers/input/serio/serio.c | 3 +- drivers/input/touchscreen/ucb1400_ts.c | 3 +- drivers/media/dvb/dvb-core/dvb_frontend.c | 3 +- drivers/usb/core/hub.c | 3 +- drivers/usb/storage/usb.c | 5 +-- include/linux/freezer.h | 38 +++++++++++++++++++++++ 7 files changed, 45 insertions(+), 13 deletions(-) diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index 20896d5e5f0e6..ec1b6cfefcd32 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c @@ -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"); diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index b3bc15acd3f56..7f5293828fbff 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c @@ -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"); diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c index 86aed64ec0fb9..89373b01d8f56 100644 --- a/drivers/input/touchscreen/ucb1400_ts.c +++ b/drivers/input/touchscreen/ucb1400_ts.c @@ -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 */ diff --git a/drivers/media/dvb/dvb-core/dvb_frontend.c b/drivers/media/dvb/dvb-core/dvb_frontend.c index b203640ef1c58..445f026655775 100644 --- a/drivers/media/dvb/dvb-core/dvb_frontend.c +++ b/drivers/media/dvb/dvb-core/dvb_frontend.c @@ -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)) { diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 60a8f55a0cc7d..036c3dea855e6 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -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); diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index 3451e8d03ab0e..ac6114eea0c30 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -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 */ diff --git a/include/linux/freezer.h b/include/linux/freezer.h index efded00ad08c5..08934995c7ab5 100644 --- a/include/linux/freezer.h +++ b/include/linux/freezer.h @@ -4,6 +4,7 @@ #define FREEZER_H_INCLUDED #include +#include #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 + */ + +#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 */ -- 2.39.5