aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/gfp.h5
-rw-r--r--mm/page_alloc.c35
-rw-r--r--mm/slab.c1
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
135void page_alloc_init(void); 135void page_alloc_init(void);
136#ifdef CONFIG_NUMA
137void drain_remote_pages(void);
138#else
139static 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 */
521void 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)
520static void __drain_pages(unsigned int cpu) 550static 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
diff --git a/mm/slab.c b/mm/slab.c
index c78d343b3c5f..93cbbbb39f42 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -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}