From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-wm0-f69.google.com (mail-wm0-f69.google.com [74.125.82.69]) by kanga.kvack.org (Postfix) with ESMTP id 0DF4382F64 for ; Tue, 30 Aug 2016 07:35:18 -0400 (EDT) Received: by mail-wm0-f69.google.com with SMTP id o80so13929060wme.1 for ; Tue, 30 Aug 2016 04:35:17 -0700 (PDT) Received: from mail-lf0-x241.google.com (mail-lf0-x241.google.com. [2a00:1450:4010:c07::241]) by mx.google.com with ESMTPS id 103si17613277lfx.276.2016.08.30.04.35.16 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 30 Aug 2016 04:35:16 -0700 (PDT) Received: by mail-lf0-x241.google.com with SMTP id 33so823338lfw.3 for ; Tue, 30 Aug 2016 04:35:16 -0700 (PDT) Date: Tue, 30 Aug 2016 14:35:13 +0300 From: "Kirill A. Shutemov" Subject: Re: [PATCH 1/4] mm: mlock: check against vma for actual mlock() size Message-ID: <20160830113513.GA32187@node.shutemov.name> References: <1472554781-9835-1-git-send-email-wei.guo.simon@gmail.com> <1472554781-9835-2-git-send-email-wei.guo.simon@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1472554781-9835-2-git-send-email-wei.guo.simon@gmail.com> Sender: owner-linux-mm@kvack.org List-ID: To: wei.guo.simon@gmail.com Cc: linux-mm@kvack.org, Alexey Klimov , Andrew Morton , Eric B Munson , Geert Uytterhoeven , "Kirill A. Shutemov" , linux-kernel@vger.kernel.org, linux-kselftest@vger.kernel.org, Mel Gorman , Michal Hocko , Shuah Khan , Thierry Reding , Vlastimil Babka On Tue, Aug 30, 2016 at 06:59:38PM +0800, wei.guo.simon@gmail.com wrote: > From: Simon Guo > > In do_mlock(), the check against locked memory limitation > has a hole which will fail following cases at step 3): > 1) User has a memory chunk from addressA with 50k, and user > mem lock rlimit is 64k. > 2) mlock(addressA, 30k) > 3) mlock(addressA, 40k) > > The 3rd step should have been allowed since the 40k request > is intersected with the previous 30k at step 2), and the > 3rd step is actually for mlock on the extra 10k memory. > > This patch checks vma to caculate the actual "new" mlock > size, if necessary, and ajust the logic to fix this issue. > > Signed-off-by: Simon Guo Looks reasonable to me. Few nitpicks below. > --- > mm/mlock.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 49 insertions(+) > > diff --git a/mm/mlock.c b/mm/mlock.c > index 14645be..9283187 100644 > --- a/mm/mlock.c > +++ b/mm/mlock.c > @@ -617,6 +617,43 @@ static int apply_vma_lock_flags(unsigned long start, size_t len, > return error; > } > > +/* > + * Go through vma areas and sum size of mlocked > + * vma pages, as return value. > + * Note deferred memory locking case(mlock2(,,MLOCK_ONFAULT) > + * is also counted. > + * Return value: previously mlocked page counts > + */ > +static int count_mm_mlocked_page_nr(struct mm_struct *mm, > + unsigned long start, size_t len) > +{ > + struct vm_area_struct *vma; > + int count = 0; > + > + if (mm == NULL) > + mm = current->mm; > + > + vma = find_vma(mm, start); > + if (vma == NULL) > + vma = mm->mmap; > + > + for (; vma ; vma = vma->vm_next) { > + if (start + len <= vma->vm_start) > + break; for (; vma && start + len <= vma->vm_start; vma = vma->vm_next) { > + if (vma->vm_flags && VM_LOCKED) { > + if (start > vma->vm_start) > + count -= (start - vma->vm_start); > + if (start + len < vma->vm_end) { > + count += start + len - vma->vm_start; > + break; > + } > + count += vma->vm_end - vma->vm_start; > + } > + } > + > + return (PAGE_ALIGN(count) >> PAGE_SHIFT); Redundant parenthesis. And do we need PAGE_ALIGN() here? Caller already aligned 'len', and vma boundaries are alinged. > +} > + > static __must_check int do_mlock(unsigned long start, size_t len, vm_flags_t flags) > { > unsigned long locked; > @@ -639,6 +676,18 @@ static __must_check int do_mlock(unsigned long start, size_t len, vm_flags_t fla > return -EINTR; > > locked += current->mm->locked_vm; > + if ((locked > lock_limit) && (!capable(CAP_IPC_LOCK))) { > + /* > + * It is possible that the regions requested > + * intersect with previously mlocked areas, > + * that part area in "mm->locked_vm" should > + * not be counted to new mlock increment > + * count. So check and adjust locked count > + * if necessary. > + */ > + locked -= count_mm_mlocked_page_nr(current->mm, > + start, len); > + } > > /* check against resource limits */ > if ((locked <= lock_limit) || capable(CAP_IPC_LOCK)) > -- > 1.8.3.1 > > -- > To unsubscribe, send a message with 'unsubscribe linux-mm' in > the body to majordomo@kvack.org. For more info on Linux MM, > see: http://www.linux-mm.org/ . > Don't email: email@kvack.org -- Kirill A. Shutemov -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org