LoongArch architecture development
 help / color / mirror / Atom feed
* [PATCH] LoongArch: Add tlb_flush_threshold for tlb flush range
@ 2023-09-08  1:29 Bibo Mao
  2023-09-08 22:43 ` kernel test robot
  0 siblings, 1 reply; 3+ messages in thread
From: Bibo Mao @ 2023-09-08  1:29 UTC (permalink / raw)
  To: Huacai Chen; +Cc: loongarch, linux-kernel

There is calculation in function flush_tlb_range to decide flush tlb
entries one by one or flush the whole tlbs. Instead the calculation can be
done during cpu probe stage rather than runtime flush period.

This patch adds percpu variable tlb_flush_threshold during cpu probe
stage, and removes unused percpu variabled like tlbsizemtlb,
tlbsizestlbsets/tlbsizestlbways etc.

Also this patch fixes function __update_hugetlb, it should be
effective for CONFIG_TRANSPARENT_HUGEPAGE also.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 arch/loongarch/include/asm/cpu-info.h |  4 +---
 arch/loongarch/kernel/cpu-probe.c     | 31 ++++++++++++++++-----------
 arch/loongarch/mm/tlb.c               | 11 +++-------
 3 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/arch/loongarch/include/asm/cpu-info.h b/arch/loongarch/include/asm/cpu-info.h
index 900589cb159d..523827216c1b 100644
--- a/arch/loongarch/include/asm/cpu-info.h
+++ b/arch/loongarch/include/asm/cpu-info.h
@@ -47,9 +47,7 @@ struct cpuinfo_loongarch {
 	unsigned int		cputype;
 	int			isa_level;
 	int			tlbsize;
-	int			tlbsizemtlb;
-	int			tlbsizestlbsets;
-	int			tlbsizestlbways;
+	int			tlb_flush_threshold;
 	int			cache_leaves_present; /* number of cache_leaves[] elements */
 	struct cache_desc	cache_leaves[CACHE_LEAVES_MAX];
 	int			core;   /* physical core number in package */
diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c
index e925579c7a71..ffa0a1b1ae29 100644
--- a/arch/loongarch/kernel/cpu-probe.c
+++ b/arch/loongarch/kernel/cpu-probe.c
@@ -88,7 +88,7 @@ static void set_isa(struct cpuinfo_loongarch *c, unsigned int isa)
 
 static void cpu_probe_common(struct cpuinfo_loongarch *c)
 {
-	unsigned int config;
+	unsigned int config, stlbsets, stlbways, mtlbs;
 	unsigned long asid_mask;
 
 	c->options = LOONGARCH_CPU_CPUCFG | LOONGARCH_CPU_CSR |
@@ -173,28 +173,35 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
 	c->ksave_mask &= ~(EXC_KSAVE_MASK | PERCPU_KSAVE_MASK | KVM_KSAVE_MASK);
 
 	config = read_csr_prcfg3();
+	stlbsets = 0;
+	c->tlbsize = 0;
 	switch (config & CSR_CONF3_TLBTYPE) {
 	case 0:
-		c->tlbsizemtlb = 0;
-		c->tlbsizestlbsets = 0;
-		c->tlbsizestlbways = 0;
+		mtlbs = 0;
+		stlbsets = 0;
+		stlbways = 0;
 		c->tlbsize = 0;
 		break;
 	case 1:
-		c->tlbsizemtlb = ((config & CSR_CONF3_MTLBSIZE) >> CSR_CONF3_MTLBSIZE_SHIFT) + 1;
-		c->tlbsizestlbsets = 0;
-		c->tlbsizestlbways = 0;
-		c->tlbsize = c->tlbsizemtlb + c->tlbsizestlbsets * c->tlbsizestlbways;
+		mtlbs = ((config & CSR_CONF3_MTLBSIZE) >> CSR_CONF3_MTLBSIZE_SHIFT) + 1;
+		stlbsets = 0;
+		stlbways = 0;
+		c->tlbsize = mtlbs + stlbsets * stlbways;
 		break;
 	case 2:
-		c->tlbsizemtlb = ((config & CSR_CONF3_MTLBSIZE) >> CSR_CONF3_MTLBSIZE_SHIFT) + 1;
-		c->tlbsizestlbsets = 1 << ((config & CSR_CONF3_STLBIDX) >> CSR_CONF3_STLBIDX_SHIFT);
-		c->tlbsizestlbways = ((config & CSR_CONF3_STLBWAYS) >> CSR_CONF3_STLBWAYS_SHIFT) + 1;
-		c->tlbsize = c->tlbsizemtlb + c->tlbsizestlbsets * c->tlbsizestlbways;
+		mtlbs = ((config & CSR_CONF3_MTLBSIZE) >> CSR_CONF3_MTLBSIZE_SHIFT) + 1;
+		stlbsets = 1 << ((config & CSR_CONF3_STLBIDX) >> CSR_CONF3_STLBIDX_SHIFT);
+		stlbways = ((config & CSR_CONF3_STLBWAYS) >> CSR_CONF3_STLBWAYS_SHIFT) + 1;
+		c->tlbsize = mtlbs + stlbsets * stlbways;
 		break;
 	default:
 		pr_warn("Warning: unknown TLB type\n");
 	}
+
+	if (stlbsets)
+		c->tlb_flush_threshold = c->tlbsize / 8;
+	else
+		c->tlb_flush_threshold = c->tlbsize / 2;
 }
 
 #define MAX_NAME_LEN	32
diff --git a/arch/loongarch/mm/tlb.c b/arch/loongarch/mm/tlb.c
index eb8572e201ea..d87627cb9e29 100644
--- a/arch/loongarch/mm/tlb.c
+++ b/arch/loongarch/mm/tlb.c
@@ -66,9 +66,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 		start = round_down(start, PAGE_SIZE << 1);
 		end = round_up(end, PAGE_SIZE << 1);
 		size = (end - start) >> (PAGE_SHIFT + 1);
-		if (size <= (current_cpu_data.tlbsizestlbsets ?
-			     current_cpu_data.tlbsize / 8 :
-			     current_cpu_data.tlbsize / 2)) {
+		if (size <= current_cpu_data.tlb_flush_threshold) {
 			int asid = cpu_asid(cpu, mm);
 
 			while (start < end) {
@@ -91,10 +89,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
 	local_irq_save(flags);
 	size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 	size = (size + 1) >> 1;
-	if (size <= (current_cpu_data.tlbsizestlbsets ?
-		     current_cpu_data.tlbsize / 8 :
-		     current_cpu_data.tlbsize / 2)) {
-
+	if (size <= current_cpu_data.tlb_flush_threshold) {
 		start &= (PAGE_MASK << 1);
 		end += ((PAGE_SIZE << 1) - 1);
 		end &= (PAGE_MASK << 1);
@@ -136,7 +131,7 @@ void local_flush_tlb_one(unsigned long page)
 
 static void __update_hugetlb(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
 {
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 	int idx;
 	unsigned long lo;
 	unsigned long flags;

base-commit: 744a759492b5c57ff24a6e8aabe47b17ad8ee964
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread
* [PATCH] LoongArch: Add tlb_flush_threshold for tlb flush range
@ 2023-09-07  6:27 Bibo Mao
  0 siblings, 0 replies; 3+ messages in thread
From: Bibo Mao @ 2023-09-07  6:27 UTC (permalink / raw)
  To: Huacai Chen; +Cc: WANG Xuerui, Andrew Morton, loongarch, linux-kernel

There is calculation in function flush_tlb_range to decide flush tlb
entries one by one or flush the whole tlbs. Instead the calculation can be
done during cpu probe stage rather than runtime flush period.

This patch adds percpu variable tlb_flush_threshold during cpu probe
stage, and removes unused percpu variabled like tlbsizemtlb,
tlbsizestlbsets/tlbsizestlbways etc.

Also this patch fixes function __update_hugetlb, it should be
effective for CONFIG_TRANSPARENT_HUGEPAGE also.

Signed-off-by: Bibo Mao <maobibo@loongson.cn>
---
 arch/loongarch/include/asm/cpu-info.h |  4 +---
 arch/loongarch/kernel/cpu-probe.c     | 31 ++++++++++++++++-----------
 arch/loongarch/mm/tlb.c               | 11 +++-------
 3 files changed, 23 insertions(+), 23 deletions(-)

diff --git a/arch/loongarch/include/asm/cpu-info.h b/arch/loongarch/include/asm/cpu-info.h
index 900589cb159d..523827216c1b 100644
--- a/arch/loongarch/include/asm/cpu-info.h
+++ b/arch/loongarch/include/asm/cpu-info.h
@@ -47,9 +47,7 @@ struct cpuinfo_loongarch {
 	unsigned int		cputype;
 	int			isa_level;
 	int			tlbsize;
-	int			tlbsizemtlb;
-	int			tlbsizestlbsets;
-	int			tlbsizestlbways;
+	int			tlb_flush_threshold;
 	int			cache_leaves_present; /* number of cache_leaves[] elements */
 	struct cache_desc	cache_leaves[CACHE_LEAVES_MAX];
 	int			core;   /* physical core number in package */
diff --git a/arch/loongarch/kernel/cpu-probe.c b/arch/loongarch/kernel/cpu-probe.c
index e925579c7a71..ffa0a1b1ae29 100644
--- a/arch/loongarch/kernel/cpu-probe.c
+++ b/arch/loongarch/kernel/cpu-probe.c
@@ -88,7 +88,7 @@ static void set_isa(struct cpuinfo_loongarch *c, unsigned int isa)
 
 static void cpu_probe_common(struct cpuinfo_loongarch *c)
 {
-	unsigned int config;
+	unsigned int config, stlbsets, stlbways, mtlbs;
 	unsigned long asid_mask;
 
 	c->options = LOONGARCH_CPU_CPUCFG | LOONGARCH_CPU_CSR |
@@ -173,28 +173,35 @@ static void cpu_probe_common(struct cpuinfo_loongarch *c)
 	c->ksave_mask &= ~(EXC_KSAVE_MASK | PERCPU_KSAVE_MASK | KVM_KSAVE_MASK);
 
 	config = read_csr_prcfg3();
+	stlbsets = 0;
+	c->tlbsize = 0;
 	switch (config & CSR_CONF3_TLBTYPE) {
 	case 0:
-		c->tlbsizemtlb = 0;
-		c->tlbsizestlbsets = 0;
-		c->tlbsizestlbways = 0;
+		mtlbs = 0;
+		stlbsets = 0;
+		stlbways = 0;
 		c->tlbsize = 0;
 		break;
 	case 1:
-		c->tlbsizemtlb = ((config & CSR_CONF3_MTLBSIZE) >> CSR_CONF3_MTLBSIZE_SHIFT) + 1;
-		c->tlbsizestlbsets = 0;
-		c->tlbsizestlbways = 0;
-		c->tlbsize = c->tlbsizemtlb + c->tlbsizestlbsets * c->tlbsizestlbways;
+		mtlbs = ((config & CSR_CONF3_MTLBSIZE) >> CSR_CONF3_MTLBSIZE_SHIFT) + 1;
+		stlbsets = 0;
+		stlbways = 0;
+		c->tlbsize = mtlbs + stlbsets * stlbways;
 		break;
 	case 2:
-		c->tlbsizemtlb = ((config & CSR_CONF3_MTLBSIZE) >> CSR_CONF3_MTLBSIZE_SHIFT) + 1;
-		c->tlbsizestlbsets = 1 << ((config & CSR_CONF3_STLBIDX) >> CSR_CONF3_STLBIDX_SHIFT);
-		c->tlbsizestlbways = ((config & CSR_CONF3_STLBWAYS) >> CSR_CONF3_STLBWAYS_SHIFT) + 1;
-		c->tlbsize = c->tlbsizemtlb + c->tlbsizestlbsets * c->tlbsizestlbways;
+		mtlbs = ((config & CSR_CONF3_MTLBSIZE) >> CSR_CONF3_MTLBSIZE_SHIFT) + 1;
+		stlbsets = 1 << ((config & CSR_CONF3_STLBIDX) >> CSR_CONF3_STLBIDX_SHIFT);
+		stlbways = ((config & CSR_CONF3_STLBWAYS) >> CSR_CONF3_STLBWAYS_SHIFT) + 1;
+		c->tlbsize = mtlbs + stlbsets * stlbways;
 		break;
 	default:
 		pr_warn("Warning: unknown TLB type\n");
 	}
+
+	if (stlbsets)
+		c->tlb_flush_threshold = c->tlbsize / 8;
+	else
+		c->tlb_flush_threshold = c->tlbsize / 2;
 }
 
 #define MAX_NAME_LEN	32
diff --git a/arch/loongarch/mm/tlb.c b/arch/loongarch/mm/tlb.c
index eb8572e201ea..d87627cb9e29 100644
--- a/arch/loongarch/mm/tlb.c
+++ b/arch/loongarch/mm/tlb.c
@@ -66,9 +66,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 		start = round_down(start, PAGE_SIZE << 1);
 		end = round_up(end, PAGE_SIZE << 1);
 		size = (end - start) >> (PAGE_SHIFT + 1);
-		if (size <= (current_cpu_data.tlbsizestlbsets ?
-			     current_cpu_data.tlbsize / 8 :
-			     current_cpu_data.tlbsize / 2)) {
+		if (size <= current_cpu_data.tlb_flush_threshold) {
 			int asid = cpu_asid(cpu, mm);
 
 			while (start < end) {
@@ -91,10 +89,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
 	local_irq_save(flags);
 	size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
 	size = (size + 1) >> 1;
-	if (size <= (current_cpu_data.tlbsizestlbsets ?
-		     current_cpu_data.tlbsize / 8 :
-		     current_cpu_data.tlbsize / 2)) {
-
+	if (size <= current_cpu_data.tlb_flush_threshold) {
 		start &= (PAGE_MASK << 1);
 		end += ((PAGE_SIZE << 1) - 1);
 		end &= (PAGE_MASK << 1);
@@ -136,7 +131,7 @@ void local_flush_tlb_one(unsigned long page)
 
 static void __update_hugetlb(struct vm_area_struct *vma, unsigned long address, pte_t *ptep)
 {
-#ifdef CONFIG_HUGETLB_PAGE
+#if defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)
 	int idx;
 	unsigned long lo;
 	unsigned long flags;

base-commit: 744a759492b5c57ff24a6e8aabe47b17ad8ee964
-- 
2.27.0


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

end of thread, other threads:[~2023-09-08 22:44 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-09-08  1:29 [PATCH] LoongArch: Add tlb_flush_threshold for tlb flush range Bibo Mao
2023-09-08 22:43 ` kernel test robot
  -- strict thread matches above, loose matches on Subject: below --
2023-09-07  6:27 Bibo Mao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox