diff mbox

[1/3] PM suspend/hibernate: Call notifier after freezing processes

Message ID 1428254419-7334-2-git-send-email-pali.rohar@gmail.com (mailing list archive)
State RFC, archived
Headers show

Commit Message

Pali Rohár April 5, 2015, 5:20 p.m. UTC
To prevent race conditions on userspace processes with I/O some taks must be
called after processes are freezed. This patch adds new events which are
delivered by pm_notifier_call_chain() after freezing processes when doing
suspend or hibernate action.

Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
---
 include/linux/suspend.h  |    2 ++
 kernel/power/hibernate.c |    2 ++
 kernel/power/suspend.c   |    4 +++-
 3 files changed, 7 insertions(+), 1 deletion(-)

Comments

Rafael J. Wysocki April 9, 2015, 12:28 a.m. UTC | #1
On Sunday, April 05, 2015 07:20:17 PM Pali Rohár wrote:
> To prevent race conditions on userspace processes with I/O some taks must be
> called after processes are freezed. This patch adds new events which are
> delivered by pm_notifier_call_chain() after freezing processes when doing
> suspend or hibernate action.
> 
> Signed-off-by: Pali Rohár <pali.rohar@gmail.com>

Please don't add more notifiers.  Just call whatever you need directly from
where you need to call that.

If that is device-related, try to use device PM suspend/hibernate callbacks
instead.

> ---
>  include/linux/suspend.h  |    2 ++
>  kernel/power/hibernate.c |    2 ++
>  kernel/power/suspend.c   |    4 +++-
>  3 files changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/include/linux/suspend.h b/include/linux/suspend.h
> index 5efe743..bc743c8 100644
> --- a/include/linux/suspend.h
> +++ b/include/linux/suspend.h
> @@ -368,6 +368,8 @@ static inline bool hibernation_available(void) { return false; }
>  #define PM_POST_SUSPEND		0x0004 /* Suspend finished */
>  #define PM_RESTORE_PREPARE	0x0005 /* Going to restore a saved image */
>  #define PM_POST_RESTORE		0x0006 /* Restore failed */
> +#define PM_HIBERNATION_AFTER_FREEZE	0x0007 /* After hibernation freeze */
> +#define PM_SUSPEND_AFTER_FREEZE		0x0008 /* After suspend freeze */
>  
>  extern struct mutex pm_mutex;
>  
> diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
> index 2329daa..184f7ee 100644
> --- a/kernel/power/hibernate.c
> +++ b/kernel/power/hibernate.c
> @@ -671,6 +671,8 @@ int hibernate(void)
>  	if (error)
>  		goto Exit;
>  
> +	pm_notifier_call_chain(PM_HIBERNATION_AFTER_FREEZE);
> +
>  	lock_device_hotplug();
>  	/* Allocate memory management structures */
>  	error = create_basic_memory_bitmaps();
> diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
> index b7d6b3a..1776938 100644
> --- a/kernel/power/suspend.c
> +++ b/kernel/power/suspend.c
> @@ -268,8 +268,10 @@ static int suspend_prepare(suspend_state_t state)
>  	trace_suspend_resume(TPS("freeze_processes"), 0, true);
>  	error = suspend_freeze_processes();
>  	trace_suspend_resume(TPS("freeze_processes"), 0, false);
> -	if (!error)
> +	if (!error) {
> +		pm_notifier_call_chain(PM_SUSPEND_AFTER_FREEZE);
>  		return 0;
> +	}
>  
>  	suspend_stats.failed_freeze++;
>  	dpm_save_failed_step(SUSPEND_FREEZE);
>
Pali Rohár April 9, 2015, 6:36 a.m. UTC | #2
On Thursday 09 April 2015 02:28:41 Rafael J. Wysocki wrote:
> On Sunday, April 05, 2015 07:20:17 PM Pali Rohár wrote:
> > To prevent race conditions on userspace processes with I/O
> > some taks must be called after processes are freezed. This
> > patch adds new events which are delivered by
> > pm_notifier_call_chain() after freezing processes when
> > doing suspend or hibernate action.
> > 
> > Signed-off-by: Pali Rohár <pali.rohar@gmail.com>
> 
> Please don't add more notifiers.  Just call whatever you need
> directly from where you need to call that.
> 
> If that is device-related, try to use device PM
> suspend/hibernate callbacks instead.
> 

Hi! It is not possible to use any exiting pm notifiers! This is 
reason why I added new ones. As I wrote wiping dm crypt keys must 
be done *after* userspace processes are freezed to prevent race 
conditions...

> > ---
> > 
> >  include/linux/suspend.h  |    2 ++
> >  kernel/power/hibernate.c |    2 ++
> >  kernel/power/suspend.c   |    4 +++-
> >  3 files changed, 7 insertions(+), 1 deletion(-)
> > 
> > diff --git a/include/linux/suspend.h
> > b/include/linux/suspend.h index 5efe743..bc743c8 100644
> > --- a/include/linux/suspend.h
> > +++ b/include/linux/suspend.h
> > @@ -368,6 +368,8 @@ static inline bool
> > hibernation_available(void) { return false; }
> > 
> >  #define PM_POST_SUSPEND		0x0004 /* Suspend finished */
> >  #define PM_RESTORE_PREPARE	0x0005 /* Going to restore a
> >  saved image */ #define PM_POST_RESTORE		0x0006 /*
> >  Restore
> >  failed */
> > 
> > +#define PM_HIBERNATION_AFTER_FREEZE	0x0007 /* After
> > hibernation freeze */ +#define
> > PM_SUSPEND_AFTER_FREEZE		0x0008 /* After suspend freeze */
> > 
> >  extern struct mutex pm_mutex;
> > 
> > diff --git a/kernel/power/hibernate.c
> > b/kernel/power/hibernate.c index 2329daa..184f7ee 100644
> > --- a/kernel/power/hibernate.c
> > +++ b/kernel/power/hibernate.c
> > @@ -671,6 +671,8 @@ int hibernate(void)
> > 
> >  	if (error)
> >  	
> >  		goto Exit;
> > 
> > +	pm_notifier_call_chain(PM_HIBERNATION_AFTER_FREEZE);
> > +
> > 
> >  	lock_device_hotplug();
> >  	/* Allocate memory management structures */
> >  	error = create_basic_memory_bitmaps();
> > 
> > diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
> > index b7d6b3a..1776938 100644
> > --- a/kernel/power/suspend.c
> > +++ b/kernel/power/suspend.c
> > @@ -268,8 +268,10 @@ static int
> > suspend_prepare(suspend_state_t state)
> > 
> >  	trace_suspend_resume(TPS("freeze_processes"), 0, true);
> >  	error = suspend_freeze_processes();
> >  	trace_suspend_resume(TPS("freeze_processes"), 0, false);
> > 
> > -	if (!error)
> > +	if (!error) {
> > +		pm_notifier_call_chain(PM_SUSPEND_AFTER_FREEZE);
> > 
> >  		return 0;
> > 
> > +	}
> > 
> >  	suspend_stats.failed_freeze++;
> >  	dpm_save_failed_step(SUSPEND_FREEZE);
Pali Rohár April 9, 2015, 4:55 p.m. UTC | #3
On Thursday 09 April 2015 19:13:55 Rafael J. Wysocki wrote:
> On Thursday, April 09, 2015 08:36:57 AM Pali Rohár wrote:
> > --nextPart2566388.gOmNIJrIqI
> > Content-Type: Text/Plain;
> > 
> >   charset="utf-8"
> > 
> > Content-Transfer-Encoding: quoted-printable
> > 
> > On Thursday 09 April 2015 02:28:41 Rafael J. Wysocki wrote:
> > > On Sunday, April 05, 2015 07:20:17 PM Pali Roh=C3=A1r
> > > wrote:
> > > > To prevent race conditions on userspace processes with
> > > > I/O some taks must be called after processes are
> > > > freezed. This patch adds new events which are delivered
> > > > by
> > > > pm_notifier_call_chain() after freezing processes when
> > > > doing suspend or hibernate action.
> > > >
> > > >=20
> > > >
> > > > Signed-off-by: Pali Roh=C3=A1r <pali.rohar@gmail.com>
> > >
> > >=20
> > >
> > > Please don't add more notifiers.  Just call whatever you
> > > need directly from where you need to call that.
> > >
> > >=20
> > >
> > > If that is device-related, try to use device PM
> > > suspend/hibernate callbacks instead.
> > >
> > >=20
> > 
> > Hi! It is not possible to use any exiting pm notifiers! This
> > is=20 reason why I added new ones. As I wrote wiping dm
> > crypt keys must=20 be done *after* userspace processes are
> > freezed to prevent race=20 conditions...
> 
> I'm not talking about using the existing notifiers.  I'm
> talking about calling the function you need to call directly
> from a suitable place in the system suspend code.

I need to wipe crypto keys from dm-crypt module. That module can 
be compiled as external .ko file and so kernel cannot call 
directly needed function. This is reason why I'm adding new 
notifier event.
Rafael J. Wysocki April 9, 2015, 5:13 p.m. UTC | #4
On Thursday, April 09, 2015 08:36:57 AM Pali Rohár wrote:
> 
> --nextPart2566388.gOmNIJrIqI
> Content-Type: Text/Plain;
>   charset="utf-8"
> Content-Transfer-Encoding: quoted-printable
> 
> On Thursday 09 April 2015 02:28:41 Rafael J. Wysocki wrote:
> > On Sunday, April 05, 2015 07:20:17 PM Pali Roh=C3=A1r wrote:
> > > To prevent race conditions on userspace processes with I/O
> > > some taks must be called after processes are freezed. This
> > > patch adds new events which are delivered by
> > > pm_notifier_call_chain() after freezing processes when
> > > doing suspend or hibernate action.
> > >=20
> > > Signed-off-by: Pali Roh=C3=A1r <pali.rohar@gmail.com>
> >=20
> > Please don't add more notifiers.  Just call whatever you need
> > directly from where you need to call that.
> >=20
> > If that is device-related, try to use device PM
> > suspend/hibernate callbacks instead.
> >=20
> 
> Hi! It is not possible to use any exiting pm notifiers! This is=20
> reason why I added new ones. As I wrote wiping dm crypt keys must=20
> be done *after* userspace processes are freezed to prevent race=20
> conditions...

I'm not talking about using the existing notifiers.  I'm talking about
calling the function you need to call directly from a suitable place
in the system suspend code.
diff mbox

Patch

diff --git a/include/linux/suspend.h b/include/linux/suspend.h
index 5efe743..bc743c8 100644
--- a/include/linux/suspend.h
+++ b/include/linux/suspend.h
@@ -368,6 +368,8 @@  static inline bool hibernation_available(void) { return false; }
 #define PM_POST_SUSPEND		0x0004 /* Suspend finished */
 #define PM_RESTORE_PREPARE	0x0005 /* Going to restore a saved image */
 #define PM_POST_RESTORE		0x0006 /* Restore failed */
+#define PM_HIBERNATION_AFTER_FREEZE	0x0007 /* After hibernation freeze */
+#define PM_SUSPEND_AFTER_FREEZE		0x0008 /* After suspend freeze */
 
 extern struct mutex pm_mutex;
 
diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c
index 2329daa..184f7ee 100644
--- a/kernel/power/hibernate.c
+++ b/kernel/power/hibernate.c
@@ -671,6 +671,8 @@  int hibernate(void)
 	if (error)
 		goto Exit;
 
+	pm_notifier_call_chain(PM_HIBERNATION_AFTER_FREEZE);
+
 	lock_device_hotplug();
 	/* Allocate memory management structures */
 	error = create_basic_memory_bitmaps();
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c
index b7d6b3a..1776938 100644
--- a/kernel/power/suspend.c
+++ b/kernel/power/suspend.c
@@ -268,8 +268,10 @@  static int suspend_prepare(suspend_state_t state)
 	trace_suspend_resume(TPS("freeze_processes"), 0, true);
 	error = suspend_freeze_processes();
 	trace_suspend_resume(TPS("freeze_processes"), 0, false);
-	if (!error)
+	if (!error) {
+		pm_notifier_call_chain(PM_SUSPEND_AFTER_FREEZE);
 		return 0;
+	}
 
 	suspend_stats.failed_freeze++;
 	dpm_save_failed_step(SUSPEND_FREEZE);