Commit c753d667 authored by Will Deacon's avatar Will Deacon Committed by Catalin Marinas
Browse files

arm64: mm: Simplify __flush_tlb_range_limit_excess()



__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: default avatarWill Deacon <will@kernel.org>
Reviewed-by: default avatarJonathan Cameron <jonathan.cameron@huawei.com>
Signed-off-by: default avatarRyan Roberts <ryan.roberts@arm.com>
Signed-off-by: default avatarCatalin Marinas <catalin.marinas@arm.com>
parent 057bbd8e
Loading
Loading
Loading
Loading
+11 −13
Original line number Diff line number Diff line
@@ -537,21 +537,19 @@ 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.
	 * 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() &&
	     (end - start) >= (MAX_DVM_OPS * stride)) ||
	    pages > MAX_TLBI_RANGE_PAGES)
		return true;
	if (system_supports_tlb_range())
		return pages > MAX_TLBI_RANGE_PAGES;

	return false;
	return pages >= (MAX_DVM_OPS * stride) >> PAGE_SHIFT;
}

static inline void __flush_tlb_range_nosync(struct mm_struct *mm,
@@ -565,7 +563,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;
	}
@@ -629,7 +627,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;
	}