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;
}
示例#2
0
static struct pbe * alloc_pagedir(unsigned nr_pages)
{
	unsigned num;
	struct pbe *pblist, *pbe;

	if (!nr_pages)
		return NULL;

	pr_debug("alloc_pagedir(): nr_pages = %d\n", nr_pages);
	pblist = (struct pbe *)get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
	for (pbe = pblist, num = PBES_PER_PAGE; pbe && num < nr_pages;
        		pbe = pbe->next, num += PBES_PER_PAGE) {
		pbe += PB_PAGE_SKIP;
		pbe->next = (struct pbe *)get_zeroed_page(GFP_ATOMIC | __GFP_COLD);
	}
	if (!pbe) { /* get_zeroed_page() failed */
		free_pagedir(pblist);
		pblist = NULL;
        }
	return pblist;
}
struct pbe *alloc_pagedir(unsigned int nr_pages, gfp_t gfp_mask, int safe_needed)
{
	unsigned int num;
	struct pbe *pblist, *pbe;

	if (!nr_pages)
		return NULL;

	pr_debug("alloc_pagedir(): nr_pages = %d\n", nr_pages);
	pblist = alloc_image_page(gfp_mask, safe_needed);
	/* FIXME: rewrite this ugly loop */
	for (pbe = pblist, num = PBES_PER_PAGE; pbe && num < nr_pages;
        		pbe = pbe->next, num += PBES_PER_PAGE) {
		pbe += PB_PAGE_SKIP;
		pbe->next = alloc_image_page(gfp_mask, safe_needed);
	}
	if (!pbe) { /* get_zeroed_page() failed */
		free_pagedir(pblist);
		pblist = NULL;
        }
	return pblist;
}
int pmdisk_free(void)
{
	pr_debug( "Freeing prev allocated pagedir\n" );
	free_pagedir();
	return 0;
}