Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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: Will Deacon <will@kernel.org>
Reviewed-by: Jonathan Cameron <jonathan.cameron@huawei.com>
Signed-off-by: Ryan Roberts <ryan.roberts@arm.com>
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>

authored by

Will Deacon and committed by
Catalin Marinas
c753d667 057bbd8e

+11 -13
+11 -13
arch/arm64/include/asm/tlbflush.h
··· 537 537 #define __flush_s2_tlb_range_op(op, start, pages, stride, tlb_level) \ 538 538 __flush_tlb_range_op(op, r##op, start, pages, stride, 0, tlb_level, kvm_lpa2_is_enabled()) 539 539 540 - static inline bool __flush_tlb_range_limit_excess(unsigned long start, 541 - unsigned long end, unsigned long pages, unsigned long stride) 540 + static inline bool __flush_tlb_range_limit_excess(unsigned long pages, 541 + unsigned long stride) 542 542 { 543 543 /* 544 - * When the system does not support TLB range based flush 545 - * operation, (MAX_DVM_OPS - 1) pages can be handled. But 546 - * with TLB range based operation, MAX_TLBI_RANGE_PAGES 547 - * pages can be handled. 544 + * Assume that the worst case number of DVM ops required to flush a 545 + * given range on a system that supports tlb-range is 20 (4 scales, 1 546 + * final page, 15 for alignment on LPA2 systems), which is much smaller 547 + * than MAX_DVM_OPS. 548 548 */ 549 - if ((!system_supports_tlb_range() && 550 - (end - start) >= (MAX_DVM_OPS * stride)) || 551 - pages > MAX_TLBI_RANGE_PAGES) 552 - return true; 549 + if (system_supports_tlb_range()) 550 + return pages > MAX_TLBI_RANGE_PAGES; 553 551 554 - return false; 552 + return pages >= (MAX_DVM_OPS * stride) >> PAGE_SHIFT; 555 553 } 556 554 557 555 static inline void __flush_tlb_range_nosync(struct mm_struct *mm, ··· 563 565 end = round_up(end, stride); 564 566 pages = (end - start) >> PAGE_SHIFT; 565 567 566 - if (__flush_tlb_range_limit_excess(start, end, pages, stride)) { 568 + if (__flush_tlb_range_limit_excess(pages, stride)) { 567 569 flush_tlb_mm(mm); 568 570 return; 569 571 } ··· 627 629 end = round_up(end, stride); 628 630 pages = (end - start) >> PAGE_SHIFT; 629 631 630 - if (__flush_tlb_range_limit_excess(start, end, pages, stride)) { 632 + if (__flush_tlb_range_limit_excess(pages, stride)) { 631 633 flush_tlb_all(); 632 634 return; 633 635 }