From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755387AbcAXWbu (ORCPT ); Sun, 24 Jan 2016 17:31:50 -0500 Received: from youngberry.canonical.com ([91.189.89.112]:60689 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751501AbcAXWDN (ORCPT ); Sun, 24 Jan 2016 17:03:13 -0500 From: Luis Henriques To: linux-kernel@vger.kernel.org, stable@vger.kernel.org, kernel-team@lists.ubuntu.com Cc: Naoya Horiguchi , David Rientjes , Dave Hansen , Mel Gorman , Joonsoo Kim , Hillf Danton , Mike Kravetz , Andrew Morton , Linus Torvalds , Luis Henriques Subject: [PATCH 3.16.y-ckt 042/128] mm: hugetlb: fix hugepage memory leak caused by wrong reserve count Date: Sun, 24 Jan 2016 21:59:57 +0000 Message-Id: <1453672883-2708-43-git-send-email-luis.henriques@canonical.com> In-Reply-To: <1453672883-2708-1-git-send-email-luis.henriques@canonical.com> References: <1453672883-2708-1-git-send-email-luis.henriques@canonical.com> X-Extended-Stable: 3.16 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 3.16.7-ckt23 -stable review patch. If anyone has any objections, please let me know. ---8<------------------------------------------------------------ From: Naoya Horiguchi commit a88c769548047b21f76fd71e04b6a3300ff17160 upstream. When dequeue_huge_page_vma() in alloc_huge_page() fails, we fall back on alloc_buddy_huge_page() to directly create a hugepage from the buddy allocator. In that case, however, if alloc_buddy_huge_page() succeeds we don't decrement h->resv_huge_pages, which means that successful hugetlb_fault() returns without releasing the reserve count. As a result, subsequent hugetlb_fault() might fail despite that there are still free hugepages. This patch simply adds decrementing code on that code path. I reproduced this problem when testing v4.3 kernel in the following situation: - the test machine/VM is a NUMA system, - hugepage overcommiting is enabled, - most of hugepages are allocated and there's only one free hugepage which is on node 0 (for example), - another program, which calls set_mempolicy(MPOL_BIND) to bind itself to node 1, tries to allocate a hugepage, - the allocation should fail but the reserve count is still hold. Signed-off-by: Naoya Horiguchi Cc: David Rientjes Cc: Dave Hansen Cc: Mel Gorman Cc: Joonsoo Kim Cc: Hillf Danton Cc: Mike Kravetz Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds [ luis: backported to 3.16: - use 'chg' instead of 'gbl_chg' - adjusted context ] Signed-off-by: Luis Henriques --- mm/hugetlb.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/mm/hugetlb.c b/mm/hugetlb.c index f3111955b701..b247049b534a 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -1398,7 +1398,10 @@ static struct page *alloc_huge_page(struct vm_area_struct *vma, page = alloc_buddy_huge_page(h, NUMA_NO_NODE); if (!page) goto out_uncharge_cgroup; - + if (!avoid_reserve && vma_has_reserves(vma, chg)) { + SetPagePrivate(page); + h->resv_huge_pages--; + } spin_lock(&hugetlb_lock); list_move(&page->lru, &h->hugepage_activelist); /* Fall through */