int swsusp_shrink_memory(void) { long tmp; struct zone *zone; unsigned long pages = 0; unsigned int i = 0; char *p = "-\\|/"; struct timeval start, stop; printk("Shrinking memory... "); do_gettimeofday(&start); do { long size, highmem_size; highmem_size = count_highmem_pages(); size = count_data_pages() + PAGES_FOR_IO; tmp = size; size += highmem_size; for_each_zone (zone) if (populated_zone(zone)) { if (is_highmem(zone)) { highmem_size -= zone_page_state(zone, NR_FREE_PAGES); } else { tmp -= zone_page_state(zone, NR_FREE_PAGES); tmp += zone->lowmem_reserve[ZONE_NORMAL]; tmp += snapshot_additional_pages(zone); } } if (highmem_size < 0) highmem_size = 0; tmp += highmem_size; if (tmp > 0) { tmp = __shrink_memory(tmp); if (!tmp) return -ENOMEM; pages += tmp; } else if (size > image_size / PAGE_SIZE) { tmp = __shrink_memory(size - (image_size / PAGE_SIZE)); pages += tmp; } printk("\b%c", p[i++%4]); } while (tmp > 0); do_gettimeofday(&stop); printk("\bdone (%lu pages freed)\n", pages); swsusp_show_speed(&start, &stop, pages, "Freed"); return 0; }
static int enough_free_mem(unsigned int nr_pages) { struct zone *zone; unsigned int free = 0, meta = 0; for_each_zone (zone) if (!is_highmem(zone)) { free += zone->free_pages; meta += snapshot_additional_pages(zone); } pr_debug("swsusp: pages needed: %u + %u + %u, available pages: %u\n", nr_pages, PAGES_FOR_IO, meta, free); return free > nr_pages + PAGES_FOR_IO + meta; }