From patchwork Sun May 8 18:55:56 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikulas Patocka X-Patchwork-Id: 766432 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter2.kernel.org (8.14.4/8.14.3) with ESMTP id p48J5Id8014674 for ; Sun, 8 May 2011 19:05:20 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932234Ab1EHTFS (ORCPT ); Sun, 8 May 2011 15:05:18 -0400 Received: from artax.karlin.mff.cuni.cz ([195.113.26.195]:48366 "EHLO artax.karlin.mff.cuni.cz" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932226Ab1EHTFS (ORCPT ); Sun, 8 May 2011 15:05:18 -0400 X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter2.kernel.org [140.211.167.43]); Sun, 08 May 2011 19:05:20 +0000 (UTC) X-Greylist: delayed 560 seconds by postgrey-1.27 at vger.kernel.org; Sun, 08 May 2011 15:05:18 EDT Received: by artax.karlin.mff.cuni.cz (Postfix, from userid 17421) id 303F098096; Sun, 8 May 2011 20:55:56 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by artax.karlin.mff.cuni.cz (Postfix) with ESMTP id 2FA0598062; Sun, 8 May 2011 20:55:56 +0200 (CEST) Date: Sun, 8 May 2011 20:55:56 +0200 (CEST) From: Mikulas Patocka To: linux-kernel@vger.kernel.org, linux-parisc@vger.kernel.org, Linus Torvalds cc: Hugh Dickins , Oleg Nesterov Subject: [PATCH] Don't mlock guardpage if the stack is growing up Message-ID: User-Agent: Alpine 2.00 (DEB 1167 2008-08-23) X-Personality-Disorder: Schizoid MIME-Version: 1.0 Sender: linux-parisc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-parisc@vger.kernel.org Don't mlock guardpage if the stack is growing up Linux kernel excludes guard page when performing mlock on a VMA with down-growing stack. However, some architectures have up-growing stack and locking the guard page should be excluded in this case too. This patch fixes lvm2 on PA-RISC (and possibly other architectures with up-growing stack). lvm2 calculates the number of used pages when locking and when unlocking and reports an internal error if the numbers mismatch. On PA-RISC, the kernel would incorrectly attempt to mlock the stack guard page, this causes allocation of one more page and internal error in lvm2. Signed-off-by: Mikulas Patocka --- include/linux/mm.h | 6 ++++++ mm/memory.c | 21 ++++++++++++--------- 2 files changed, 18 insertions(+), 9 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-parisc" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Index: linux-2.6.39-rc6-fast/include/linux/mm.h =================================================================== --- linux-2.6.39-rc6-fast.orig/include/linux/mm.h 2011-05-07 05:59:51.000000000 +0200 +++ linux-2.6.39-rc6-fast/include/linux/mm.h 2011-05-07 05:59:52.000000000 +0200 @@ -1016,6 +1016,12 @@ static inline int vma_stack_continue(str return vma && (vma->vm_end == addr) && (vma->vm_flags & VM_GROWSDOWN); } +/* Is the vma a continuation of the stack vma below it? */ +static inline int vma_stack_growsup_continue(struct vm_area_struct *vma, unsigned long addr) +{ + return vma && (vma->vm_start == addr) && (vma->vm_flags & VM_GROWSUP); +} + extern unsigned long move_page_tables(struct vm_area_struct *vma, unsigned long old_addr, struct vm_area_struct *new_vma, unsigned long new_addr, unsigned long len); Index: linux-2.6.39-rc6-fast/mm/memory.c =================================================================== --- linux-2.6.39-rc6-fast.orig/mm/memory.c 2011-05-07 05:59:51.000000000 +0200 +++ linux-2.6.39-rc6-fast/mm/memory.c 2011-05-07 05:59:52.000000000 +0200 @@ -1412,9 +1412,12 @@ no_page_table: static inline int stack_guard_page(struct vm_area_struct *vma, unsigned long addr) { - return (vma->vm_flags & VM_GROWSDOWN) && + return ((vma->vm_flags & VM_GROWSDOWN) && (vma->vm_start == addr) && - !vma_stack_continue(vma->vm_prev, addr); + !vma_stack_continue(vma->vm_prev, addr)) || + ((vma->vm_flags & VM_GROWSUP) && + (vma->vm_end == addr + PAGE_SIZE) && + !vma_stack_growsup_continue(vma->vm_next, addr + PAGE_SIZE)); } /** @@ -1551,18 +1554,18 @@ int __get_user_pages(struct task_struct continue; } - /* - * If we don't actually want the page itself, - * and it's the stack guard page, just skip it. - */ - if (!pages && stack_guard_page(vma, start)) - goto next_page; - do { struct page *page; unsigned int foll_flags = gup_flags; /* + * If we don't actually want the page itself, + * and it's the stack guard page, just skip it. + */ + if (!pages && stack_guard_page(vma, start)) + goto next_page; + + /* * If we have a pending SIGKILL, don't keep faulting * pages and potentially allocating memory. */