Example #1
0
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;
}