aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Hocko <mhocko@suse.com>2016-05-23 19:25:45 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-23 20:04:14 -0400
commit4e80153a6044bcd9a7d65c1ec4b1d1c44ba0ed6c (patch)
tree003fcb1ecafae6143e8e159517b6905f3442d5ee
parent2d6c928241add2848e4eebfce407e95164229976 (diff)
mm, proc: make clear_refs killable
CLEAR_REFS_MM_HIWATER_RSS and CLEAR_REFS_SOFT_DIRTY are relying on mmap_sem for write. If the waiting task gets killed by the oom killer and it would operate on the current's mm it would block oom_reaper from asynchronous address space reclaim and reduce the chances of timely OOM resolving. Wait for the lock in the killable mode and return with EINTR if the task got killed while waiting. This will also expedite the return to the userspace and do_exit even if the mm is remote. Signed-off-by: Michal Hocko <mhocko@suse.com> Acked-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Vlastimil Babka <vbabka@suse.cz> Cc: Petr Cermak <petrcermak@chromium.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/proc/task_mmu.c11
1 files changed, 9 insertions, 2 deletions
diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c
index 541583510cfb..4648c7f63ae2 100644
--- a/fs/proc/task_mmu.c
+++ b/fs/proc/task_mmu.c
@@ -1027,11 +1027,15 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf,
1027 }; 1027 };
1028 1028
1029 if (type == CLEAR_REFS_MM_HIWATER_RSS) { 1029 if (type == CLEAR_REFS_MM_HIWATER_RSS) {
1030 if (down_write_killable(&mm->mmap_sem)) {
1031 count = -EINTR;
1032 goto out_mm;
1033 }
1034
1030 /* 1035 /*
1031 * Writing 5 to /proc/pid/clear_refs resets the peak 1036 * Writing 5 to /proc/pid/clear_refs resets the peak
1032 * resident set size to this mm's current rss value. 1037 * resident set size to this mm's current rss value.
1033 */ 1038 */
1034 down_write(&mm->mmap_sem);
1035 reset_mm_hiwater_rss(mm); 1039 reset_mm_hiwater_rss(mm);
1036 up_write(&mm->mmap_sem); 1040 up_write(&mm->mmap_sem);
1037 goto out_mm; 1041 goto out_mm;
@@ -1043,7 +1047,10 @@ static ssize_t clear_refs_write(struct file *file, const char __user *buf,
1043 if (!(vma->vm_flags & VM_SOFTDIRTY)) 1047 if (!(vma->vm_flags & VM_SOFTDIRTY))
1044 continue; 1048 continue;
1045 up_read(&mm->mmap_sem); 1049 up_read(&mm->mmap_sem);
1046 down_write(&mm->mmap_sem); 1050 if (down_write_killable(&mm->mmap_sem)) {
1051 count = -EINTR;
1052 goto out_mm;
1053 }
1047 for (vma = mm->mmap; vma; vma = vma->vm_next) { 1054 for (vma = mm->mmap; vma; vma = vma->vm_next) {
1048 vma->vm_flags &= ~VM_SOFTDIRTY; 1055 vma->vm_flags &= ~VM_SOFTDIRTY;
1049 vma_set_page_prot(vma); 1056 vma_set_page_prot(vma);