Skip to contentSkip to conversation

release early... powermac g5 suspend to disk

PATCH Johannes Berg 2 participants 3 messages Jun 23, 2006 – Jun 29, 2006

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

Wow. 2 days and a mostly destroyed XFS filesystem (it's still running but I better not touch some directories or it goes belly up, xfs_repair craps out too) I actually suspended my quad powermac a few times.

Half of the time I'll be told by the softlockup watchdog that it locked up, but sometimes it actually works, that is, it suspends and resumes.

Issues: I don't save MPIC state. Hence, anything that is compiled in as modules will no longer get IRQs after resume. Like USB on my system. So I only ohci_hcd and ehci_hcd before suspend, reload later (from a script) and I can still use the keyboard after ;)

Same goes for tg3 even though it is built-in. Well, I held off looking at the MPIC because Ben said he was rewriting the whole interrupt stuff anyway.

Other issues: yeah, this is extremely ugly. If you like your machine, don't take a look.

There must be dozens of bad and undocumented assumptions too. Like running with the same hashtables while copying back as before, etc. Not restoring the MSR because, well, it crashes then ;) Very strange code to flush caches, not sure it's even correct. Etc. etc. Oh and yes, I really am that clueless and don't see the bigger issues ;)

Oh and as you can see in the first hunk here, I had to modify the generic code too...

kernel/power/snapshot.c +8 -1
@@ -177,7 +177,13 @@
 		return 0;
 
 	page = pfn_to_page(pfn);
+/*
+    I currently mark the physical memory that we reserve
+    and _don't_ map for kernel access as Nosave so we won't
+    try to save it... Not sure what to do.
+
 	BUG_ON(PageReserved(page) && PageNosave(page));
+*/
 	if (PageNosave(page))
 		return 0;
 	if (PageReserved(page) && pfn_is_nosave(pfn))
@@ -185,7 +191,8 @@
 	if (PageNosaveFree(page))
 		return 0;
 
-	return 1;
+	/* we have a memory hole for PCI accesses! */
+	return page_is_ram(pfn);
 }
 
 unsigned int count_data_pages(void)
arch/powerpc/kernel/Makefile +1 -0
@@ -37,6 +37,7 @@
 obj-$(CONFIG_6xx)		+= idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o
 obj-$(CONFIG_TAU)		+= tau_6xx.o
 obj32-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_32.o
+obj64-$(CONFIG_SOFTWARE_SUSPEND) += swsusp_64.o swsusp_asm64.o
 obj32-$(CONFIG_MODULES)		+= module_32.o
 obj-$(CONFIG_E500)		+= perfmon_fsl_booke.o
 
kernel/power/Kconfig +2 -2
@@ -38,7 +38,7 @@
 
 config SOFTWARE_SUSPEND
 	bool "Software Suspend"
-	depends on PM && SWAP && (X86 && (!SMP || SUSPEND_SMP)) || ((FRV || PPC32) && !SMP)
+	depends on PM && SWAP && ((X86 || PPC64) && (!SMP || SUSPEND_SMP)) || ((FRV || PPC32) && !SMP)
 	---help---
 	  Enable the possibility of suspending the machine.
 	  It doesn't need ACPI or APM.
@@ -96,5 +96,5 @@
 
 config SUSPEND_SMP
 	bool
-	depends on HOTPLUG_CPU && X86 && PM
+	depends on HOTPLUG_CPU && (X86 || PPC64) && PM
 	default y
arch/powerpc/platforms/powermac/setup.c +3 -0
@@ -457,8 +457,10 @@
 {
 	printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state);
 
+#ifdef CONFIG_PPC32
 	/* Restore userland MMU context */
 	set_context(current->active_mm->context, current->active_mm->pgd);
+#endif
 
 	return 0;
 }
@@ -490,6 +492,7 @@
 {
 	initializing = 0;
 #ifdef CONFIG_SOFTWARE_SUSPEND
+	iommu_init_late();
 	pm_set_ops(&pmac_pm_ops);
 #endif /* CONFIG_SOFTWARE_SUSPEND */
 	/* this is udbg (which is __init) and we can later use it during
include/asm/suspend.h new file +9 -0
@@ -0,0 +1,9 @@
+#ifndef __ASM_POWERPC_SUSPEND_H
+#define __ASM_POWERPC_SUSPEND_H
+
+static inline int arch_prepare_suspend(void)
+{
+	return 0;
+}
+
+#endif /* __ASM_POWERPC_SUSPEND_H */
include/linux/suspend.h +1 -1
Index: linux-2.6-git/include/linux/suspend.h
===================================================================
@@ -1,7 +1,7 @@
 #ifndef _LINUX_SWSUSP_H
 #define _LINUX_SWSUSP_H
 
-#if defined(CONFIG_X86) || defined(CONFIG_FRV) || defined(CONFIG_PPC32)
+#if defined(CONFIG_X86) || defined(CONFIG_FRV) || defined(CONFIG_PPC32) || defined(CONFIG_PPC64)
 #include <asm/suspend.h>
 #endif
 #include <linux/swap.h>
arch/powerpc/kernel/swsusp_64.c new file +37 -0
@@ -0,0 +1,37 @@
+/*
+ * PowerPC 64-bit swsusp implementation
+ *
+ * Copyright 2006 Johannes Berg <[email protected]>
+ *
+ * GPLv2
+ */
+
+#include <asm/system.h>
+
+void save_processor_state(void)
+{
+}
+
+void restore_processor_state(void)
+{
+}
+
+static int set_up_temporary_mappings(void)
+{
+	/* uh oh. we should do something here! */
+	return 0;
+}
+
+/* in swsusp_asm64.S */
+extern int restore_image(void);
+
+int swsusp_arch_resume(void)
+{
+	int err;
+
+	err = set_up_temporary_mappings();
+	if (err)
+		return err;
+	/* well, in reality, restore_image() won't return (to here) */
+	return restore_image();
+}
arch/powerpc/kernel/swsusp_asm64.S new file +218 -0

218 lines not on this page · raw message

arch/powerpc/sysdev/dart_iommu.c +42 -0

54 lines not on this page · raw message

include/asm-powerpc/iommu.h +3 -0
@@ -97,6 +97,9 @@
 #endif
 
 extern void alloc_dart_table(void);
+#ifdef CONFIG_SOFTWARE_SUSPEND
+extern void iommu_init_late(void);
+#endif
 
 #endif /* __KERNEL__ */
 #endif /* _ASM_IOMMU_H */
arch/powerpc/kernel/asm-offsets.c +2 -2
@@ -22,12 +22,12 @@
 #include <linux/types.h>
 #include <linux/mman.h>
 #include <linux/mm.h>
+#include <linux/suspend.h>
 #ifdef CONFIG_PPC64
 #include <linux/time.h>
 #include <linux/hardirq.h>
 #else
 #include <linux/ptrace.h>
-#include <linux/suspend.h>
 #endif
 
 #include <asm/io.h>
@@ -243,11 +243,11 @@
 	DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
 	DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
 
-#ifndef CONFIG_PPC64
 	DEFINE(pbe_address, offsetof(struct pbe, address));
 	DEFINE(pbe_orig_address, offsetof(struct pbe, orig_address));
 	DEFINE(pbe_next, offsetof(struct pbe, next));
 
+#ifndef CONFIG_PPC64
 	DEFINE(TASK_SIZE, TASK_SIZE);
 	DEFINE(NUM_USER_SEGMENTS, TASK_SIZE>>28);
 #endif /* ! CONFIG_PPC64 */
arch/powerpc/kernel/idle.c +4 -1
@@ -34,8 +34,11 @@
 #include <asm/smp.h>
 
 #ifdef CONFIG_HOTPLUG_CPU
+/* this is used for software suspend, and that shuts down
+ * CPUs even while the system is still booting... */
 #define cpu_should_die()	(cpu_is_offline(smp_processor_id()) && \
-				 system_state == SYSTEM_RUNNING)
+				   (system_state == SYSTEM_RUNNING     \
+				 || system_state == SYSTEM_BOOTING))
 #else
 #define cpu_should_die()	0
 #endif
#1 lore raw

Hi!

Quoted 3 lines

Wow. 2 days and a mostly destroyed XFS filesystem (it's still running but I better not touch some directories or it goes belly up, xfs_repair craps out too) I actually suspended my quad powermac a few times.

Congratulations! Hehe, you have nice testcase for xfs now :-).

[ext2 is the filesystem you proably want to use while hacking such code].

Quoted 8 lines

Half of the time I'll be told by the softlockup watchdog that it locked up, but sometimes it actually works, that is, it suspends and resumes.

Issues: I don't save MPIC state. Hence, anything that is compiled in as modules will no longer get IRQs after resume. Like USB on my system. So I only ohci_hcd and ehci_hcd before suspend, reload later (from a script) and I can still use the keyboard after ;)

Quoted 6 lines

Same goes for tg3 even though it is built-in. Well, I held off looking at the MPIC because Ben said he was rewriting the whole interrupt stuff anyway.

Other issues: yeah, this is extremely ugly. If you like your machine, don't take a look.

I like my machine. I'll take a look anyway ;-). It is not _that_ bad... at least it is short :).
Pavel

kernel/power/snapshot.c line 186

Quoted 13 lines
kernel/power/snapshot.c +6 -0
@@ -177,7 +177,13 @@
 		return 0;
 
 	page = pfn_to_page(pfn);
+/*
+    I currently mark the physical memory that we reserve
+    and _don't_ map for kernel access as Nosave so we won't
+    try to save it... Not sure what to do.
+
 	BUG_ON(PageReserved(page) && PageNosave(page));
+*/

I believe this is gone in -git kernels for some other reasons.
Pavel

Signature · 2 lines
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html
#2 lore raw

Hi,

Quoted 1 line

Congratulations! Hehe, you have nice testcase for xfs now :-).

Yeah, already posted to xfs list ;)

Quoted 1 line

[ext2 is the filesystem you proably want to use while hacking such code].

Mounting read-only hasn't wrecked it any further so far :) And I was too lazy to install a second system... Should've, I guess, hd is large enough anyway.

Quoted 2 lines
Quoted 2 lines

Half of the time I'll be told by the softlockup watchdog that it locked up, but sometimes it actually works, that is, it suspends and resumes.

Obviously that was phrased wrongly -- the code hangs and the softlockup watchdog indicates it. But I don't know why. Can writing the MSR hang?

Quoted 1 line

I believe this is gone in -git kernels for some other reasons.

I'm not even sure the hack I did there with marking the area as nosave is good. At the very least the code shouldn't live in the MPIC file since the code reserving the chunk doesn't either.

What about the page_is_ram() part? Doesn't any other platform have a RAM hole between 2 and 4 GB? Or is that handled more generically with discontig support? (and if yes, how does discontig support work?)

johannes