aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichal Hocko <mhocko@suse.com>2016-05-23 19:26:02 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-05-23 20:04:14 -0400
commitf268dfe905d4682150d4acbb25f59adc04cd9398 (patch)
treefe801df15a0b82af4ac665bfa92db7804c06f9b5
parent013373e8b86735086ac86aff782637f7e58ff84d (diff)
exec: make exec path waiting for mmap_sem killable
setup_arg_pages requires mmap_sem for write. If the waiting task gets killed by the oom killer 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. All the callers are already handling error path and the fatal signal doesn't need any additional treatment. The same applies to __bprm_mm_init. Signed-off-by: Michal Hocko <mhocko@suse.com> Acked-by: Oleg Nesterov <oleg@redhat.com> Acked-by: Vlastimil Babka <vbabka@suse.cz> Cc: Alexander Viro <viro@zeniv.linux.org.uk> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--fs/exec.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/exec.c b/fs/exec.c
index 4f079bd083af..887c1c955df8 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -263,7 +263,10 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
263 if (!vma) 263 if (!vma)
264 return -ENOMEM; 264 return -ENOMEM;
265 265
266 down_write(&mm->mmap_sem); 266 if (down_write_killable(&mm->mmap_sem)) {
267 err = -EINTR;
268 goto err_free;
269 }
267 vma->vm_mm = mm; 270 vma->vm_mm = mm;
268 271
269 /* 272 /*
@@ -290,6 +293,7 @@ static int __bprm_mm_init(struct linux_binprm *bprm)
290 return 0; 293 return 0;
291err: 294err:
292 up_write(&mm->mmap_sem); 295 up_write(&mm->mmap_sem);
296err_free:
293 bprm->vma = NULL; 297 bprm->vma = NULL;
294 kmem_cache_free(vm_area_cachep, vma); 298 kmem_cache_free(vm_area_cachep, vma);
295 return err; 299 return err;
@@ -696,7 +700,9 @@ int setup_arg_pages(struct linux_binprm *bprm,
696 bprm->loader -= stack_shift; 700 bprm->loader -= stack_shift;
697 bprm->exec -= stack_shift; 701 bprm->exec -= stack_shift;
698 702
699 down_write(&mm->mmap_sem); 703 if (down_write_killable(&mm->mmap_sem))
704 return -EINTR;
705
700 vm_flags = VM_STACK_FLAGS; 706 vm_flags = VM_STACK_FLAGS;
701 707
702 /* 708 /*