Skip to content

Commit

Permalink
freezer: introduce freezer-friendly waiting macros
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Rafael J. Wysocki authored and Linus Torvalds committed Oct 18, 2007
1 parent 2e13189 commit e42837b
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 13 deletions.
3 changes: 1 addition & 2 deletions drivers/input/gameport/gameport.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
3 changes: 1 addition & 2 deletions drivers/input/serio/serio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
3 changes: 1 addition & 2 deletions drivers/input/touchscreen/ucb1400_ts.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
3 changes: 2 additions & 1 deletion drivers/media/dvb/dvb-core/dvb_frontend.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
3 changes: 1 addition & 2 deletions drivers/usb/core/hub.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 1 addition & 4 deletions drivers/usb/storage/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
38 changes: 38 additions & 0 deletions include/linux/freezer.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#define FREEZER_H_INCLUDED

#include <linux/sched.h>
#include <linux/wait.h>

#ifdef CONFIG_PM_SLEEP
/*
Expand Down Expand Up @@ -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; }
Expand All @@ -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 */

0 comments on commit e42837b

Please sign in to comment.