From 6306d4857d08b5aa6f190cdd54fe3231f3a35d9f Mon Sep 17 00:00:00 2001 From: Andrew Morton <akpm@digeo.com> Date: Sun, 29 Dec 2002 21:40:31 -0800 Subject: [PATCH] [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. --- include/linux/suspend.h | 3 +++ mm/page_alloc.c | 25 +++++++++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/include/linux/suspend.h b/include/linux/suspend.h index a481f80034fa..80b4a657b49c 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -46,6 +46,9 @@ struct suspend_header { /* mm/vmscan.c */ extern int shrink_mem(void); +/* mm/page_alloc.c */ +extern void drain_local_pages(void); + /* kernel/suspend.c */ extern void software_suspend(void); extern void software_resume(void); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 7de787fd57d9..1c8015736d61 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -350,6 +350,31 @@ int is_head_of_free_region(struct page *page) spin_unlock_irqrestore(&zone->lock, flags); 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 */ /* -- 2.30.9