From: Olof Johansson 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); _