Re: [RFC] PM: Add PM_RESUME_PREPARE and PM_POST_RESUME notifiers

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, 30 Oct 2007, Rafael J. Wysocki wrote:

> > Drivers might want to do different things at the beginning of
> > hibernation and the beginning of a restore.
> > 
> > Alternatively, the user interface can be changed.  The current 
> > organization is slightly illogical; there should be different ioctls 
> > for prepare-to-create-snapshot and prepare-to-restore-snapshot instead 
> > of a single SNAPSHOT_FREEZE for both.  How about adding RESTORE_FREEZE 
> > and RESTORE_UNFREEZE; does this sound good?
> 
> Hm, we could define separate FREEZE ioctls for restore, but if they end up
> doing the same as the analogous snapshot ones, they'll be somewhat redundant
> ...

How do you like this version of the patch then?  Redundancy is kept to 
a minimum.

(Strictly speaking, we should have two different notification codes for 
PM_POST_HIBERNATION: one for use after the atomic snapshot has been 
created and one for use after it has been restored.  But I'm not going 
to worry about that right now.)

Alan Stern



Index: usb-2.6/Documentation/power/notifiers.txt
===================================================================
--- usb-2.6.orig/Documentation/power/notifiers.txt
+++ usb-2.6/Documentation/power/notifiers.txt
@@ -28,6 +28,14 @@ PM_POST_HIBERNATION	The system memory st
 			hibernation.  Device drivers' .resume() callbacks have
 			been executed and tasks have been thawed.
 
+PM_RESTORE_PREPARE	The system is going to restore a hibernation image.
+			If all goes well the restored kernel will issue a
+			PM_POST_HIBERNATION notification.
+
+PM_POST_RESTORE		An error occurred during the hibernation restore.
+			Device drivers' .resume() callbacks have been executed
+			and tasks have been thawed.
+
 PM_SUSPEND_PREPARE	The system is preparing for a suspend.
 
 PM_POST_SUSPEND		The system has just resumed or an error occured during
Index: usb-2.6/include/linux/notifier.h
===================================================================
--- usb-2.6.orig/include/linux/notifier.h
+++ usb-2.6/include/linux/notifier.h
@@ -230,6 +230,8 @@ static inline int notifier_to_errno(int 
 #define PM_POST_HIBERNATION	0x0002 /* Hibernation finished */
 #define PM_SUSPEND_PREPARE	0x0003 /* Going to suspend the system */
 #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 */
 
 /* Console keyboard events.
  * Note: KBD_KEYCODE is always sent before KBD_UNBOUND_KEYCODE, KBD_UNICODE and
Index: usb-2.6/kernel/power/disk.c
===================================================================
--- usb-2.6.orig/kernel/power/disk.c
+++ usb-2.6/kernel/power/disk.c
@@ -489,6 +489,10 @@ static int software_resume(void)
 		goto Unlock;
 	}
 
+	error = pm_notifier_call_chain(PM_RESTORE_PREPARE);
+	if (error)
+		goto Exit;
+
 	error = create_basic_memory_bitmaps();
 	if (error)
 		goto Finish;
@@ -512,6 +516,8 @@ static int software_resume(void)
  Done:
 	free_basic_memory_bitmaps();
  Finish:
+	pm_notifier_call_chain(PM_POST_RESTORE);
+ Exit:
 	atomic_inc(&snapshot_device_available);
 	/* For success case, the suspend path will release the lock */
  Unlock:
Index: usb-2.6/Documentation/power/userland-swsusp.txt
===================================================================
--- usb-2.6.orig/Documentation/power/userland-swsusp.txt
+++ usb-2.6/Documentation/power/userland-swsusp.txt
@@ -26,11 +26,12 @@ once at a time.
 
 The ioctl() commands recognized by the device are:
 
-SNAPSHOT_FREEZE - freeze user space processes (the current process is
-	not frozen); this is required for SNAPSHOT_ATOMIC_SNAPSHOT
-	and SNAPSHOT_ATOMIC_RESTORE to succeed
+SNAPSHOT_FREEZE - freeze user space processes in preparation for creating
+	an atomic snapshot (the current process is not frozen); this is
+	required for SNAPSHOT_ATOMIC_SNAPSHOT to succeed
 
 SNAPSHOT_UNFREEZE - thaw user space processes frozen by SNAPSHOT_FREEZE
+	after the snapshot has been created or restored
 
 SNAPSHOT_ATOMIC_SNAPSHOT - create a snapshot of the system memory; the
 	last argument of ioctl() should be a pointer to an int variable,
@@ -41,6 +42,15 @@ SNAPSHOT_ATOMIC_SNAPSHOT - create a snap
 	has been created the read() operation can be used to transfer
 	it out of the kernel
 
+SNAPSHOT_RESTORE_FREEZE - freeze user space processes in preparation for
+	restoring an atomic snapshot (the current pocess is not frozen);
+	this is required for SNAPSHOT_ATOMIC_RESTORE to succeed
+
+SNAPSHOT_RESTORE_UNFREEZE - thaw user space processes frozen by
+	SNAPSHOT_RESTORE_FREEZE; this should be used when
+	SNAPSHOT_ATOMIC_RESTORE fails (if it succeeds the current process
+	won't exist any more)
+
 SNAPSHOT_ATOMIC_RESTORE - restore the system memory state from the
 	uploaded snapshot image; before calling it you should transfer
 	the system memory snapshot back to the kernel using the write()
@@ -157,7 +167,8 @@ mechanism and the userland utilities usi
 means, such as checksums, to ensure the integrity of the snapshot image.
 
 The suspending and resuming utilities MUST lock themselves in memory,
-preferrably using mlockall(), before calling SNAPSHOT_FREEZE.
+preferrably using mlockall(), before calling SNAPSHOT_FREEZE or
+SNAPSHOT_RESTORE_FREEZE.
 
 The suspending utility MUST check the value stored by SNAPSHOT_ATOMIC_SNAPSHOT
 in the memory location pointed to by the last argument of ioctl() and proceed
Index: usb-2.6/kernel/power/power.h
===================================================================
--- usb-2.6.orig/kernel/power/power.h
+++ usb-2.6/kernel/power/power.h
@@ -160,7 +160,9 @@ struct resume_swap_area {
 #define SNAPSHOT_PMOPS			_IOW(SNAPSHOT_IOC_MAGIC, 12, unsigned int)
 #define SNAPSHOT_SET_SWAP_AREA		_IOW(SNAPSHOT_IOC_MAGIC, 13, \
 							struct resume_swap_area)
-#define SNAPSHOT_IOC_MAXNR	13
+#define SNAPSHOT_RESTORE_FREEZE		_IO(SNAPSHOT_IOC_MAGIC, 14)
+#define SNAPSHOT_RESTORE_UNFREEZE	_IO(SNAPSHOT_IOC_MAGIC, 15)
+#define SNAPSHOT_IOC_MAXNR	15
 
 #define PMOPS_PREPARE	1
 #define PMOPS_ENTER	2
Index: usb-2.6/kernel/power/user.c
===================================================================
--- usb-2.6.orig/kernel/power/user.c
+++ usb-2.6/kernel/power/user.c
@@ -128,6 +128,42 @@ static ssize_t snapshot_write(struct fil
 	return res;
 }
 
+static int user_freeze(struct snapshot_data *data, int pre_msg, int err_msg)
+{
+	int error = 0;
+
+	if (data->frozen)
+		return error;
+	mutex_lock(&pm_mutex);
+	error = pm_notifier_call_chain(pre_msg);
+	if (!error) {
+		printk("Syncing filesystems ... ");
+		sys_sync();
+		printk("done.\n");
+
+		error = freeze_processes();
+		if (error)
+			thaw_processes();
+	}
+	if (error)
+		pm_notifier_call_chain(err_msg);
+	mutex_unlock(&pm_mutex);
+	if (!error)
+		data->frozen = 1;
+	return error;
+}
+
+static void user_unfreeze(struct snapshot_data *data, int post_msg)
+{
+	if (!data->frozen || data->ready)
+		return;
+	mutex_lock(&pm_mutex);
+	thaw_processes();
+	pm_notifier_call_chain(post_msg);
+	mutex_unlock(&pm_mutex);
+	data->frozen = 0;
+}
+
 static int snapshot_ioctl(struct inode *inode, struct file *filp,
                           unsigned int cmd, unsigned long arg)
 {
@@ -148,34 +184,20 @@ static int snapshot_ioctl(struct inode *
 	switch (cmd) {
 
 	case SNAPSHOT_FREEZE:
-		if (data->frozen)
-			break;
-		mutex_lock(&pm_mutex);
-		error = pm_notifier_call_chain(PM_HIBERNATION_PREPARE);
-		if (!error) {
-			printk("Syncing filesystems ... ");
-			sys_sync();
-			printk("done.\n");
-
-			error = freeze_processes();
-			if (error)
-				thaw_processes();
-		}
-		if (error)
-			pm_notifier_call_chain(PM_POST_HIBERNATION);
-		mutex_unlock(&pm_mutex);
-		if (!error)
-			data->frozen = 1;
+		error = user_freeze(data, PM_HIBERNATION_PREPARE,
+				PM_POST_HIBERNATION);
+		break;
+
+	case SNAPSHOT_RESTORE_FREEZE:
+		error = user_freeze(data, PM_RESTORE_PREPARE, PM_POST_RESTORE);
 		break;
 
 	case SNAPSHOT_UNFREEZE:
-		if (!data->frozen || data->ready)
-			break;
-		mutex_lock(&pm_mutex);
-		thaw_processes();
-		pm_notifier_call_chain(PM_POST_HIBERNATION);
-		mutex_unlock(&pm_mutex);
-		data->frozen = 0;
+		user_unfreeze(data, PM_POST_HIBERNATION);
+		break;
+
+	case SNAPSHOT_RESTORE_UNFREEZE:
+		user_unfreeze(data, PM_POST_RESTORE);
 		break;
 
 	case SNAPSHOT_ATOMIC_SNAPSHOT:

_______________________________________________
linux-pm mailing list
linux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxx
https://lists.linux-foundation.org/mailman/listinfo/linux-pm

[Index of Archives]     [Linux ACPI]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [CPU Freq]     [Kernel Newbies]     [Fedora Kernel]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux