linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RESEND PATCH v5 0/6] arm64: tlb: add support for TTL feature
@ 2020-06-25  8:03 Zhenyu Ye
  2020-06-25  8:03 ` [RESEND PATCH v5 1/6] arm64: Detect the ARMv8.4 " Zhenyu Ye
                   ` (6 more replies)
  0 siblings, 7 replies; 11+ messages in thread
From: Zhenyu Ye @ 2020-06-25  8:03 UTC (permalink / raw)
  To: catalin.marinas, peterz, mark.rutland, will, aneesh.kumar, akpm,
	npiggin, arnd, rostedt, maz, suzuki.poulose, tglx, yuzhao,
	Dave.Martin, steven.price, broonie, guohanjun
  Cc: yezhenyu2, linux-arm-kernel, linux-kernel, linux-arch, linux-mm,
	arm, xiexiangyou, prime.zeng, zhangshaokun, kuhn.chenqun

In order to reduce the cost of TLB invalidation, ARMv8.4 provides
the TTL field in TLBI instruction.  The TTL field indicates the
level of page table walk holding the leaf entry for the address
being invalidated.  This series provide support for this feature.

When ARMv8.4-TTL is implemented, the operand for TLBIs looks like
below:

* +----------+-------+----------------------+
* |   ASID   |  TTL  |        BADDR         |
* +----------+-------+----------------------+
* |63      48|47   44|43                   0|

See patches for details, Thanks.

--
ChangeList:
v5:
rebase the series on Linux 5.8-rc2.

v4:
implement flush_*_tlb_range only on arm64.

v3:
minor changes: reduce the indentation levels of __tlbi_level().

v2:
rebase series on Linux 5.7-rc1 and simplify the code implementation.

v1:
add support for TTL feature in arm64.

Marc Zyngier (2):
  arm64: Detect the ARMv8.4 TTL feature
  arm64: Add level-hinted TLB invalidation helper

Peter Zijlstra (Intel) (1):
  tlb: mmu_gather: add tlb_flush_*_range APIs

Zhenyu Ye (3):
  arm64: Add tlbi_user_level TLB invalidation helper
  arm64: tlb: Set the TTL field in flush_tlb_range
  arm64: tlb: Set the TTL field in flush_*_tlb_range

 arch/arm64/include/asm/cpucaps.h  |  3 +-
 arch/arm64/include/asm/pgtable.h  | 10 ++++++
 arch/arm64/include/asm/sysreg.h   |  1 +
 arch/arm64/include/asm/tlb.h      | 29 +++++++++++++++-
 arch/arm64/include/asm/tlbflush.h | 54 +++++++++++++++++++++++++-----
 arch/arm64/kernel/cpufeature.c    | 11 +++++++
 include/asm-generic/tlb.h         | 55 ++++++++++++++++++++++---------
 7 files changed, 138 insertions(+), 25 deletions(-)

-- 
2.26.2



^ permalink raw reply	[flat|nested] 11+ messages in thread

* [RESEND PATCH v5 1/6] arm64: Detect the ARMv8.4 TTL feature
  2020-06-25  8:03 [RESEND PATCH v5 0/6] arm64: tlb: add support for TTL feature Zhenyu Ye
@ 2020-06-25  8:03 ` Zhenyu Ye
  2020-06-25  8:03 ` [RESEND PATCH v5 2/6] arm64: Add level-hinted TLB invalidation helper Zhenyu Ye
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Zhenyu Ye @ 2020-06-25  8:03 UTC (permalink / raw)
  To: catalin.marinas, peterz, mark.rutland, will, aneesh.kumar, akpm,
	npiggin, arnd, rostedt, maz, suzuki.poulose, tglx, yuzhao,
	Dave.Martin, steven.price, broonie, guohanjun
  Cc: yezhenyu2, linux-arm-kernel, linux-kernel, linux-arch, linux-mm,
	arm, xiexiangyou, prime.zeng, zhangshaokun, kuhn.chenqun

From: Marc Zyngier <maz@kernel.org>

In order to reduce the cost of TLB invalidation, the ARMv8.4 TTL
feature allows TLBs to be issued with a level allowing for quicker
invalidation.

Let's detect the feature for now. Further patches will implement
its actual usage.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Zhenyu Ye <yezhenyu2@huawei.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/include/asm/cpucaps.h |  3 ++-
 arch/arm64/include/asm/sysreg.h  |  1 +
 arch/arm64/kernel/cpufeature.c   | 11 +++++++++++
 3 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/arch/arm64/include/asm/cpucaps.h b/arch/arm64/include/asm/cpucaps.h
index d7b3bb0cb180..d44ba903d11d 100644
--- a/arch/arm64/include/asm/cpucaps.h
+++ b/arch/arm64/include/asm/cpucaps.h
@@ -62,7 +62,8 @@
 #define ARM64_HAS_GENERIC_AUTH			52
 #define ARM64_HAS_32BIT_EL1			53
 #define ARM64_BTI				54
+#define ARM64_HAS_ARMv8_4_TTL			55
 
-#define ARM64_NCAPS				55
+#define ARM64_NCAPS				56
 
 #endif /* __ASM_CPUCAPS_H */
diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h
index 463175f80341..8c209aa17273 100644
--- a/arch/arm64/include/asm/sysreg.h
+++ b/arch/arm64/include/asm/sysreg.h
@@ -746,6 +746,7 @@
 
 /* id_aa64mmfr2 */
 #define ID_AA64MMFR2_E0PD_SHIFT		60
+#define ID_AA64MMFR2_TTL_SHIFT		48
 #define ID_AA64MMFR2_FWB_SHIFT		40
 #define ID_AA64MMFR2_AT_SHIFT		32
 #define ID_AA64MMFR2_LVA_SHIFT		16
diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
index 4ae41670c2e6..bda002078ec5 100644
--- a/arch/arm64/kernel/cpufeature.c
+++ b/arch/arm64/kernel/cpufeature.c
@@ -323,6 +323,7 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr1[] = {
 
 static const struct arm64_ftr_bits ftr_id_aa64mmfr2[] = {
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_E0PD_SHIFT, 4, 0),
+	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_TTL_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_FWB_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_AT_SHIFT, 4, 0),
 	ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_LVA_SHIFT, 4, 0),
@@ -1880,6 +1881,16 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
 		.matches = has_cpuid_feature,
 		.cpu_enable = cpu_has_fwb,
 	},
+	{
+		.desc = "ARMv8.4 Translation Table Level",
+		.type = ARM64_CPUCAP_SYSTEM_FEATURE,
+		.capability = ARM64_HAS_ARMv8_4_TTL,
+		.sys_reg = SYS_ID_AA64MMFR2_EL1,
+		.sign = FTR_UNSIGNED,
+		.field_pos = ID_AA64MMFR2_TTL_SHIFT,
+		.min_field_value = 1,
+		.matches = has_cpuid_feature,
+	},
 #ifdef CONFIG_ARM64_HW_AFDBM
 	{
 		/*
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RESEND PATCH v5 2/6] arm64: Add level-hinted TLB invalidation helper
  2020-06-25  8:03 [RESEND PATCH v5 0/6] arm64: tlb: add support for TTL feature Zhenyu Ye
  2020-06-25  8:03 ` [RESEND PATCH v5 1/6] arm64: Detect the ARMv8.4 " Zhenyu Ye
@ 2020-06-25  8:03 ` Zhenyu Ye
  2020-06-25  8:03 ` [RESEND PATCH v5 3/6] arm64: Add tlbi_user_level " Zhenyu Ye
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Zhenyu Ye @ 2020-06-25  8:03 UTC (permalink / raw)
  To: catalin.marinas, peterz, mark.rutland, will, aneesh.kumar, akpm,
	npiggin, arnd, rostedt, maz, suzuki.poulose, tglx, yuzhao,
	Dave.Martin, steven.price, broonie, guohanjun
  Cc: yezhenyu2, linux-arm-kernel, linux-kernel, linux-arch, linux-mm,
	arm, xiexiangyou, prime.zeng, zhangshaokun, kuhn.chenqun

From: Marc Zyngier <maz@kernel.org>

Add a level-hinted TLB invalidation helper that only gets used if
ARMv8.4-TTL gets detected.

Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Zhenyu Ye <yezhenyu2@huawei.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/include/asm/tlbflush.h | 29 +++++++++++++++++++++++++++++
 1 file changed, 29 insertions(+)

diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index bc3949064725..8adbd6fd8489 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -10,6 +10,7 @@
 
 #ifndef __ASSEMBLY__
 
+#include <linux/bitfield.h>
 #include <linux/mm_types.h>
 #include <linux/sched.h>
 #include <asm/cputype.h>
@@ -59,6 +60,34 @@
 		__ta;						\
 	})
 
+#define TLBI_TTL_MASK	GENMASK_ULL(47, 44)
+
+#define __tlbi_level(op, addr, level) do {			\
+	u64 arg = addr;						\
+								\
+	if (cpus_have_const_cap(ARM64_HAS_ARMv8_4_TTL) &&	\
+	    level) {						\
+		u64 ttl = level;				\
+								\
+		switch (PAGE_SIZE) {				\
+		case SZ_4K:					\
+			ttl |= 1 << 2;				\
+			break;					\
+		case SZ_16K:					\
+			ttl |= 2 << 2;				\
+			break;					\
+		case SZ_64K:					\
+			ttl |= 3 << 2;				\
+			break;					\
+		}						\
+								\
+		arg &= ~TLBI_TTL_MASK;				\
+		arg |= FIELD_PREP(TLBI_TTL_MASK, ttl);		\
+	}							\
+								\
+	__tlbi(op,  arg);					\
+} while (0)
+
 /*
  *	TLB Invalidation
  *	================
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RESEND PATCH v5 3/6] arm64: Add tlbi_user_level TLB invalidation helper
  2020-06-25  8:03 [RESEND PATCH v5 0/6] arm64: tlb: add support for TTL feature Zhenyu Ye
  2020-06-25  8:03 ` [RESEND PATCH v5 1/6] arm64: Detect the ARMv8.4 " Zhenyu Ye
  2020-06-25  8:03 ` [RESEND PATCH v5 2/6] arm64: Add level-hinted TLB invalidation helper Zhenyu Ye
@ 2020-06-25  8:03 ` Zhenyu Ye
  2020-07-09 16:48   ` Catalin Marinas
  2020-06-25  8:03 ` [RESEND PATCH v5 4/6] tlb: mmu_gather: add tlb_flush_*_range APIs Zhenyu Ye
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 11+ messages in thread
From: Zhenyu Ye @ 2020-06-25  8:03 UTC (permalink / raw)
  To: catalin.marinas, peterz, mark.rutland, will, aneesh.kumar, akpm,
	npiggin, arnd, rostedt, maz, suzuki.poulose, tglx, yuzhao,
	Dave.Martin, steven.price, broonie, guohanjun
  Cc: yezhenyu2, linux-arm-kernel, linux-kernel, linux-arch, linux-mm,
	arm, xiexiangyou, prime.zeng, zhangshaokun, kuhn.chenqun

Add a level-hinted parameter to __tlbi_user, which only gets used
if ARMv8.4-TTL gets detected.

ARMv8.4-TTL provides the TTL field in tlbi instruction to indicate
the level of translation table walk holding the leaf entry for the
address that is being invalidated.

This patch set the default level value of flush_tlb_range() to 0,
which will be updated in future patches.  And set the ttl value of
flush_tlb_page_nosync() to 3 because it is only called to flush a
single pte page.

Signed-off-by: Zhenyu Ye <yezhenyu2@huawei.com>
---
 arch/arm64/include/asm/tlbflush.h | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index 8adbd6fd8489..bfb58e62c127 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -88,6 +88,12 @@
 	__tlbi(op,  arg);					\
 } while (0)
 
+#define __tlbi_user_level(op, arg, level) do {				\
+	if (arm64_kernel_unmapped_at_el0())				\
+		__tlbi_level(op, (arg | USER_ASID_FLAG), level);	\
+} while (0)
+
+
 /*
  *	TLB Invalidation
  *	================
@@ -189,8 +195,9 @@ static inline void flush_tlb_page_nosync(struct vm_area_struct *vma,
 	unsigned long addr = __TLBI_VADDR(uaddr, ASID(vma->vm_mm));
 
 	dsb(ishst);
-	__tlbi(vale1is, addr);
-	__tlbi_user(vale1is, addr);
+	/* This function is only called on a small page */
+	__tlbi_level(vale1is, addr, 3);
+	__tlbi_user_level(vale1is, addr, 3);
 }
 
 static inline void flush_tlb_page(struct vm_area_struct *vma,
@@ -230,11 +237,11 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
 	dsb(ishst);
 	for (addr = start; addr < end; addr += stride) {
 		if (last_level) {
-			__tlbi(vale1is, addr);
-			__tlbi_user(vale1is, addr);
+			__tlbi_level(vale1is, addr, 0);
+			__tlbi_user_level(vale1is, addr, 0);
 		} else {
-			__tlbi(vae1is, addr);
-			__tlbi_user(vae1is, addr);
+			__tlbi_level(vae1is, addr, 0);
+			__tlbi_user_level(vae1is, addr, 0);
 		}
 	}
 	dsb(ish);
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RESEND PATCH v5 4/6] tlb: mmu_gather: add tlb_flush_*_range APIs
  2020-06-25  8:03 [RESEND PATCH v5 0/6] arm64: tlb: add support for TTL feature Zhenyu Ye
                   ` (2 preceding siblings ...)
  2020-06-25  8:03 ` [RESEND PATCH v5 3/6] arm64: Add tlbi_user_level " Zhenyu Ye
@ 2020-06-25  8:03 ` Zhenyu Ye
  2020-06-25  8:03 ` [RESEND PATCH v5 5/6] arm64: tlb: Set the TTL field in flush_tlb_range Zhenyu Ye
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 11+ messages in thread
From: Zhenyu Ye @ 2020-06-25  8:03 UTC (permalink / raw)
  To: catalin.marinas, peterz, mark.rutland, will, aneesh.kumar, akpm,
	npiggin, arnd, rostedt, maz, suzuki.poulose, tglx, yuzhao,
	Dave.Martin, steven.price, broonie, guohanjun
  Cc: yezhenyu2, linux-arm-kernel, linux-kernel, linux-arch, linux-mm,
	arm, xiexiangyou, prime.zeng, zhangshaokun, kuhn.chenqun

From: "Peter Zijlstra (Intel)" <peterz@infradead.org>

tlb_flush_{pte|pmd|pud|p4d}_range() adjust the tlb->start and
tlb->end, then set corresponding cleared_*.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Signed-off-by: Zhenyu Ye <yezhenyu2@huawei.com>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
---
 include/asm-generic/tlb.h | 55 ++++++++++++++++++++++++++++-----------
 1 file changed, 40 insertions(+), 15 deletions(-)

diff --git a/include/asm-generic/tlb.h b/include/asm-generic/tlb.h
index 3f1649a8cf55..ef75ec86f865 100644
--- a/include/asm-generic/tlb.h
+++ b/include/asm-generic/tlb.h
@@ -512,6 +512,38 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm
 }
 #endif
 
+/*
+ * tlb_flush_{pte|pmd|pud|p4d}_range() adjust the tlb->start and tlb->end,
+ * and set corresponding cleared_*.
+ */
+static inline void tlb_flush_pte_range(struct mmu_gather *tlb,
+				     unsigned long address, unsigned long size)
+{
+	__tlb_adjust_range(tlb, address, size);
+	tlb->cleared_ptes = 1;
+}
+
+static inline void tlb_flush_pmd_range(struct mmu_gather *tlb,
+				     unsigned long address, unsigned long size)
+{
+	__tlb_adjust_range(tlb, address, size);
+	tlb->cleared_pmds = 1;
+}
+
+static inline void tlb_flush_pud_range(struct mmu_gather *tlb,
+				     unsigned long address, unsigned long size)
+{
+	__tlb_adjust_range(tlb, address, size);
+	tlb->cleared_puds = 1;
+}
+
+static inline void tlb_flush_p4d_range(struct mmu_gather *tlb,
+				     unsigned long address, unsigned long size)
+{
+	__tlb_adjust_range(tlb, address, size);
+	tlb->cleared_p4ds = 1;
+}
+
 #ifndef __tlb_remove_tlb_entry
 #define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0)
 #endif
@@ -525,19 +557,17 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm
  */
 #define tlb_remove_tlb_entry(tlb, ptep, address)		\
 	do {							\
-		__tlb_adjust_range(tlb, address, PAGE_SIZE);	\
-		tlb->cleared_ptes = 1;				\
+		tlb_flush_pte_range(tlb, address, PAGE_SIZE);	\
 		__tlb_remove_tlb_entry(tlb, ptep, address);	\
 	} while (0)
 
 #define tlb_remove_huge_tlb_entry(h, tlb, ptep, address)	\
 	do {							\
 		unsigned long _sz = huge_page_size(h);		\
-		__tlb_adjust_range(tlb, address, _sz);		\
 		if (_sz == PMD_SIZE)				\
-			tlb->cleared_pmds = 1;			\
+			tlb_flush_pmd_range(tlb, address, _sz);	\
 		else if (_sz == PUD_SIZE)			\
-			tlb->cleared_puds = 1;			\
+			tlb_flush_pud_range(tlb, address, _sz);	\
 		__tlb_remove_tlb_entry(tlb, ptep, address);	\
 	} while (0)
 
@@ -551,8 +581,7 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm
 
 #define tlb_remove_pmd_tlb_entry(tlb, pmdp, address)			\
 	do {								\
-		__tlb_adjust_range(tlb, address, HPAGE_PMD_SIZE);	\
-		tlb->cleared_pmds = 1;					\
+		tlb_flush_pmd_range(tlb, address, HPAGE_PMD_SIZE);	\
 		__tlb_remove_pmd_tlb_entry(tlb, pmdp, address);		\
 	} while (0)
 
@@ -566,8 +595,7 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm
 
 #define tlb_remove_pud_tlb_entry(tlb, pudp, address)			\
 	do {								\
-		__tlb_adjust_range(tlb, address, HPAGE_PUD_SIZE);	\
-		tlb->cleared_puds = 1;					\
+		tlb_flush_pud_range(tlb, address, HPAGE_PUD_SIZE);	\
 		__tlb_remove_pud_tlb_entry(tlb, pudp, address);		\
 	} while (0)
 
@@ -592,9 +620,8 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm
 #ifndef pte_free_tlb
 #define pte_free_tlb(tlb, ptep, address)			\
 	do {							\
-		__tlb_adjust_range(tlb, address, PAGE_SIZE);	\
+		tlb_flush_pmd_range(tlb, address, PAGE_SIZE);	\
 		tlb->freed_tables = 1;				\
-		tlb->cleared_pmds = 1;				\
 		__pte_free_tlb(tlb, ptep, address);		\
 	} while (0)
 #endif
@@ -602,9 +629,8 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm
 #ifndef pmd_free_tlb
 #define pmd_free_tlb(tlb, pmdp, address)			\
 	do {							\
-		__tlb_adjust_range(tlb, address, PAGE_SIZE);	\
+		tlb_flush_pud_range(tlb, address, PAGE_SIZE);	\
 		tlb->freed_tables = 1;				\
-		tlb->cleared_puds = 1;				\
 		__pmd_free_tlb(tlb, pmdp, address);		\
 	} while (0)
 #endif
@@ -612,9 +638,8 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm
 #ifndef pud_free_tlb
 #define pud_free_tlb(tlb, pudp, address)			\
 	do {							\
-		__tlb_adjust_range(tlb, address, PAGE_SIZE);	\
+		tlb_flush_p4d_range(tlb, address, PAGE_SIZE);	\
 		tlb->freed_tables = 1;				\
-		tlb->cleared_p4ds = 1;				\
 		__pud_free_tlb(tlb, pudp, address);		\
 	} while (0)
 #endif
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RESEND PATCH v5 5/6] arm64: tlb: Set the TTL field in flush_tlb_range
  2020-06-25  8:03 [RESEND PATCH v5 0/6] arm64: tlb: add support for TTL feature Zhenyu Ye
                   ` (3 preceding siblings ...)
  2020-06-25  8:03 ` [RESEND PATCH v5 4/6] tlb: mmu_gather: add tlb_flush_*_range APIs Zhenyu Ye
@ 2020-06-25  8:03 ` Zhenyu Ye
  2020-06-25  8:03 ` [RESEND PATCH v5 6/6] arm64: tlb: Set the TTL field in flush_*_tlb_range Zhenyu Ye
  2020-07-07 13:49 ` [RESEND PATCH v5 0/6] arm64: tlb: add support for TTL feature Catalin Marinas
  6 siblings, 0 replies; 11+ messages in thread
From: Zhenyu Ye @ 2020-06-25  8:03 UTC (permalink / raw)
  To: catalin.marinas, peterz, mark.rutland, will, aneesh.kumar, akpm,
	npiggin, arnd, rostedt, maz, suzuki.poulose, tglx, yuzhao,
	Dave.Martin, steven.price, broonie, guohanjun
  Cc: yezhenyu2, linux-arm-kernel, linux-kernel, linux-arch, linux-mm,
	arm, xiexiangyou, prime.zeng, zhangshaokun, kuhn.chenqun

This patch uses the cleared_* in struct mmu_gather to set the
TTL field in flush_tlb_range().

Signed-off-by: Zhenyu Ye <yezhenyu2@huawei.com>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
---
 arch/arm64/include/asm/tlb.h      | 29 ++++++++++++++++++++++++++++-
 arch/arm64/include/asm/tlbflush.h | 14 ++++++++------
 2 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/arch/arm64/include/asm/tlb.h b/arch/arm64/include/asm/tlb.h
index b76df828e6b7..61c97d3b58c7 100644
--- a/arch/arm64/include/asm/tlb.h
+++ b/arch/arm64/include/asm/tlb.h
@@ -21,11 +21,37 @@ static void tlb_flush(struct mmu_gather *tlb);
 
 #include <asm-generic/tlb.h>
 
+/*
+ * get the tlbi levels in arm64.  Default value is 0 if more than one
+ * of cleared_* is set or neither is set.
+ * Arm64 doesn't support p4ds now.
+ */
+static inline int tlb_get_level(struct mmu_gather *tlb)
+{
+	if (tlb->cleared_ptes && !(tlb->cleared_pmds ||
+				   tlb->cleared_puds ||
+				   tlb->cleared_p4ds))
+		return 3;
+
+	if (tlb->cleared_pmds && !(tlb->cleared_ptes ||
+				   tlb->cleared_puds ||
+				   tlb->cleared_p4ds))
+		return 2;
+
+	if (tlb->cleared_puds && !(tlb->cleared_ptes ||
+				   tlb->cleared_pmds ||
+				   tlb->cleared_p4ds))
+		return 1;
+
+	return 0;
+}
+
 static inline void tlb_flush(struct mmu_gather *tlb)
 {
 	struct vm_area_struct vma = TLB_FLUSH_VMA(tlb->mm, 0);
 	bool last_level = !tlb->freed_tables;
 	unsigned long stride = tlb_get_unmap_size(tlb);
+	int tlb_level = tlb_get_level(tlb);
 
 	/*
 	 * If we're tearing down the address space then we only care about
@@ -38,7 +64,8 @@ static inline void tlb_flush(struct mmu_gather *tlb)
 		return;
 	}
 
-	__flush_tlb_range(&vma, tlb->start, tlb->end, stride, last_level);
+	__flush_tlb_range(&vma, tlb->start, tlb->end, stride,
+			  last_level, tlb_level);
 }
 
 static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h
index bfb58e62c127..84cb98b60b7b 100644
--- a/arch/arm64/include/asm/tlbflush.h
+++ b/arch/arm64/include/asm/tlbflush.h
@@ -215,7 +215,8 @@ static inline void flush_tlb_page(struct vm_area_struct *vma,
 
 static inline void __flush_tlb_range(struct vm_area_struct *vma,
 				     unsigned long start, unsigned long end,
-				     unsigned long stride, bool last_level)
+				     unsigned long stride, bool last_level,
+				     int tlb_level)
 {
 	unsigned long asid = ASID(vma->vm_mm);
 	unsigned long addr;
@@ -237,11 +238,11 @@ static inline void __flush_tlb_range(struct vm_area_struct *vma,
 	dsb(ishst);
 	for (addr = start; addr < end; addr += stride) {
 		if (last_level) {
-			__tlbi_level(vale1is, addr, 0);
-			__tlbi_user_level(vale1is, addr, 0);
+			__tlbi_level(vale1is, addr, tlb_level);
+			__tlbi_user_level(vale1is, addr, tlb_level);
 		} else {
-			__tlbi_level(vae1is, addr, 0);
-			__tlbi_user_level(vae1is, addr, 0);
+			__tlbi_level(vae1is, addr, tlb_level);
+			__tlbi_user_level(vae1is, addr, tlb_level);
 		}
 	}
 	dsb(ish);
@@ -253,8 +254,9 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
 	/*
 	 * We cannot use leaf-only invalidation here, since we may be invalidating
 	 * table entries as part of collapsing hugepages or moving page tables.
+	 * Set the tlb_level to 0 because we can not get enough information here.
 	 */
-	__flush_tlb_range(vma, start, end, PAGE_SIZE, false);
+	__flush_tlb_range(vma, start, end, PAGE_SIZE, false, 0);
 }
 
 static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end)
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [RESEND PATCH v5 6/6] arm64: tlb: Set the TTL field in flush_*_tlb_range
  2020-06-25  8:03 [RESEND PATCH v5 0/6] arm64: tlb: add support for TTL feature Zhenyu Ye
                   ` (4 preceding siblings ...)
  2020-06-25  8:03 ` [RESEND PATCH v5 5/6] arm64: tlb: Set the TTL field in flush_tlb_range Zhenyu Ye
@ 2020-06-25  8:03 ` Zhenyu Ye
  2020-07-07 13:49 ` [RESEND PATCH v5 0/6] arm64: tlb: add support for TTL feature Catalin Marinas
  6 siblings, 0 replies; 11+ messages in thread
From: Zhenyu Ye @ 2020-06-25  8:03 UTC (permalink / raw)
  To: catalin.marinas, peterz, mark.rutland, will, aneesh.kumar, akpm,
	npiggin, arnd, rostedt, maz, suzuki.poulose, tglx, yuzhao,
	Dave.Martin, steven.price, broonie, guohanjun
  Cc: yezhenyu2, linux-arm-kernel, linux-kernel, linux-arch, linux-mm,
	arm, xiexiangyou, prime.zeng, zhangshaokun, kuhn.chenqun

This patch implement flush_{pmd|pud}_tlb_range() in arm64 by
calling __flush_tlb_range() with the corresponding stride and
tlb_level values.

Signed-off-by: Zhenyu Ye <yezhenyu2@huawei.com>
---
 arch/arm64/include/asm/pgtable.h | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 758e2d1577d0..d5d3fbe73953 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -40,6 +40,16 @@ extern void __pmd_error(const char *file, int line, unsigned long val);
 extern void __pud_error(const char *file, int line, unsigned long val);
 extern void __pgd_error(const char *file, int line, unsigned long val);
 
+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
+#define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE
+
+/* Set stride and tlb_level in flush_*_tlb_range */
+#define flush_pmd_tlb_range(vma, addr, end)	\
+	__flush_tlb_range(vma, addr, end, PMD_SIZE, false, 2)
+#define flush_pud_tlb_range(vma, addr, end)	\
+	__flush_tlb_range(vma, addr, end, PUD_SIZE, false, 1)
+#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
+
 /*
  * ZERO_PAGE is a global shared page that is always zero: used
  * for zero-mapped memory areas etc..
-- 
2.26.2



^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [RESEND PATCH v5 0/6] arm64: tlb: add support for TTL feature
  2020-06-25  8:03 [RESEND PATCH v5 0/6] arm64: tlb: add support for TTL feature Zhenyu Ye
                   ` (5 preceding siblings ...)
  2020-06-25  8:03 ` [RESEND PATCH v5 6/6] arm64: tlb: Set the TTL field in flush_*_tlb_range Zhenyu Ye
@ 2020-07-07 13:49 ` Catalin Marinas
  6 siblings, 0 replies; 11+ messages in thread
From: Catalin Marinas @ 2020-07-07 13:49 UTC (permalink / raw)
  To: arnd, broonie, guohanjun, suzuki.poulose, npiggin, maz,
	steven.price, aneesh.kumar, peterz, Zhenyu Ye, mark.rutland,
	Dave.Martin, will, yuzhao, akpm, tglx, rostedt
  Cc: xiexiangyou, kuhn.chenqun, zhangshaokun, linux-kernel, arm,
	linux-arch, prime.zeng, linux-mm, linux-arm-kernel

On Thu, 25 Jun 2020 16:03:08 +0800, Zhenyu Ye wrote:
> In order to reduce the cost of TLB invalidation, ARMv8.4 provides
> the TTL field in TLBI instruction.  The TTL field indicates the
> level of page table walk holding the leaf entry for the address
> being invalidated.  This series provide support for this feature.
> 
> When ARMv8.4-TTL is implemented, the operand for TLBIs looks like
> below:
> 
> [...]

Applied to arm64 (for-next/tlbi), thanks!

[3/6] arm64: Add tlbi_user_level TLB invalidation helper
      https://git.kernel.org/arm64/c/e735b98a5fe0
[4/6] tlb: mmu_gather: add tlb_flush_*_range APIs
      https://git.kernel.org/arm64/c/2631ed00b049
[5/6] arm64: tlb: Set the TTL field in flush_tlb_range
      https://git.kernel.org/arm64/c/c4ab2cbc1d87
[6/6] arm64: tlb: Set the TTL field in flush_*_tlb_range
      https://git.kernel.org/arm64/c/a7ac1cfa4c05

I haven't included the first 2 patches as I rebased the above on top of
Marc's TTL branch:

git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms.git kvm-arm64/ttl-for-arm64

-- 
Catalin


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RESEND PATCH v5 3/6] arm64: Add tlbi_user_level TLB invalidation helper
  2020-06-25  8:03 ` [RESEND PATCH v5 3/6] arm64: Add tlbi_user_level " Zhenyu Ye
@ 2020-07-09 16:48   ` Catalin Marinas
  2020-07-10  1:20     ` Zhenyu Ye
  0 siblings, 1 reply; 11+ messages in thread
From: Catalin Marinas @ 2020-07-09 16:48 UTC (permalink / raw)
  To: Zhenyu Ye
  Cc: peterz, mark.rutland, will, aneesh.kumar, akpm, npiggin, arnd,
	rostedt, maz, suzuki.poulose, tglx, yuzhao, Dave.Martin,
	steven.price, broonie, guohanjun, linux-arm-kernel, linux-kernel,
	linux-arch, linux-mm, arm, xiexiangyou, prime.zeng, zhangshaokun,
	kuhn.chenqun

On Thu, Jun 25, 2020 at 04:03:11PM +0800, Zhenyu Ye wrote:
> @@ -189,8 +195,9 @@ static inline void flush_tlb_page_nosync(struct vm_area_struct *vma,
>  	unsigned long addr = __TLBI_VADDR(uaddr, ASID(vma->vm_mm));
>  
>  	dsb(ishst);
> -	__tlbi(vale1is, addr);
> -	__tlbi_user(vale1is, addr);
> +	/* This function is only called on a small page */
> +	__tlbi_level(vale1is, addr, 3);
> +	__tlbi_user_level(vale1is, addr, 3);
>  }

Actually, that's incorrect. It was ok in v2 of your patches when I
suggested to drop level 0, just leave the function unchanged but I
missed that you updated it to pass level 3.

pmdp_set_access_flags -> ptep_set_access_flags ->
flush_tlb_fix_spurious_fault -> flush_tlb_page -> flush_tlb_page_nosync.

-- 
Catalin

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RESEND PATCH v5 3/6] arm64: Add tlbi_user_level TLB invalidation helper
  2020-07-09 16:48   ` Catalin Marinas
@ 2020-07-10  1:20     ` Zhenyu Ye
  2020-07-10  8:53       ` Catalin Marinas
  0 siblings, 1 reply; 11+ messages in thread
From: Zhenyu Ye @ 2020-07-10  1:20 UTC (permalink / raw)
  To: Catalin Marinas
  Cc: peterz, mark.rutland, will, aneesh.kumar, akpm, npiggin, arnd,
	rostedt, maz, suzuki.poulose, tglx, yuzhao, Dave.Martin,
	steven.price, broonie, guohanjun, linux-arm-kernel, linux-kernel,
	linux-arch, linux-mm, arm, xiexiangyou, prime.zeng, zhangshaokun,
	kuhn.chenqun

Hi Catalin,

On 2020/7/10 0:48, Catalin Marinas wrote:
> On Thu, Jun 25, 2020 at 04:03:11PM +0800, Zhenyu Ye wrote:
>> @@ -189,8 +195,9 @@ static inline void flush_tlb_page_nosync(struct vm_area_struct *vma,
>>  	unsigned long addr = __TLBI_VADDR(uaddr, ASID(vma->vm_mm));
>>  
>>  	dsb(ishst);
>> -	__tlbi(vale1is, addr);
>> -	__tlbi_user(vale1is, addr);
>> +	/* This function is only called on a small page */
>> +	__tlbi_level(vale1is, addr, 3);
>> +	__tlbi_user_level(vale1is, addr, 3);
>>  }
> 
> Actually, that's incorrect. It was ok in v2 of your patches when I
> suggested to drop level 0, just leave the function unchanged but I
> missed that you updated it to pass level 3.
> 
> pmdp_set_access_flags -> ptep_set_access_flags ->
> flush_tlb_fix_spurious_fault -> flush_tlb_page -> flush_tlb_page_nosync.

How do you want to fix this error? I notice that this series have been applied
to arm64 (for-next/tlbi).  Should I send a new series based on arm64 (for-next/tlbi)?

Thanks,
Zhenyu


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [RESEND PATCH v5 3/6] arm64: Add tlbi_user_level TLB invalidation helper
  2020-07-10  1:20     ` Zhenyu Ye
@ 2020-07-10  8:53       ` Catalin Marinas
  0 siblings, 0 replies; 11+ messages in thread
From: Catalin Marinas @ 2020-07-10  8:53 UTC (permalink / raw)
  To: Zhenyu Ye
  Cc: peterz, mark.rutland, will, aneesh.kumar, akpm, npiggin, arnd,
	rostedt, maz, suzuki.poulose, tglx, yuzhao, Dave.Martin,
	steven.price, broonie, guohanjun, linux-arm-kernel, linux-kernel,
	linux-arch, linux-mm, arm, xiexiangyou, prime.zeng, zhangshaokun,
	kuhn.chenqun

On Fri, Jul 10, 2020 at 09:20:59AM +0800, Zhenyu Ye wrote:
> On 2020/7/10 0:48, Catalin Marinas wrote:
> > On Thu, Jun 25, 2020 at 04:03:11PM +0800, Zhenyu Ye wrote:
> >> @@ -189,8 +195,9 @@ static inline void flush_tlb_page_nosync(struct vm_area_struct *vma,
> >>  	unsigned long addr = __TLBI_VADDR(uaddr, ASID(vma->vm_mm));
> >>  
> >>  	dsb(ishst);
> >> -	__tlbi(vale1is, addr);
> >> -	__tlbi_user(vale1is, addr);
> >> +	/* This function is only called on a small page */
> >> +	__tlbi_level(vale1is, addr, 3);
> >> +	__tlbi_user_level(vale1is, addr, 3);
> >>  }
> > 
> > Actually, that's incorrect. It was ok in v2 of your patches when I
> > suggested to drop level 0, just leave the function unchanged but I
> > missed that you updated it to pass level 3.
> > 
> > pmdp_set_access_flags -> ptep_set_access_flags ->
> > flush_tlb_fix_spurious_fault -> flush_tlb_page -> flush_tlb_page_nosync.
> 
> How do you want to fix this error? I notice that this series have been applied
> to arm64 (for-next/tlbi).  Should I send a new series based on arm64 (for-next/tlbi)?

Just a patch on top with a Fixes: tag.

Thanks.

-- 
Catalin

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2020-07-10  8:53 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-06-25  8:03 [RESEND PATCH v5 0/6] arm64: tlb: add support for TTL feature Zhenyu Ye
2020-06-25  8:03 ` [RESEND PATCH v5 1/6] arm64: Detect the ARMv8.4 " Zhenyu Ye
2020-06-25  8:03 ` [RESEND PATCH v5 2/6] arm64: Add level-hinted TLB invalidation helper Zhenyu Ye
2020-06-25  8:03 ` [RESEND PATCH v5 3/6] arm64: Add tlbi_user_level " Zhenyu Ye
2020-07-09 16:48   ` Catalin Marinas
2020-07-10  1:20     ` Zhenyu Ye
2020-07-10  8:53       ` Catalin Marinas
2020-06-25  8:03 ` [RESEND PATCH v5 4/6] tlb: mmu_gather: add tlb_flush_*_range APIs Zhenyu Ye
2020-06-25  8:03 ` [RESEND PATCH v5 5/6] arm64: tlb: Set the TTL field in flush_tlb_range Zhenyu Ye
2020-06-25  8:03 ` [RESEND PATCH v5 6/6] arm64: tlb: Set the TTL field in flush_*_tlb_range Zhenyu Ye
2020-07-07 13:49 ` [RESEND PATCH v5 0/6] arm64: tlb: add support for TTL feature Catalin Marinas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).