Commit 695f0559 authored by Petr Cermak's avatar Petr Cermak Committed by Linus Torvalds

fs/proc/task_mmu.c: add user-space support for resetting mm->hiwater_rss (peak RSS)

Peak resident size of a process can be reset back to the process's
current rss value by writing "5" to /proc/pid/clear_refs.  The driving
use-case for this would be getting the peak RSS value, which can be
retrieved from the VmHWM field in /proc/pid/status, per benchmark
iteration or test scenario.

[akpm@linux-foundation.org: clarify behaviour in documentation]
Signed-off-by: default avatarPetr Cermak <petrcermak@chromium.org>
Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Primiano Tucci <primiano@chromium.org>
Cc: Petr Cermak <petrcermak@chromium.org>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent d170cf46
...@@ -489,6 +489,10 @@ To clear the bits for the file mapped pages associated with the process ...@@ -489,6 +489,10 @@ To clear the bits for the file mapped pages associated with the process
To clear the soft-dirty bit To clear the soft-dirty bit
> echo 4 > /proc/PID/clear_refs > echo 4 > /proc/PID/clear_refs
To reset the peak resident set size ("high water mark") to the process's
current value:
> echo 5 > /proc/PID/clear_refs
Any other value written to /proc/PID/clear_refs will have no effect. Any other value written to /proc/PID/clear_refs will have no effect.
The /proc/pid/pagemap gives the PFN, which can be used to find the pageflags The /proc/pid/pagemap gives the PFN, which can be used to find the pageflags
......
...@@ -732,6 +732,7 @@ enum clear_refs_types { ...@@ -732,6 +732,7 @@ enum clear_refs_types {
CLEAR_REFS_ANON, CLEAR_REFS_ANON,
CLEAR_REFS_MAPPED, CLEAR_REFS_MAPPED,
CLEAR_REFS_SOFT_DIRTY, CLEAR_REFS_SOFT_DIRTY,
CLEAR_REFS_MM_HIWATER_RSS,
CLEAR_REFS_LAST, CLEAR_REFS_LAST,
}; };
...@@ -907,6 +908,18 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, ...@@ -907,6 +908,18 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf,
.mm = mm, .mm = mm,
.private = &cp, .private = &cp,
}; };
if (type == CLEAR_REFS_MM_HIWATER_RSS) {
/*
* Writing 5 to /proc/pid/clear_refs resets the peak
* resident set size to this mm's current rss value.
*/
down_write(&mm->mmap_sem);
reset_mm_hiwater_rss(mm);
up_write(&mm->mmap_sem);
goto out_mm;
}
down_read(&mm->mmap_sem); down_read(&mm->mmap_sem);
if (type == CLEAR_REFS_SOFT_DIRTY) { if (type == CLEAR_REFS_SOFT_DIRTY) {
for (vma = mm->mmap; vma; vma = vma->vm_next) { for (vma = mm->mmap; vma; vma = vma->vm_next) {
...@@ -928,6 +941,7 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf, ...@@ -928,6 +941,7 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf,
mmu_notifier_invalidate_range_end(mm, 0, -1); mmu_notifier_invalidate_range_end(mm, 0, -1);
flush_tlb_mm(mm); flush_tlb_mm(mm);
up_read(&mm->mmap_sem); up_read(&mm->mmap_sem);
out_mm:
mmput(mm); mmput(mm);
} }
put_task_struct(task); put_task_struct(task);
......
...@@ -1408,6 +1408,11 @@ static inline void update_hiwater_vm(struct mm_struct *mm) ...@@ -1408,6 +1408,11 @@ static inline void update_hiwater_vm(struct mm_struct *mm)
mm->hiwater_vm = mm->total_vm; mm->hiwater_vm = mm->total_vm;
} }
static inline void reset_mm_hiwater_rss(struct mm_struct *mm)
{
mm->hiwater_rss = get_mm_rss(mm);
}
static inline void setmax_mm_hiwater_rss(unsigned long *maxrss, static inline void setmax_mm_hiwater_rss(unsigned long *maxrss,
struct mm_struct *mm) struct mm_struct *mm)
{ {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment