aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2007-10-18 06:04:45 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-10-18 17:37:19 -0400
commite42837bcd35b75bb59ae5d3e62f87be1aeeb05c3 (patch)
treeaa9666b080dc75ef3fa27992f042a422f7a979b7
parent2e1318956ce6bf149af5c5e98499b5cd99f99c89 (diff)
freezer: introduce freezer-friendly waiting macros
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>
-rw-r--r--drivers/input/gameport/gameport.c3
-rw-r--r--drivers/input/serio/serio.c3
-rw-r--r--drivers/input/touchscreen/ucb1400_ts.c3
-rw-r--r--drivers/media/dvb/dvb-core/dvb_frontend.c3
-rw-r--r--drivers/usb/core/hub.c3
-rw-r--r--drivers/usb/storage/usb.c5
-rw-r--r--include/linux/freezer.h38
7 files changed, 45 insertions, 13 deletions
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index 20896d5e5f0e..ec1b6cfefcd3 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -448,9 +448,8 @@ static int gameport_thread(void *nothing)
448 set_freezable(); 448 set_freezable();
449 do { 449 do {
450 gameport_handle_event(); 450 gameport_handle_event();
451 wait_event_interruptible(gameport_wait, 451 wait_event_freezable(gameport_wait,
452 kthread_should_stop() || !list_empty(&gameport_event_list)); 452 kthread_should_stop() || !list_empty(&gameport_event_list));
453 try_to_freeze();
454 } while (!kthread_should_stop()); 453 } while (!kthread_should_stop());
455 454
456 printk(KERN_DEBUG "gameport: kgameportd exiting\n"); 455 printk(KERN_DEBUG "gameport: kgameportd exiting\n");
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index b3bc15acd3f5..7f5293828fbf 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -387,9 +387,8 @@ static int serio_thread(void *nothing)
387 set_freezable(); 387 set_freezable();
388 do { 388 do {
389 serio_handle_event(); 389 serio_handle_event();
390 wait_event_interruptible(serio_wait, 390 wait_event_freezable(serio_wait,
391 kthread_should_stop() || !list_empty(&serio_event_list)); 391 kthread_should_stop() || !list_empty(&serio_event_list));
392 try_to_freeze();
393 } while (!kthread_should_stop()); 392 } while (!kthread_should_stop());
394 393
395 printk(KERN_DEBUG "serio: kseriod exiting\n"); 394 printk(KERN_DEBUG "serio: kseriod exiting\n");
diff --git a/drivers/input/touchscreen/ucb1400_ts.c b/drivers/input/touchscreen/ucb1400_ts.c
index 86aed64ec0fb..89373b01d8f5 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)
333 timeout = msecs_to_jiffies(10); 333 timeout = msecs_to_jiffies(10);
334 } 334 }
335 335
336 wait_event_interruptible_timeout(ucb->ts_wait, 336 wait_event_freezable_timeout(ucb->ts_wait,
337 ucb->irq_pending || ucb->ts_restart || kthread_should_stop(), 337 ucb->irq_pending || ucb->ts_restart || kthread_should_stop(),
338 timeout); 338 timeout);
339 try_to_freeze();
340 } 339 }
341 340
342 /* Send the "pen off" if we are stopping with the pen still active */ 341 /* 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 b203640ef1c5..445f02665577 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)
527 up(&fepriv->sem); /* is locked when we enter the thread... */ 527 up(&fepriv->sem); /* is locked when we enter the thread... */
528restart: 528restart:
529 timeout = wait_event_interruptible_timeout(fepriv->wait_queue, 529 timeout = wait_event_interruptible_timeout(fepriv->wait_queue,
530 dvb_frontend_should_wakeup(fe) || kthread_should_stop(), 530 dvb_frontend_should_wakeup(fe) || kthread_should_stop()
531 || freezing(current),
531 fepriv->delay); 532 fepriv->delay);
532 533
533 if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) { 534 if (kthread_should_stop() || dvb_frontend_is_exiting(fe)) {
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 60a8f55a0cc7..036c3dea855e 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -2870,10 +2870,9 @@ static int hub_thread(void *__unused)
2870 set_freezable(); 2870 set_freezable();
2871 do { 2871 do {
2872 hub_events(); 2872 hub_events();
2873 wait_event_interruptible(khubd_wait, 2873 wait_event_freezable(khubd_wait,
2874 !list_empty(&hub_event_list) || 2874 !list_empty(&hub_event_list) ||
2875 kthread_should_stop()); 2875 kthread_should_stop());
2876 try_to_freeze();
2877 } while (!kthread_should_stop() || !list_empty(&hub_event_list)); 2876 } while (!kthread_should_stop() || !list_empty(&hub_event_list));
2878 2877
2879 pr_debug("%s: khubd exiting\n", usbcore_name); 2878 pr_debug("%s: khubd exiting\n", usbcore_name);
diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
index 3451e8d03ab0..ac6114eea0c3 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)
907 if (delay_use > 0) { 907 if (delay_use > 0) {
908 printk(KERN_DEBUG "usb-storage: waiting for device " 908 printk(KERN_DEBUG "usb-storage: waiting for device "
909 "to settle before scanning\n"); 909 "to settle before scanning\n");
910retry: 910 wait_event_freezable_timeout(us->delay_wait,
911 wait_event_interruptible_timeout(us->delay_wait,
912 test_bit(US_FLIDX_DISCONNECTING, &us->flags), 911 test_bit(US_FLIDX_DISCONNECTING, &us->flags),
913 delay_use * HZ); 912 delay_use * HZ);
914 if (try_to_freeze())
915 goto retry;
916 } 913 }
917 914
918 /* If the device is still connected, perform the scanning */ 915 /* If the device is still connected, perform the scanning */
diff --git a/include/linux/freezer.h b/include/linux/freezer.h
index efded00ad08c..08934995c7ab 100644
--- a/include/linux/freezer.h
+++ b/include/linux/freezer.h
@@ -4,6 +4,7 @@
4#define FREEZER_H_INCLUDED 4#define FREEZER_H_INCLUDED
5 5
6#include <linux/sched.h> 6#include <linux/sched.h>
7#include <linux/wait.h>
7 8
8#ifdef CONFIG_PM_SLEEP 9#ifdef CONFIG_PM_SLEEP
9/* 10/*
@@ -126,6 +127,36 @@ static inline void set_freezable(void)
126 current->flags &= ~PF_NOFREEZE; 127 current->flags &= ~PF_NOFREEZE;
127} 128}
128 129
130/*
131 * Freezer-friendly wrappers around wait_event_interruptible() and
132 * wait_event_interruptible_timeout(), originally defined in <linux/wait.h>
133 */
134
135#define wait_event_freezable(wq, condition) \
136({ \
137 int __retval; \
138 do { \
139 __retval = wait_event_interruptible(wq, \
140 (condition) || freezing(current)); \
141 if (__retval && !freezing(current)) \
142 break; \
143 else if (!(condition)) \
144 __retval = -ERESTARTSYS; \
145 } while (try_to_freeze()); \
146 __retval; \
147})
148
149
150#define wait_event_freezable_timeout(wq, condition, timeout) \
151({ \
152 long __retval = timeout; \
153 do { \
154 __retval = wait_event_interruptible_timeout(wq, \
155 (condition) || freezing(current), \
156 __retval); \
157 } while (try_to_freeze()); \
158 __retval; \
159})
129#else /* !CONFIG_PM_SLEEP */ 160#else /* !CONFIG_PM_SLEEP */
130static inline int frozen(struct task_struct *p) { return 0; } 161static inline int frozen(struct task_struct *p) { return 0; }
131static inline int freezing(struct task_struct *p) { return 0; } 162static inline int freezing(struct task_struct *p) { return 0; }
@@ -143,6 +174,13 @@ static inline void freezer_do_not_count(void) {}
143static inline void freezer_count(void) {} 174static inline void freezer_count(void) {}
144static inline int freezer_should_skip(struct task_struct *p) { return 0; } 175static inline int freezer_should_skip(struct task_struct *p) { return 0; }
145static inline void set_freezable(void) {} 176static inline void set_freezable(void) {}
177
178#define wait_event_freezable(wq, condition) \
179 wait_event_interruptible(wq, condition)
180
181#define wait_event_freezable_timeout(wq, condition, timeout) \
182 wait_event_interruptible_timeout(wq, condition, timeout)
183
146#endif /* !CONFIG_PM_SLEEP */ 184#endif /* !CONFIG_PM_SLEEP */
147 185
148#endif /* FREEZER_H_INCLUDED */ 186#endif /* FREEZER_H_INCLUDED */