From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 6C163233721 for ; Fri, 2 Jan 2026 15:23:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.140.110.172 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767367441; cv=none; b=j8MtsGI2elncZT51dvmWKzGXb33Q0jeMmqc+zdreNojBSo+KAW76Lu2pAPtE6slQFO0x301ogNpBG7RPAJ5otJ1+rWr3AWGMWCIlRkpvN1REPRMXeHmcNMMralFS6VUFiTkwfXM8BsysFPBTiOKfftCRLX0kH/ZJ6QoRollterM= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767367441; c=relaxed/simple; bh=1u9p7qFUYmXsbkeChrZ1H153oxjLCcbuK7OrHibeCgY=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=Z1sthj+fqqN7Pgh7t/WvBew9OyqrHW9/+Wd4vPDZd5rfiv4OdXt9PNUiqBUfzidnRuPschPQbMyOGfEhkY0KTjd91OSGg53xkoG+xju/rPDARbRW9HsFXfgFJoaQmuXvJgubxcp3w6lFfz8ePMqMspvNVSz1vuFffG9xxiTKVj8= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com; spf=pass smtp.mailfrom=arm.com; arc=none smtp.client-ip=217.140.110.172 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=arm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=arm.com 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 C849F497; Fri, 2 Jan 2026 07:23:51 -0800 (PST) Received: from [10.57.94.221] (unknown [10.57.94.221]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id F06873F5A1; Fri, 2 Jan 2026 07:23:56 -0800 (PST) Message-ID: <68852420-47fc-4dcc-b724-4cf13720b88c@arm.com> Date: Fri, 2 Jan 2026 15:23:55 +0000 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH v1 08/13] arm64: mm: Simplify __flush_tlb_range_limit_excess() Content-Language: en-GB To: Dev Jain , Will Deacon , Ard Biesheuvel , Catalin Marinas , Mark Rutland , Linus Torvalds , Oliver Upton , Marc Zyngier , Linu Cherian Cc: linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org References: <20251216144601.2106412-1-ryan.roberts@arm.com> <20251216144601.2106412-9-ryan.roberts@arm.com> <3de2b568-66f8-432f-a501-b19ca6c3a805@arm.com> From: Ryan Roberts In-Reply-To: <3de2b568-66f8-432f-a501-b19ca6c3a805@arm.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit On 17/12/2025 08:12, Dev Jain wrote: > > On 16/12/25 8:15 pm, Ryan Roberts wrote: >> From: Will Deacon >> >> __flush_tlb_range_limit_excess() is unnecessarily complicated: >> >> - It takes a 'start', 'end' and 'pages' argument, whereas it only >> needs 'pages' (which the caller has computed from the other two >> arguments!). >> >> - It erroneously compares 'pages' with MAX_TLBI_RANGE_PAGES when >> the system doesn't support range-based invalidation but the range to >> be invalidated would result in fewer than MAX_DVM_OPS invalidations. >> >> Simplify the function so that it no longer takes the 'start' and 'end' >> arguments and only considers the MAX_TLBI_RANGE_PAGES threshold on >> systems that implement range-based invalidation. >> >> Signed-off-by: Will Deacon >> Signed-off-by: Ryan Roberts >> --- >> arch/arm64/include/asm/tlbflush.h | 20 ++++++-------------- >> 1 file changed, 6 insertions(+), 14 deletions(-) >> >> diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h >> index 0e1902f66e01..3b72a71feac0 100644 >> --- a/arch/arm64/include/asm/tlbflush.h >> +++ b/arch/arm64/include/asm/tlbflush.h >> @@ -527,21 +527,13 @@ static __always_inline void __flush_tlb_range_op(tlbi_op lop, tlbi_op rop, >> #define __flush_s2_tlb_range_op(op, start, pages, stride, tlb_level) \ >> __flush_tlb_range_op(op, r##op, start, pages, stride, 0, tlb_level, kvm_lpa2_is_enabled()) >> >> -static inline bool __flush_tlb_range_limit_excess(unsigned long start, >> - unsigned long end, unsigned long pages, unsigned long stride) >> +static inline bool __flush_tlb_range_limit_excess(unsigned long pages, >> + unsigned long stride) >> { >> - /* >> - * When the system does not support TLB range based flush >> - * operation, (MAX_DVM_OPS - 1) pages can be handled. But >> - * with TLB range based operation, MAX_TLBI_RANGE_PAGES >> - * pages can be handled. >> - */ >> - if ((!system_supports_tlb_range() && >> - (end - start) >= (MAX_DVM_OPS * stride)) || >> - pages > MAX_TLBI_RANGE_PAGES) >> + if (system_supports_tlb_range() && pages > MAX_TLBI_RANGE_PAGES) >> return true; >> >> - return false; >> + return pages >= (MAX_DVM_OPS * stride) >> PAGE_SHIFT; > > The function will return true if tlb range is supported, but > ((MAX_DVM_OPS * stride) >> PAGE_SHIFT) < pages <= MAX_TLBI_RANGE_PAGES. > So I think you need to do > https://lore.kernel.org/all/1b15b4f0-5490-4dac-8344-e716dd189751@arm.com/ I agree with your overall proposal, but I think a few of the details are not quite correct. I think the max number of DVM ops that could be issued by a single __flush_tlb_range() call on a system with tlb-range is 20, not 4 as you suggest; - 4 for each of the scales - 1 for the final single page - 15 to align to a 64K boundary on systems with LPA2 (with 4K page size) But that doesn't really change your argument. So proposing to change it to this in next version: static inline bool __flush_tlb_range_limit_excess(unsigned long pages, unsigned long stride) { /* * Assume that the worst case number of DVM ops required to flush a * given range on a system that supports tlb-range is 20 (4 scales, 1 * final page, 15 for alignment on LPA2 systems), which is much smaller * than MAX_DVM_OPS. */ if (system_supports_tlb_range()) return pages > MAX_TLBI_RANGE_PAGES; return pages >= (MAX_DVM_OPS * stride) >> PAGE_SHIFT; } Thanks, Ryan > >> } >> >> static inline void __flush_tlb_range_nosync(struct mm_struct *mm, >> @@ -555,7 +547,7 @@ static inline void __flush_tlb_range_nosync(struct mm_struct *mm, >> end = round_up(end, stride); >> pages = (end - start) >> PAGE_SHIFT; >> >> - if (__flush_tlb_range_limit_excess(start, end, pages, stride)) { >> + if (__flush_tlb_range_limit_excess(pages, stride)) { >> flush_tlb_mm(mm); >> return; >> } >> @@ -619,7 +611,7 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end >> end = round_up(end, stride); >> pages = (end - start) >> PAGE_SHIFT; >> >> - if (__flush_tlb_range_limit_excess(start, end, pages, stride)) { >> + if (__flush_tlb_range_limit_excess(pages, stride)) { >> flush_tlb_all(); >> return; >> }