Commit 1f1cd7054fe7f45e65dd4963d0a38e5ab7a57cae
Committed by
Linus Torvalds
1 parent
363ee17f0f
Exists in
master
and in
16 other branches
mm/mlock: prepare params outside critical region
All mlock related syscalls prepare lock limits, lengths and start parameters with the mmap_sem held. Move this logic outside of the critical region. For the case of mlock, continue incrementing the amount already locked by mm->locked_vm with the rwsem taken. Signed-off-by: Davidlohr Bueso <davidlohr@hp.com> Cc: Rik van Riel <riel@redhat.com> Reviewed-by: Michel Lespinasse <walken@google.com> Acked-by: Vlastimil Babka <vbabka@suse.cz> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 11 additions and 7 deletions Side-by-side Diff
mm/mlock.c
... | ... | @@ -709,19 +709,21 @@ |
709 | 709 | |
710 | 710 | lru_add_drain_all(); /* flush pagevec */ |
711 | 711 | |
712 | - down_write(¤t->mm->mmap_sem); | |
713 | 712 | len = PAGE_ALIGN(len + (start & ~PAGE_MASK)); |
714 | 713 | start &= PAGE_MASK; |
715 | 714 | |
716 | - locked = len >> PAGE_SHIFT; | |
717 | - locked += current->mm->locked_vm; | |
718 | - | |
719 | 715 | lock_limit = rlimit(RLIMIT_MEMLOCK); |
720 | 716 | lock_limit >>= PAGE_SHIFT; |
717 | + locked = len >> PAGE_SHIFT; | |
721 | 718 | |
719 | + down_write(¤t->mm->mmap_sem); | |
720 | + | |
721 | + locked += current->mm->locked_vm; | |
722 | + | |
722 | 723 | /* check against resource limits */ |
723 | 724 | if ((locked <= lock_limit) || capable(CAP_IPC_LOCK)) |
724 | 725 | error = do_mlock(start, len, 1); |
726 | + | |
725 | 727 | up_write(¤t->mm->mmap_sem); |
726 | 728 | if (!error) |
727 | 729 | error = __mm_populate(start, len, 0); |
728 | 730 | |
729 | 731 | |
... | ... | @@ -732,11 +734,13 @@ |
732 | 734 | { |
733 | 735 | int ret; |
734 | 736 | |
735 | - down_write(¤t->mm->mmap_sem); | |
736 | 737 | len = PAGE_ALIGN(len + (start & ~PAGE_MASK)); |
737 | 738 | start &= PAGE_MASK; |
739 | + | |
740 | + down_write(¤t->mm->mmap_sem); | |
738 | 741 | ret = do_mlock(start, len, 0); |
739 | 742 | up_write(¤t->mm->mmap_sem); |
743 | + | |
740 | 744 | return ret; |
741 | 745 | } |
742 | 746 | |
743 | 747 | |
... | ... | @@ -781,12 +785,12 @@ |
781 | 785 | if (flags & MCL_CURRENT) |
782 | 786 | lru_add_drain_all(); /* flush pagevec */ |
783 | 787 | |
784 | - down_write(¤t->mm->mmap_sem); | |
785 | - | |
786 | 788 | lock_limit = rlimit(RLIMIT_MEMLOCK); |
787 | 789 | lock_limit >>= PAGE_SHIFT; |
788 | 790 | |
789 | 791 | ret = -ENOMEM; |
792 | + down_write(¤t->mm->mmap_sem); | |
793 | + | |
790 | 794 | if (!(flags & MCL_CURRENT) || (current->mm->total_vm <= lock_limit) || |
791 | 795 | capable(CAP_IPC_LOCK)) |
792 | 796 | ret = do_mlockall(flags); |