Commit 6306d485 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] add drain_local_pages() for CONFIG_SOFTWARE_SUSPEND

swsusp gets confused when pages which it freed do not appear in the
buddy lists.  So provide a function which will drain the calling CPU's
per-cpu-pages into the buddy.

The patch has been tested by Pavel.  Presence of the new code is
conditional on CONFIG_SOFTWARE_SUSPEND.
parent 6aa1fff3
...@@ -46,6 +46,9 @@ struct suspend_header { ...@@ -46,6 +46,9 @@ struct suspend_header {
/* mm/vmscan.c */ /* mm/vmscan.c */
extern int shrink_mem(void); extern int shrink_mem(void);
/* mm/page_alloc.c */
extern void drain_local_pages(void);
/* kernel/suspend.c */ /* kernel/suspend.c */
extern void software_suspend(void); extern void software_suspend(void);
extern void software_resume(void); extern void software_resume(void);
......
...@@ -350,6 +350,31 @@ int is_head_of_free_region(struct page *page) ...@@ -350,6 +350,31 @@ int is_head_of_free_region(struct page *page)
spin_unlock_irqrestore(&zone->lock, flags); spin_unlock_irqrestore(&zone->lock, flags);
return 0; return 0;
} }
/*
* Spill all of this CPU's per-cpu pages back into the buddy allocator.
*/
void drain_local_pages(void)
{
unsigned long flags;
struct zone *zone;
int i;
local_irq_save(flags);
for_each_zone(zone) {
struct per_cpu_pageset *pset;
pset = &zone->pageset[smp_processor_id()];
for (i = 0; i < ARRAY_SIZE(pset->pcp); i++) {
struct per_cpu_pages *pcp;
pcp = &pset->pcp[i];
pcp->count -= free_pages_bulk(zone, pcp->count,
&pcp->list, 0);
}
}
local_irq_restore(flags);
}
#endif /* CONFIG_SOFTWARE_SUSPEND */ #endif /* CONFIG_SOFTWARE_SUSPEND */
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment