diff options
author | Christoph Lameter <clameter@sgi.com> | 2006-01-08 04:01:02 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-08 23:12:44 -0500 |
commit | 1a75a6c825c17249ca49f050a872a04ce0997ce3 (patch) | |
tree | 2ca8fc6513a20e5b4bec67686323ce1f5c8e237c /fs/proc | |
parent | 38e35860dbe6197a4b42eb6e8b47da940b7695dd (diff) |
[PATCH] Fold numa_maps into mempolicies.c
First discussed at http://marc.theaimsgroup.com/?t=113149255100001&r=1&w=2
- Use the check_range() in mempolicy.c to gather statistics.
- Improve the numa_maps code in general and fix some comments.
Signed-off-by: Christoph Lameter <clameter@sgi.com>
Cc: Andi Kleen <ak@muc.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/proc')
-rw-r--r-- | fs/proc/task_mmu.c | 127 |
1 files changed, 5 insertions, 122 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 50bd5a8f0446..0eaad41f4658 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -390,129 +390,12 @@ struct seq_operations proc_pid_smaps_op = { | |||
390 | }; | 390 | }; |
391 | 391 | ||
392 | #ifdef CONFIG_NUMA | 392 | #ifdef CONFIG_NUMA |
393 | 393 | extern int show_numa_map(struct seq_file *m, void *v); | |
394 | struct numa_maps { | ||
395 | unsigned long pages; | ||
396 | unsigned long anon; | ||
397 | unsigned long mapped; | ||
398 | unsigned long mapcount_max; | ||
399 | unsigned long node[MAX_NUMNODES]; | ||
400 | }; | ||
401 | |||
402 | /* | ||
403 | * Calculate numa node maps for a vma | ||
404 | */ | ||
405 | static struct numa_maps *get_numa_maps(struct vm_area_struct *vma) | ||
406 | { | ||
407 | int i; | ||
408 | struct page *page; | ||
409 | unsigned long vaddr; | ||
410 | struct numa_maps *md = kmalloc(sizeof(struct numa_maps), GFP_KERNEL); | ||
411 | |||
412 | if (!md) | ||
413 | return NULL; | ||
414 | md->pages = 0; | ||
415 | md->anon = 0; | ||
416 | md->mapped = 0; | ||
417 | md->mapcount_max = 0; | ||
418 | for_each_node(i) | ||
419 | md->node[i] =0; | ||
420 | |||
421 | for (vaddr = vma->vm_start; vaddr < vma->vm_end; vaddr += PAGE_SIZE) { | ||
422 | page = follow_page(vma, vaddr, 0); | ||
423 | if (page) { | ||
424 | int count = page_mapcount(page); | ||
425 | |||
426 | if (count) | ||
427 | md->mapped++; | ||
428 | if (count > md->mapcount_max) | ||
429 | md->mapcount_max = count; | ||
430 | md->pages++; | ||
431 | if (PageAnon(page)) | ||
432 | md->anon++; | ||
433 | md->node[page_to_nid(page)]++; | ||
434 | } | ||
435 | cond_resched(); | ||
436 | } | ||
437 | return md; | ||
438 | } | ||
439 | |||
440 | static int show_numa_map(struct seq_file *m, void *v) | ||
441 | { | ||
442 | struct task_struct *task = m->private; | ||
443 | struct vm_area_struct *vma = v; | ||
444 | struct mempolicy *pol; | ||
445 | struct numa_maps *md; | ||
446 | struct zone **z; | ||
447 | int n; | ||
448 | int first; | ||
449 | |||
450 | if (!vma->vm_mm) | ||
451 | return 0; | ||
452 | |||
453 | md = get_numa_maps(vma); | ||
454 | if (!md) | ||
455 | return 0; | ||
456 | |||
457 | seq_printf(m, "%08lx", vma->vm_start); | ||
458 | pol = get_vma_policy(task, vma, vma->vm_start); | ||
459 | /* Print policy */ | ||
460 | switch (pol->policy) { | ||
461 | case MPOL_PREFERRED: | ||
462 | seq_printf(m, " prefer=%d", pol->v.preferred_node); | ||
463 | break; | ||
464 | case MPOL_BIND: | ||
465 | seq_printf(m, " bind={"); | ||
466 | first = 1; | ||
467 | for (z = pol->v.zonelist->zones; *z; z++) { | ||
468 | |||
469 | if (!first) | ||
470 | seq_putc(m, ','); | ||
471 | else | ||
472 | first = 0; | ||
473 | seq_printf(m, "%d/%s", (*z)->zone_pgdat->node_id, | ||
474 | (*z)->name); | ||
475 | } | ||
476 | seq_putc(m, '}'); | ||
477 | break; | ||
478 | case MPOL_INTERLEAVE: | ||
479 | seq_printf(m, " interleave={"); | ||
480 | first = 1; | ||
481 | for_each_node(n) { | ||
482 | if (node_isset(n, pol->v.nodes)) { | ||
483 | if (!first) | ||
484 | seq_putc(m,','); | ||
485 | else | ||
486 | first = 0; | ||
487 | seq_printf(m, "%d",n); | ||
488 | } | ||
489 | } | ||
490 | seq_putc(m, '}'); | ||
491 | break; | ||
492 | default: | ||
493 | seq_printf(m," default"); | ||
494 | break; | ||
495 | } | ||
496 | seq_printf(m, " MaxRef=%lu Pages=%lu Mapped=%lu", | ||
497 | md->mapcount_max, md->pages, md->mapped); | ||
498 | if (md->anon) | ||
499 | seq_printf(m," Anon=%lu",md->anon); | ||
500 | |||
501 | for_each_online_node(n) { | ||
502 | if (md->node[n]) | ||
503 | seq_printf(m, " N%d=%lu", n, md->node[n]); | ||
504 | } | ||
505 | seq_putc(m, '\n'); | ||
506 | kfree(md); | ||
507 | if (m->count < m->size) /* vma is copied successfully */ | ||
508 | m->version = (vma != get_gate_vma(task)) ? vma->vm_start : 0; | ||
509 | return 0; | ||
510 | } | ||
511 | 394 | ||
512 | struct seq_operations proc_pid_numa_maps_op = { | 395 | struct seq_operations proc_pid_numa_maps_op = { |
513 | .start = m_start, | 396 | .start = m_start, |
514 | .next = m_next, | 397 | .next = m_next, |
515 | .stop = m_stop, | 398 | .stop = m_stop, |
516 | .show = show_numa_map | 399 | .show = show_numa_map |
517 | }; | 400 | }; |
518 | #endif | 401 | #endif |