mm: make mmap_sem for write waits killable for mm syscalls
[platform/kernel/linux-exynos.git] / mm / mmap.c
index b9274a0..11e1f2c 100644 (file)
--- a/mm/mmap.c
+++ b/mm/mmap.c
@@ -178,7 +178,8 @@ SYSCALL_DEFINE1(brk, unsigned long, brk)
        unsigned long min_brk;
        bool populate;
 
-       down_write(&mm->mmap_sem);
+       if (down_write_killable(&mm->mmap_sem))
+               return -EINTR;
 
 #ifdef CONFIG_COMPAT_BRK
        /*
@@ -1332,7 +1333,7 @@ SYSCALL_DEFINE6(mmap_pgoff, unsigned long, addr, unsigned long, len,
 
        flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);
 
-       retval = vm_mmap_pgoff(file, addr, len, prot, flags, pgoff);
+       retval = vm_mmap_pgoff(file, addr, len, prot, flags, pgoff, true);
 out_fput:
        if (file)
                fput(file);
@@ -2493,6 +2494,10 @@ int vm_munmap(unsigned long start, size_t len)
        int ret;
        struct mm_struct *mm = current->mm;
 
+       /*
+        * XXX convert to down_write_killable as soon as all users are able
+        * to handle the error.
+        */
        down_write(&mm->mmap_sem);
        ret = do_munmap(mm, start, len);
        up_write(&mm->mmap_sem);
@@ -2502,8 +2507,15 @@ EXPORT_SYMBOL(vm_munmap);
 
 SYSCALL_DEFINE2(munmap, unsigned long, addr, size_t, len)
 {
+       int ret;
+       struct mm_struct *mm = current->mm;
+
        profile_munmap(addr);
-       return vm_munmap(addr, len);
+       if (down_write_killable(&mm->mmap_sem))
+               return -EINTR;
+       ret = do_munmap(mm, addr, len);
+       up_write(&mm->mmap_sem);
+       return ret;
 }
 
 
@@ -2535,7 +2547,9 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size,
        if (pgoff + (size >> PAGE_SHIFT) < pgoff)
                return ret;
 
-       down_write(&mm->mmap_sem);
+       if (down_write_killable(&mm->mmap_sem))
+               return -EINTR;
+
        vma = find_vma(mm, start);
 
        if (!vma || !(vma->vm_flags & VM_SHARED))
@@ -2700,6 +2714,11 @@ unsigned long vm_brk(unsigned long addr, unsigned long len)
        unsigned long ret;
        bool populate;
 
+       /*
+        * XXX not all users are chcecking the return value, convert
+        * to down_write_killable after they are able to cope with
+        * error
+        */
        down_write(&mm->mmap_sem);
        ret = do_brk(addr, len);
        populate = ((mm->def_flags & VM_LOCKED) != 0);