Skip to contentSkip to conversation

freezer: reimplement wait_event_freezekillable using freezer_do_not_count/freezer_count()

PATCH Applied Tejun Heo 2 participants 8 messages Nov 3, 2011 – Nov 4, 2011

Subsystems (3)
lore
Share & tools
lore

Tejun Heo

author
#0 lore raw

PATCH 1/2 freezer: reimplement wait_event_freezekillable using freezer_do_not_count/freezer_count()

From: Oleg Nesterov <[email protected]>

Commit 27920651fe "PM / Freezer: Make fake_signal_wake_up() wake TASK_KILLABLE tasks too" updated fake_signal_wake_up() used by freezer to wake up KILLABLE tasks. Sending unsolicited wakeups to tasks in killable sleep is dangerous as there are code paths which depend on tasks not waking up spuriously from KILLABLE sleep.

For example. sys_read() or page can sleep in TASK_KILLABLE assuming that wait/down/whatever _killable can only fail if we can not return to the usermode. TASK_TRACED is another obvious example.

The offending commit was to resolve freezer hang during system PM operations caused by KILLABLE sleeps in network filesystems. wait_event_freezekillable(), which depends on the spurious KILLABLE wakeup, was added by f06ac72e92 "cifs, freezer: add wait_event_freezekillable and have cifs use it" to be used to implement killable & freezable sleeps in network filesystems.

To prepare for reverting of 27920651fe, this patch reimplements wait_event_freezekillable() using freezer_do_not_count/freezer_count() so that it doesn't depend on the spurious KILLABLE wakeup. This isn't very nice but should do for now.

tj: Refreshed patch to apply to linus/master and updated commit
description on Rafael's request.

LKML-Reference: <[email protected]>

---
 include/linux/freezer.h |   11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)
include/linux/freezer.h +3 -8
Index: work/include/linux/freezer.h
===================================================================
@@ -143,14 +143,9 @@ static inline void set_freezable_with_si
 #define wait_event_freezekillable(wq, condition)			\
 ({									\
 	int __retval;							\
-	do {								\
-		__retval = wait_event_killable(wq,			\
-				(condition) || freezing(current));	\
-		if (__retval && !freezing(current))			\
-			break;						\
-		else if (!(condition))					\
-			__retval = -ERESTARTSYS;			\
-	} while (try_to_freeze());					\
+	freezer_do_not_count();						\
+	__retval = wait_event_killable(wq, (condition));		\
+	freezer_count();						\
 	__retval;							\
 })
 
author
#1 lore raw

PATCH 2/2 freezer: revert 27920651fe "PM / Freezer: Make fake_signal_wake_up() wake TASK_KILLABLE tasks too"

Commit 27920651fe "PM / Freezer: Make fake_signal_wake_up() wake TASK_KILLABLE tasks too" updated fake_signal_wake_up() used by freezer to wake up KILLABLE tasks. Sending unsolicited wakeups to tasks in killable sleep is dangerous as there are code paths which depend on tasks not waking up spuriously from KILLABLE sleep.

For example. sys_read() or page can sleep in TASK_KILLABLE assuming that wait/down/whatever _killable can only fail if we can not return to the usermode. TASK_TRACED is another obvious example.

The previous patch updated wait_event_freezekillable() such that it doesn't depend on the spurious wakeup. This patch reverts the offending commit.

Note that the spurious KILLABLE wakeup had other implicit effects in KILLABLE sleeps in nfs and cifs and those will need further updates to regain freezekillable behavior.

LKML-Reference: <[email protected]>
---
This will cause conflict with the pending linux-next patches but the resolution should be trivial. Simply changing @resume from 0 to 1 is enough.

Thanks.

 kernel/freezer.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/freezer.c +1 -1
Index: work/kernel/freezer.c
===================================================================
@@ -67,7 +67,7 @@ static void fake_signal_wake_up(struct t
 	unsigned long flags;
 
 	spin_lock_irqsave(&p->sighand->siglock, flags);
-	signal_wake_up(p, 1);
+	signal_wake_up(p, 0);
 	spin_unlock_irqrestore(&p->sighand->siglock, flags);
 }
 
#7 lore raw
In reply to Tejun Heo
Quoted 24 lines · Tejun Heo

From: Oleg Nesterov <[email protected]>

Commit 27920651fe "PM / Freezer: Make fake_signal_wake_up() wake TASK_KILLABLE tasks too" updated fake_signal_wake_up() used by freezer to wake up KILLABLE tasks. Sending unsolicited wakeups to tasks in killable sleep is dangerous as there are code paths which depend on tasks not waking up spuriously from KILLABLE sleep.

For example. sys_read() or page can sleep in TASK_KILLABLE assuming that wait/down/whatever _killable can only fail if we can not return to the usermode. TASK_TRACED is another obvious example.

The offending commit was to resolve freezer hang during system PM operations caused by KILLABLE sleeps in network filesystems. wait_event_freezekillable(), which depends on the spurious KILLABLE wakeup, was added by f06ac72e92 "cifs, freezer: add wait_event_freezekillable and have cifs use it" to be used to implement killable & freezable sleeps in network filesystems.

To prepare for reverting of 27920651fe, this patch reimplements wait_event_freezekillable() using freezer_do_not_count/freezer_count() so that it doesn't depend on the spurious KILLABLE wakeup. This isn't very nice but should do for now.

Quoted 7 lines

tj: Refreshed patch to apply to linus/master and updated commit
description on Rafael's request.

LKML-Reference: <[email protected]>

Applied to linux-pm/linux-next.

Thanks,
Rafael

Quoted 28 lines
---
 include/linux/freezer.h |   11 +++--------
 1 file changed, 3 insertions(+), 8 deletions(-)

Index: work/include/linux/freezer.h
===================================================================

include/linux/freezer.h +3 -8
@@ -143,14 +143,9 @@ static inline void set_freezable_with_si
 #define wait_event_freezekillable(wq, condition)			\
 ({									\
 	int __retval;							\
-	do {								\
-		__retval = wait_event_killable(wq,			\
-				(condition) || freezing(current));	\
-		if (__retval && !freezing(current))			\
-			break;						\
-		else if (!(condition))					\
-			__retval = -ERESTARTSYS;			\
-	} while (try_to_freeze());					\
+	freezer_do_not_count();						\
+	__retval = wait_event_killable(wq, (condition));		\
+	freezer_count();						\
 	__retval;							\
 })
 
#2 lore raw

Re: [PATCH pm-for-3.2 2/2] freezer: revert 27920651fe "PM / Freezer: Make fake_signal_wake_up() wake TASK_KILLABLE tasks too"

In reply to Tejun Heo
Quoted 14 lines · Tejun Heo

Commit 27920651fe "PM / Freezer: Make fake_signal_wake_up() wake TASK_KILLABLE tasks too" updated fake_signal_wake_up() used by freezer to wake up KILLABLE tasks. Sending unsolicited wakeups to tasks in killable sleep is dangerous as there are code paths which depend on tasks not waking up spuriously from KILLABLE sleep.

For example. sys_read() or page can sleep in TASK_KILLABLE assuming that wait/down/whatever _killable can only fail if we can not return to the usermode. TASK_TRACED is another obvious example.

The previous patch updated wait_event_freezekillable() such that it doesn't depend on the spurious wakeup. This patch reverts the offending commit.

Quoted 7 lines

Note that the spurious KILLABLE wakeup had other implicit effects in KILLABLE sleeps in nfs and cifs and those will need further updates to regain freezekillable behavior.

LKML-Reference: <[email protected]>

Applied to linux-pm/linux-next.

Thanks,
Rafael

Quoted 25 lines

---
This will cause conflict with the pending linux-next patches but the resolution should be trivial. Simply changing @resume from 0 to 1 is enough.

Thanks.

 kernel/freezer.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

Index: work/kernel/freezer.c
===================================================================

kernel/freezer.c +1 -1
@@ -67,7 +67,7 @@ static void fake_signal_wake_up(struct t
 	unsigned long flags;
 
 	spin_lock_irqsave(&p->sighand->siglock, flags);
-	signal_wake_up(p, 1);
+	signal_wake_up(p, 0);
 	spin_unlock_irqrestore(&p->sighand->siglock, flags);
 }
 
author
#3 lore raw

Re: [PATCH pm-for-3.2 2/2] freezer: revert 27920651fe "PM / Freezer: Make fake_signal_wake_up() wake TASK_KILLABLE tasks too"

Hello, Rafael.

Quoted 19 lines · Rafael J. Wysocki
Quoted 18 lines · Tejun Heo

Commit 27920651fe "PM / Freezer: Make fake_signal_wake_up() wake TASK_KILLABLE tasks too" updated fake_signal_wake_up() used by freezer to wake up KILLABLE tasks. Sending unsolicited wakeups to tasks in killable sleep is dangerous as there are code paths which depend on tasks not waking up spuriously from KILLABLE sleep.

For example. sys_read() or page can sleep in TASK_KILLABLE assuming that wait/down/whatever _killable can only fail if we can not return to the usermode. TASK_TRACED is another obvious example.

The previous patch updated wait_event_freezekillable() such that it doesn't depend on the spurious wakeup. This patch reverts the offending commit.

Note that the spurious KILLABLE wakeup had other implicit effects in KILLABLE sleeps in nfs and cifs and those will need further updates to regain freezekillable behavior.

Quoted 5 lines
Quoted 3 lines

LKML-Reference: <[email protected]>

Applied to linux-pm/linux-next.

Just to be sure, as the commit which changed fake_signal_wake_up() to use KILLABLE wakeup is already mainline, these two will have to be pushed as fixes after some time in this devel cycle.

Thanks.

Signature · 1 line
tejun
#4 lore raw

Re: [PATCH pm-for-3.2 2/2] freezer: revert 27920651fe "PM / Freezer: Make fake_signal_wake_up() wake TASK_KILLABLE tasks too"

Quoted 26 lines · Tejun Heo

Hello, Rafael.

Quoted 23 lines · Rafael J. Wysocki
Quoted 21 lines · Tejun Heo

Commit 27920651fe "PM / Freezer: Make fake_signal_wake_up() wake TASK_KILLABLE tasks too" updated fake_signal_wake_up() used by freezer to wake up KILLABLE tasks. Sending unsolicited wakeups to tasks in killable sleep is dangerous as there are code paths which depend on tasks not waking up spuriously from KILLABLE sleep.

For example. sys_read() or page can sleep in TASK_KILLABLE assuming that wait/down/whatever _killable can only fail if we can not return to the usermode. TASK_TRACED is another obvious example.

The previous patch updated wait_event_freezekillable() such that it doesn't depend on the spurious wakeup. This patch reverts the offending commit.

Note that the spurious KILLABLE wakeup had other implicit effects in KILLABLE sleeps in nfs and cifs and those will need further updates to regain freezekillable behavior.

LKML-Reference: <[email protected]>

Quoted 5 lines
Quoted 1 line

Applied to linux-pm/linux-next.

Just to be sure, as the commit which changed fake_signal_wake_up() to use KILLABLE wakeup is already mainline, these two will have to be pushed as fixes after some time in this devel cycle.

Yes, they are 3.2 material and I'm going to push them in the next few days along with a number of other PM-related fixes/cleanups. Is that OK?

Rafael

author
#5 lore raw

Re: [PATCH pm-for-3.2 2/2] freezer: revert 27920651fe "PM / Freezer: Make fake_signal_wake_up() wake TASK_KILLABLE tasks too"

Quoted 6 lines · Rafael J. Wysocki
Quoted 3 lines

Just to be sure, as the commit which changed fake_signal_wake_up() to use KILLABLE wakeup is already mainline, these two will have to be pushed as fixes after some time in this devel cycle.

Yes, they are 3.2 material and I'm going to push them in the next few days along with a number of other PM-related fixes/cleanups. Is that OK?

Yeap, definitely. Just got a bit worried that it was going into linux-next. Thanks. :)

Signature · 1 line
tejun
#6 lore raw

Re: [PATCH pm-for-3.2 2/2] freezer: revert 27920651fe "PM / Freezer: Make fake_signal_wake_up() wake TASK_KILLABLE tasks too"

Quoted 10 lines · Tejun Heo
Quoted 6 lines · Rafael J. Wysocki
Quoted 3 lines

Just to be sure, as the commit which changed fake_signal_wake_up() to use KILLABLE wakeup is already mainline, these two will have to be pushed as fixes after some time in this devel cycle.

Yes, they are 3.2 material and I'm going to push them in the next few days along with a number of other PM-related fixes/cleanups. Is that OK?

Yeap, definitely. Just got a bit worried that it was going into linux-next. Thanks. :)

As long as the merge window is open linux-next contains material for the current development cycle.

Thanks,
Rafael