void do_magic_suspend_2(void) { int is_problem; read_swapfiles(); is_problem = suspend_prepare_image(); spin_unlock_irq(&suspend_pagedir_lock); if (!is_problem) { kernel_fpu_end(); /* save_processor_state() does kernel_fpu_begin, and we need to revert it in order to pass in_atomic() checks */ BUG_ON(in_atomic()); suspend_save_image(); suspend_power_down(); /* FIXME: if suspend_power_down is commented out, console is lost after few suspends ?! */ } printk(KERN_EMERG "%sSuspend failed, trying to recover...\n", name_suspend); MDELAY(1000); /* So user can wait and report us messages if armageddon comes :-) */ barrier(); mb(); spin_lock_irq(&suspend_pagedir_lock); /* Done to disable interrupts */ mdelay(1000); free_pages((unsigned long) pagedir_nosave, pagedir_order); spin_unlock_irq(&suspend_pagedir_lock); mark_swapfiles(((swp_entry_t) {0}), MARK_SWAP_RESUME); }
int pmdisk_suspend(void) { int error = 0; if ((error = read_swapfiles())) return error; drain_local_pages(); pm_pagedir_nosave = NULL; pr_debug("pmdisk: Counting pages to copy.\n" ); count_pages(); pr_debug("pmdisk: (pages needed: %d + %d free: %d)\n", pmdisk_pages,PAGES_FOR_IO,nr_free_pages()); if (!enough_free_mem()) return -ENOMEM; if (!enough_swap()) return -ENOSPC; if ((error = alloc_pagedir())) { pr_debug("pmdisk: Allocating pagedir failed.\n"); return error; } if ((error = alloc_image_pages())) { pr_debug("pmdisk: Allocating image pages failed.\n"); free_pagedir(); return error; } nr_copy_pages_check = pmdisk_pages; pagedir_order_check = pagedir_order; /* During allocating of suspend pagedir, new cold pages may appear. * Kill them */ drain_local_pages(); /* copy */ copy_pages(); /* * End of critical section. From now on, we can write to memory, * but we should not touch disk. This specially means we must _not_ * touch swap space! Except we must write out our image of course. */ pr_debug("pmdisk: %d pages copied\n", pmdisk_pages ); return 0; }