From patchwork Mon Feb 17 14:07:53 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ryan Roberts X-Patchwork-Id: 13977906 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7B0E8C021A9 for ; Mon, 17 Feb 2025 14:08:26 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 12172280058; Mon, 17 Feb 2025 09:08:26 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 0D15428004D; Mon, 17 Feb 2025 09:08:26 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id EDCF4280058; Mon, 17 Feb 2025 09:08:25 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id CF1FA28004D for ; Mon, 17 Feb 2025 09:08:25 -0500 (EST) Received: from smtpin26.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay02.hostedemail.com (Postfix) with ESMTP id 4BA2D12045C for ; Mon, 17 Feb 2025 14:08:25 +0000 (UTC) X-FDA: 83129616570.26.9418CFB Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by imf03.hostedemail.com (Postfix) with ESMTP id 9200E20017 for ; Mon, 17 Feb 2025 14:08:23 +0000 (UTC) Authentication-Results: imf03.hostedemail.com; dkim=none; spf=pass (imf03.hostedemail.com: domain of ryan.roberts@arm.com designates 217.140.110.172 as permitted sender) smtp.mailfrom=ryan.roberts@arm.com; dmarc=pass (policy=none) header.from=arm.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1739801303; a=rsa-sha256; cv=none; b=6SLBxJOaksGz/TRxnviFaJOYjRaLKG7gx5hJ6siFzrQotZJHQVd27PfqQhKMevauSbMlzk fY7T1bIflOMhiRy0BUP3QDB+N4A9jvK1U5vUq9D8oSX5wqzbL/fIKiFvrYYAolqJbrjxFk WMXG46UwBE3xMTPheuTbEwDMQvQFbIc= ARC-Authentication-Results: i=1; imf03.hostedemail.com; dkim=none; spf=pass (imf03.hostedemail.com: domain of ryan.roberts@arm.com designates 217.140.110.172 as permitted sender) smtp.mailfrom=ryan.roberts@arm.com; dmarc=pass (policy=none) header.from=arm.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1739801303; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=QjvR6b5BjqryM3DMHxFhTSbOzPrvcdNa2MPAXtRZ3A4=; b=SBxQLKHGj55CWSyXeAbWPLLZFX2oDGuYnnHTpFzWaWNN4AunofP8cZRs4CLMYrIaagwk/6 QC6IFXUCEIGO+k1f4LDEHRORVcQChoadOL200eLAMjDB5LDhW+xwJE7zxkgY90CDKPehpJ VliJtYvsTAAZYPv3ryhdl9FTaQxpa94= 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 1DD911A2D; Mon, 17 Feb 2025 06:08:42 -0800 (PST) Received: from e125769.cambridge.arm.com (e125769.cambridge.arm.com [10.1.196.27]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A3E023F6A8; Mon, 17 Feb 2025 06:08:20 -0800 (PST) From: Ryan Roberts To: Catalin Marinas , Will Deacon , Pasha Tatashin , Andrew Morton , Uladzislau Rezki , Christoph Hellwig , David Hildenbrand , "Matthew Wilcox (Oracle)" , Mark Rutland , Anshuman Khandual , Alexandre Ghiti , Kevin Brodsky Cc: Ryan Roberts , linux-arm-kernel@lists.infradead.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH v2 01/14] arm64: hugetlb: Cleanup huge_pte size discovery mechanisms Date: Mon, 17 Feb 2025 14:07:53 +0000 Message-ID: <20250217140809.1702789-2-ryan.roberts@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250217140809.1702789-1-ryan.roberts@arm.com> References: <20250217140809.1702789-1-ryan.roberts@arm.com> MIME-Version: 1.0 X-Stat-Signature: kqgqsqcku6u5wz8dyu5miejzbuh3rncy X-Rspamd-Server: rspam06 X-Rspamd-Queue-Id: 9200E20017 X-Rspam-User: X-HE-Tag: 1739801303-242449 X-HE-Meta: U2FsdGVkX1/eE4W1r1ylTPgQ6AZ4P9+AtjM2pklVNCW72H4vKHu2vv12mGOCo1FcBz8HVZFgAReYSKtCyGulCde4OhDbLcDeWdViNfDsZJrEviDbaIBnFMTqTyyNZBI7yoNn5v9Wz7iRaui+2tN0fE7Ea3LforIbwgAE2u5g6NBe8YhCbI9Xo6umvGgpDGXSZExAuJZGrDgfjkOBtGbhqw6+HJoZjBZgZE4zL2Kwc3FdF6v1Tivi9hac2qYU8jmeu5RQ2LfBpRc3Vun4R0yuldWrmSP0/XynV9WTafe8LYErSgV1q/DzFT98PHUxm/fNkROZoYIOGI2HIvJ6DHOgPqTdAVYEsnWkBLuWfp+4umNyiJ+19ETWaCo6bhzOTrhe4SXJfA/xv3OHdwhW6RJicvPotUD4tS2XrrVXqZrzIh5QRvFGc8kPmAfHsztchPheA+KwVzg8fU0y6UyItEe0yr+Hg8ICWij1o9F1qw7nn/STszm10NDGmd9bp+2KXq8BdOdPhMrmXB04oujPYQm8VHt7H+7d2yasjo0P3eVe43I28xvWJuplSVG0uSkS9iOQk0k5uvw4z6YTGi7ISI/H0A/8bX8HUTJr5bljG3blMAr5A3Hqc2/d9YwM6BLaHUY2duKuJ8qAI1xkb2V6EDJpMey/z3lcWQmJYGAFPHI3gafWFnD5ufcDkDWQbTpyKlVXxDPZYfNSrkuE7Gw8Pa8OIyL+eHXP5UHguwEYZhigvb86lkR0pkXR82JhrqrCX8RFXl6PlkrmdjvAR1ppjO5HJsHoLtao8fOJh+1BTlkanXQhhKjg3kIsBk57K4nHI9NEB0LPPP848TuwUarSml60W+KCOalGsc6vBpLOnCBNIGr1nd1Su5MWRl0E3veaUumvxXaC1xOfoUe6V0Px6nyCRN36SOxLlvRut9uMN2cQWMSlELWNuJsZJBPuecM9WxuzPd/pc/B8y7A3Gbpka6Q If7SlqdH +4ovoMIi6v7ERar/lVPB7n1HEi/JzrqQ9j7F65grMhmrK3JqrkqAEZ4kBC51M0SmGr/BMXm0eS1EqvHt4wClSBU6tXabXIxxQfU+Edwcvoja4kEodo6MJup52dv8VLdpx+pSyKc37FESKWwNgLZrcr+eFrFLzceLw7GsyYA2mRKAZE3CkIVYPkw5W91U0AYtPQhHNf6ODW/5FpMg= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: Not all huge_pte helper APIs explicitly provide the size of the huge_pte. So the helpers have to depend on various methods to determine the size of the huge_pte. Some of these methods are dubious. Let's clean up the code to use preferred methods and retire the dubious ones. The options in order of preference: - If size is provided as parameter, use it together with num_contig_ptes(). This is explicit and works for both present and non-present ptes. - If vma is provided as a parameter, retrieve size via huge_page_size(hstate_vma(vma)) and use it together with num_contig_ptes(). This is explicit and works for both present and non-present ptes. - If the pte is present and contiguous, use find_num_contig() to walk the pgtable to find the level and infer the number of ptes from level. Only works for *present* ptes. - If the pte is present and not contiguous and you can infer from this that only 1 pte needs to be operated on. This is ok if you don't care about the absolute size, and just want to know the number of ptes. - NEVER rely on resolving the PFN of a present pte to a folio and getting the folio's size. This is fragile at best, because there is nothing to stop the core-mm from allocating a folio twice as big as the huge_pte then mapping it across 2 consecutive huge_ptes. Or just partially mapping it. Where we require that the pte is present, add warnings if not-present. Signed-off-by: Ryan Roberts --- arch/arm64/mm/hugetlbpage.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index 614b2feddba2..31ea826a8a09 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -136,7 +136,7 @@ pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep) if (!pte_present(orig_pte) || !pte_cont(orig_pte)) return orig_pte; - ncontig = num_contig_ptes(page_size(pte_page(orig_pte)), &pgsize); + ncontig = find_num_contig(mm, addr, ptep, &pgsize); for (i = 0; i < ncontig; i++, ptep++) { pte_t pte = __ptep_get(ptep); @@ -445,16 +445,19 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma, pgprot_t hugeprot; pte_t orig_pte; + VM_WARN_ON(!pte_present(pte)); + if (!pte_cont(pte)) return __ptep_set_access_flags(vma, addr, ptep, pte, dirty); - ncontig = find_num_contig(mm, addr, ptep, &pgsize); + ncontig = num_contig_ptes(huge_page_size(hstate_vma(vma)), &pgsize); dpfn = pgsize >> PAGE_SHIFT; if (!__cont_access_flags_changed(ptep, pte, ncontig)) return 0; orig_pte = get_clear_contig_flush(mm, addr, ptep, pgsize, ncontig); + VM_WARN_ON(!pte_present(orig_pte)); /* Make sure we don't lose the dirty or young state */ if (pte_dirty(orig_pte)) @@ -479,7 +482,10 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm, size_t pgsize; pte_t pte; - if (!pte_cont(__ptep_get(ptep))) { + pte = __ptep_get(ptep); + VM_WARN_ON(!pte_present(pte)); + + if (!pte_cont(pte)) { __ptep_set_wrprotect(mm, addr, ptep); return; } @@ -503,11 +509,15 @@ pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, struct mm_struct *mm = vma->vm_mm; size_t pgsize; int ncontig; + pte_t pte; + + pte = __ptep_get(ptep); + VM_WARN_ON(!pte_present(pte)); - if (!pte_cont(__ptep_get(ptep))) + if (!pte_cont(pte)) return ptep_clear_flush(vma, addr, ptep); - ncontig = find_num_contig(mm, addr, ptep, &pgsize); + ncontig = num_contig_ptes(huge_page_size(hstate_vma(vma)), &pgsize); return get_clear_contig_flush(mm, addr, ptep, pgsize, ncontig); }