freezer: reimplement wait_event_freezekillable using freezer_do_not_count/freezer_count()
Subsystems (3)
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
@@ -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; \ })
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
@@ -67,7 +67,7 @@ static void fake_signal_wake_up(struct tunsigned 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); }
Rafael J. Wysocki
AppliedRe: [PATCH pm-for-3.2 2/2] freezer: revert 27920651fe "PM / Freezer: Make fake_signal_wake_up() wake TASK_KILLABLE tasks too"
Quoted 14 lines · Tejun Heo
Commit
27920651fe"PM / Freezer: Makefake_signal_wake_up()wakeTASK_KILLABLEtasks too" updatedfake_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 inTASK_KILLABLEassuming that wait/down/whatever_killablecan only fail if we can not return to the usermode.TASK_TRACEDis 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.
Signed-off-by Tejun Heo <[email protected]>Cc Jeff Layton <[email protected]>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 tunsigned 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); }
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: Makefake_signal_wake_up()wakeTASK_KILLABLEtasks too" updatedfake_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 inTASK_KILLABLEassuming that wait/down/whatever_killablecan only fail if we can not return to the usermode.TASK_TRACEDis 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
Signed-off-by Tejun Heo <[email protected]>Cc Jeff Layton <[email protected]>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
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: Makefake_signal_wake_up()wakeTASK_KILLABLEtasks too" updatedfake_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 inTASK_KILLABLEassuming that wait/down/whatever_killablecan only fail if we can not return to the usermode.TASK_TRACEDis 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.
Signed-off-by Tejun Heo <[email protected]>Cc Jeff Layton <[email protected]>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
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
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
Rafael J. Wysocki
AppliedQuoted 24 lines · Tejun Heo
From: Oleg Nesterov <[email protected]>
Commit
27920651fe"PM / Freezer: Makefake_signal_wake_up()wakeTASK_KILLABLEtasks too" updatedfake_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 inTASK_KILLABLEassuming that wait/down/whatever_killablecan only fail if we can not return to the usermode.TASK_TRACEDis 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 byf06ac72e92"cifs, freezer: addwait_event_freezekillableand have cifs use it" to be used to implement killable & freezable sleeps in network filesystems.To prepare for reverting of
27920651fe, this patch reimplementswait_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.Signed-off-by Oleg Nesterov <[email protected]>Signed-off-by Tejun Heo <[email protected]>Cc Jeff Layton <[email protected]>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; \ })