Received: by 2002:a05:6a10:22f:0:0:0:0 with SMTP id 15csp3211309pxk; Mon, 28 Sep 2020 11:07:11 -0700 (PDT) X-Google-Smtp-Source: ABdhPJww39I2hvjaNutsAb9tH604sSLnoEV9qAGQ/dHr3JrNo6I+FAxHJkJy5HQUkvBcfNlTv17t X-Received: by 2002:a50:9fa1:: with SMTP id c30mr3042539edf.207.1601316430875; Mon, 28 Sep 2020 11:07:10 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1601316430; cv=none; d=google.com; s=arc-20160816; b=q+Gvl26N+vUoDXqTCCHSyY5Lzjm2Sg5OjGPV76i+6eKK6sbcWANIsr7yqjAxEYB39/ Sf3iLL6J02rYJn9H2j3MEoFKJwbqXfA6HbJC+233h1ip7ItkQjC7jKVCIQerdCUq8rCb aBcqj2ny1TBNHzRC3KcK2MCBHC5tQ1CyrBXmZL8tJVdD7S2/H4cNmaxq7ahqbjrj5xAr Ly/5c4+O3nrFi8SGoZlvR/9kHjw204B6AeCMlWHORzVJFdnXvPiQFVUlDDmNpYZFAFBf kbHIkLyFkxb8R66HQ1Edp7uHvAkCIUOqBIHAECQvfZkKHR5/iPgUT8C1TzoT9luPoyIz 4CTQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version:reply-to :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature:dkim-signature; bh=ibZzjGtUmXNRxN5Ks+shsif1f52725VsPFkhAaQPr2s=; b=OuB4VHvJ74HZwo5Ot7rETi1JoSizsUR9v7zruh3CCJ5C4Hl0cmArgNMW+YcogzGN9V JuuvWgHxlXCS8xsCwVOFKvLyBi1AvwhR5JqCM2UKN35VlMyYlgP6E88TSl9yxWJMC+B4 UR8IRpQXTPvzLtVK4xOujM8kT+it/ikqXChDU/JCQR5JpRrWtIbxFwuaIT3Zw7IUNMIM A6eifVhKL9P1udNSUMxcDRPfFwRSRvYtS6KDqRiI4A4dE6W0tTKMFpT5d+ncccLIV7Fg I/zsoLATPX7j3Pvb62Epq5Q0pkrtzbUQ3JohEYz/eLmlFE/+udDTLPQasS3JfNQrD4mE owKg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@sent.com header.s=fm1 header.b=XoR5kJLQ; dkim=pass header.i=@messagingengine.com header.s=fm3 header.b=l4IGgVOd; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sent.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id ox7si1101482ejb.336.2020.09.28.11.06.48; Mon, 28 Sep 2020 11:07:10 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@sent.com header.s=fm1 header.b=XoR5kJLQ; dkim=pass header.i=@messagingengine.com header.s=fm3 header.b=l4IGgVOd; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=sent.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727006AbgI1SCT (ORCPT + 99 others); Mon, 28 Sep 2020 14:02:19 -0400 Received: from wnew3-smtp.messagingengine.com ([64.147.123.17]:59003 "EHLO wnew3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726798AbgI1SBT (ORCPT ); Mon, 28 Sep 2020 14:01:19 -0400 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailnew.west.internal (Postfix) with ESMTP id B0D5BE1E; Mon, 28 Sep 2020 13:55:22 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Mon, 28 Sep 2020 13:55:23 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sent.com; h=from :to:cc:subject:date:message-id:in-reply-to:references:reply-to :mime-version:content-transfer-encoding; s=fm1; bh=ibZzjGtUmXNRx N5Ks+shsif1f52725VsPFkhAaQPr2s=; b=XoR5kJLQUL6nBYC9owYSwRWOgPzHD PuIqp/bJRAg1phhiy5eBZSKaE6kwmrz2e3OUEpqaavw685V2W/rUIL07/jmHlKhp qkkLP/f3mE9izBcpVpVBMJ8ObyVcB97XPyTzOQCFB2s96TPY0OYVNCHMbWPAMIaf cMePPbmoa/CmIqy2XRAWv5ioAePR3z0SyRfnywZxkFDrQFbr4zWZeLTu/YPGPup7 igPwTIPk8q4L5Ty0p/UgX2ZYpw/zas0spnYYNZusx9yh6n5tqrra3caJE78w5ZIs DLuSGG+fHev8rRhmSsHav0i4Ihz/QnI+gPOctddiBCOcMXYgZreXNOLcA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:reply-to:subject :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm3; bh=ibZzjGtUmXNRxN5Ks+shsif1f52725VsPFkhAaQPr2s=; b=l4IGgVOd 0x5MR01ycWOtAC/Qp6b/tLeE+QORW0hvfDXZx9VZW/afDTtnKAWS3vXsaUP9oUsV TYXp0+GfAG3VsUYGJksYldnMX7yKfcOUir+aNsYzfsCRIGcGjf4OsvlhEBQmDqTo +RR/zBg6+7IFnfeLpLnGpplXYIPjknpXxc3Mi/jOihG2/ImB62thIkafp63/Shfu oM48V3sKUBMzY/S3hEQeIH05oi4jDxSWo/QaND2HBLxwXgqQlX4uqjMXvLjEFHeZ nmYI9ZrTljz7kZm+a63n0R/+MfnPZEkibPIgUPt8jpNGjx3V5AQ2I/2ZCAl2Swfh wvoJIwioqkDjPQ== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedujedrvdeigdeliecutefuodetggdotefrodftvf curfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfghnecu uegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenuc fjughrpefhvffufffkofgjfhhrggfgsedtkeertdertddtnecuhfhrohhmpegkihcujggr nhcuoeiiihdrhigrnhesshgvnhhtrdgtohhmqeenucggtffrrghtthgvrhhnpeduhfffve ektdduhfdutdfgtdekkedvhfetuedufedtgffgvdevleehheevjefgtdenucfkphepuddv rdegiedruddtiedrudeigeenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmh grihhlfhhrohhmpeiiihdrhigrnhesshgvnhhtrdgtohhm X-ME-Proxy: Received: from nvrsysarch6.NVidia.COM (unknown [12.46.106.164]) by mail.messagingengine.com (Postfix) with ESMTPA id CD7A33064610; Mon, 28 Sep 2020 13:55:21 -0400 (EDT) From: Zi Yan To: linux-mm@kvack.org Cc: "Kirill A . Shutemov" , Roman Gushchin , Rik van Riel , Matthew Wilcox , Shakeel Butt , Yang Shi , Jason Gunthorpe , Mike Kravetz , Michal Hocko , David Hildenbrand , William Kucharski , Andrea Arcangeli , John Hubbard , David Nellans , linux-kernel@vger.kernel.org, Zi Yan Subject: [RFC PATCH v2 11/30] mm: thp: handling PUD THP reference bit. Date: Mon, 28 Sep 2020 13:54:09 -0400 Message-Id: <20200928175428.4110504-12-zi.yan@sent.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200928175428.4110504-1-zi.yan@sent.com> References: <20200928175428.4110504-1-zi.yan@sent.com> Reply-To: Zi Yan MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Zi Yan Add PUD-level TLB flush ops and teach page_vma_mapped_talk about PUD THPs. Signed-off-by: Zi Yan --- arch/x86/include/asm/pgtable.h | 3 +++ arch/x86/mm/pgtable.c | 13 +++++++++++++ include/linux/mmu_notifier.h | 13 +++++++++++++ include/linux/pgtable.h | 14 ++++++++++++++ include/linux/rmap.h | 1 + mm/page_vma_mapped.c | 33 +++++++++++++++++++++++++++++---- mm/rmap.c | 12 +++++++++--- 7 files changed, 82 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 199de6be2f6d..8bf7bfd71a46 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -1127,6 +1127,9 @@ extern int pudp_test_and_clear_young(struct vm_area_struct *vma, extern int pmdp_clear_flush_young(struct vm_area_struct *vma, unsigned long address, pmd_t *pmdp); +#define __HAVE_ARCH_PUDP_CLEAR_YOUNG_FLUSH +extern int pudp_clear_flush_young(struct vm_area_struct *vma, + unsigned long address, pud_t *pudp); #define pmd_write pmd_write static inline int pmd_write(pmd_t pmd) diff --git a/arch/x86/mm/pgtable.c b/arch/x86/mm/pgtable.c index 7be73aee6183..e4a2dffcc418 100644 --- a/arch/x86/mm/pgtable.c +++ b/arch/x86/mm/pgtable.c @@ -633,6 +633,19 @@ int pmdp_clear_flush_young(struct vm_area_struct *vma, return young; } +int pudp_clear_flush_young(struct vm_area_struct *vma, + unsigned long address, pud_t *pudp) +{ + int young; + + VM_BUG_ON(address & ~HPAGE_PUD_MASK); + + young = pudp_test_and_clear_young(vma, address, pudp); + if (young) + flush_tlb_range(vma, address, address + HPAGE_PUD_SIZE); + + return young; +} #endif /** diff --git a/include/linux/mmu_notifier.h b/include/linux/mmu_notifier.h index b8200782dede..4ffa179e654f 100644 --- a/include/linux/mmu_notifier.h +++ b/include/linux/mmu_notifier.h @@ -557,6 +557,19 @@ static inline void mmu_notifier_range_init_migrate( __young; \ }) +#define pudp_clear_flush_young_notify(__vma, __address, __pudp) \ +({ \ + int __young; \ + struct vm_area_struct *___vma = __vma; \ + unsigned long ___address = __address; \ + __young = pudp_clear_flush_young(___vma, ___address, __pudp); \ + __young |= mmu_notifier_clear_flush_young(___vma->vm_mm, \ + ___address, \ + ___address + \ + PUD_SIZE); \ + __young; \ +}) + #define ptep_clear_young_notify(__vma, __address, __ptep) \ ({ \ int __young; \ diff --git a/include/linux/pgtable.h b/include/linux/pgtable.h index 1f6d46465c54..bb163504fb01 100644 --- a/include/linux/pgtable.h +++ b/include/linux/pgtable.h @@ -243,6 +243,20 @@ static inline int pmdp_clear_flush_young(struct vm_area_struct *vma, #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ #endif +#ifndef __HAVE_ARCH_PUDP_CLEAR_YOUNG_FLUSH +#ifdef CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD +extern int pudp_clear_flush_young(struct vm_area_struct *vma, + unsigned long address, pud_t *pudp); +#else +int pudp_clear_flush_young(struct vm_area_struct *vma, + unsigned long address, pud_t *pudp) +{ + BUILD_BUG(); + return 0; +} +#endif /* CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD */ +#endif + #ifndef __HAVE_ARCH_PTEP_GET_AND_CLEAR static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long address, diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 3a6adfa70fb0..0af61dd193d2 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -206,6 +206,7 @@ struct page_vma_mapped_walk { struct page *page; struct vm_area_struct *vma; unsigned long address; + pud_t *pud; pmd_t *pmd; pte_t *pte; spinlock_t *ptl; diff --git a/mm/page_vma_mapped.c b/mm/page_vma_mapped.c index 5e77b269c330..f88e845ad5e6 100644 --- a/mm/page_vma_mapped.c +++ b/mm/page_vma_mapped.c @@ -145,9 +145,12 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw) struct page *page = pvmw->page; pgd_t *pgd; p4d_t *p4d; - pud_t *pud; + pud_t pude; pmd_t pmde; + if (!pvmw->pte && !pvmw->pmd && pvmw->pud) + return not_found(pvmw); + /* The only possible pmd mapping has been handled on last iteration */ if (pvmw->pmd && !pvmw->pte) return not_found(pvmw); @@ -174,10 +177,32 @@ bool page_vma_mapped_walk(struct page_vma_mapped_walk *pvmw) p4d = p4d_offset(pgd, pvmw->address); if (!p4d_present(*p4d)) return false; - pud = pud_offset(p4d, pvmw->address); - if (!pud_present(*pud)) + pvmw->pud = pud_offset(p4d, pvmw->address); + + /* + * Make sure the pud value isn't cached in a register by the + * compiler and used as a stale value after we've observed a + * subsequent update. + */ + pude = READ_ONCE(*pvmw->pud); + if (pud_trans_huge(pude)) { + pvmw->ptl = pud_lock(mm, pvmw->pud); + if (likely(pud_trans_huge(*pvmw->pud))) { + if (pvmw->flags & PVMW_MIGRATION) + return not_found(pvmw); + if (pud_page(*pvmw->pud) != page) + return not_found(pvmw); + return true; + } else if (!pud_present(*pvmw->pud)) + return not_found(pvmw); + + /* THP pud was split under us: handle on pmd level */ + spin_unlock(pvmw->ptl); + pvmw->ptl = NULL; + } else if (!pud_present(pude)) return false; - pvmw->pmd = pmd_offset(pud, pvmw->address); + + pvmw->pmd = pmd_offset(pvmw->pud, pvmw->address); /* * Make sure the pmd value isn't cached in a register by the * compiler and used as a stale value after we've observed a diff --git a/mm/rmap.c b/mm/rmap.c index 5683f367a792..629f8fe7ffac 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -803,9 +803,15 @@ static bool page_referenced_one(struct page *page, struct vm_area_struct *vma, referenced++; } } else if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE)) { - if (pmdp_clear_flush_young_notify(vma, address, - pvmw.pmd)) - referenced++; + if (pvmw.pmd) { + if (pmdp_clear_flush_young_notify(vma, address, + pvmw.pmd)) + referenced++; + } else if (pvmw.pud) { + if (pudp_clear_flush_young_notify(vma, address, + pvmw.pud)) + referenced++; + } } else { /* unexpected pmd-mapped page? */ WARN_ON_ONCE(1); -- 2.28.0