diff options
-rw-r--r-- | include/linux/gfp.h | 5 | ||||
-rw-r--r-- | mm/page_alloc.c | 35 | ||||
-rw-r--r-- | mm/slab.c | 1 |
3 files changed, 39 insertions, 2 deletions
diff --git a/include/linux/gfp.h b/include/linux/gfp.h index 208535fd4832..8d6bf608b199 100644 --- a/include/linux/gfp.h +++ b/include/linux/gfp.h | |||
@@ -133,5 +133,10 @@ extern void FASTCALL(free_cold_page(struct page *page)); | |||
133 | #define free_page(addr) free_pages((addr),0) | 133 | #define free_page(addr) free_pages((addr),0) |
134 | 134 | ||
135 | void page_alloc_init(void); | 135 | void page_alloc_init(void); |
136 | #ifdef CONFIG_NUMA | ||
137 | void drain_remote_pages(void); | ||
138 | #else | ||
139 | static inline void drain_remote_pages(void) { }; | ||
140 | #endif | ||
136 | 141 | ||
137 | #endif /* __LINUX_GFP_H */ | 142 | #endif /* __LINUX_GFP_H */ |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index be05d17bd7df..a95e72d7f945 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -516,6 +516,36 @@ static int rmqueue_bulk(struct zone *zone, unsigned int order, | |||
516 | return allocated; | 516 | return allocated; |
517 | } | 517 | } |
518 | 518 | ||
519 | #ifdef CONFIG_NUMA | ||
520 | /* Called from the slab reaper to drain remote pagesets */ | ||
521 | void drain_remote_pages(void) | ||
522 | { | ||
523 | struct zone *zone; | ||
524 | int i; | ||
525 | unsigned long flags; | ||
526 | |||
527 | local_irq_save(flags); | ||
528 | for_each_zone(zone) { | ||
529 | struct per_cpu_pageset *pset; | ||
530 | |||
531 | /* Do not drain local pagesets */ | ||
532 | if (zone->zone_pgdat->node_id == numa_node_id()) | ||
533 | continue; | ||
534 | |||
535 | pset = zone->pageset[smp_processor_id()]; | ||
536 | for (i = 0; i < ARRAY_SIZE(pset->pcp); i++) { | ||
537 | struct per_cpu_pages *pcp; | ||
538 | |||
539 | pcp = &pset->pcp[i]; | ||
540 | if (pcp->count) | ||
541 | pcp->count -= free_pages_bulk(zone, pcp->count, | ||
542 | &pcp->list, 0); | ||
543 | } | ||
544 | } | ||
545 | local_irq_restore(flags); | ||
546 | } | ||
547 | #endif | ||
548 | |||
519 | #if defined(CONFIG_PM) || defined(CONFIG_HOTPLUG_CPU) | 549 | #if defined(CONFIG_PM) || defined(CONFIG_HOTPLUG_CPU) |
520 | static void __drain_pages(unsigned int cpu) | 550 | static void __drain_pages(unsigned int cpu) |
521 | { | 551 | { |
@@ -1271,12 +1301,13 @@ void show_free_areas(void) | |||
1271 | pageset = zone_pcp(zone, cpu); | 1301 | pageset = zone_pcp(zone, cpu); |
1272 | 1302 | ||
1273 | for (temperature = 0; temperature < 2; temperature++) | 1303 | for (temperature = 0; temperature < 2; temperature++) |
1274 | printk("cpu %d %s: low %d, high %d, batch %d\n", | 1304 | printk("cpu %d %s: low %d, high %d, batch %d used:%d\n", |
1275 | cpu, | 1305 | cpu, |
1276 | temperature ? "cold" : "hot", | 1306 | temperature ? "cold" : "hot", |
1277 | pageset->pcp[temperature].low, | 1307 | pageset->pcp[temperature].low, |
1278 | pageset->pcp[temperature].high, | 1308 | pageset->pcp[temperature].high, |
1279 | pageset->pcp[temperature].batch); | 1309 | pageset->pcp[temperature].batch, |
1310 | pageset->pcp[temperature].count); | ||
1280 | } | 1311 | } |
1281 | } | 1312 | } |
1282 | 1313 | ||
@@ -2851,6 +2851,7 @@ next: | |||
2851 | } | 2851 | } |
2852 | check_irq_on(); | 2852 | check_irq_on(); |
2853 | up(&cache_chain_sem); | 2853 | up(&cache_chain_sem); |
2854 | drain_remote_pages(); | ||
2854 | /* Setup the next iteration */ | 2855 | /* Setup the next iteration */ |
2855 | schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC + smp_processor_id()); | 2856 | schedule_delayed_work(&__get_cpu_var(reap_work), REAPTIMEOUT_CPUC + smp_processor_id()); |
2856 | } | 2857 | } |