From patchwork Sat Jan 7 23:37:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hugh Dickins X-Patchwork-Id: 712318 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3twyYR1H3Fz9sxS for ; Sun, 8 Jan 2017 10:39:07 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="L7Xz+4U7"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3twyYR06P8zDqWc for ; Sun, 8 Jan 2017 10:39:07 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="L7Xz+4U7"; dkim-atps=neutral X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Received: from mail-pg0-x232.google.com (mail-pg0-x232.google.com [IPv6:2607:f8b0:400e:c05::232]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3twyWw6XQBzDqWT for ; Sun, 8 Jan 2017 10:37:48 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=google.com header.i=@google.com header.b="L7Xz+4U7"; dkim-atps=neutral Received: by mail-pg0-x232.google.com with SMTP id 14so18455958pgg.1 for ; Sat, 07 Jan 2017 15:37:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:from:to:cc:subject:message-id:user-agent:mime-version; bh=1SO5kkzD+Z2dbhPAB1IcZ3Qvjw06JNfdhViMb3UNP1c=; b=L7Xz+4U7McFc7O60ex7cssIPuJy2kn1tn4rDoAx4P5nhi+M0v0p5Xsr6fnRNP/7B2j putWLRUMgH+RDRL7ReFZb5JXCjBymjTsQyYvIDHrSFZQtrW9f1aPR0ayIdcGY9EQaeVz eF81/nAgIEtusUZD7OLXkCQpjMVsV2xp3pMQhdfGd+lhRjOjdMoZQMP3Ko370s/FfwgY 3cv1zc8R2Rz0snFXKlWzFDuW2Ys016djwSOJwbkI/oga2ZHCR/duxPhoqcZFrE5npK4C jPRdowtKpan0zSITvk8F5RJ6+aKCpiYJld/WFYAVbRuCUOJt4SMdRkY+Kb0idEcQdyrW c+yA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:user-agent :mime-version; bh=1SO5kkzD+Z2dbhPAB1IcZ3Qvjw06JNfdhViMb3UNP1c=; b=K/oEI+U5RiDe9HHTjI3q4G0UcqHHx8WPs7C7VawSRg3RZiynL6oiTVitEEl18zLGb1 LDPRCHTy6WNrJuxMgMXUcbQkq83l6bwUvYuWq3C5OTZw+vU8YDjGPLHN51FPZTCX6A7+ 6Z4cPYV96Ak1GwOHNVG2pyvTZVOVcfVXhSyt3uMOFJDI2VGGdYga3q72Wx2dAlWdICpJ cuNnTof1udmMo3EMApFAYKLZAw06pv1hocS5nM6Fxz7DlIxy2YTwrHRjOOj3cwdXtaqZ CPPMaiDwnGKF/QSWh605xQgCzrSqutY4MdB+2RpC4tk8U1D5WZ4HMeQH0tcpD2sq3Wjj b21w== X-Gm-Message-State: AIkVDXIFUjxfEgKZz+BDqXq9oxCZYaDDPkfsKojTneHliqOCPv1G5pctua7CJXkE1j94LL9R X-Received: by 10.84.178.7 with SMTP id y7mr4952156plb.60.1483832263991; Sat, 07 Jan 2017 15:37:43 -0800 (PST) Received: from eggly.attlocal.net (172-10-233-147.lightspeed.sntcca.sbcglobal.net. [172.10.233.147]) by smtp.gmail.com with ESMTPSA id 78sm103942114pfj.23.2017.01.07.15.37.41 (version=TLS1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 07 Jan 2017 15:37:42 -0800 (PST) Date: Sat, 7 Jan 2017 15:37:31 -0800 (PST) From: Hugh Dickins X-X-Sender: hugh@eggly.anvils To: Linus Torvalds , "Aneesh Kumar K.V" Subject: [PATCH] mm: stop leaking PageTables Message-ID: User-Agent: Alpine 2.11 (LSU 23 2013-08-11) MIME-Version: 1.0 X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: linux-mm@kvack.org, Andrew Morton , linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org, "Kirill A. Shutemov" Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" 4.10-rc loadtest (even on x86, even without THPCache) fails with "fork: Cannot allocate memory" or some such; and /proc/meminfo shows PageTables growing. rc1 removed the freeing of an unused preallocated pagetable after do_fault_around() has called map_pages(): which is usually a good optimization, so that the followup doesn't have to reallocate one; but it's not sufficient to shift the freeing into alloc_set_pte(), since there are failure cases (most commonly VM_FAULT_RETRY) which never reach finish_fault(). Check and free it at the outer level in do_fault(), then we don't need to worry in alloc_set_pte(), and can restore that to how it was (I cannot find any reason to pte_free() under lock as it was doing). And fix a separate pagetable leak, or crash, introduced by the same change, that could only show up on some ppc64: why does do_set_pmd()'s failure case attempt to withdraw a pagetable when it never deposited one, at the same time overwriting (so leaking) the vmf->prealloc_pte? Residue of an earlier implementation, perhaps? Delete it. Fixes: 953c66c2b22a ("mm: THP page cache support for ppc64") Signed-off-by: Hugh Dickins Reviewed-by: Aneesh Kumar K.V Acked-by: Kirill A. Shutemov --- mm/memory.c | 47 ++++++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) --- 4.10-rc2/mm/memory.c 2016-12-25 18:40:50.830453384 -0800 +++ linux/mm/memory.c 2017-01-07 13:34:29.373381551 -0800 @@ -3008,13 +3008,6 @@ static int do_set_pmd(struct vm_fault *v ret = 0; count_vm_event(THP_FILE_MAPPED); out: - /* - * If we are going to fallback to pte mapping, do a - * withdraw with pmd lock held. - */ - if (arch_needs_pgtable_deposit() && ret == VM_FAULT_FALLBACK) - vmf->prealloc_pte = pgtable_trans_huge_withdraw(vma->vm_mm, - vmf->pmd); spin_unlock(vmf->ptl); return ret; } @@ -3055,20 +3048,18 @@ int alloc_set_pte(struct vm_fault *vmf, ret = do_set_pmd(vmf, page); if (ret != VM_FAULT_FALLBACK) - goto fault_handled; + return ret; } if (!vmf->pte) { ret = pte_alloc_one_map(vmf); if (ret) - goto fault_handled; + return ret; } /* Re-check under ptl */ - if (unlikely(!pte_none(*vmf->pte))) { - ret = VM_FAULT_NOPAGE; - goto fault_handled; - } + if (unlikely(!pte_none(*vmf->pte))) + return VM_FAULT_NOPAGE; flush_icache_page(vma, page); entry = mk_pte(page, vma->vm_page_prot); @@ -3088,15 +3079,8 @@ int alloc_set_pte(struct vm_fault *vmf, /* no need to invalidate: a not-present page won't be cached */ update_mmu_cache(vma, vmf->address, vmf->pte); - ret = 0; -fault_handled: - /* preallocated pagetable is unused: free it */ - if (vmf->prealloc_pte) { - pte_free(vmf->vma->vm_mm, vmf->prealloc_pte); - vmf->prealloc_pte = 0; - } - return ret; + return 0; } @@ -3360,15 +3344,24 @@ static int do_shared_fault(struct vm_fau static int do_fault(struct vm_fault *vmf) { struct vm_area_struct *vma = vmf->vma; + int ret; /* The VMA was not fully populated on mmap() or missing VM_DONTEXPAND */ if (!vma->vm_ops->fault) - return VM_FAULT_SIGBUS; - if (!(vmf->flags & FAULT_FLAG_WRITE)) - return do_read_fault(vmf); - if (!(vma->vm_flags & VM_SHARED)) - return do_cow_fault(vmf); - return do_shared_fault(vmf); + ret = VM_FAULT_SIGBUS; + else if (!(vmf->flags & FAULT_FLAG_WRITE)) + ret = do_read_fault(vmf); + else if (!(vma->vm_flags & VM_SHARED)) + ret = do_cow_fault(vmf); + else + ret = do_shared_fault(vmf); + + /* preallocated pagetable is unused: free it */ + if (vmf->prealloc_pte) { + pte_free(vma->vm_mm, vmf->prealloc_pte); + vmf->prealloc_pte = 0; + } + return ret; } static int numa_migrate_prep(struct page *page, struct vm_area_struct *vma,