diff options
author | Moussa A. Ba <moussa.a.ba@gmail.com> | 2009-09-21 20:02:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-22 10:17:33 -0400 |
commit | 398499d5f3613c47f2143b8c54a04efb5d7a6da9 (patch) | |
tree | 0b337ca1d0e20caa2295c159d5c0deadf362e4a0 | |
parent | 7103ad323b1ae32bedc3267402117e2f8b45e48d (diff) |
pagemap clear_refs: modify to specify anon or mapped vma clearing
The patch makes the clear_refs more versatile in adding the option to
select anonymous pages or file backed pages for clearing. This addition
has a measurable impact on user space application performance as it
decreases the number of pagewalks in scenarios where one is only
interested in a specific type of page (anonymous or file mapped).
The patch adds anonymous and file backed filters to the clear_refs interface.
echo 1 > /proc/PID/clear_refs resets the bits on all pages
echo 2 > /proc/PID/clear_refs resets the bits on anonymous pages only
echo 3 > /proc/PID/clear_refs resets the bits on file backed pages only
Any other value is ignored
Signed-off-by: Moussa A. Ba <moussa.a.ba@gmail.com>
Signed-off-by: Jared E. Hulbert <jaredeh@gmail.com>
Acked-by: David Rientjes <rientjes@google.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | Documentation/filesystems/proc.txt | 13 | ||||
-rw-r--r-- | fs/proc/task_mmu.c | 28 |
2 files changed, 37 insertions, 4 deletions
diff --git a/Documentation/filesystems/proc.txt b/Documentation/filesystems/proc.txt index 1c96cb6c7972..ae7f8bb1b7bc 100644 --- a/Documentation/filesystems/proc.txt +++ b/Documentation/filesystems/proc.txt | |||
@@ -375,6 +375,19 @@ of memory currently marked as referenced or accessed. | |||
375 | This file is only present if the CONFIG_MMU kernel configuration option is | 375 | This file is only present if the CONFIG_MMU kernel configuration option is |
376 | enabled. | 376 | enabled. |
377 | 377 | ||
378 | The /proc/PID/clear_refs is used to reset the PG_Referenced and ACCESSED/YOUNG | ||
379 | bits on both physical and virtual pages associated with a process. | ||
380 | To clear the bits for all the pages associated with the process | ||
381 | > echo 1 > /proc/PID/clear_refs | ||
382 | |||
383 | To clear the bits for the anonymous pages associated with the process | ||
384 | > echo 2 > /proc/PID/clear_refs | ||
385 | |||
386 | To clear the bits for the file mapped pages associated with the process | ||
387 | > echo 3 > /proc/PID/clear_refs | ||
388 | Any other value written to /proc/PID/clear_refs will have no effect. | ||
389 | |||
390 | |||
378 | 1.2 Kernel data | 391 | 1.2 Kernel data |
379 | --------------- | 392 | --------------- |
380 | 393 | ||
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c index 9bd8be1d235c..59e98fea34a4 100644 --- a/fs/proc/task_mmu.c +++ b/fs/proc/task_mmu.c | |||
@@ -465,6 +465,10 @@ static int clear_refs_pte_range(pmd_t *pmd, unsigned long addr, | |||
465 | return 0; | 465 | return 0; |
466 | } | 466 | } |
467 | 467 | ||
468 | #define CLEAR_REFS_ALL 1 | ||
469 | #define CLEAR_REFS_ANON 2 | ||
470 | #define CLEAR_REFS_MAPPED 3 | ||
471 | |||
468 | static ssize_t clear_refs_write(struct file *file, const char __user *buf, | 472 | static ssize_t clear_refs_write(struct file *file, const char __user *buf, |
469 | size_t count, loff_t *ppos) | 473 | size_t count, loff_t *ppos) |
470 | { | 474 | { |
@@ -472,13 +476,15 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, | |||
472 | char buffer[PROC_NUMBUF], *end; | 476 | char buffer[PROC_NUMBUF], *end; |
473 | struct mm_struct *mm; | 477 | struct mm_struct *mm; |
474 | struct vm_area_struct *vma; | 478 | struct vm_area_struct *vma; |
479 | int type; | ||
475 | 480 | ||
476 | memset(buffer, 0, sizeof(buffer)); | 481 | memset(buffer, 0, sizeof(buffer)); |
477 | if (count > sizeof(buffer) - 1) | 482 | if (count > sizeof(buffer) - 1) |
478 | count = sizeof(buffer) - 1; | 483 | count = sizeof(buffer) - 1; |
479 | if (copy_from_user(buffer, buf, count)) | 484 | if (copy_from_user(buffer, buf, count)) |
480 | return -EFAULT; | 485 | return -EFAULT; |
481 | if (!simple_strtol(buffer, &end, 0)) | 486 | type = simple_strtol(buffer, &end, 0); |
487 | if (type < CLEAR_REFS_ALL || type > CLEAR_REFS_MAPPED) | ||
482 | return -EINVAL; | 488 | return -EINVAL; |
483 | if (*end == '\n') | 489 | if (*end == '\n') |
484 | end++; | 490 | end++; |
@@ -494,9 +500,23 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, | |||
494 | down_read(&mm->mmap_sem); | 500 | down_read(&mm->mmap_sem); |
495 | for (vma = mm->mmap; vma; vma = vma->vm_next) { | 501 | for (vma = mm->mmap; vma; vma = vma->vm_next) { |
496 | clear_refs_walk.private = vma; | 502 | clear_refs_walk.private = vma; |
497 | if (!is_vm_hugetlb_page(vma)) | 503 | if (is_vm_hugetlb_page(vma)) |
498 | walk_page_range(vma->vm_start, vma->vm_end, | 504 | continue; |
499 | &clear_refs_walk); | 505 | /* |
506 | * Writing 1 to /proc/pid/clear_refs affects all pages. | ||
507 | * | ||
508 | * Writing 2 to /proc/pid/clear_refs only affects | ||
509 | * Anonymous pages. | ||
510 | * | ||
511 | * Writing 3 to /proc/pid/clear_refs only affects file | ||
512 | * mapped pages. | ||
513 | */ | ||
514 | if (type == CLEAR_REFS_ANON && vma->vm_file) | ||
515 | continue; | ||
516 | if (type == CLEAR_REFS_MAPPED && !vma->vm_file) | ||
517 | continue; | ||
518 | walk_page_range(vma->vm_start, vma->vm_end, | ||
519 | &clear_refs_walk); | ||
500 | } | 520 | } |
501 | flush_tlb_mm(mm); | 521 | flush_tlb_mm(mm); |
502 | up_read(&mm->mmap_sem); | 522 | up_read(&mm->mmap_sem); |