From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: linux-pm@lists.linux-foundation.org
Cc: Matthew Garrett <mjg59@srcf.ucam.org>,
Miklos Szeredi <miklos@szeredi.hu>,
Mauro Carvalho Chehab <mchehab@infradead.org>,
Pavel Machek <pavel@ucw.cz>, Oleg Nesterov <oleg@tv-sign.ru>
Subject: [RFC][PATCH -mm 4/7] Freezer: Introduce freezer-firendly waiting macros (updated 2x)
Date: Thu, 12 Jul 2007 14:23:37 +0200 [thread overview]
Message-ID: <200707121423.38527.rjw@sisk.pl> (raw)
In-Reply-To: <200707121230.52060.rjw@sisk.pl>
On Thursday, 12 July 2007 12:30, Rafael J. Wysocki wrote:
> On Thursday, 12 July 2007 01:02, Oleg Nesterov wrote:
> > On 07/12, Rafael J. Wysocki wrote:
> > >
> > > +#define wait_event_freezable(wq, condition) \
> > > +({ \
> > > + int __ret; \
> > > + do { \
> > > + __ret = wait_event_interruptible(wq, \
> > > + (condition) || freezing(current)); \
> > > + try_to_freeze(); \
> > > + } while (!(condition)); \
> > > + __ret; \
> > > +})
> >
> > This is still not right in general, I believe.
> >
> > It will spin if the caller is signalled. You changed the freezer, but
> > kthread can use signals anyway.
> >
> > It returns only when "condition" is true, so the "__ret" is meaningless.
>
> Yes, this is a mistake. The second one is also wrong. :-(
>
> Please see the fixed patch below.
Ugh, there still is a mistake in there, sorry.
[--snip--]
> +
> +#define wait_event_freezable(wq, condition) \
> +({ \
> + int __ret; \
> + do { \
> + __ret = wait_event_interruptible(wq, \
> + (condition) || freezing(current)); \
> + if (!__ret && !freezing(current)) \
There should be (__ret && !freezing(current)) here (ie. if we've been woken up
by a signal and this is not the freezing signal, break out of the loop.
Below is the corrected version.
Greetings,
Rafael
---
From: Rafael J. Wysocki <rjw@sisk.pl>
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>
---
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 | 42 ++++++++++++++++++++++++++++--
7 files changed, 47 insertions(+), 15 deletions(-)
Index: linux-2.6.22-rc6-mm1/include/linux/freezer.h
===================================================================
--- linux-2.6.22-rc6-mm1.orig/include/linux/freezer.h
+++ linux-2.6.22-rc6-mm1/include/linux/freezer.h
@@ -4,6 +4,7 @@
#define FREEZER_H_INCLUDED
#include <linux/sched.h>
+#include <linux/wait.h>
#ifdef CONFIG_PM
/*
@@ -126,7 +127,37 @@ static inline void set_freezable(void)
current->flags &= ~PF_NOFREEZE;
}
-#else
+/*
+ * 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 __ret; \
+ do { \
+ __ret = wait_event_interruptible(wq, \
+ (condition) || freezing(current)); \
+ if (__ret && !freezing(current)) \
+ break; \
+ else if (!(condition)) \
+ __ret = -ERESTARTSYS; \
+ } while (try_to_freeze()); \
+ __ret; \
+})
+
+
+#define wait_event_freezable_timeout(wq, condition, timeout) \
+({ \
+ long __ret = timeout; \
+ do { \
+ __ret = wait_event_interruptible_timeout(wq, \
+ (condition) || freezing(current), \
+ __ret); \
+ } while (try_to_freeze()); \
+ __ret; \
+})
+#else /* CONFIG_PM */
static inline int frozen(struct task_struct *p) { return 0; }
static inline int freezing(struct task_struct *p) { return 0; }
static inline void set_freeze_flag(struct task_struct *p) {}
@@ -143,6 +174,13 @@ static inline void freezer_do_not_count(
static inline void freezer_count(void) {}
static inline int freezer_should_skip(struct task_struct *p) { return 0; }
static inline void set_freezable(void) {}
-#endif
+
+#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 */
#endif /* FREEZER_H_INCLUDED */
Index: linux-2.6.22-rc6-mm1/drivers/input/gameport/gameport.c
===================================================================
--- linux-2.6.22-rc6-mm1.orig/drivers/input/gameport/gameport.c
+++ linux-2.6.22-rc6-mm1/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");
Index: linux-2.6.22-rc6-mm1/drivers/input/serio/serio.c
===================================================================
--- linux-2.6.22-rc6-mm1.orig/drivers/input/serio/serio.c
+++ linux-2.6.22-rc6-mm1/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");
Index: linux-2.6.22-rc6-mm1/drivers/input/touchscreen/ucb1400_ts.c
===================================================================
--- linux-2.6.22-rc6-mm1.orig/drivers/input/touchscreen/ucb1400_ts.c
+++ linux-2.6.22-rc6-mm1/drivers/input/touchscreen/ucb1400_ts.c
@@ -334,10 +334,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: linux-2.6.22-rc6-mm1/drivers/media/dvb/dvb-core/dvb_frontend.c
===================================================================
--- linux-2.6.22-rc6-mm1.orig/drivers/media/dvb/dvb-core/dvb_frontend.c
+++ linux-2.6.22-rc6-mm1/drivers/media/dvb/dvb-core/dvb_frontend.c
@@ -528,7 +528,8 @@ static int dvb_frontend_thread(void *dat
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: linux-2.6.22-rc6-mm1/drivers/usb/core/hub.c
===================================================================
--- linux-2.6.22-rc6-mm1.orig/drivers/usb/core/hub.c
+++ linux-2.6.22-rc6-mm1/drivers/usb/core/hub.c
@@ -2729,10 +2729,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: linux-2.6.22-rc6-mm1/drivers/usb/storage/usb.c
===================================================================
--- linux-2.6.22-rc6-mm1.orig/drivers/usb/storage/usb.c
+++ linux-2.6.22-rc6-mm1/drivers/usb/storage/usb.c
@@ -913,12 +913,9 @@ static int usb_stor_scan_thread(void * _
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 */
next prev parent reply other threads:[~2007-07-12 12:23 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-07-11 22:06 [RFC][PATCH -mm 0/7] Freezer update (updated) Rafael J. Wysocki
2007-07-11 22:08 ` [RFC][PATCH -mm 1/7] Freezer: Document relationship with memory shrinking Rafael J. Wysocki
2007-07-11 22:10 ` [RFC][PATCH -mm 2/7] Freezer: Do not sync filesystems from freeze_processes Rafael J. Wysocki
2007-07-11 22:42 ` Pavel Machek
2007-07-11 22:12 ` [RFC][PATCH -mm 3/7] Freezer: Prevent new tasks from inheriting TIF_FREEZE set Rafael J. Wysocki
2007-07-11 22:25 ` Nigel Cunningham
2007-07-11 22:13 ` [RFC][PATCH -mm 4/7] Freezer: Introduce freezer-firendly waiting macros Rafael J. Wysocki
2007-07-11 22:56 ` Pavel Machek
2007-07-12 10:33 ` Rafael J. Wysocki
2007-07-11 23:02 ` Oleg Nesterov
2007-07-12 10:30 ` [RFC][PATCH -mm 4/7] Freezer: Introduce freezer-firendly waiting macros (updated) Rafael J. Wysocki
2007-07-12 12:23 ` Rafael J. Wysocki [this message]
2007-07-11 22:14 ` [RFC][PATCH -mm 5/7] Freezer: Do not send signals to kernel threads (updated) Rafael J. Wysocki
2007-07-11 22:16 ` [RFC][PATCH -mm 6/7] Freezer: Be more verbose Rafael J. Wysocki
2007-07-11 22:58 ` Pavel Machek
2007-07-12 10:39 ` [RFC][PATCH -mm 6/7] Freezer: Be more verbose (updated) Rafael J. Wysocki
2007-07-11 22:17 ` [RFC][PATCH -mm 7/7] Freezer: Use freezing timeout more efficiently Rafael J. Wysocki
2007-07-12 10:38 ` [RFC][PATCH -mm 7/7] Freezer: Use freezing timeout more efficiently (updated) Rafael J. Wysocki
2007-07-13 23:43 ` [RFC][PATCH -mm 7/7] Freezer: Use freezing timeout more efficiently Pavel Machek
2007-07-14 9:20 ` Rafael J. Wysocki
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200707121423.38527.rjw@sisk.pl \
--to=rjw@sisk.pl \
--cc=linux-pm@lists.linux-foundation.org \
--cc=mchehab@infradead.org \
--cc=miklos@szeredi.hu \
--cc=mjg59@srcf.ucam.org \
--cc=oleg@tv-sign.ru \
--cc=pavel@ucw.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox