From: Olof Johansson <olof@austin.ibm.com>

It's currently a boolean, but that means that system_running goes to zero
again when shutting down.  So we then use code (in the page allocator) which
is only designed to be used during bootup - it is marked __init.

So we need to be able to distinguish early boot state from late shutdown
state.  Rename system_running to system_state and give it the three
appropriate states.


---

 25-akpm/arch/ppc/platforms/pmac_nvram.c |    8 ++++----
 25-akpm/include/linux/kernel.h          |    8 +++++++-
 25-akpm/init/main.c                     |    8 ++------
 25-akpm/kernel/kmod.c                   |    2 +-
 25-akpm/kernel/printk.c                 |    3 ++-
 25-akpm/kernel/sched.c                  |    3 ++-
 25-akpm/kernel/sys.c                    |    8 ++++----
 25-akpm/mm/page_alloc.c                 |    2 +-
 8 files changed, 23 insertions(+), 19 deletions(-)

diff -puN arch/ppc/platforms/pmac_nvram.c~system_running-fix arch/ppc/platforms/pmac_nvram.c
--- 25/arch/ppc/platforms/pmac_nvram.c~system_running-fix	2004-04-03 02:59:45.490437344 -0800
+++ 25-akpm/arch/ppc/platforms/pmac_nvram.c	2004-04-03 02:59:45.505435064 -0800
@@ -154,11 +154,11 @@ static unsigned char __pmac pmu_nvram_re
 	struct adb_request req;
 	DECLARE_COMPLETION(req_complete); 
 	
-	req.arg = system_running ? &req_complete : NULL;
+	req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
 	if (pmu_request(&req, pmu_nvram_complete, 3, PMU_READ_NVRAM,
 			(addr >> 8) & 0xff, addr & 0xff))
 		return 0xff;
-	if (system_running)
+	if (system_state == SYSTEM_RUNNING)
 		wait_for_completion(&req_complete);
 	while (!req.complete)
 		pmu_poll();
@@ -170,11 +170,11 @@ static void __pmac pmu_nvram_write_byte(
 	struct adb_request req;
 	DECLARE_COMPLETION(req_complete); 
 	
-	req.arg = system_running ? &req_complete : NULL;
+	req.arg = system_state == SYSTEM_RUNNING ? &req_complete : NULL;
 	if (pmu_request(&req, pmu_nvram_complete, 4, PMU_WRITE_NVRAM,
 			(addr >> 8) & 0xff, addr & 0xff, val))
 		return;
-	if (system_running)
+	if (system_state == SYSTEM_RUNNING)
 		wait_for_completion(&req_complete);
 	while (!req.complete)
 		pmu_poll();
diff -puN include/linux/kernel.h~system_running-fix include/linux/kernel.h
--- 25/include/linux/kernel.h~system_running-fix	2004-04-03 02:59:45.491437192 -0800
+++ 25-akpm/include/linux/kernel.h	2004-04-03 02:59:45.505435064 -0800
@@ -109,9 +109,15 @@ static inline void console_verbose(void)
 extern void bust_spinlocks(int yes);
 extern int oops_in_progress;		/* If set, an oops, panic(), BUG() or die() is in progress */
 extern int panic_on_oops;
-extern int system_running;
+extern int system_state;		/* See values below */
 extern int tainted;
 extern const char *print_tainted(void);
+
+/* Values used for system_state */
+#define SYSTEM_BOOTING 0
+#define SYSTEM_RUNNING 1
+#define SYSTEM_SHUTDOWN 2
+
 #define TAINT_PROPRIETARY_MODULE	(1<<0)
 #define TAINT_FORCED_MODULE		(1<<1)
 #define TAINT_UNSAFE_SMP		(1<<2)
diff -puN init/main.c~system_running-fix init/main.c
--- 25/init/main.c~system_running-fix	2004-04-03 02:59:45.493436888 -0800
+++ 25-akpm/init/main.c	2004-04-03 02:59:45.506434912 -0800
@@ -94,11 +94,7 @@ extern void driver_init(void);
 extern void tc_init(void);
 #endif
 
-/*
- * Are we up and running (ie do we have all the infrastructure
- * set up)
- */
-int system_running;
+int system_state;	/* SYSTEM_BOOTING/RUNNING/SHUTDOWN */
 
 /*
  * Boot command-line arguments
@@ -613,7 +609,7 @@ static int init(void * unused)
 	 */
 	free_initmem();
 	unlock_kernel();
-	system_running = 1;
+	system_state = SYSTEM_RUNNING;
 
 	if (sys_open("/dev/console", O_RDWR, 0) < 0)
 		printk("Warning: unable to open an initial console.\n");
diff -puN kernel/kmod.c~system_running-fix kernel/kmod.c
--- 25/kernel/kmod.c~system_running-fix	2004-04-03 02:59:45.495436584 -0800
+++ 25-akpm/kernel/kmod.c	2004-04-03 02:59:45.506434912 -0800
@@ -249,7 +249,7 @@ int call_usermodehelper(char *path, char
 	};
 	DECLARE_WORK(work, __call_usermodehelper, &sub_info);
 
-	if (!system_running)
+	if (system_state != SYSTEM_RUNNING)
 		return -EBUSY;
 
 	if (path[0] == '\0')
diff -puN kernel/printk.c~system_running-fix kernel/printk.c
--- 25/kernel/printk.c~system_running-fix	2004-04-03 02:59:45.496436432 -0800
+++ 25-akpm/kernel/printk.c	2004-04-03 02:59:45.507434760 -0800
@@ -522,7 +522,8 @@ asmlinkage int printk(const char *fmt, .
 			log_level_unknown = 1;
 	}
 
-	if (!cpu_online(smp_processor_id()) && !system_running) {
+	if (!cpu_online(smp_processor_id()) &&
+	    system_state != SYSTEM_RUNNING) {
 		/*
 		 * Some console drivers may assume that per-cpu resources have
 		 * been allocated.  So don't allow them to be called by this
diff -puN kernel/sched.c~system_running-fix kernel/sched.c
--- 25/kernel/sched.c~system_running-fix	2004-04-03 02:59:45.498436128 -0800
+++ 25-akpm/kernel/sched.c	2004-04-03 02:59:45.509434456 -0800
@@ -2982,7 +2982,8 @@ void __might_sleep(char *file, int line)
 #if defined(in_atomic)
 	static unsigned long prev_jiffy;	/* ratelimiting */
 
-	if ((in_atomic() || irqs_disabled()) && system_running) {
+	if ((in_atomic() || irqs_disabled()) &&
+	    system_state == SYSTEM_RUNNING) {
 		if (time_before(jiffies, prev_jiffy + HZ) && prev_jiffy)
 			return;
 		prev_jiffy = jiffies;
diff -puN kernel/sys.c~system_running-fix kernel/sys.c
--- 25/kernel/sys.c~system_running-fix	2004-04-03 02:59:45.500435824 -0800
+++ 25-akpm/kernel/sys.c	2004-04-03 02:59:45.511434152 -0800
@@ -436,7 +436,7 @@ asmlinkage long sys_reboot(int magic1, i
 	switch (cmd) {
 	case LINUX_REBOOT_CMD_RESTART:
 		notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
-		system_running = 0;
+		system_state = SYSTEM_SHUTDOWN;
 		device_shutdown();
 		printk(KERN_EMERG "Restarting system.\n");
 		machine_restart(NULL);
@@ -452,7 +452,7 @@ asmlinkage long sys_reboot(int magic1, i
 
 	case LINUX_REBOOT_CMD_HALT:
 		notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
-		system_running = 0;
+		system_state = SYSTEM_SHUTDOWN;
 		device_shutdown();
 		printk(KERN_EMERG "System halted.\n");
 		machine_halt();
@@ -462,7 +462,7 @@ asmlinkage long sys_reboot(int magic1, i
 
 	case LINUX_REBOOT_CMD_POWER_OFF:
 		notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
-		system_running = 0;
+		system_state = SYSTEM_SHUTDOWN;
 		device_shutdown();
 		printk(KERN_EMERG "Power down.\n");
 		machine_power_off();
@@ -478,7 +478,7 @@ asmlinkage long sys_reboot(int magic1, i
 		buffer[sizeof(buffer) - 1] = '\0';
 
 		notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer);
-		system_running = 0;
+		system_state = SYSTEM_SHUTDOWN;
 		device_shutdown();
 		printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer);
 		machine_restart(buffer);
diff -puN mm/page_alloc.c~system_running-fix mm/page_alloc.c
--- 25/mm/page_alloc.c~system_running-fix	2004-04-03 02:59:45.501435672 -0800
+++ 25-akpm/mm/page_alloc.c	2004-04-03 02:59:45.512434000 -0800
@@ -734,7 +734,7 @@ fastcall unsigned long __get_free_pages(
 	struct page * page;
 
 #ifdef CONFIG_NUMA
-	if (unlikely(!system_running))
+	if (unlikely(system_state == SYSTEM_BOOTING))
 		return get_boot_pages(gfp_mask, order);
 #endif
 	page = alloc_pages(gfp_mask, order);

_