Received: by 2002:a05:7412:8d10:b0:f3:1519:9f41 with SMTP id bj16csp257690rdb; Tue, 5 Dec 2023 04:53:00 -0800 (PST) X-Google-Smtp-Source: AGHT+IF4HybN05NyKcNIun/ZgvQpe/dTESETBAPKH1x4uzIjwqCqDLLtIukErcoYogI2dXP4fOhQ X-Received: by 2002:a17:903:32ce:b0:1d0:7b65:9f8a with SMTP id i14-20020a17090332ce00b001d07b659f8amr3396555plr.51.1701780779751; Tue, 05 Dec 2023 04:52:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1701780779; cv=none; d=google.com; s=arc-20160816; b=viJG47EYHKPv5laGE9PIzLoyU7CTDEZ2laRdFB4aUZmkeuGYvofsYrrT2a/QTMrI6g vQPUOfK7JxrxwQNfJE0nfW3d10yIIwpInv/3/DUAcHXcpKLxyh5LZC4/xpza6H77rigV MTbaCOMwuvzju2P6qNvwG21i4104KwXfCKzZeCeOcjK+OD7AhOJZ8bGIXrRBOEpIRs/q 5JJNlWUnba5oV5LXp5wzk9MygaWt5sgD0jfXN7XfK1cHKz6wlSabrkCGwHsR2KerD4B+ UA2tqp6T8WA78wZhTPnjeShCh5alcNP9SVmij8eAuwU0YbFwqP8uwXCevsxyxoq9oLQE VDiA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:in-reply-to:from :references:cc:to:content-language:subject:user-agent:mime-version :date:message-id; bh=1DpMF9u9LT3f4T4qNMW6sTPN+qjWTgWbSid1qtWB+o4=; fh=GlLzLBhqF07GE0FJUf82nnkBDPyXS9iIZ0BDzvPX32s=; b=Xfd6HycXQUGV+8kToY9gJvKtxwF/9skZwi9VFSgKdM6gLE9Z5uDOiXAp0/Pi/Z2f8U cu5bT+L1Faa9CKXhRWUsqb+rOBhVHXEQvJRLmtcIdXIfYfDHGicmCnfOAu1ZZTuGnfa8 STKBByNMB+vNKd+SJXyJs6RjGX3fRaSAeAXTsizgXguveYXQuLPY9ZA1HUxCr2aqfWKU LS71S22+nalk9VUgNGolbrV8/2rpX8iTOzzNwjWUFktBwKs49MohnmsiXdR/KkCw2xNx Z0O9DPW7jBcSQlDrao5E3/k0KwgBGQJEY8dpojCxr40zz1wzDBTE9dGxAmny9XcKeMM1 BsUg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Return-Path: Received: from agentk.vger.email (agentk.vger.email. [23.128.96.32]) by mx.google.com with ESMTPS id iz13-20020a170902ef8d00b001d03e572976si5407076plb.591.2023.12.05.04.52.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 05 Dec 2023 04:52:59 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) client-ip=23.128.96.32; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.32 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=arm.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by agentk.vger.email (Postfix) with ESMTP id 6E6DC8047555; Tue, 5 Dec 2023 04:52:56 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at agentk.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1345280AbjLEMwi (ORCPT + 99 others); Tue, 5 Dec 2023 07:52:38 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34848 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1345320AbjLEMwh (ORCPT ); Tue, 5 Dec 2023 07:52:37 -0500 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by lindbergh.monkeyblade.net (Postfix) with ESMTP id 93E34A1 for ; Tue, 5 Dec 2023 04:52:42 -0800 (PST) Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 24428139F; Tue, 5 Dec 2023 04:53:28 -0800 (PST) Received: from [10.57.73.130] (unknown [10.57.73.130]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id E5BAA3F5A1; Tue, 5 Dec 2023 04:52:39 -0800 (PST) Message-ID: Date: Tue, 5 Dec 2023 12:52:38 +0000 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH RFC 23/39] mm/rmap: introduce folio_remove_rmap_[pte|ptes|pmd]() Content-Language: en-GB To: David Hildenbrand , linux-kernel@vger.kernel.org Cc: linux-mm@kvack.org, Andrew Morton , "Matthew Wilcox (Oracle)" , Hugh Dickins , Yin Fengwei , Mike Kravetz , Muchun Song , Peter Xu References: <20231204142146.91437-1-david@redhat.com> <20231204142146.91437-24-david@redhat.com> From: Ryan Roberts In-Reply-To: <20231204142146.91437-24-david@redhat.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-0.8 required=5.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on agentk.vger.email Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (agentk.vger.email [0.0.0.0]); Tue, 05 Dec 2023 04:52:56 -0800 (PST) On 04/12/2023 14:21, David Hildenbrand wrote: > Let's mimic what we did with folio_add_file_rmap_*() and > folio_add_anon_rmap_*() so we can similarly replace page_remove_rmap() > next. > > Make the compiler always special-case on the granularity by using > __always_inline. > > We're adding folio_remove_rmap_ptes() handling right away, as we want to > use that soon for batching rmap operations when unmapping PTE-mapped > large folios. > > Signed-off-by: David Hildenbrand > --- > include/linux/rmap.h | 6 ++++ > mm/rmap.c | 76 ++++++++++++++++++++++++++++++++++++-------- > 2 files changed, 68 insertions(+), 14 deletions(-) > > diff --git a/include/linux/rmap.h b/include/linux/rmap.h > index 017b216915f19..dd4ffb1d8ae04 100644 > --- a/include/linux/rmap.h > +++ b/include/linux/rmap.h > @@ -241,6 +241,12 @@ void folio_add_file_rmap_pmd(struct folio *, struct page *, > struct vm_area_struct *); > void page_remove_rmap(struct page *, struct vm_area_struct *, > bool compound); > +void folio_remove_rmap_ptes(struct folio *, struct page *, unsigned int nr, > + struct vm_area_struct *); > +#define folio_remove_rmap_pte(folio, page, vma) \ > + folio_remove_rmap_ptes(folio, page, 1, vma) > +void folio_remove_rmap_pmd(struct folio *, struct page *, > + struct vm_area_struct *); > > void hugetlb_add_anon_rmap(struct folio *, struct vm_area_struct *, > unsigned long address, rmap_t flags); > diff --git a/mm/rmap.c b/mm/rmap.c > index 3587225055c5e..50b6909157ac1 100644 > --- a/mm/rmap.c > +++ b/mm/rmap.c > @@ -1463,25 +1463,36 @@ void page_remove_rmap(struct page *page, struct vm_area_struct *vma, > bool compound) > { > struct folio *folio = page_folio(page); > + > + if (likely(!compound)) > + folio_remove_rmap_pte(folio, page, vma); > + else > + folio_remove_rmap_pmd(folio, page, vma); > +} > + > +static __always_inline void __folio_remove_rmap(struct folio *folio, > + struct page *page, unsigned int nr_pages, > + struct vm_area_struct *vma, enum rmap_mode mode) > +{ > atomic_t *mapped = &folio->_nr_pages_mapped; > - int nr = 0, nr_pmdmapped = 0; > - bool last; > + int last, nr = 0, nr_pmdmapped = 0; nit: you're being inconsistent across the functions with signed vs unsigned for page counts (e.g. nr, nr_pmdmapped) - see __folio_add_rmap(), __folio_add_file_rmap(), __folio_add_anon_rmap(). I suggest pick one and stick to it. Personally I'd go with signed int (since that's what all the counters in struct folio that we are manipulating are, underneath the atomic_t) then check that nr_pages > 0 in __folio_rmap_sanity_checks(). > enum node_stat_item idx; > > - VM_WARN_ON_FOLIO(folio_test_hugetlb(folio), folio); > - VM_BUG_ON_PAGE(compound && !PageHead(page), page); > + __folio_rmap_sanity_checks(folio, page, nr_pages, mode); > > /* Is page being unmapped by PTE? Is this its last map to be removed? */ > - if (likely(!compound)) { > - last = atomic_add_negative(-1, &page->_mapcount); > - nr = last; > - if (last && folio_test_large(folio)) { > - nr = atomic_dec_return_relaxed(mapped); > - nr = (nr < COMPOUND_MAPPED); > - } > - } else if (folio_test_pmd_mappable(folio)) { > - /* That test is redundant: it's for safety or to optimize out */ > + if (likely(mode == RMAP_MODE_PTE)) { > + do { > + last = atomic_add_negative(-1, &page->_mapcount); > + if (last && folio_test_large(folio)) { > + last = atomic_dec_return_relaxed(mapped); > + last = (last < COMPOUND_MAPPED); > + } > > + if (last) > + nr++; > + } while (page++, --nr_pages > 0); > + } else if (mode == RMAP_MODE_PMD) { > last = atomic_add_negative(-1, &folio->_entire_mapcount); > if (last) { > nr = atomic_sub_return_relaxed(COMPOUND_MAPPED, mapped); > @@ -1517,7 +1528,7 @@ void page_remove_rmap(struct page *page, struct vm_area_struct *vma, > * is still mapped. > */ > if (folio_test_pmd_mappable(folio) && folio_test_anon(folio)) folio_test_pmd_mappable() -> folio_test_large() Since you're converting this to support batch PTE removal, it might as well also support smaller-than-pmd too? I currently have a patch to do this same change in the multi-size THP series. > - if (!compound || nr < nr_pmdmapped) > + if (mode == RMAP_MODE_PTE || nr < nr_pmdmapped) > deferred_split_folio(folio); > } > > @@ -1532,6 +1543,43 @@ void page_remove_rmap(struct page *page, struct vm_area_struct *vma, > munlock_vma_folio(folio, vma); > } > > +/** > + * folio_remove_rmap_ptes - remove PTE mappings from a page range of a folio > + * @folio: The folio to remove the mappings from > + * @page: The first page to remove > + * @nr_pages: The number of pages that will be removed from the mapping > + * @vma: The vm area from which the mappings are removed > + * > + * The page range of the folio is defined by [page, page + nr_pages) > + * > + * The caller needs to hold the page table lock. > + */ > +void folio_remove_rmap_ptes(struct folio *folio, struct page *page, > + unsigned int nr_pages, struct vm_area_struct *vma) > +{ > + __folio_remove_rmap(folio, page, nr_pages, vma, RMAP_MODE_PTE); > +} > + > +/** > + * folio_remove_rmap_pmd - remove a PMD mapping from a page range of a folio > + * @folio: The folio to remove the mapping from > + * @page: The first page to remove > + * @vma: The vm area from which the mapping is removed > + * > + * The page range of the folio is defined by [page, page + HPAGE_PMD_NR) > + * > + * The caller needs to hold the page table lock. > + */ > +void folio_remove_rmap_pmd(struct folio *folio, struct page *page, > + struct vm_area_struct *vma) > +{ > +#ifdef CONFIG_TRANSPARENT_HUGEPAGE > + __folio_remove_rmap(folio, page, HPAGE_PMD_NR, vma, RMAP_MODE_PMD); > +#else > + WARN_ON_ONCE(true); > +#endif > +} > + > /* > * @arg: enum ttu_flags will be passed to this argument > */