int swsusp_shrink_memory(void) { long size, tmp; struct zone *zone; unsigned long pages = 0; unsigned int i = 0; char *p = "-\\|/"; printk("Shrinking memory... "); do { size = 2 * count_highmem_pages(); size += size / 50 + count_data_pages(); size += (size + PBES_PER_PAGE - 1) / PBES_PER_PAGE + PAGES_FOR_IO; tmp = size; for_each_zone (zone) if (!is_highmem(zone)) tmp -= zone->free_pages; if (tmp > 0) { tmp = shrink_all_memory(SHRINK_BITE); if (!tmp) return -ENOMEM; pages += tmp; } else if (size > image_size / PAGE_SIZE) { tmp = shrink_all_memory(SHRINK_BITE); pages += tmp; } printk("\b%c", p[i++%4]); } while (tmp > 0); printk("\bdone (%lu pages freed)\n", pages); return 0; }
static void free_some_memory(void) { printk("Freeing memory: "); while (shrink_all_memory(10000)) printk("."); printk("|\n"); }
static int suspend_prepare(suspend_state_t state) { int error = 0; unsigned int free_pages; if (!pm_ops || !pm_ops->enter) return -EPERM; pm_prepare_console(); disable_nonboot_cpus(); if (num_online_cpus() != 1) { error = -EPERM; goto Enable_cpu; } if (freeze_processes()) { error = -EAGAIN; goto Thaw; } if ((free_pages = nr_free_pages()) < FREE_PAGE_NUMBER) { pr_debug("PM: free some memory\n"); shrink_all_memory(FREE_PAGE_NUMBER - free_pages); if (nr_free_pages() < FREE_PAGE_NUMBER) { error = -ENOMEM; printk(KERN_ERR "PM: No enough memory\n"); goto Thaw; } } if (pm_ops->prepare) { if ((error = pm_ops->prepare(state))) goto Thaw; } if ((error = device_suspend(PMSG_SUSPEND))) { printk(KERN_ERR "Some devices failed to suspend\n"); goto Finish; } return 0; Finish: if (pm_ops->finish) pm_ops->finish(state); Thaw: thaw_processes(); Enable_cpu: enable_nonboot_cpus(); pm_restore_console(); return error; }
static int suspend_prepare(suspend_state_t state) { int error; unsigned int free_pages; if (!pm_ops || !pm_ops->enter) return -EPERM; pm_prepare_console(); if (freeze_processes()) { error = -EAGAIN; goto Thaw; } if ((free_pages = global_page_state(NR_FREE_PAGES)) < FREE_PAGE_NUMBER) { pr_debug("PM: free some memory\n"); shrink_all_memory(FREE_PAGE_NUMBER - free_pages); if (nr_free_pages() < FREE_PAGE_NUMBER) { error = -ENOMEM; printk(KERN_ERR "PM: No enough memory\n"); goto Thaw; } } if (pm_ops->prepare) { if ((error = pm_ops->prepare(state))) goto Thaw; } suspend_console(); error = device_suspend(PMSG_SUSPEND); if (error) { printk(KERN_ERR "Some devices failed to suspend\n"); goto Resume_devices; } error = disable_nonboot_cpus(); if (!error) return 0; enable_nonboot_cpus(); Resume_devices: pm_finish(state); device_resume(); resume_console(); Thaw: thaw_processes(); pm_restore_console(); return error; }
/** * suspend_prepare - Do prep work before entering low-power state. * * This is common code that is called for each state that we're entering. * Run suspend notifiers, allocate a console and stop all processes. */ static int suspend_prepare(void) { int error; unsigned int free_pages; if (!suspend_ops || !suspend_ops->enter) return -EPERM; pm_prepare_console(); error = pm_notifier_call_chain(PM_SUSPEND_PREPARE); if (error) goto Finish; error = usermodehelper_disable(); if (error) goto Finish; if (suspend_freeze_processes()) { error = -EAGAIN; goto Thaw; } error = wait_timed_wakelocks(); if (error) { error = -EAGAIN; goto Thaw; } free_pages = global_page_state(NR_FREE_PAGES); if (free_pages < FREE_PAGE_NUMBER) { pr_debug("PM: free some memory\n"); shrink_all_memory(FREE_PAGE_NUMBER - free_pages); if (nr_free_pages() < FREE_PAGE_NUMBER) { error = -ENOMEM; printk(KERN_ERR "PM: No enough memory\n"); } } if (!error) return 0; Thaw: suspend_thaw_processes(); usermodehelper_enable(); Finish: pm_notifier_call_chain(PM_POST_SUSPEND); pm_restore_console(); return error; }
static void free_some_memory(void) { unsigned int i = 0; unsigned int tmp; unsigned long pages = 0; char *p = "-\\|/"; printk("Freeing memory... "); while ((tmp = shrink_all_memory(10000))) { pages += tmp; printk("\b%c", p[i]); i++; if (i > 3) i = 0; } printk("\bdone (%li pages freed)\n", pages); }
static inline unsigned long __shrink_memory(long tmp) { if (tmp > SHRINK_BITE) tmp = SHRINK_BITE; return shrink_all_memory(tmp); }