diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/mempolicy.c | 6 | ||||
-rw-r--r-- | mm/page_alloc.c | 23 | ||||
-rw-r--r-- | mm/vmstat.c | 73 |
3 files changed, 50 insertions, 52 deletions
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index 6b9740bbf4c0..e07e27e846a2 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -1209,10 +1209,8 @@ static struct page *alloc_page_interleave(gfp_t gfp, unsigned order, | |||
1209 | 1209 | ||
1210 | zl = NODE_DATA(nid)->node_zonelists + gfp_zone(gfp); | 1210 | zl = NODE_DATA(nid)->node_zonelists + gfp_zone(gfp); |
1211 | page = __alloc_pages(gfp, order, zl); | 1211 | page = __alloc_pages(gfp, order, zl); |
1212 | if (page && page_zone(page) == zl->zones[0]) { | 1212 | if (page && page_zone(page) == zl->zones[0]) |
1213 | zone_pcp(zl->zones[0],get_cpu())->interleave_hit++; | 1213 | inc_zone_page_state(page, NUMA_INTERLEAVE_HIT); |
1214 | put_cpu(); | ||
1215 | } | ||
1216 | return page; | 1214 | return page; |
1217 | } | 1215 | } |
1218 | 1216 | ||
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 6aa2c31f513b..d61671260f92 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -709,27 +709,6 @@ void drain_local_pages(void) | |||
709 | } | 709 | } |
710 | #endif /* CONFIG_PM */ | 710 | #endif /* CONFIG_PM */ |
711 | 711 | ||
712 | static void zone_statistics(struct zonelist *zonelist, struct zone *z, int cpu) | ||
713 | { | ||
714 | #ifdef CONFIG_NUMA | ||
715 | pg_data_t *pg = z->zone_pgdat; | ||
716 | pg_data_t *orig = zonelist->zones[0]->zone_pgdat; | ||
717 | struct per_cpu_pageset *p; | ||
718 | |||
719 | p = zone_pcp(z, cpu); | ||
720 | if (pg == orig) { | ||
721 | p->numa_hit++; | ||
722 | } else { | ||
723 | p->numa_miss++; | ||
724 | zone_pcp(zonelist->zones[0], cpu)->numa_foreign++; | ||
725 | } | ||
726 | if (pg == NODE_DATA(numa_node_id())) | ||
727 | p->local_node++; | ||
728 | else | ||
729 | p->other_node++; | ||
730 | #endif | ||
731 | } | ||
732 | |||
733 | /* | 712 | /* |
734 | * Free a 0-order page | 713 | * Free a 0-order page |
735 | */ | 714 | */ |
@@ -827,7 +806,7 @@ again: | |||
827 | } | 806 | } |
828 | 807 | ||
829 | __mod_page_state_zone(zone, pgalloc, 1 << order); | 808 | __mod_page_state_zone(zone, pgalloc, 1 << order); |
830 | zone_statistics(zonelist, zone, cpu); | 809 | zone_statistics(zonelist, zone); |
831 | local_irq_restore(flags); | 810 | local_irq_restore(flags); |
832 | put_cpu(); | 811 | put_cpu(); |
833 | 812 | ||
diff --git a/mm/vmstat.c b/mm/vmstat.c index 06a6d1052198..ee7f89666250 100644 --- a/mm/vmstat.c +++ b/mm/vmstat.c | |||
@@ -185,9 +185,8 @@ EXPORT_SYMBOL(mod_zone_page_state); | |||
185 | * in between and therefore the atomicity vs. interrupt cannot be exploited | 185 | * in between and therefore the atomicity vs. interrupt cannot be exploited |
186 | * in a useful way here. | 186 | * in a useful way here. |
187 | */ | 187 | */ |
188 | void __inc_zone_page_state(struct page *page, enum zone_stat_item item) | 188 | static void __inc_zone_state(struct zone *zone, enum zone_stat_item item) |
189 | { | 189 | { |
190 | struct zone *zone = page_zone(page); | ||
191 | s8 *p = diff_pointer(zone, item); | 190 | s8 *p = diff_pointer(zone, item); |
192 | 191 | ||
193 | (*p)++; | 192 | (*p)++; |
@@ -197,6 +196,11 @@ void __inc_zone_page_state(struct page *page, enum zone_stat_item item) | |||
197 | *p = 0; | 196 | *p = 0; |
198 | } | 197 | } |
199 | } | 198 | } |
199 | |||
200 | void __inc_zone_page_state(struct page *page, enum zone_stat_item item) | ||
201 | { | ||
202 | __inc_zone_state(page_zone(page), item); | ||
203 | } | ||
200 | EXPORT_SYMBOL(__inc_zone_page_state); | 204 | EXPORT_SYMBOL(__inc_zone_page_state); |
201 | 205 | ||
202 | void __dec_zone_page_state(struct page *page, enum zone_stat_item item) | 206 | void __dec_zone_page_state(struct page *page, enum zone_stat_item item) |
@@ -213,22 +217,23 @@ void __dec_zone_page_state(struct page *page, enum zone_stat_item item) | |||
213 | } | 217 | } |
214 | EXPORT_SYMBOL(__dec_zone_page_state); | 218 | EXPORT_SYMBOL(__dec_zone_page_state); |
215 | 219 | ||
220 | void inc_zone_state(struct zone *zone, enum zone_stat_item item) | ||
221 | { | ||
222 | unsigned long flags; | ||
223 | |||
224 | local_irq_save(flags); | ||
225 | __inc_zone_state(zone, item); | ||
226 | local_irq_restore(flags); | ||
227 | } | ||
228 | |||
216 | void inc_zone_page_state(struct page *page, enum zone_stat_item item) | 229 | void inc_zone_page_state(struct page *page, enum zone_stat_item item) |
217 | { | 230 | { |
218 | unsigned long flags; | 231 | unsigned long flags; |
219 | struct zone *zone; | 232 | struct zone *zone; |
220 | s8 *p; | ||
221 | 233 | ||
222 | zone = page_zone(page); | 234 | zone = page_zone(page); |
223 | local_irq_save(flags); | 235 | local_irq_save(flags); |
224 | p = diff_pointer(zone, item); | 236 | __inc_zone_state(zone, item); |
225 | |||
226 | (*p)++; | ||
227 | |||
228 | if (unlikely(*p > STAT_THRESHOLD)) { | ||
229 | zone_page_state_add(*p, zone, item); | ||
230 | *p = 0; | ||
231 | } | ||
232 | local_irq_restore(flags); | 237 | local_irq_restore(flags); |
233 | } | 238 | } |
234 | EXPORT_SYMBOL(inc_zone_page_state); | 239 | EXPORT_SYMBOL(inc_zone_page_state); |
@@ -297,6 +302,28 @@ EXPORT_SYMBOL(refresh_vm_stats); | |||
297 | 302 | ||
298 | #endif | 303 | #endif |
299 | 304 | ||
305 | #ifdef CONFIG_NUMA | ||
306 | /* | ||
307 | * zonelist = the list of zones passed to the allocator | ||
308 | * z = the zone from which the allocation occurred. | ||
309 | * | ||
310 | * Must be called with interrupts disabled. | ||
311 | */ | ||
312 | void zone_statistics(struct zonelist *zonelist, struct zone *z) | ||
313 | { | ||
314 | if (z->zone_pgdat == zonelist->zones[0]->zone_pgdat) { | ||
315 | __inc_zone_state(z, NUMA_HIT); | ||
316 | } else { | ||
317 | __inc_zone_state(z, NUMA_MISS); | ||
318 | __inc_zone_state(zonelist->zones[0], NUMA_FOREIGN); | ||
319 | } | ||
320 | if (z->zone_pgdat == NODE_DATA(numa_node_id())) | ||
321 | __inc_zone_state(z, NUMA_LOCAL); | ||
322 | else | ||
323 | __inc_zone_state(z, NUMA_OTHER); | ||
324 | } | ||
325 | #endif | ||
326 | |||
300 | #ifdef CONFIG_PROC_FS | 327 | #ifdef CONFIG_PROC_FS |
301 | 328 | ||
302 | #include <linux/seq_file.h> | 329 | #include <linux/seq_file.h> |
@@ -369,6 +396,15 @@ static char *vmstat_text[] = { | |||
369 | "nr_unstable", | 396 | "nr_unstable", |
370 | "nr_bounce", | 397 | "nr_bounce", |
371 | 398 | ||
399 | #ifdef CONFIG_NUMA | ||
400 | "numa_hit", | ||
401 | "numa_miss", | ||
402 | "numa_foreign", | ||
403 | "numa_interleave", | ||
404 | "numa_local", | ||
405 | "numa_other", | ||
406 | #endif | ||
407 | |||
372 | /* Event counters */ | 408 | /* Event counters */ |
373 | "pgpgin", | 409 | "pgpgin", |
374 | "pgpgout", | 410 | "pgpgout", |
@@ -490,21 +526,6 @@ static int zoneinfo_show(struct seq_file *m, void *arg) | |||
490 | pageset->pcp[j].high, | 526 | pageset->pcp[j].high, |
491 | pageset->pcp[j].batch); | 527 | pageset->pcp[j].batch); |
492 | } | 528 | } |
493 | #ifdef CONFIG_NUMA | ||
494 | seq_printf(m, | ||
495 | "\n numa_hit: %lu" | ||
496 | "\n numa_miss: %lu" | ||
497 | "\n numa_foreign: %lu" | ||
498 | "\n interleave_hit: %lu" | ||
499 | "\n local_node: %lu" | ||
500 | "\n other_node: %lu", | ||
501 | pageset->numa_hit, | ||
502 | pageset->numa_miss, | ||
503 | pageset->numa_foreign, | ||
504 | pageset->interleave_hit, | ||
505 | pageset->local_node, | ||
506 | pageset->other_node); | ||
507 | #endif | ||
508 | } | 529 | } |
509 | seq_printf(m, | 530 | seq_printf(m, |
510 | "\n all_unreclaimable: %u" | 531 | "\n all_unreclaimable: %u" |