Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp8247206ybi; Tue, 23 Jul 2019 05:25:00 -0700 (PDT) X-Google-Smtp-Source: APXvYqyeA3hilb4qwRQQ816NA1mnHHTW/RBPZxk23n8lcw0iiZnCzENITbJoLNZ02CBfbDfnhY4B X-Received: by 2002:aa7:81d9:: with SMTP id c25mr5634787pfn.255.1563884700704; Tue, 23 Jul 2019 05:25:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1563884700; cv=none; d=google.com; s=arc-20160816; b=nqk0++VR+2yjmi1J58yq37dm7cSU0S0Cr7EwrUXoBg2inl+usa4mkO2OQmFLHAYEhE RC4twehAhoji7Jm3ts4VimnrxlOYOePvzR3VKdaGBB0P5NNA0YdLhVoXGg7Ige4hmhsB +W9bev0PefBuVKbx23J7xlBWrrF4e1gWZyxlCo0zmuG+cXQYMX6wySdn2RWCV+Fxx29x OTdZ1sx9xNHRFoQzbiSmV6opAE1YnEgJwrt0El+DviBGPezdBQ0VSSVrE86MzllwwljI 44a9tcZC1uEaNCb9rk4HK+BuNJgp0voAW0EMcn2Xuha6XTHnRTXq2maiVwuvyK8Kp35N TqeQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from; bh=F+p/XLzgGK35dc/+vVCczri8W+LLCyIKn+GJ6nstQ1U=; b=mzrenmSZOsAW9o2pevbDkj18UWxm7O8tQsEjZqSDLqGYPC1AO3u7iHDcjE81iBFUFs hbG0hgm4QNXuSMoOct1dNGi4L0bT1QbZKxFJvoq2kdg1JfUZ+eZ9R6NmlhCpGpVcA9n1 SrH0SYg0BwwIaYEXDV8kXN6fJKyb6ojgQ+4lQZjQF36iKA0K2HrjbH52lEsdADiruvp9 qt1g2alW5tB29yULvC1YxfiAZ8Q+/x7mtd1iwpCyVDMSofn7VEgc6UfXEiDsjNt8oN+q CUbanLPycK0AJkCQXzHWfwn+KEsPkHhIlr2YIOGj7hR/m0iCAxAHX+gE/IRhFGnuJDR/ z8mg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=NONE dis=NONE) header.from=vmware.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t19si12174543pfe.94.2019.07.23.05.24.44; Tue, 23 Jul 2019 05:25:00 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=QUARANTINE sp=NONE dis=NONE) header.from=vmware.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2387953AbfGWDJC (ORCPT + 99 others); Mon, 22 Jul 2019 23:09:02 -0400 Received: from ex13-edg-ou-001.vmware.com ([208.91.0.189]:12355 "EHLO EX13-EDG-OU-001.vmware.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387905AbfGWDJA (ORCPT ); Mon, 22 Jul 2019 23:09:00 -0400 Received: from sc9-mailhost2.vmware.com (10.113.161.72) by EX13-EDG-OU-001.vmware.com (10.113.208.155) with Microsoft SMTP Server id 15.0.1156.6; Mon, 22 Jul 2019 20:08:40 -0700 Received: from akaher-lnx-dev.eng.vmware.com (unknown [10.110.19.203]) by sc9-mailhost2.vmware.com (Postfix) with ESMTP id 79BFAB24DB; Mon, 22 Jul 2019 23:08:52 -0400 (EDT) From: Ajay Kaher To: CC: , , , , , , , , , , , , , , , , , , Punit Agrawal , Michal Hocko , "Kirill A. Shutemov" , "Aneesh Kumar K . V" , Catalin Marinas , Will Deacon , Naoya Horiguchi , Mark Rutland , Hillf Danton , Mike Kravetz , Andrew Morton Subject: [PATCH 5/8] mm, gup: ensure real head page is ref-counted when using hugepages Date: Tue, 23 Jul 2019 16:38:28 +0530 Message-ID: <1563880111-19058-6-git-send-email-akaher@vmware.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1563880111-19058-1-git-send-email-akaher@vmware.com> References: <1563880111-19058-1-git-send-email-akaher@vmware.com> MIME-Version: 1.0 Content-Type: text/plain Received-SPF: None (EX13-EDG-OU-001.vmware.com: akaher@vmware.com does not designate permitted sender hosts) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Punit Agrawal commit d63206ee32b6e64b0e12d46e5d6004afd9913713 upstream. When speculatively taking references to a hugepage using page_cache_add_speculative() in gup_huge_pmd(), it is assumed that the page returned by pmd_page() is the head page. Although normally true, this assumption doesn't hold when the hugepage comprises of successive page table entries such as when using contiguous bit on arm64 at PTE or PMD levels. This can be addressed by ensuring that the page passed to page_cache_add_speculative() is the real head or by de-referencing the head page within the function. We take the first approach to keep the usage pattern aligned with page_cache_get_speculative() where users already pass the appropriate page, i.e., the de-referenced head. Apply the same logic to fix gup_huge_[pud|pgd]() as well. [punit.agrawal@arm.com: fix arm64 ltp failure] Link: http://lkml.kernel.org/r/20170619170145.25577-5-punit.agrawal@arm.com Link: http://lkml.kernel.org/r/20170522133604.11392-3-punit.agrawal@arm.com Signed-off-by: Punit Agrawal Acked-by: Steve Capper Cc: Michal Hocko Cc: "Kirill A. Shutemov" Cc: Aneesh Kumar K.V Cc: Catalin Marinas Cc: Will Deacon Cc: Naoya Horiguchi Cc: Mark Rutland Cc: Hillf Danton Cc: Mike Kravetz Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds Signed-off-by: Ajay Kaher Reviewed-by: Srivatsa S. Bhat (VMware) --- mm/gup.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mm/gup.c b/mm/gup.c index 6e7cfaa..fae4d1e 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -1132,8 +1132,7 @@ static int gup_huge_pmd(pmd_t orig, pmd_t *pmdp, unsigned long addr, return 0; refs = 0; - head = pmd_page(orig); - page = head + ((addr & ~PMD_MASK) >> PAGE_SHIFT); + page = pmd_page(orig) + ((addr & ~PMD_MASK) >> PAGE_SHIFT); tail = page; do { pages[*nr] = page; @@ -1142,6 +1141,7 @@ static int gup_huge_pmd(pmd_t orig, pmd_t *pmdp, unsigned long addr, refs++; } while (addr += PAGE_SIZE, addr != end); + head = compound_head(pmd_page(orig)); if (!page_cache_add_speculative(head, refs)) { *nr -= refs; return 0; @@ -1178,8 +1178,7 @@ static int gup_huge_pud(pud_t orig, pud_t *pudp, unsigned long addr, return 0; refs = 0; - head = pud_page(orig); - page = head + ((addr & ~PUD_MASK) >> PAGE_SHIFT); + page = pud_page(orig) + ((addr & ~PUD_MASK) >> PAGE_SHIFT); tail = page; do { pages[*nr] = page; @@ -1188,6 +1187,7 @@ static int gup_huge_pud(pud_t orig, pud_t *pudp, unsigned long addr, refs++; } while (addr += PAGE_SIZE, addr != end); + head = compound_head(pud_page(orig)); if (!page_cache_add_speculative(head, refs)) { *nr -= refs; return 0; @@ -1220,8 +1220,7 @@ static int gup_huge_pgd(pgd_t orig, pgd_t *pgdp, unsigned long addr, return 0; refs = 0; - head = pgd_page(orig); - page = head + ((addr & ~PGDIR_MASK) >> PAGE_SHIFT); + page = pgd_page(orig) + ((addr & ~PGDIR_MASK) >> PAGE_SHIFT); tail = page; do { pages[*nr] = page; @@ -1230,6 +1229,7 @@ static int gup_huge_pgd(pgd_t orig, pgd_t *pgdp, unsigned long addr, refs++; } while (addr += PAGE_SIZE, addr != end); + head = compound_head(pgd_page(orig)); if (!page_cache_add_speculative(head, refs)) { *nr -= refs; return 0; -- 2.7.4