linux-mm.kvack.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/4] riscv: tlb flush improvements
@ 2023-08-01  8:53 Alexandre Ghiti
  2023-08-01  8:53 ` [PATCH v3 1/4] riscv: Improve flush_tlb() Alexandre Ghiti
                   ` (5 more replies)
  0 siblings, 6 replies; 22+ messages in thread
From: Alexandre Ghiti @ 2023-08-01  8:53 UTC (permalink / raw)
  To: Will Deacon, Aneesh Kumar K . V, Andrew Morton, Nick Piggin,
	Peter Zijlstra, Mayuresh Chitale, Vincent Chen, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, linux-arch, linux-mm, linux-riscv,
	linux-kernel
  Cc: Alexandre Ghiti

This series optimizes the tlb flushes on riscv which used to simply
flush the whole tlb whatever the size of the range to flush or the size
of the stride.

Patch 3 introduces a threshold that is microarchitecture specific and
will very likely be modified by vendors, not sure though which mechanism
we'll use to do that (dt? alternatives? vendor initialization code?).

Next steps would be to implement:
- svinval extension as Mayuresh did here [1]
- BATCHED_UNMAP_TLB_FLUSH (I'll wait for arm64 patchset to land)
- MMU_GATHER_RCU_TABLE_FREE
- MMU_GATHER_MERGE_VMAS

Any other idea welcome.

[1] https://lore.kernel.org/linux-riscv/20230623123849.1425805-1-mchitale@ventanamicro.com/

Changes in v3:
- Add RB from Andrew, thanks!
- Unwrap a few lines, as suggested by Andrew
- Introduce defines for -1 constants used in tlbflush.c, as suggested by Andrew and Conor
- Use huge_page_size() directly instead of using the shift, as suggested by Andrew
- Remove misleading comments as suggested by Conor

Changes in v2:
- Make static tlb_flush_all_threshold, we'll figure out later how to
  override this value on a vendor basis, as suggested by Conor and Palmer
- Fix nommu build, as reported by Conor

Alexandre Ghiti (4):
  riscv: Improve flush_tlb()
  riscv: Improve flush_tlb_range() for hugetlb pages
  riscv: Make __flush_tlb_range() loop over pte instead of flushing the
    whole tlb
  riscv: Improve flush_tlb_kernel_range()

 arch/riscv/include/asm/tlb.h      |  8 ++-
 arch/riscv/include/asm/tlbflush.h | 12 ++--
 arch/riscv/mm/tlbflush.c          | 98 ++++++++++++++++++++++++++-----
 3 files changed, 99 insertions(+), 19 deletions(-)

-- 
2.39.2



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

* [PATCH v3 1/4] riscv: Improve flush_tlb()
  2023-08-01  8:53 [PATCH v3 0/4] riscv: tlb flush improvements Alexandre Ghiti
@ 2023-08-01  8:53 ` Alexandre Ghiti
  2023-08-01  8:54 ` [PATCH v3 2/4] riscv: Improve flush_tlb_range() for hugetlb pages Alexandre Ghiti
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 22+ messages in thread
From: Alexandre Ghiti @ 2023-08-01  8:53 UTC (permalink / raw)
  To: Will Deacon, Aneesh Kumar K . V, Andrew Morton, Nick Piggin,
	Peter Zijlstra, Mayuresh Chitale, Vincent Chen, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, linux-arch, linux-mm, linux-riscv,
	linux-kernel
  Cc: Alexandre Ghiti, Andrew Jones

For now, flush_tlb() simply calls flush_tlb_mm() which results in a
flush of the whole TLB. So let's use mmu_gather fields to provide a more
fine-grained flush of the TLB.

Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
 arch/riscv/include/asm/tlb.h      | 8 +++++++-
 arch/riscv/include/asm/tlbflush.h | 3 +++
 arch/riscv/mm/tlbflush.c          | 7 +++++++
 3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/include/asm/tlb.h b/arch/riscv/include/asm/tlb.h
index 120bcf2ed8a8..1eb5682b2af6 100644
--- a/arch/riscv/include/asm/tlb.h
+++ b/arch/riscv/include/asm/tlb.h
@@ -15,7 +15,13 @@ static void tlb_flush(struct mmu_gather *tlb);
 
 static inline void tlb_flush(struct mmu_gather *tlb)
 {
-	flush_tlb_mm(tlb->mm);
+#ifdef CONFIG_MMU
+	if (tlb->fullmm || tlb->need_flush_all)
+		flush_tlb_mm(tlb->mm);
+	else
+		flush_tlb_mm_range(tlb->mm, tlb->start, tlb->end,
+				   tlb_get_unmap_size(tlb));
+#endif
 }
 
 #endif /* _ASM_RISCV_TLB_H */
diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h
index a09196f8de68..f5c4fb0ae642 100644
--- a/arch/riscv/include/asm/tlbflush.h
+++ b/arch/riscv/include/asm/tlbflush.h
@@ -32,6 +32,8 @@ static inline void local_flush_tlb_page(unsigned long addr)
 #if defined(CONFIG_SMP) && defined(CONFIG_MMU)
 void flush_tlb_all(void);
 void flush_tlb_mm(struct mm_struct *mm);
+void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
+			unsigned long end, unsigned int page_size);
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr);
 void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 		     unsigned long end);
@@ -52,6 +54,7 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
 }
 
 #define flush_tlb_mm(mm) flush_tlb_all()
+#define flush_tlb_mm_range(mm, start, end, page_size) flush_tlb_all()
 #endif /* !CONFIG_SMP || !CONFIG_MMU */
 
 /* Flush a range of kernel pages */
diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
index 77be59aadc73..fa03289853d8 100644
--- a/arch/riscv/mm/tlbflush.c
+++ b/arch/riscv/mm/tlbflush.c
@@ -132,6 +132,13 @@ void flush_tlb_mm(struct mm_struct *mm)
 	__flush_tlb_range(mm, 0, -1, PAGE_SIZE);
 }
 
+void flush_tlb_mm_range(struct mm_struct *mm,
+			unsigned long start, unsigned long end,
+			unsigned int page_size)
+{
+	__flush_tlb_range(mm, start, end - start, page_size);
+}
+
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
 {
 	__flush_tlb_range(vma->vm_mm, addr, PAGE_SIZE, PAGE_SIZE);
-- 
2.39.2



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

* [PATCH v3 2/4] riscv: Improve flush_tlb_range() for hugetlb pages
  2023-08-01  8:53 [PATCH v3 0/4] riscv: tlb flush improvements Alexandre Ghiti
  2023-08-01  8:53 ` [PATCH v3 1/4] riscv: Improve flush_tlb() Alexandre Ghiti
@ 2023-08-01  8:54 ` Alexandre Ghiti
  2023-08-01  8:54 ` [PATCH v3 3/4] riscv: Make __flush_tlb_range() loop over pte instead of flushing the whole tlb Alexandre Ghiti
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 22+ messages in thread
From: Alexandre Ghiti @ 2023-08-01  8:54 UTC (permalink / raw)
  To: Will Deacon, Aneesh Kumar K . V, Andrew Morton, Nick Piggin,
	Peter Zijlstra, Mayuresh Chitale, Vincent Chen, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, linux-arch, linux-mm, linux-riscv,
	linux-kernel
  Cc: Alexandre Ghiti, Andrew Jones

flush_tlb_range() uses a fixed stride of PAGE_SIZE and in its current form,
when a hugetlb mapping needs to be flushed, flush_tlb_range() flushes the
whole tlb: so set a stride of the size of the hugetlb mapping in order to
only flush the hugetlb mapping.

Note that THPs are directly handled by flush_pmd_tlb_range().

Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
 arch/riscv/mm/tlbflush.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
index fa03289853d8..d883df0dee4a 100644
--- a/arch/riscv/mm/tlbflush.c
+++ b/arch/riscv/mm/tlbflush.c
@@ -3,6 +3,7 @@
 #include <linux/mm.h>
 #include <linux/smp.h>
 #include <linux/sched.h>
+#include <linux/hugetlb.h>
 #include <asm/sbi.h>
 #include <asm/mmu_context.h>
 
@@ -147,7 +148,13 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
 void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 		     unsigned long end)
 {
-	__flush_tlb_range(vma->vm_mm, start, end - start, PAGE_SIZE);
+	unsigned long stride_size;
+
+	stride_size = is_vm_hugetlb_page(vma) ?
+				huge_page_size(hstate_vma(vma)) :
+				PAGE_SIZE;
+
+	__flush_tlb_range(vma->vm_mm, start, end - start, stride_size);
 }
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start,
-- 
2.39.2



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

* [PATCH v3 3/4] riscv: Make __flush_tlb_range() loop over pte instead of flushing the whole tlb
  2023-08-01  8:53 [PATCH v3 0/4] riscv: tlb flush improvements Alexandre Ghiti
  2023-08-01  8:53 ` [PATCH v3 1/4] riscv: Improve flush_tlb() Alexandre Ghiti
  2023-08-01  8:54 ` [PATCH v3 2/4] riscv: Improve flush_tlb_range() for hugetlb pages Alexandre Ghiti
@ 2023-08-01  8:54 ` Alexandre Ghiti
  2023-08-01  8:54 ` [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range() Alexandre Ghiti
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 22+ messages in thread
From: Alexandre Ghiti @ 2023-08-01  8:54 UTC (permalink / raw)
  To: Will Deacon, Aneesh Kumar K . V, Andrew Morton, Nick Piggin,
	Peter Zijlstra, Mayuresh Chitale, Vincent Chen, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, linux-arch, linux-mm, linux-riscv,
	linux-kernel
  Cc: Alexandre Ghiti, Andrew Jones

Currently, when the range to flush covers more than one page (a 4K page or
a hugepage), __flush_tlb_range() flushes the whole tlb. Flushing the whole
tlb comes with a greater cost than flushing a single entry so we should
flush single entries up to a certain threshold so that:
threshold * cost of flushing a single entry < cost of flushing the whole
tlb.

Co-developed-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Signed-off-by: Mayuresh Chitale <mchitale@ventanamicro.com>
Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
 arch/riscv/mm/tlbflush.c | 48 ++++++++++++++++++++++++++++++++++++----
 1 file changed, 44 insertions(+), 4 deletions(-)

diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
index d883df0dee4a..0c955c474f3a 100644
--- a/arch/riscv/mm/tlbflush.c
+++ b/arch/riscv/mm/tlbflush.c
@@ -7,6 +7,9 @@
 #include <asm/sbi.h>
 #include <asm/mmu_context.h>
 
+#define FLUSH_TLB_MAX_SIZE	((unsigned long)-1)
+#define FLUSH_TLB_NO_ASID	((unsigned long)-1)
+
 static inline void local_flush_tlb_all_asid(unsigned long asid)
 {
 	__asm__ __volatile__ ("sfence.vma x0, %0"
@@ -24,13 +27,48 @@ static inline void local_flush_tlb_page_asid(unsigned long addr,
 			: "memory");
 }
 
+/*
+ * Flush entire TLB if number of entries to be flushed is greater
+ * than the threshold below.
+ */
+static unsigned long tlb_flush_all_threshold __read_mostly = 64;
+
+static void local_flush_tlb_range_threshold_asid(unsigned long start,
+						 unsigned long size,
+						 unsigned long stride,
+						 unsigned long asid)
+{
+	u16 nr_ptes_in_range = DIV_ROUND_UP(size, stride);
+	int i;
+
+	if (nr_ptes_in_range > tlb_flush_all_threshold) {
+		if (asid != FLUSH_TLB_NO_ASID)
+			local_flush_tlb_all_asid(asid);
+		else
+			local_flush_tlb_all();
+		return;
+	}
+
+	for (i = 0; i < nr_ptes_in_range; ++i) {
+		if (asid != FLUSH_TLB_NO_ASID)
+			local_flush_tlb_page_asid(start, asid);
+		else
+			local_flush_tlb_page(start);
+		start += stride;
+	}
+}
+
 static inline void local_flush_tlb_range(unsigned long start,
 		unsigned long size, unsigned long stride)
 {
 	if (size <= stride)
 		local_flush_tlb_page(start);
-	else
+	else if (size == FLUSH_TLB_MAX_SIZE)
 		local_flush_tlb_all();
+	else
+		local_flush_tlb_range_threshold_asid(start, size, stride,
+						     FLUSH_TLB_NO_ASID);
+
 }
 
 static inline void local_flush_tlb_range_asid(unsigned long start,
@@ -38,8 +76,10 @@ static inline void local_flush_tlb_range_asid(unsigned long start,
 {
 	if (size <= stride)
 		local_flush_tlb_page_asid(start, asid);
-	else
+	else if (size == FLUSH_TLB_MAX_SIZE)
 		local_flush_tlb_all_asid(asid);
+	else
+		local_flush_tlb_range_threshold_asid(start, size, stride, asid);
 }
 
 static void __ipi_flush_tlb_all(void *info)
@@ -52,7 +92,7 @@ void flush_tlb_all(void)
 	if (riscv_use_ipi_for_rfence())
 		on_each_cpu(__ipi_flush_tlb_all, NULL, 1);
 	else
-		sbi_remote_sfence_vma(NULL, 0, -1);
+		sbi_remote_sfence_vma(NULL, 0, FLUSH_TLB_MAX_SIZE);
 }
 
 struct flush_tlb_range_data {
@@ -130,7 +170,7 @@ static void __flush_tlb_range(struct mm_struct *mm, unsigned long start,
 
 void flush_tlb_mm(struct mm_struct *mm)
 {
-	__flush_tlb_range(mm, 0, -1, PAGE_SIZE);
+	__flush_tlb_range(mm, 0, FLUSH_TLB_MAX_SIZE, PAGE_SIZE);
 }
 
 void flush_tlb_mm_range(struct mm_struct *mm,
-- 
2.39.2



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

* [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range()
  2023-08-01  8:53 [PATCH v3 0/4] riscv: tlb flush improvements Alexandre Ghiti
                   ` (2 preceding siblings ...)
  2023-08-01  8:54 ` [PATCH v3 3/4] riscv: Make __flush_tlb_range() loop over pte instead of flushing the whole tlb Alexandre Ghiti
@ 2023-08-01  8:54 ` Alexandre Ghiti
  2023-09-06 11:48   ` Lad, Prabhakar
  2023-09-09 19:00   ` Samuel Holland
  2023-09-06 13:00 ` [PATCH v3 0/4] riscv: tlb flush improvements patchwork-bot+linux-riscv
  2023-09-09 20:11 ` Samuel Holland
  5 siblings, 2 replies; 22+ messages in thread
From: Alexandre Ghiti @ 2023-08-01  8:54 UTC (permalink / raw)
  To: Will Deacon, Aneesh Kumar K . V, Andrew Morton, Nick Piggin,
	Peter Zijlstra, Mayuresh Chitale, Vincent Chen, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, linux-arch, linux-mm, linux-riscv,
	linux-kernel
  Cc: Alexandre Ghiti, Andrew Jones

This function used to simply flush the whole tlb of all harts, be more
subtile and try to only flush the range.

The problem is that we can only use PAGE_SIZE as stride since we don't know
the size of the underlying mapping and then this function will be improved
only if the size of the region to flush is < threshold * PAGE_SIZE.

Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
---
 arch/riscv/include/asm/tlbflush.h | 11 +++++-----
 arch/riscv/mm/tlbflush.c          | 34 +++++++++++++++++++++++--------
 2 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h
index f5c4fb0ae642..7426fdcd8ec5 100644
--- a/arch/riscv/include/asm/tlbflush.h
+++ b/arch/riscv/include/asm/tlbflush.h
@@ -37,6 +37,7 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
 void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr);
 void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 		     unsigned long end);
+void flush_tlb_kernel_range(unsigned long start, unsigned long end);
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 #define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE
 void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start,
@@ -53,15 +54,15 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
 	local_flush_tlb_all();
 }
 
-#define flush_tlb_mm(mm) flush_tlb_all()
-#define flush_tlb_mm_range(mm, start, end, page_size) flush_tlb_all()
-#endif /* !CONFIG_SMP || !CONFIG_MMU */
-
 /* Flush a range of kernel pages */
 static inline void flush_tlb_kernel_range(unsigned long start,
 	unsigned long end)
 {
-	flush_tlb_all();
+	local_flush_tlb_all();
 }
 
+#define flush_tlb_mm(mm) flush_tlb_all()
+#define flush_tlb_mm_range(mm, start, end, page_size) flush_tlb_all()
+#endif /* !CONFIG_SMP || !CONFIG_MMU */
+
 #endif /* _ASM_RISCV_TLBFLUSH_H */
diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
index 0c955c474f3a..687808013758 100644
--- a/arch/riscv/mm/tlbflush.c
+++ b/arch/riscv/mm/tlbflush.c
@@ -120,18 +120,27 @@ static void __flush_tlb_range(struct mm_struct *mm, unsigned long start,
 			      unsigned long size, unsigned long stride)
 {
 	struct flush_tlb_range_data ftd;
-	struct cpumask *cmask = mm_cpumask(mm);
-	unsigned int cpuid;
+	struct cpumask *cmask, full_cmask;
 	bool broadcast;
 
-	if (cpumask_empty(cmask))
-		return;
+	if (mm) {
+		unsigned int cpuid;
+
+		cmask = mm_cpumask(mm);
+		if (cpumask_empty(cmask))
+			return;
+
+		cpuid = get_cpu();
+		/* check if the tlbflush needs to be sent to other CPUs */
+		broadcast = cpumask_any_but(cmask, cpuid) < nr_cpu_ids;
+	} else {
+		cpumask_setall(&full_cmask);
+		cmask = &full_cmask;
+		broadcast = true;
+	}
 
-	cpuid = get_cpu();
-	/* check if the tlbflush needs to be sent to other CPUs */
-	broadcast = cpumask_any_but(cmask, cpuid) < nr_cpu_ids;
 	if (static_branch_unlikely(&use_asid_allocator)) {
-		unsigned long asid = atomic_long_read(&mm->context.id) & asid_mask;
+		unsigned long asid = mm ? atomic_long_read(&mm->context.id) & asid_mask : 0;
 
 		if (broadcast) {
 			if (riscv_use_ipi_for_rfence()) {
@@ -165,7 +174,8 @@ static void __flush_tlb_range(struct mm_struct *mm, unsigned long start,
 		}
 	}
 
-	put_cpu();
+	if (mm)
+		put_cpu();
 }
 
 void flush_tlb_mm(struct mm_struct *mm)
@@ -196,6 +206,12 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
 
 	__flush_tlb_range(vma->vm_mm, start, end - start, stride_size);
 }
+
+void flush_tlb_kernel_range(unsigned long start, unsigned long end)
+{
+	__flush_tlb_range(NULL, start, end, PAGE_SIZE);
+}
+
 #ifdef CONFIG_TRANSPARENT_HUGEPAGE
 void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start,
 			unsigned long end)
-- 
2.39.2



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

* Re: [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range()
  2023-08-01  8:54 ` [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range() Alexandre Ghiti
@ 2023-09-06 11:48   ` Lad, Prabhakar
  2023-09-06 12:01     ` Alexandre Ghiti
  2023-09-06 20:22     ` Nadav Amit
  2023-09-09 19:00   ` Samuel Holland
  1 sibling, 2 replies; 22+ messages in thread
From: Lad, Prabhakar @ 2023-09-06 11:48 UTC (permalink / raw)
  To: Alexandre Ghiti
  Cc: Geert Uytterhoeven, Will Deacon, Aneesh Kumar K . V,
	Andrew Morton, Nick Piggin, Peter Zijlstra, Mayuresh Chitale,
	Vincent Chen, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	linux-arch, linux-mm, linux-riscv, linux-kernel, Andrew Jones

Hi Alexandre,

On Tue, Aug 1, 2023 at 9:58 AM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
>
> This function used to simply flush the whole tlb of all harts, be more
> subtile and try to only flush the range.
>
> The problem is that we can only use PAGE_SIZE as stride since we don't know
> the size of the underlying mapping and then this function will be improved
> only if the size of the region to flush is < threshold * PAGE_SIZE.
>
> Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
> Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
> ---
>  arch/riscv/include/asm/tlbflush.h | 11 +++++-----
>  arch/riscv/mm/tlbflush.c          | 34 +++++++++++++++++++++++--------
>  2 files changed, 31 insertions(+), 14 deletions(-)
>
After applying this patch, I am seeing module load issues on RZ/Five
(complete log [0]). I am testing defconfig + [1] (rz/five related
configs).

Any pointers on what could be an issue here?

[0] https://paste.debian.net/1291116/
[1] https://paste.debian.net/1291118/

Cheers,
Prabhakar

> diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h
> index f5c4fb0ae642..7426fdcd8ec5 100644
> --- a/arch/riscv/include/asm/tlbflush.h
> +++ b/arch/riscv/include/asm/tlbflush.h
> @@ -37,6 +37,7 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
>  void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr);
>  void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
>                      unsigned long end);
> +void flush_tlb_kernel_range(unsigned long start, unsigned long end);
>  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>  #define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE
>  void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start,
> @@ -53,15 +54,15 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
>         local_flush_tlb_all();
>  }
>
> -#define flush_tlb_mm(mm) flush_tlb_all()
> -#define flush_tlb_mm_range(mm, start, end, page_size) flush_tlb_all()
> -#endif /* !CONFIG_SMP || !CONFIG_MMU */
> -
>  /* Flush a range of kernel pages */
>  static inline void flush_tlb_kernel_range(unsigned long start,
>         unsigned long end)
>  {
> -       flush_tlb_all();
> +       local_flush_tlb_all();
>  }
>
> +#define flush_tlb_mm(mm) flush_tlb_all()
> +#define flush_tlb_mm_range(mm, start, end, page_size) flush_tlb_all()
> +#endif /* !CONFIG_SMP || !CONFIG_MMU */
> +
>  #endif /* _ASM_RISCV_TLBFLUSH_H */
> diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
> index 0c955c474f3a..687808013758 100644
> --- a/arch/riscv/mm/tlbflush.c
> +++ b/arch/riscv/mm/tlbflush.c
> @@ -120,18 +120,27 @@ static void __flush_tlb_range(struct mm_struct *mm, unsigned long start,
>                               unsigned long size, unsigned long stride)
>  {
>         struct flush_tlb_range_data ftd;
> -       struct cpumask *cmask = mm_cpumask(mm);
> -       unsigned int cpuid;
> +       struct cpumask *cmask, full_cmask;
>         bool broadcast;
>
> -       if (cpumask_empty(cmask))
> -               return;
> +       if (mm) {
> +               unsigned int cpuid;
> +
> +               cmask = mm_cpumask(mm);
> +               if (cpumask_empty(cmask))
> +                       return;
> +
> +               cpuid = get_cpu();
> +               /* check if the tlbflush needs to be sent to other CPUs */
> +               broadcast = cpumask_any_but(cmask, cpuid) < nr_cpu_ids;
> +       } else {
> +               cpumask_setall(&full_cmask);
> +               cmask = &full_cmask;
> +               broadcast = true;
> +       }
>
> -       cpuid = get_cpu();
> -       /* check if the tlbflush needs to be sent to other CPUs */
> -       broadcast = cpumask_any_but(cmask, cpuid) < nr_cpu_ids;
>         if (static_branch_unlikely(&use_asid_allocator)) {
> -               unsigned long asid = atomic_long_read(&mm->context.id) & asid_mask;
> +               unsigned long asid = mm ? atomic_long_read(&mm->context.id) & asid_mask : 0;
>
>                 if (broadcast) {
>                         if (riscv_use_ipi_for_rfence()) {
> @@ -165,7 +174,8 @@ static void __flush_tlb_range(struct mm_struct *mm, unsigned long start,
>                 }
>         }
>
> -       put_cpu();
> +       if (mm)
> +               put_cpu();
>  }
>
>  void flush_tlb_mm(struct mm_struct *mm)
> @@ -196,6 +206,12 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
>
>         __flush_tlb_range(vma->vm_mm, start, end - start, stride_size);
>  }
> +
> +void flush_tlb_kernel_range(unsigned long start, unsigned long end)
> +{
> +       __flush_tlb_range(NULL, start, end, PAGE_SIZE);
> +}
> +
>  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>  void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start,
>                         unsigned long end)
> --
> 2.39.2
>
>


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

* Re: [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range()
  2023-09-06 11:48   ` Lad, Prabhakar
@ 2023-09-06 12:01     ` Alexandre Ghiti
  2023-09-06 12:08       ` Lad, Prabhakar
  2023-09-06 20:22     ` Nadav Amit
  1 sibling, 1 reply; 22+ messages in thread
From: Alexandre Ghiti @ 2023-09-06 12:01 UTC (permalink / raw)
  To: Lad, Prabhakar
  Cc: Geert Uytterhoeven, Will Deacon, Aneesh Kumar K . V,
	Andrew Morton, Nick Piggin, Peter Zijlstra, Mayuresh Chitale,
	Vincent Chen, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	linux-arch, linux-mm, linux-riscv, linux-kernel, Andrew Jones

Hi Prabhakar,

On Wed, Sep 6, 2023 at 1:49 PM Lad, Prabhakar
<prabhakar.csengg@gmail.com> wrote:
>
> Hi Alexandre,
>
> On Tue, Aug 1, 2023 at 9:58 AM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> >
> > This function used to simply flush the whole tlb of all harts, be more
> > subtile and try to only flush the range.
> >
> > The problem is that we can only use PAGE_SIZE as stride since we don't know
> > the size of the underlying mapping and then this function will be improved
> > only if the size of the region to flush is < threshold * PAGE_SIZE.
> >
> > Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
> > Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
> > ---
> >  arch/riscv/include/asm/tlbflush.h | 11 +++++-----
> >  arch/riscv/mm/tlbflush.c          | 34 +++++++++++++++++++++++--------
> >  2 files changed, 31 insertions(+), 14 deletions(-)
> >
> After applying this patch, I am seeing module load issues on RZ/Five
> (complete log [0]). I am testing defconfig + [1] (rz/five related
> configs).
>
> Any pointers on what could be an issue here?

Can you give me the exact version of the kernel you use? The trap
addresses are vmalloc addresses, and a fix for those landed very late
in the release cycle.

>
> [0] https://paste.debian.net/1291116/
> [1] https://paste.debian.net/1291118/
>
> Cheers,
> Prabhakar
>
> > diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h
> > index f5c4fb0ae642..7426fdcd8ec5 100644
> > --- a/arch/riscv/include/asm/tlbflush.h
> > +++ b/arch/riscv/include/asm/tlbflush.h
> > @@ -37,6 +37,7 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
> >  void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr);
> >  void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
> >                      unsigned long end);
> > +void flush_tlb_kernel_range(unsigned long start, unsigned long end);
> >  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
> >  #define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE
> >  void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start,
> > @@ -53,15 +54,15 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
> >         local_flush_tlb_all();
> >  }
> >
> > -#define flush_tlb_mm(mm) flush_tlb_all()
> > -#define flush_tlb_mm_range(mm, start, end, page_size) flush_tlb_all()
> > -#endif /* !CONFIG_SMP || !CONFIG_MMU */
> > -
> >  /* Flush a range of kernel pages */
> >  static inline void flush_tlb_kernel_range(unsigned long start,
> >         unsigned long end)
> >  {
> > -       flush_tlb_all();
> > +       local_flush_tlb_all();
> >  }
> >
> > +#define flush_tlb_mm(mm) flush_tlb_all()
> > +#define flush_tlb_mm_range(mm, start, end, page_size) flush_tlb_all()
> > +#endif /* !CONFIG_SMP || !CONFIG_MMU */
> > +
> >  #endif /* _ASM_RISCV_TLBFLUSH_H */
> > diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
> > index 0c955c474f3a..687808013758 100644
> > --- a/arch/riscv/mm/tlbflush.c
> > +++ b/arch/riscv/mm/tlbflush.c
> > @@ -120,18 +120,27 @@ static void __flush_tlb_range(struct mm_struct *mm, unsigned long start,
> >                               unsigned long size, unsigned long stride)
> >  {
> >         struct flush_tlb_range_data ftd;
> > -       struct cpumask *cmask = mm_cpumask(mm);
> > -       unsigned int cpuid;
> > +       struct cpumask *cmask, full_cmask;
> >         bool broadcast;
> >
> > -       if (cpumask_empty(cmask))
> > -               return;
> > +       if (mm) {
> > +               unsigned int cpuid;
> > +
> > +               cmask = mm_cpumask(mm);
> > +               if (cpumask_empty(cmask))
> > +                       return;
> > +
> > +               cpuid = get_cpu();
> > +               /* check if the tlbflush needs to be sent to other CPUs */
> > +               broadcast = cpumask_any_but(cmask, cpuid) < nr_cpu_ids;
> > +       } else {
> > +               cpumask_setall(&full_cmask);
> > +               cmask = &full_cmask;
> > +               broadcast = true;
> > +       }
> >
> > -       cpuid = get_cpu();
> > -       /* check if the tlbflush needs to be sent to other CPUs */
> > -       broadcast = cpumask_any_but(cmask, cpuid) < nr_cpu_ids;
> >         if (static_branch_unlikely(&use_asid_allocator)) {
> > -               unsigned long asid = atomic_long_read(&mm->context.id) & asid_mask;
> > +               unsigned long asid = mm ? atomic_long_read(&mm->context.id) & asid_mask : 0;
> >
> >                 if (broadcast) {
> >                         if (riscv_use_ipi_for_rfence()) {
> > @@ -165,7 +174,8 @@ static void __flush_tlb_range(struct mm_struct *mm, unsigned long start,
> >                 }
> >         }
> >
> > -       put_cpu();
> > +       if (mm)
> > +               put_cpu();
> >  }
> >
> >  void flush_tlb_mm(struct mm_struct *mm)
> > @@ -196,6 +206,12 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
> >
> >         __flush_tlb_range(vma->vm_mm, start, end - start, stride_size);
> >  }
> > +
> > +void flush_tlb_kernel_range(unsigned long start, unsigned long end)
> > +{
> > +       __flush_tlb_range(NULL, start, end, PAGE_SIZE);
> > +}
> > +
> >  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
> >  void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start,
> >                         unsigned long end)
> > --
> > 2.39.2
> >
> >


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

* Re: [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range()
  2023-09-06 12:01     ` Alexandre Ghiti
@ 2023-09-06 12:08       ` Lad, Prabhakar
  2023-09-06 12:18         ` Alexandre Ghiti
  0 siblings, 1 reply; 22+ messages in thread
From: Lad, Prabhakar @ 2023-09-06 12:08 UTC (permalink / raw)
  To: Alexandre Ghiti
  Cc: Geert Uytterhoeven, Will Deacon, Aneesh Kumar K . V,
	Andrew Morton, Nick Piggin, Peter Zijlstra, Mayuresh Chitale,
	Vincent Chen, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	linux-arch, linux-mm, linux-riscv, linux-kernel, Andrew Jones

Hi Alexandre,

On Wed, Sep 6, 2023 at 1:01 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
>
> Hi Prabhakar,
>
> On Wed, Sep 6, 2023 at 1:49 PM Lad, Prabhakar
> <prabhakar.csengg@gmail.com> wrote:
> >
> > Hi Alexandre,
> >
> > On Tue, Aug 1, 2023 at 9:58 AM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > >
> > > This function used to simply flush the whole tlb of all harts, be more
> > > subtile and try to only flush the range.
> > >
> > > The problem is that we can only use PAGE_SIZE as stride since we don't know
> > > the size of the underlying mapping and then this function will be improved
> > > only if the size of the region to flush is < threshold * PAGE_SIZE.
> > >
> > > Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
> > > Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
> > > ---
> > >  arch/riscv/include/asm/tlbflush.h | 11 +++++-----
> > >  arch/riscv/mm/tlbflush.c          | 34 +++++++++++++++++++++++--------
> > >  2 files changed, 31 insertions(+), 14 deletions(-)
> > >
> > After applying this patch, I am seeing module load issues on RZ/Five
> > (complete log [0]). I am testing defconfig + [1] (rz/five related
> > configs).
> >
> > Any pointers on what could be an issue here?
>
> Can you give me the exact version of the kernel you use? The trap
> addresses are vmalloc addresses, and a fix for those landed very late
> in the release cycle.
>
I am using next-20230906, Ive pushed a branch [1] for you to have a look.

[0] https://github.com/prabhakarlad/linux/tree/rzfive-debug

Cheers,
Prabhakar


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

* Re: [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range()
  2023-09-06 12:08       ` Lad, Prabhakar
@ 2023-09-06 12:18         ` Alexandre Ghiti
  2023-09-06 12:23           ` Lad, Prabhakar
  0 siblings, 1 reply; 22+ messages in thread
From: Alexandre Ghiti @ 2023-09-06 12:18 UTC (permalink / raw)
  To: Lad, Prabhakar
  Cc: Geert Uytterhoeven, Will Deacon, Aneesh Kumar K . V,
	Andrew Morton, Nick Piggin, Peter Zijlstra, Mayuresh Chitale,
	Vincent Chen, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	linux-arch, linux-mm, linux-riscv, linux-kernel, Andrew Jones

On Wed, Sep 6, 2023 at 2:09 PM Lad, Prabhakar
<prabhakar.csengg@gmail.com> wrote:
>
> Hi Alexandre,
>
> On Wed, Sep 6, 2023 at 1:01 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> >
> > Hi Prabhakar,
> >
> > On Wed, Sep 6, 2023 at 1:49 PM Lad, Prabhakar
> > <prabhakar.csengg@gmail.com> wrote:
> > >
> > > Hi Alexandre,
> > >
> > > On Tue, Aug 1, 2023 at 9:58 AM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > > >
> > > > This function used to simply flush the whole tlb of all harts, be more
> > > > subtile and try to only flush the range.
> > > >
> > > > The problem is that we can only use PAGE_SIZE as stride since we don't know
> > > > the size of the underlying mapping and then this function will be improved
> > > > only if the size of the region to flush is < threshold * PAGE_SIZE.
> > > >
> > > > Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
> > > > Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
> > > > ---
> > > >  arch/riscv/include/asm/tlbflush.h | 11 +++++-----
> > > >  arch/riscv/mm/tlbflush.c          | 34 +++++++++++++++++++++++--------
> > > >  2 files changed, 31 insertions(+), 14 deletions(-)
> > > >
> > > After applying this patch, I am seeing module load issues on RZ/Five
> > > (complete log [0]). I am testing defconfig + [1] (rz/five related
> > > configs).
> > >
> > > Any pointers on what could be an issue here?
> >
> > Can you give me the exact version of the kernel you use? The trap
> > addresses are vmalloc addresses, and a fix for those landed very late
> > in the release cycle.
> >
> I am using next-20230906, Ive pushed a branch [1] for you to have a look.
>
> [0] https://github.com/prabhakarlad/linux/tree/rzfive-debug

Great, thanks, I had to get rid of this possibility :)

As-is, I have no idea, can you try to "bisect" the problem? I mean
which patch in the series leads to those traps?

Thanks!

Alex

>
> Cheers,
> Prabhakar


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

* Re: [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range()
  2023-09-06 12:18         ` Alexandre Ghiti
@ 2023-09-06 12:23           ` Lad, Prabhakar
  2023-09-06 12:43             ` Alexandre Ghiti
  0 siblings, 1 reply; 22+ messages in thread
From: Lad, Prabhakar @ 2023-09-06 12:23 UTC (permalink / raw)
  To: Alexandre Ghiti
  Cc: Geert Uytterhoeven, Will Deacon, Aneesh Kumar K . V,
	Andrew Morton, Nick Piggin, Peter Zijlstra, Mayuresh Chitale,
	Vincent Chen, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	linux-arch, linux-mm, linux-riscv, linux-kernel, Andrew Jones

Hi Alexandre,

On Wed, Sep 6, 2023 at 1:18 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
>
> On Wed, Sep 6, 2023 at 2:09 PM Lad, Prabhakar
> <prabhakar.csengg@gmail.com> wrote:
> >
> > Hi Alexandre,
> >
> > On Wed, Sep 6, 2023 at 1:01 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > >
> > > Hi Prabhakar,
> > >
> > > On Wed, Sep 6, 2023 at 1:49 PM Lad, Prabhakar
> > > <prabhakar.csengg@gmail.com> wrote:
> > > >
> > > > Hi Alexandre,
> > > >
> > > > On Tue, Aug 1, 2023 at 9:58 AM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > > > >
> > > > > This function used to simply flush the whole tlb of all harts, be more
> > > > > subtile and try to only flush the range.
> > > > >
> > > > > The problem is that we can only use PAGE_SIZE as stride since we don't know
> > > > > the size of the underlying mapping and then this function will be improved
> > > > > only if the size of the region to flush is < threshold * PAGE_SIZE.
> > > > >
> > > > > Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
> > > > > Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
> > > > > ---
> > > > >  arch/riscv/include/asm/tlbflush.h | 11 +++++-----
> > > > >  arch/riscv/mm/tlbflush.c          | 34 +++++++++++++++++++++++--------
> > > > >  2 files changed, 31 insertions(+), 14 deletions(-)
> > > > >
> > > > After applying this patch, I am seeing module load issues on RZ/Five
> > > > (complete log [0]). I am testing defconfig + [1] (rz/five related
> > > > configs).
> > > >
> > > > Any pointers on what could be an issue here?
> > >
> > > Can you give me the exact version of the kernel you use? The trap
> > > addresses are vmalloc addresses, and a fix for those landed very late
> > > in the release cycle.
> > >
> > I am using next-20230906, Ive pushed a branch [1] for you to have a look.
> >
> > [0] https://github.com/prabhakarlad/linux/tree/rzfive-debug
>
> Great, thanks, I had to get rid of this possibility :)
>
> As-is, I have no idea, can you try to "bisect" the problem? I mean
> which patch in the series leads to those traps?
>
Oops sorry for not mentioning earlier, this is the offending patch
which leads to the issues seen on rz/five.

Cheers,
Prabhakar


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

* Re: [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range()
  2023-09-06 12:23           ` Lad, Prabhakar
@ 2023-09-06 12:43             ` Alexandre Ghiti
  2023-09-06 13:16               ` Palmer Dabbelt
  2023-09-06 13:54               ` Lad, Prabhakar
  0 siblings, 2 replies; 22+ messages in thread
From: Alexandre Ghiti @ 2023-09-06 12:43 UTC (permalink / raw)
  To: Lad, Prabhakar
  Cc: Geert Uytterhoeven, Will Deacon, Aneesh Kumar K . V,
	Andrew Morton, Nick Piggin, Peter Zijlstra, Mayuresh Chitale,
	Vincent Chen, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	linux-arch, linux-mm, linux-riscv, linux-kernel, Andrew Jones

On Wed, Sep 6, 2023 at 2:24 PM Lad, Prabhakar
<prabhakar.csengg@gmail.com> wrote:
>
> Hi Alexandre,
>
> On Wed, Sep 6, 2023 at 1:18 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> >
> > On Wed, Sep 6, 2023 at 2:09 PM Lad, Prabhakar
> > <prabhakar.csengg@gmail.com> wrote:
> > >
> > > Hi Alexandre,
> > >
> > > On Wed, Sep 6, 2023 at 1:01 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > > >
> > > > Hi Prabhakar,
> > > >
> > > > On Wed, Sep 6, 2023 at 1:49 PM Lad, Prabhakar
> > > > <prabhakar.csengg@gmail.com> wrote:
> > > > >
> > > > > Hi Alexandre,
> > > > >
> > > > > On Tue, Aug 1, 2023 at 9:58 AM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > > > > >
> > > > > > This function used to simply flush the whole tlb of all harts, be more
> > > > > > subtile and try to only flush the range.
> > > > > >
> > > > > > The problem is that we can only use PAGE_SIZE as stride since we don't know
> > > > > > the size of the underlying mapping and then this function will be improved
> > > > > > only if the size of the region to flush is < threshold * PAGE_SIZE.
> > > > > >
> > > > > > Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
> > > > > > Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
> > > > > > ---
> > > > > >  arch/riscv/include/asm/tlbflush.h | 11 +++++-----
> > > > > >  arch/riscv/mm/tlbflush.c          | 34 +++++++++++++++++++++++--------
> > > > > >  2 files changed, 31 insertions(+), 14 deletions(-)
> > > > > >
> > > > > After applying this patch, I am seeing module load issues on RZ/Five
> > > > > (complete log [0]). I am testing defconfig + [1] (rz/five related
> > > > > configs).
> > > > >
> > > > > Any pointers on what could be an issue here?
> > > >
> > > > Can you give me the exact version of the kernel you use? The trap
> > > > addresses are vmalloc addresses, and a fix for those landed very late
> > > > in the release cycle.
> > > >
> > > I am using next-20230906, Ive pushed a branch [1] for you to have a look.
> > >
> > > [0] https://github.com/prabhakarlad/linux/tree/rzfive-debug
> >
> > Great, thanks, I had to get rid of this possibility :)
> >
> > As-is, I have no idea, can you try to "bisect" the problem? I mean
> > which patch in the series leads to those traps?
> >
> Oops sorry for not mentioning earlier, this is the offending patch
> which leads to the issues seen on rz/five.

Ok, so at least I found the following problem, but I don't see how
that could fix your issue: can you give a try anyway? I keep looking
into this, thanks

diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
index df2a0838c3a1..b5692bc6c76a 100644
--- a/arch/riscv/mm/tlbflush.c
+++ b/arch/riscv/mm/tlbflush.c
@@ -239,7 +239,7 @@ void flush_tlb_range(struct vm_area_struct *vma,
unsigned long start,

 void flush_tlb_kernel_range(unsigned long start, unsigned long end)
 {
-       __flush_tlb_range(NULL, start, end, PAGE_SIZE);
+       __flush_tlb_range(NULL, start, end - start, PAGE_SIZE);
 }

 #ifdef CONFIG_TRANSPARENT_HUGEPAGE

>
> Cheers,
> Prabhakar


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

* Re: [PATCH v3 0/4] riscv: tlb flush improvements
  2023-08-01  8:53 [PATCH v3 0/4] riscv: tlb flush improvements Alexandre Ghiti
                   ` (3 preceding siblings ...)
  2023-08-01  8:54 ` [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range() Alexandre Ghiti
@ 2023-09-06 13:00 ` patchwork-bot+linux-riscv
  2023-09-09 20:11 ` Samuel Holland
  5 siblings, 0 replies; 22+ messages in thread
From: patchwork-bot+linux-riscv @ 2023-09-06 13:00 UTC (permalink / raw)
  To: Alexandre Ghiti
  Cc: linux-riscv, will, aneesh.kumar, akpm, npiggin, peterz, mchitale,
	vincent.chen, paul.walmsley, palmer, aou, linux-arch, linux-mm,
	linux-kernel

Hello:

This series was applied to riscv/linux.git (for-next)
by Palmer Dabbelt <palmer@rivosinc.com>:

On Tue,  1 Aug 2023 10:53:58 +0200 you wrote:
> This series optimizes the tlb flushes on riscv which used to simply
> flush the whole tlb whatever the size of the range to flush or the size
> of the stride.
> 
> Patch 3 introduces a threshold that is microarchitecture specific and
> will very likely be modified by vendors, not sure though which mechanism
> we'll use to do that (dt? alternatives? vendor initialization code?).
> 
> [...]

Here is the summary with links:
  - [v3,1/4] riscv: Improve flush_tlb()
    https://git.kernel.org/riscv/c/1245a70831b9
  - [v3,2/4] riscv: Improve flush_tlb_range() for hugetlb pages
    https://git.kernel.org/riscv/c/9d6fb1015281
  - [v3,3/4] riscv: Make __flush_tlb_range() loop over pte instead of flushing the whole tlb
    https://git.kernel.org/riscv/c/cfe5187b7e93
  - [v3,4/4] riscv: Improve flush_tlb_kernel_range()
    https://git.kernel.org/riscv/c/bbc9ad35b51b

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html




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

* Re: [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range()
  2023-09-06 12:43             ` Alexandre Ghiti
@ 2023-09-06 13:16               ` Palmer Dabbelt
  2023-09-06 13:54               ` Lad, Prabhakar
  1 sibling, 0 replies; 22+ messages in thread
From: Palmer Dabbelt @ 2023-09-06 13:16 UTC (permalink / raw)
  To: alexghiti
  Cc: prabhakar.csengg, geert+renesas, Will Deacon, aneesh.kumar, akpm,
	npiggin, peterz, mchitale, vincent.chen, Paul Walmsley, aou,
	linux-arch, linux-mm, linux-riscv, linux-kernel, ajones

On Wed, 06 Sep 2023 05:43:46 PDT (-0700), alexghiti@rivosinc.com wrote:
> On Wed, Sep 6, 2023 at 2:24 PM Lad, Prabhakar
> <prabhakar.csengg@gmail.com> wrote:
>>
>> Hi Alexandre,
>>
>> On Wed, Sep 6, 2023 at 1:18 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
>> >
>> > On Wed, Sep 6, 2023 at 2:09 PM Lad, Prabhakar
>> > <prabhakar.csengg@gmail.com> wrote:
>> > >
>> > > Hi Alexandre,
>> > >
>> > > On Wed, Sep 6, 2023 at 1:01 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
>> > > >
>> > > > Hi Prabhakar,
>> > > >
>> > > > On Wed, Sep 6, 2023 at 1:49 PM Lad, Prabhakar
>> > > > <prabhakar.csengg@gmail.com> wrote:
>> > > > >
>> > > > > Hi Alexandre,
>> > > > >
>> > > > > On Tue, Aug 1, 2023 at 9:58 AM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
>> > > > > >
>> > > > > > This function used to simply flush the whole tlb of all harts, be more
>> > > > > > subtile and try to only flush the range.
>> > > > > >
>> > > > > > The problem is that we can only use PAGE_SIZE as stride since we don't know
>> > > > > > the size of the underlying mapping and then this function will be improved
>> > > > > > only if the size of the region to flush is < threshold * PAGE_SIZE.
>> > > > > >
>> > > > > > Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
>> > > > > > Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
>> > > > > > ---
>> > > > > >  arch/riscv/include/asm/tlbflush.h | 11 +++++-----
>> > > > > >  arch/riscv/mm/tlbflush.c          | 34 +++++++++++++++++++++++--------
>> > > > > >  2 files changed, 31 insertions(+), 14 deletions(-)
>> > > > > >
>> > > > > After applying this patch, I am seeing module load issues on RZ/Five
>> > > > > (complete log [0]). I am testing defconfig + [1] (rz/five related
>> > > > > configs).
>> > > > >
>> > > > > Any pointers on what could be an issue here?
>> > > >
>> > > > Can you give me the exact version of the kernel you use? The trap
>> > > > addresses are vmalloc addresses, and a fix for those landed very late
>> > > > in the release cycle.
>> > > >
>> > > I am using next-20230906, Ive pushed a branch [1] for you to have a look.
>> > >
>> > > [0] https://github.com/prabhakarlad/linux/tree/rzfive-debug
>> >
>> > Great, thanks, I had to get rid of this possibility :)
>> >
>> > As-is, I have no idea, can you try to "bisect" the problem? I mean
>> > which patch in the series leads to those traps?
>> >
>> Oops sorry for not mentioning earlier, this is the offending patch
>> which leads to the issues seen on rz/five.
>
> Ok, so at least I found the following problem, but I don't see how
> that could fix your issue: can you give a try anyway? I keep looking
> into this, thanks
>
> diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
> index df2a0838c3a1..b5692bc6c76a 100644
> --- a/arch/riscv/mm/tlbflush.c
> +++ b/arch/riscv/mm/tlbflush.c
> @@ -239,7 +239,7 @@ void flush_tlb_range(struct vm_area_struct *vma,
> unsigned long start,
>
>  void flush_tlb_kernel_range(unsigned long start, unsigned long end)
>  {
> -       __flush_tlb_range(NULL, start, end, PAGE_SIZE);
> +       __flush_tlb_range(NULL, start, end - start, PAGE_SIZE);
>  }
>
>  #ifdef CONFIG_TRANSPARENT_HUGEPAGE

Alex and I were talking a bit.  I'm OK just dropping the TLB flush 
series for this release, that way we can get to the bottom of what's 
wrong.

>
>>
>> Cheers,
>> Prabhakar


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

* Re: [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range()
  2023-09-06 12:43             ` Alexandre Ghiti
  2023-09-06 13:16               ` Palmer Dabbelt
@ 2023-09-06 13:54               ` Lad, Prabhakar
  2023-09-07  9:05                 ` Alexandre Ghiti
  1 sibling, 1 reply; 22+ messages in thread
From: Lad, Prabhakar @ 2023-09-06 13:54 UTC (permalink / raw)
  To: Alexandre Ghiti
  Cc: Geert Uytterhoeven, Will Deacon, Aneesh Kumar K . V,
	Andrew Morton, Nick Piggin, Peter Zijlstra, Mayuresh Chitale,
	Vincent Chen, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	linux-arch, linux-mm, linux-riscv, linux-kernel, Andrew Jones

Hi Alexandre,

On Wed, Sep 6, 2023 at 1:43 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
>
> On Wed, Sep 6, 2023 at 2:24 PM Lad, Prabhakar
> <prabhakar.csengg@gmail.com> wrote:
> >
> > Hi Alexandre,
> >
> > On Wed, Sep 6, 2023 at 1:18 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > >
> > > On Wed, Sep 6, 2023 at 2:09 PM Lad, Prabhakar
> > > <prabhakar.csengg@gmail.com> wrote:
> > > >
> > > > Hi Alexandre,
> > > >
> > > > On Wed, Sep 6, 2023 at 1:01 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > > > >
> > > > > Hi Prabhakar,
> > > > >
> > > > > On Wed, Sep 6, 2023 at 1:49 PM Lad, Prabhakar
> > > > > <prabhakar.csengg@gmail.com> wrote:
> > > > > >
> > > > > > Hi Alexandre,
> > > > > >
> > > > > > On Tue, Aug 1, 2023 at 9:58 AM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > > > > > >
> > > > > > > This function used to simply flush the whole tlb of all harts, be more
> > > > > > > subtile and try to only flush the range.
> > > > > > >
> > > > > > > The problem is that we can only use PAGE_SIZE as stride since we don't know
> > > > > > > the size of the underlying mapping and then this function will be improved
> > > > > > > only if the size of the region to flush is < threshold * PAGE_SIZE.
> > > > > > >
> > > > > > > Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
> > > > > > > Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
> > > > > > > ---
> > > > > > >  arch/riscv/include/asm/tlbflush.h | 11 +++++-----
> > > > > > >  arch/riscv/mm/tlbflush.c          | 34 +++++++++++++++++++++++--------
> > > > > > >  2 files changed, 31 insertions(+), 14 deletions(-)
> > > > > > >
> > > > > > After applying this patch, I am seeing module load issues on RZ/Five
> > > > > > (complete log [0]). I am testing defconfig + [1] (rz/five related
> > > > > > configs).
> > > > > >
> > > > > > Any pointers on what could be an issue here?
> > > > >
> > > > > Can you give me the exact version of the kernel you use? The trap
> > > > > addresses are vmalloc addresses, and a fix for those landed very late
> > > > > in the release cycle.
> > > > >
> > > > I am using next-20230906, Ive pushed a branch [1] for you to have a look.
> > > >
> > > > [0] https://github.com/prabhakarlad/linux/tree/rzfive-debug
> > >
> > > Great, thanks, I had to get rid of this possibility :)
> > >
> > > As-is, I have no idea, can you try to "bisect" the problem? I mean
> > > which patch in the series leads to those traps?
> > >
> > Oops sorry for not mentioning earlier, this is the offending patch
> > which leads to the issues seen on rz/five.
>
> Ok, so at least I found the following problem, but I don't see how
> that could fix your issue: can you give a try anyway? I keep looking
> into this, thanks
>
> diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
> index df2a0838c3a1..b5692bc6c76a 100644
> --- a/arch/riscv/mm/tlbflush.c
> +++ b/arch/riscv/mm/tlbflush.c
> @@ -239,7 +239,7 @@ void flush_tlb_range(struct vm_area_struct *vma,
> unsigned long start,
>
>  void flush_tlb_kernel_range(unsigned long start, unsigned long end)
>  {
> -       __flush_tlb_range(NULL, start, end, PAGE_SIZE);
> +       __flush_tlb_range(NULL, start, end - start, PAGE_SIZE);
>  }
>
I am able to reproduce the issue with the above change too.

Cheers,
Prabhakar


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

* Re: [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range()
  2023-09-06 11:48   ` Lad, Prabhakar
  2023-09-06 12:01     ` Alexandre Ghiti
@ 2023-09-06 20:22     ` Nadav Amit
  2023-09-07 13:47       ` Alexandre Ghiti
  1 sibling, 1 reply; 22+ messages in thread
From: Nadav Amit @ 2023-09-06 20:22 UTC (permalink / raw)
  To: Lad, Prabhakar
  Cc: Alexandre Ghiti, Geert Uytterhoeven, Will Deacon,
	Aneesh Kumar K . V, Andrew Morton, Nick Piggin, Peter Zijlstra,
	Mayuresh Chitale, Vincent Chen, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, linux-arch, linux-mm, linux-riscv,
	Linux Kernel Mailing List, Andrew Jones



> On Sep 6, 2023, at 4:48 AM, Lad, Prabhakar <prabhakar.csengg@gmail.com> wrote:
> 
> Hi Alexandre,
> 
> On Tue, Aug 1, 2023 at 9:58 AM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
>> 
>> This function used to simply flush the whole tlb of all harts, be more
>> subtile and try to only flush the range.
>> 
>> The problem is that we can only use PAGE_SIZE as stride since we don't know
>> the size of the underlying mapping and then this function will be improved
>> only if the size of the region to flush is < threshold * PAGE_SIZE.
>> 
>> Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
>> Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
>> ---
>> arch/riscv/include/asm/tlbflush.h | 11 +++++-----
>> arch/riscv/mm/tlbflush.c          | 34 +++++++++++++++++++++++--------
>> 2 files changed, 31 insertions(+), 14 deletions(-)
>> 
> After applying this patch, I am seeing module load issues on RZ/Five
> (complete log [0]). I am testing defconfig + [1] (rz/five related
> configs).
> 
> Any pointers on what could be an issue here?

None of my business, but looking at your code, it seems that you do not memory
barrier before reading mm_cpumask() in __flush_tlb_range(). I believe you
would want to synchronize __flush_tlb_range with switch_mm() similarly to the
way it is done in x86.



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

* Re: [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range()
  2023-09-06 13:54               ` Lad, Prabhakar
@ 2023-09-07  9:05                 ` Alexandre Ghiti
  2023-09-07 10:49                   ` Lad, Prabhakar
  0 siblings, 1 reply; 22+ messages in thread
From: Alexandre Ghiti @ 2023-09-07  9:05 UTC (permalink / raw)
  To: Lad, Prabhakar
  Cc: Geert Uytterhoeven, Will Deacon, Aneesh Kumar K . V,
	Andrew Morton, Nick Piggin, Peter Zijlstra, Mayuresh Chitale,
	Vincent Chen, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	linux-arch, linux-mm, linux-riscv, linux-kernel, Andrew Jones

Hi Prabhakar,

On Wed, Sep 6, 2023 at 3:55 PM Lad, Prabhakar
<prabhakar.csengg@gmail.com> wrote:
>
> Hi Alexandre,
>
> On Wed, Sep 6, 2023 at 1:43 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> >
> > On Wed, Sep 6, 2023 at 2:24 PM Lad, Prabhakar
> > <prabhakar.csengg@gmail.com> wrote:
> > >
> > > Hi Alexandre,
> > >
> > > On Wed, Sep 6, 2023 at 1:18 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > > >
> > > > On Wed, Sep 6, 2023 at 2:09 PM Lad, Prabhakar
> > > > <prabhakar.csengg@gmail.com> wrote:
> > > > >
> > > > > Hi Alexandre,
> > > > >
> > > > > On Wed, Sep 6, 2023 at 1:01 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > > > > >
> > > > > > Hi Prabhakar,
> > > > > >
> > > > > > On Wed, Sep 6, 2023 at 1:49 PM Lad, Prabhakar
> > > > > > <prabhakar.csengg@gmail.com> wrote:
> > > > > > >
> > > > > > > Hi Alexandre,
> > > > > > >
> > > > > > > On Tue, Aug 1, 2023 at 9:58 AM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > > > > > > >
> > > > > > > > This function used to simply flush the whole tlb of all harts, be more
> > > > > > > > subtile and try to only flush the range.
> > > > > > > >
> > > > > > > > The problem is that we can only use PAGE_SIZE as stride since we don't know
> > > > > > > > the size of the underlying mapping and then this function will be improved
> > > > > > > > only if the size of the region to flush is < threshold * PAGE_SIZE.
> > > > > > > >
> > > > > > > > Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
> > > > > > > > Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
> > > > > > > > ---
> > > > > > > >  arch/riscv/include/asm/tlbflush.h | 11 +++++-----
> > > > > > > >  arch/riscv/mm/tlbflush.c          | 34 +++++++++++++++++++++++--------
> > > > > > > >  2 files changed, 31 insertions(+), 14 deletions(-)
> > > > > > > >
> > > > > > > After applying this patch, I am seeing module load issues on RZ/Five
> > > > > > > (complete log [0]). I am testing defconfig + [1] (rz/five related
> > > > > > > configs).
> > > > > > >
> > > > > > > Any pointers on what could be an issue here?
> > > > > >
> > > > > > Can you give me the exact version of the kernel you use? The trap
> > > > > > addresses are vmalloc addresses, and a fix for those landed very late
> > > > > > in the release cycle.
> > > > > >
> > > > > I am using next-20230906, Ive pushed a branch [1] for you to have a look.
> > > > >
> > > > > [0] https://github.com/prabhakarlad/linux/tree/rzfive-debug
> > > >
> > > > Great, thanks, I had to get rid of this possibility :)
> > > >
> > > > As-is, I have no idea, can you try to "bisect" the problem? I mean
> > > > which patch in the series leads to those traps?
> > > >
> > > Oops sorry for not mentioning earlier, this is the offending patch
> > > which leads to the issues seen on rz/five.
> >
> > Ok, so at least I found the following problem, but I don't see how
> > that could fix your issue: can you give a try anyway? I keep looking
> > into this, thanks
> >
> > diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
> > index df2a0838c3a1..b5692bc6c76a 100644
> > --- a/arch/riscv/mm/tlbflush.c
> > +++ b/arch/riscv/mm/tlbflush.c
> > @@ -239,7 +239,7 @@ void flush_tlb_range(struct vm_area_struct *vma,
> > unsigned long start,
> >
> >  void flush_tlb_kernel_range(unsigned long start, unsigned long end)
> >  {
> > -       __flush_tlb_range(NULL, start, end, PAGE_SIZE);
> > +       __flush_tlb_range(NULL, start, end - start, PAGE_SIZE);
> >  }
> >
> I am able to reproduce the issue with the above change too.

I can't reproduce the problem on my Unmatched or Qemu, so it is not
easy to debug. But I took another look at your traces and something is
weird to me. In the following trace (and there is another one), the
trap is taken at 0xffffffff015ca034, which is the beginning of
rz_ssi_probe(): that's a page fault, so no translation was found (or
an invalid one is cached).

[   16.586527] Unable to handle kernel paging request at virtual
address ffffffff015ca034
[   16.594750] Oops [#3]
...
[   16.622000] epc : rz_ssi_probe+0x0/0x52a [snd_soc_rz_ssi]
...
[   16.708697] status: 0000000200000120 badaddr: ffffffff015ca034
cause: 000000000000000c
[   16.716580] [<ffffffff015ca034>] rz_ssi_probe+0x0/0x52a
[snd_soc_rz_ssi]
...

But then here we are able to read the code at this same address:
[   16.821620] Code: 0109 6597 0000 8593 5f65 7097 7f34 80e7 7aa0 b7a9
(7139) f822

So that looks like a "transient" error. Do you know if you uarch
caches invalid TLB entries? If you don't know, I have just written
some piece of code to determine if it does, let me know.

Do those errors always happen?

>
> Cheers,
> Prabhakar


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

* Re: [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range()
  2023-09-07  9:05                 ` Alexandre Ghiti
@ 2023-09-07 10:49                   ` Lad, Prabhakar
  2023-09-08 12:34                     ` Alexandre Ghiti
  0 siblings, 1 reply; 22+ messages in thread
From: Lad, Prabhakar @ 2023-09-07 10:49 UTC (permalink / raw)
  To: Alexandre Ghiti
  Cc: Geert Uytterhoeven, Will Deacon, Aneesh Kumar K . V,
	Andrew Morton, Nick Piggin, Peter Zijlstra, Mayuresh Chitale,
	Vincent Chen, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	linux-arch, linux-mm, linux-riscv, linux-kernel, Andrew Jones

Hi Alexandre,

On Thu, Sep 7, 2023 at 10:06 AM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
>
> Hi Prabhakar,
>
> On Wed, Sep 6, 2023 at 3:55 PM Lad, Prabhakar
> <prabhakar.csengg@gmail.com> wrote:
> >
> > Hi Alexandre,
> >
> > On Wed, Sep 6, 2023 at 1:43 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > >
> > > On Wed, Sep 6, 2023 at 2:24 PM Lad, Prabhakar
> > > <prabhakar.csengg@gmail.com> wrote:
> > > >
> > > > Hi Alexandre,
> > > >
> > > > On Wed, Sep 6, 2023 at 1:18 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > > > >
> > > > > On Wed, Sep 6, 2023 at 2:09 PM Lad, Prabhakar
> > > > > <prabhakar.csengg@gmail.com> wrote:
> > > > > >
> > > > > > Hi Alexandre,
> > > > > >
> > > > > > On Wed, Sep 6, 2023 at 1:01 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > > > > > >
> > > > > > > Hi Prabhakar,
> > > > > > >
> > > > > > > On Wed, Sep 6, 2023 at 1:49 PM Lad, Prabhakar
> > > > > > > <prabhakar.csengg@gmail.com> wrote:
> > > > > > > >
> > > > > > > > Hi Alexandre,
> > > > > > > >
> > > > > > > > On Tue, Aug 1, 2023 at 9:58 AM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > > > > > > > >
> > > > > > > > > This function used to simply flush the whole tlb of all harts, be more
> > > > > > > > > subtile and try to only flush the range.
> > > > > > > > >
> > > > > > > > > The problem is that we can only use PAGE_SIZE as stride since we don't know
> > > > > > > > > the size of the underlying mapping and then this function will be improved
> > > > > > > > > only if the size of the region to flush is < threshold * PAGE_SIZE.
> > > > > > > > >
> > > > > > > > > Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
> > > > > > > > > Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
> > > > > > > > > ---
> > > > > > > > >  arch/riscv/include/asm/tlbflush.h | 11 +++++-----
> > > > > > > > >  arch/riscv/mm/tlbflush.c          | 34 +++++++++++++++++++++++--------
> > > > > > > > >  2 files changed, 31 insertions(+), 14 deletions(-)
> > > > > > > > >
> > > > > > > > After applying this patch, I am seeing module load issues on RZ/Five
> > > > > > > > (complete log [0]). I am testing defconfig + [1] (rz/five related
> > > > > > > > configs).
> > > > > > > >
> > > > > > > > Any pointers on what could be an issue here?
> > > > > > >
> > > > > > > Can you give me the exact version of the kernel you use? The trap
> > > > > > > addresses are vmalloc addresses, and a fix for those landed very late
> > > > > > > in the release cycle.
> > > > > > >
> > > > > > I am using next-20230906, Ive pushed a branch [1] for you to have a look.
> > > > > >
> > > > > > [0] https://github.com/prabhakarlad/linux/tree/rzfive-debug
> > > > >
> > > > > Great, thanks, I had to get rid of this possibility :)
> > > > >
> > > > > As-is, I have no idea, can you try to "bisect" the problem? I mean
> > > > > which patch in the series leads to those traps?
> > > > >
> > > > Oops sorry for not mentioning earlier, this is the offending patch
> > > > which leads to the issues seen on rz/five.
> > >
> > > Ok, so at least I found the following problem, but I don't see how
> > > that could fix your issue: can you give a try anyway? I keep looking
> > > into this, thanks
> > >
> > > diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
> > > index df2a0838c3a1..b5692bc6c76a 100644
> > > --- a/arch/riscv/mm/tlbflush.c
> > > +++ b/arch/riscv/mm/tlbflush.c
> > > @@ -239,7 +239,7 @@ void flush_tlb_range(struct vm_area_struct *vma,
> > > unsigned long start,
> > >
> > >  void flush_tlb_kernel_range(unsigned long start, unsigned long end)
> > >  {
> > > -       __flush_tlb_range(NULL, start, end, PAGE_SIZE);
> > > +       __flush_tlb_range(NULL, start, end - start, PAGE_SIZE);
> > >  }
> > >
> > I am able to reproduce the issue with the above change too.
>
> I can't reproduce the problem on my Unmatched or Qemu, so it is not
> easy to debug. But I took another look at your traces and something is
> weird to me. In the following trace (and there is another one), the
> trap is taken at 0xffffffff015ca034, which is the beginning of
> rz_ssi_probe(): that's a page fault, so no translation was found (or
> an invalid one is cached).
>
> [   16.586527] Unable to handle kernel paging request at virtual
> address ffffffff015ca034
> [   16.594750] Oops [#3]
> ...
> [   16.622000] epc : rz_ssi_probe+0x0/0x52a [snd_soc_rz_ssi]
> ...
> [   16.708697] status: 0000000200000120 badaddr: ffffffff015ca034
> cause: 000000000000000c
> [   16.716580] [<ffffffff015ca034>] rz_ssi_probe+0x0/0x52a
> [snd_soc_rz_ssi]
> ...
>
> But then here we are able to read the code at this same address:
> [   16.821620] Code: 0109 6597 0000 8593 5f65 7097 7f34 80e7 7aa0 b7a9
> (7139) f822
>
> So that looks like a "transient" error. Do you know if you uarch
> caches invalid TLB entries? If you don't know, I have just written
> some piece of code to determine if it does, let me know.
>
No I dont, can you please share the details so that I can pass on the
information to you.

> Do those errors always happen?
>
Yes they do.

Cheers,
Prabhakar


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

* Re: [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range()
  2023-09-06 20:22     ` Nadav Amit
@ 2023-09-07 13:47       ` Alexandre Ghiti
  0 siblings, 0 replies; 22+ messages in thread
From: Alexandre Ghiti @ 2023-09-07 13:47 UTC (permalink / raw)
  To: Nadav Amit, Lad, Prabhakar
  Cc: Alexandre Ghiti, Geert Uytterhoeven, Will Deacon,
	Aneesh Kumar K . V, Andrew Morton, Nick Piggin, Peter Zijlstra,
	Mayuresh Chitale, Vincent Chen, Paul Walmsley, Palmer Dabbelt,
	Albert Ou, linux-arch, linux-mm, linux-riscv,
	Linux Kernel Mailing List, Andrew Jones

Hi Nadav,

On 06/09/2023 22:22, Nadav Amit wrote:
>
>> On Sep 6, 2023, at 4:48 AM, Lad, Prabhakar <prabhakar.csengg@gmail.com> wrote:
>>
>> Hi Alexandre,
>>
>> On Tue, Aug 1, 2023 at 9:58 AM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
>>> This function used to simply flush the whole tlb of all harts, be more
>>> subtile and try to only flush the range.
>>>
>>> The problem is that we can only use PAGE_SIZE as stride since we don't know
>>> the size of the underlying mapping and then this function will be improved
>>> only if the size of the region to flush is < threshold * PAGE_SIZE.
>>>
>>> Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
>>> Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
>>> ---
>>> arch/riscv/include/asm/tlbflush.h | 11 +++++-----
>>> arch/riscv/mm/tlbflush.c          | 34 +++++++++++++++++++++++--------
>>> 2 files changed, 31 insertions(+), 14 deletions(-)
>>>
>> After applying this patch, I am seeing module load issues on RZ/Five
>> (complete log [0]). I am testing defconfig + [1] (rz/five related
>> configs).
>>
>> Any pointers on what could be an issue here?
> None of my business, but looking at your code, it seems that you do not memory
> barrier before reading mm_cpumask() in __flush_tlb_range(). I believe you
> would want to synchronize __flush_tlb_range with switch_mm() similarly to the
> way it is done in x86.
>

Noted, I'll take a look at that, thanks for the advice!

Alex



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

* Re: [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range()
  2023-09-07 10:49                   ` Lad, Prabhakar
@ 2023-09-08 12:34                     ` Alexandre Ghiti
  0 siblings, 0 replies; 22+ messages in thread
From: Alexandre Ghiti @ 2023-09-08 12:34 UTC (permalink / raw)
  To: Lad, Prabhakar
  Cc: Geert Uytterhoeven, Will Deacon, Aneesh Kumar K . V,
	Andrew Morton, Nick Piggin, Peter Zijlstra, Mayuresh Chitale,
	Vincent Chen, Paul Walmsley, Palmer Dabbelt, Albert Ou,
	linux-arch, linux-mm, linux-riscv, linux-kernel, Andrew Jones

Hi Prabhakar,

On Thu, Sep 7, 2023 at 12:50 PM Lad, Prabhakar
<prabhakar.csengg@gmail.com> wrote:
>
> Hi Alexandre,
>
> On Thu, Sep 7, 2023 at 10:06 AM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> >
> > Hi Prabhakar,
> >
> > On Wed, Sep 6, 2023 at 3:55 PM Lad, Prabhakar
> > <prabhakar.csengg@gmail.com> wrote:
> > >
> > > Hi Alexandre,
> > >
> > > On Wed, Sep 6, 2023 at 1:43 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > > >
> > > > On Wed, Sep 6, 2023 at 2:24 PM Lad, Prabhakar
> > > > <prabhakar.csengg@gmail.com> wrote:
> > > > >
> > > > > Hi Alexandre,
> > > > >
> > > > > On Wed, Sep 6, 2023 at 1:18 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > > > > >
> > > > > > On Wed, Sep 6, 2023 at 2:09 PM Lad, Prabhakar
> > > > > > <prabhakar.csengg@gmail.com> wrote:
> > > > > > >
> > > > > > > Hi Alexandre,
> > > > > > >
> > > > > > > On Wed, Sep 6, 2023 at 1:01 PM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > > > > > > >
> > > > > > > > Hi Prabhakar,
> > > > > > > >
> > > > > > > > On Wed, Sep 6, 2023 at 1:49 PM Lad, Prabhakar
> > > > > > > > <prabhakar.csengg@gmail.com> wrote:
> > > > > > > > >
> > > > > > > > > Hi Alexandre,
> > > > > > > > >
> > > > > > > > > On Tue, Aug 1, 2023 at 9:58 AM Alexandre Ghiti <alexghiti@rivosinc.com> wrote:
> > > > > > > > > >
> > > > > > > > > > This function used to simply flush the whole tlb of all harts, be more
> > > > > > > > > > subtile and try to only flush the range.
> > > > > > > > > >
> > > > > > > > > > The problem is that we can only use PAGE_SIZE as stride since we don't know
> > > > > > > > > > the size of the underlying mapping and then this function will be improved
> > > > > > > > > > only if the size of the region to flush is < threshold * PAGE_SIZE.
> > > > > > > > > >
> > > > > > > > > > Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
> > > > > > > > > > Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
> > > > > > > > > > ---
> > > > > > > > > >  arch/riscv/include/asm/tlbflush.h | 11 +++++-----
> > > > > > > > > >  arch/riscv/mm/tlbflush.c          | 34 +++++++++++++++++++++++--------
> > > > > > > > > >  2 files changed, 31 insertions(+), 14 deletions(-)
> > > > > > > > > >
> > > > > > > > > After applying this patch, I am seeing module load issues on RZ/Five
> > > > > > > > > (complete log [0]). I am testing defconfig + [1] (rz/five related
> > > > > > > > > configs).
> > > > > > > > >
> > > > > > > > > Any pointers on what could be an issue here?
> > > > > > > >
> > > > > > > > Can you give me the exact version of the kernel you use? The trap
> > > > > > > > addresses are vmalloc addresses, and a fix for those landed very late
> > > > > > > > in the release cycle.
> > > > > > > >
> > > > > > > I am using next-20230906, Ive pushed a branch [1] for you to have a look.
> > > > > > >
> > > > > > > [0] https://github.com/prabhakarlad/linux/tree/rzfive-debug
> > > > > >
> > > > > > Great, thanks, I had to get rid of this possibility :)
> > > > > >
> > > > > > As-is, I have no idea, can you try to "bisect" the problem? I mean
> > > > > > which patch in the series leads to those traps?
> > > > > >
> > > > > Oops sorry for not mentioning earlier, this is the offending patch
> > > > > which leads to the issues seen on rz/five.
> > > >
> > > > Ok, so at least I found the following problem, but I don't see how
> > > > that could fix your issue: can you give a try anyway? I keep looking
> > > > into this, thanks
> > > >
> > > > diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
> > > > index df2a0838c3a1..b5692bc6c76a 100644
> > > > --- a/arch/riscv/mm/tlbflush.c
> > > > +++ b/arch/riscv/mm/tlbflush.c
> > > > @@ -239,7 +239,7 @@ void flush_tlb_range(struct vm_area_struct *vma,
> > > > unsigned long start,
> > > >
> > > >  void flush_tlb_kernel_range(unsigned long start, unsigned long end)
> > > >  {
> > > > -       __flush_tlb_range(NULL, start, end, PAGE_SIZE);
> > > > +       __flush_tlb_range(NULL, start, end - start, PAGE_SIZE);
> > > >  }
> > > >
> > > I am able to reproduce the issue with the above change too.
> >
> > I can't reproduce the problem on my Unmatched or Qemu, so it is not
> > easy to debug. But I took another look at your traces and something is
> > weird to me. In the following trace (and there is another one), the
> > trap is taken at 0xffffffff015ca034, which is the beginning of
> > rz_ssi_probe(): that's a page fault, so no translation was found (or
> > an invalid one is cached).
> >
> > [   16.586527] Unable to handle kernel paging request at virtual
> > address ffffffff015ca034
> > [   16.594750] Oops [#3]
> > ...
> > [   16.622000] epc : rz_ssi_probe+0x0/0x52a [snd_soc_rz_ssi]
> > ...
> > [   16.708697] status: 0000000200000120 badaddr: ffffffff015ca034
> > cause: 000000000000000c
> > [   16.716580] [<ffffffff015ca034>] rz_ssi_probe+0x0/0x52a
> > [snd_soc_rz_ssi]
> > ...
> >
> > But then here we are able to read the code at this same address:
> > [   16.821620] Code: 0109 6597 0000 8593 5f65 7097 7f34 80e7 7aa0 b7a9
> > (7139) f822
> >
> > So that looks like a "transient" error. Do you know if you uarch
> > caches invalid TLB entries? If you don't know, I have just written
> > some piece of code to determine if it does, let me know.
> >
> No I dont, can you please share the details so that I can pass on the
> information to you.
>
> > Do those errors always happen?
> >
> Yes they do.
>

I still can't reproduce those errors, I built different configs
including yours, insmod/rmmod a few modules but still can't reproduce
that. I'm having a hard time understanding how the correct mapping
magically appears in the trap handler. We finally removed this
patchset from 6.6...

You can give the following patch a try to determine if your uarch
caches invalid TLB entries, but honestly, I'm not sure if that would
help (but it will test my patch :)). The output can be seen in dmesg
"uarch caches invalid entries:".

If the trap addresses are constant, I would try to breakpoint on
flush_tlb_kernel_range() on those addresses and see what happens:
maybe that's an alignment issue or something else, maybe that's not
even called before the trap...etc. More info are welcome :)

Thanks!

diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c
index 80af436c04ac..8f863b251898 100644
--- a/arch/riscv/mm/init.c
+++ b/arch/riscv/mm/init.c
@@ -58,6 +58,8 @@ bool pgtable_l5_enabled = IS_ENABLED(CONFIG_64BIT)
&& !IS_ENABLED(CONFIG_XIP_KER
 EXPORT_SYMBOL(pgtable_l4_enabled);
 EXPORT_SYMBOL(pgtable_l5_enabled);

+bool tlb_caching_invalid_entries;
+
 phys_addr_t phys_ram_base __ro_after_init;
 EXPORT_SYMBOL(phys_ram_base);

@@ -752,6 +754,18 @@ static void __init disable_pgtable_l4(void)
        satp_mode = SATP_MODE_39;
 }

+static void __init enable_pgtable_l5(void)
+{
+       pgtable_l5_enabled = true;
+       satp_mode = SATP_MODE_57;
+}
+
+static void __init enable_pgtable_l4(void)
+{
+       pgtable_l4_enabled = true;
+       satp_mode = SATP_MODE_48;
+}
+
 static int __init print_no4lvl(char *p)
 {
        pr_info("Disabled 4-level and 5-level paging");
@@ -828,6 +842,113 @@ static __init void set_satp_mode(uintptr_t dtb_pa)
        memset(early_pud, 0, PAGE_SIZE);
        memset(early_pmd, 0, PAGE_SIZE);
 }
+
+/* Determine at runtime if the uarch caches invalid TLB entries */
+static __init void set_tlb_caching_invalid_entries(void)
+{
+#define NR_RETRIES_CACHING_INVALID_ENTRIES     50
+       uintptr_t set_tlb_caching_invalid_entries_pmd = ((unsigned
long)set_tlb_caching_invalid_entries) & PMD_MASK;
+       // TODO the test_addr as defined below could go into another pud...
+       uintptr_t test_addr = set_tlb_caching_invalid_entries_pmd + 2
* PMD_SIZE;
+       pmd_t valid_pmd;
+       u64 satp;
+       int i = 0;
+
+       /* To ease the page table creation */
+       // TODO use variable instead, like in the clean, nop stap_mode too
+       disable_pgtable_l5();
+       disable_pgtable_l4();
+
+       /* Establish a mapping for set_tlb_caching_invalid_entries() in sv39 */
+       create_pgd_mapping(early_pg_dir,
+                          set_tlb_caching_invalid_entries_pmd,
+                          (uintptr_t)early_pmd,
+                          PGDIR_SIZE, PAGE_TABLE);
+
+       /* Handle the case where set_tlb_caching_invalid_entries
straddles 2 PMDs */
+       create_pmd_mapping(early_pmd,
+                          set_tlb_caching_invalid_entries_pmd,
+                          set_tlb_caching_invalid_entries_pmd,
+                          PMD_SIZE, PAGE_KERNEL_EXEC);
+       create_pmd_mapping(early_pmd,
+                          set_tlb_caching_invalid_entries_pmd + PMD_SIZE,
+                          set_tlb_caching_invalid_entries_pmd + PMD_SIZE,
+                          PMD_SIZE, PAGE_KERNEL_EXEC);
+
+       /* Establish an invalid mapping */
+       create_pmd_mapping(early_pmd, test_addr, 0, PMD_SIZE, __pgprot(0));
+
+       /* Precompute the valid pmd here because the mapping for
pfn_pmd() won't exist */
+       valid_pmd =
pfn_pmd(PFN_DOWN(set_tlb_caching_invalid_entries_pmd), PAGE_KERNEL);
+
+       local_flush_tlb_all();
+       satp = PFN_DOWN((uintptr_t)&early_pg_dir) | SATP_MODE_39;
+       csr_write(CSR_SATP, satp);
+
+       /*
+        * Set stvec to after the trapping access, access this invalid mapping
+        * and legitimately trap
+        */
+       // TODO: Should I save the previous stvec?
+#define ASM_STR(x)     __ASM_STR(x)
+       asm volatile(
+               "la a0, 1f                              \n"
+               "csrw " ASM_STR(CSR_TVEC) ", a0         \n"
+               "ld a0, 0(%0)                           \n"
+               ".align 2                               \n"
+               "1:                                     \n"
+               :
+               : "r" (test_addr)
+               : "a0"
+       );
+
+       /* Now establish a valid mapping to check if the invalid one
is cached */
+       early_pmd[pmd_index(test_addr)] = valid_pmd;
+
+       /*
+        * Access the valid mapping multiple times: indeed, we can't use
+        * sfence.vma as a barrier to make sure the cpu did not reorder accesses
+        * so we may trap even if the uarch does not cache invalid entries. By
+        * trying a few times, we make sure that those uarchs will see the right
+        * mapping at some point.
+        */
+
+       i = NR_RETRIES_CACHING_INVALID_ENTRIES;
+
+#define ASM_STR(x)     __ASM_STR(x)
+       asm_volatile_goto(
+               "la a0, 1f                                      \n"
+               "csrw " ASM_STR(CSR_TVEC) ", a0                 \n"
+               ".align 2                                       \n"
+               "1:                                             \n"
+               "addi %0, %0, -1                                \n"
+               "blt %0, zero, %l[caching_invalid_entries]      \n"
+               "ld a0, 0(%1)                                   \n"
+               :
+               : "r" (i), "r" (test_addr)
+               : "a0"
+               : caching_invalid_entries
+       );
+
+       csr_write(CSR_SATP, 0ULL);
+       local_flush_tlb_all();
+
+       /* If we don't trap, the uarch does not cache invalid entries! */
+       tlb_caching_invalid_entries = false;
+       goto clean;
+
+caching_invalid_entries:
+       csr_write(CSR_SATP, 0ULL);
+       local_flush_tlb_all();
+
+       tlb_caching_invalid_entries = true;
+clean:
+       memset(early_pg_dir, 0, PAGE_SIZE);
+       memset(early_pmd, 0, PAGE_SIZE);
+
+       enable_pgtable_l4();
+       enable_pgtable_l5();
+}
 #endif

 /*
@@ -1040,6 +1161,7 @@ asmlinkage void __init setup_vm(uintptr_t dtb_pa)
 #endif

 #if defined(CONFIG_64BIT) && !defined(CONFIG_XIP_KERNEL)
+       set_tlb_caching_invalid_entries();
        set_satp_mode(dtb_pa);
 #endif

@@ -1290,6 +1412,9 @@ static void __init setup_vm_final(void)
        local_flush_tlb_all();

        pt_ops_set_late();
+
+       pr_info("uarch caches invalid entries: %s",
+               tlb_caching_invalid_entries ? "yes": "no");
 }
 #else
 asmlinkage void __init setup_vm(uintptr_t dtb_pa)


> Cheers,
> Prabhakar


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

* Re: [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range()
  2023-08-01  8:54 ` [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range() Alexandre Ghiti
  2023-09-06 11:48   ` Lad, Prabhakar
@ 2023-09-09 19:00   ` Samuel Holland
  2023-09-11  8:33     ` Alexandre Ghiti
  1 sibling, 1 reply; 22+ messages in thread
From: Samuel Holland @ 2023-09-09 19:00 UTC (permalink / raw)
  To: Alexandre Ghiti
  Cc: Andrew Jones, Will Deacon, Aneesh Kumar K . V, Andrew Morton,
	Nick Piggin, Peter Zijlstra, Mayuresh Chitale, Vincent Chen,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-arch, linux-mm,
	linux-riscv, linux-kernel

Hi Alex,

On 8/1/23 03:54, Alexandre Ghiti wrote:
> This function used to simply flush the whole tlb of all harts, be more
> subtile and try to only flush the range.
> 
> The problem is that we can only use PAGE_SIZE as stride since we don't know
> the size of the underlying mapping and then this function will be improved
> only if the size of the region to flush is < threshold * PAGE_SIZE.
> 
> Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
> Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
> ---
>  arch/riscv/include/asm/tlbflush.h | 11 +++++-----
>  arch/riscv/mm/tlbflush.c          | 34 +++++++++++++++++++++++--------
>  2 files changed, 31 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h
> index f5c4fb0ae642..7426fdcd8ec5 100644
> --- a/arch/riscv/include/asm/tlbflush.h
> +++ b/arch/riscv/include/asm/tlbflush.h
> @@ -37,6 +37,7 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
>  void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr);
>  void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
>  		     unsigned long end);
> +void flush_tlb_kernel_range(unsigned long start, unsigned long end);
>  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>  #define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE
>  void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start,
> @@ -53,15 +54,15 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
>  	local_flush_tlb_all();
>  }
>  
> -#define flush_tlb_mm(mm) flush_tlb_all()
> -#define flush_tlb_mm_range(mm, start, end, page_size) flush_tlb_all()
> -#endif /* !CONFIG_SMP || !CONFIG_MMU */
> -
>  /* Flush a range of kernel pages */
>  static inline void flush_tlb_kernel_range(unsigned long start,
>  	unsigned long end)
>  {
> -	flush_tlb_all();
> +	local_flush_tlb_all();
>  }
>  
> +#define flush_tlb_mm(mm) flush_tlb_all()
> +#define flush_tlb_mm_range(mm, start, end, page_size) flush_tlb_all()
> +#endif /* !CONFIG_SMP || !CONFIG_MMU */
> +
>  #endif /* _ASM_RISCV_TLBFLUSH_H */
> diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
> index 0c955c474f3a..687808013758 100644
> --- a/arch/riscv/mm/tlbflush.c
> +++ b/arch/riscv/mm/tlbflush.c
> @@ -120,18 +120,27 @@ static void __flush_tlb_range(struct mm_struct *mm, unsigned long start,
>  			      unsigned long size, unsigned long stride)
>  {
>  	struct flush_tlb_range_data ftd;
> -	struct cpumask *cmask = mm_cpumask(mm);
> -	unsigned int cpuid;
> +	struct cpumask *cmask, full_cmask;
>  	bool broadcast;
>  
> -	if (cpumask_empty(cmask))
> -		return;
> +	if (mm) {
> +		unsigned int cpuid;
> +
> +		cmask = mm_cpumask(mm);
> +		if (cpumask_empty(cmask))
> +			return;
> +
> +		cpuid = get_cpu();
> +		/* check if the tlbflush needs to be sent to other CPUs */
> +		broadcast = cpumask_any_but(cmask, cpuid) < nr_cpu_ids;
> +	} else {
> +		cpumask_setall(&full_cmask);
> +		cmask = &full_cmask;
> +		broadcast = true;
> +	}
>  
> -	cpuid = get_cpu();
> -	/* check if the tlbflush needs to be sent to other CPUs */
> -	broadcast = cpumask_any_but(cmask, cpuid) < nr_cpu_ids;
>  	if (static_branch_unlikely(&use_asid_allocator)) {
> -		unsigned long asid = atomic_long_read(&mm->context.id) & asid_mask;
> +		unsigned long asid = mm ? atomic_long_read(&mm->context.id) & asid_mask : 0;

I think the bug is here. Passing a value of 0 for the ASID is not the
same as passing the ASID in register x0. Only in the latter case does
the TLB flush apply to global mappings, which is what you need for
flush_tlb_kernel_range().

Regards,
Samuel

>  
>  		if (broadcast) {
>  			if (riscv_use_ipi_for_rfence()) {
> @@ -165,7 +174,8 @@ static void __flush_tlb_range(struct mm_struct *mm, unsigned long start,
>  		}
>  	}
>  
> -	put_cpu();
> +	if (mm)
> +		put_cpu();
>  }
>  
>  void flush_tlb_mm(struct mm_struct *mm)
> @@ -196,6 +206,12 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
>  
>  	__flush_tlb_range(vma->vm_mm, start, end - start, stride_size);
>  }
> +
> +void flush_tlb_kernel_range(unsigned long start, unsigned long end)
> +{
> +	__flush_tlb_range(NULL, start, end, PAGE_SIZE);
> +}
> +
>  #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>  void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start,
>  			unsigned long end)



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

* Re: [PATCH v3 0/4] riscv: tlb flush improvements
  2023-08-01  8:53 [PATCH v3 0/4] riscv: tlb flush improvements Alexandre Ghiti
                   ` (4 preceding siblings ...)
  2023-09-06 13:00 ` [PATCH v3 0/4] riscv: tlb flush improvements patchwork-bot+linux-riscv
@ 2023-09-09 20:11 ` Samuel Holland
  5 siblings, 0 replies; 22+ messages in thread
From: Samuel Holland @ 2023-09-09 20:11 UTC (permalink / raw)
  To: Alexandre Ghiti
  Cc: Will Deacon, Aneesh Kumar K . V, Andrew Morton, Nick Piggin,
	Peter Zijlstra, Mayuresh Chitale, Vincent Chen, Paul Walmsley,
	Palmer Dabbelt, Albert Ou, linux-arch, linux-mm, linux-riscv,
	linux-kernel

On 8/1/23 03:53, Alexandre Ghiti wrote:
> This series optimizes the tlb flushes on riscv which used to simply
> flush the whole tlb whatever the size of the range to flush or the size
> of the stride.
> 
> Patch 3 introduces a threshold that is microarchitecture specific and
> will very likely be modified by vendors, not sure though which mechanism
> we'll use to do that (dt? alternatives? vendor initialization code?).

Certainly we would want to set the threshold to zero on SiFive platforms
affected by CIP-1200, since they cannot use address-based sfence.vma at
all. At least this case could be handled in the existing errata patch
function. I don't know about other platforms.

Regards,
Samuel

> 
> Next steps would be to implement:
> - svinval extension as Mayuresh did here [1]
> - BATCHED_UNMAP_TLB_FLUSH (I'll wait for arm64 patchset to land)
> - MMU_GATHER_RCU_TABLE_FREE
> - MMU_GATHER_MERGE_VMAS
> 
> Any other idea welcome.
> 
> [1] https://lore.kernel.org/linux-riscv/20230623123849.1425805-1-mchitale@ventanamicro.com/
> 
> Changes in v3:
> - Add RB from Andrew, thanks!
> - Unwrap a few lines, as suggested by Andrew
> - Introduce defines for -1 constants used in tlbflush.c, as suggested by Andrew and Conor
> - Use huge_page_size() directly instead of using the shift, as suggested by Andrew
> - Remove misleading comments as suggested by Conor
> 
> Changes in v2:
> - Make static tlb_flush_all_threshold, we'll figure out later how to
>   override this value on a vendor basis, as suggested by Conor and Palmer
> - Fix nommu build, as reported by Conor
> 
> Alexandre Ghiti (4):
>   riscv: Improve flush_tlb()
>   riscv: Improve flush_tlb_range() for hugetlb pages
>   riscv: Make __flush_tlb_range() loop over pte instead of flushing the
>     whole tlb
>   riscv: Improve flush_tlb_kernel_range()
> 
>  arch/riscv/include/asm/tlb.h      |  8 ++-
>  arch/riscv/include/asm/tlbflush.h | 12 ++--
>  arch/riscv/mm/tlbflush.c          | 98 ++++++++++++++++++++++++++-----
>  3 files changed, 99 insertions(+), 19 deletions(-)
> 



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

* Re: [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range()
  2023-09-09 19:00   ` Samuel Holland
@ 2023-09-11  8:33     ` Alexandre Ghiti
  0 siblings, 0 replies; 22+ messages in thread
From: Alexandre Ghiti @ 2023-09-11  8:33 UTC (permalink / raw)
  To: Samuel Holland, Alexandre Ghiti
  Cc: Andrew Jones, Will Deacon, Aneesh Kumar K . V, Andrew Morton,
	Nick Piggin, Peter Zijlstra, Mayuresh Chitale, Vincent Chen,
	Paul Walmsley, Palmer Dabbelt, Albert Ou, linux-arch, linux-mm,
	linux-riscv, linux-kernel


On 09/09/2023 21:00, Samuel Holland wrote:
> Hi Alex,
>
> On 8/1/23 03:54, Alexandre Ghiti wrote:
>> This function used to simply flush the whole tlb of all harts, be more
>> subtile and try to only flush the range.
>>
>> The problem is that we can only use PAGE_SIZE as stride since we don't know
>> the size of the underlying mapping and then this function will be improved
>> only if the size of the region to flush is < threshold * PAGE_SIZE.
>>
>> Signed-off-by: Alexandre Ghiti <alexghiti@rivosinc.com>
>> Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
>> ---
>>   arch/riscv/include/asm/tlbflush.h | 11 +++++-----
>>   arch/riscv/mm/tlbflush.c          | 34 +++++++++++++++++++++++--------
>>   2 files changed, 31 insertions(+), 14 deletions(-)
>>
>> diff --git a/arch/riscv/include/asm/tlbflush.h b/arch/riscv/include/asm/tlbflush.h
>> index f5c4fb0ae642..7426fdcd8ec5 100644
>> --- a/arch/riscv/include/asm/tlbflush.h
>> +++ b/arch/riscv/include/asm/tlbflush.h
>> @@ -37,6 +37,7 @@ void flush_tlb_mm_range(struct mm_struct *mm, unsigned long start,
>>   void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr);
>>   void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
>>   		     unsigned long end);
>> +void flush_tlb_kernel_range(unsigned long start, unsigned long end);
>>   #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>>   #define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE
>>   void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start,
>> @@ -53,15 +54,15 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
>>   	local_flush_tlb_all();
>>   }
>>   
>> -#define flush_tlb_mm(mm) flush_tlb_all()
>> -#define flush_tlb_mm_range(mm, start, end, page_size) flush_tlb_all()
>> -#endif /* !CONFIG_SMP || !CONFIG_MMU */
>> -
>>   /* Flush a range of kernel pages */
>>   static inline void flush_tlb_kernel_range(unsigned long start,
>>   	unsigned long end)
>>   {
>> -	flush_tlb_all();
>> +	local_flush_tlb_all();
>>   }
>>   
>> +#define flush_tlb_mm(mm) flush_tlb_all()
>> +#define flush_tlb_mm_range(mm, start, end, page_size) flush_tlb_all()
>> +#endif /* !CONFIG_SMP || !CONFIG_MMU */
>> +
>>   #endif /* _ASM_RISCV_TLBFLUSH_H */
>> diff --git a/arch/riscv/mm/tlbflush.c b/arch/riscv/mm/tlbflush.c
>> index 0c955c474f3a..687808013758 100644
>> --- a/arch/riscv/mm/tlbflush.c
>> +++ b/arch/riscv/mm/tlbflush.c
>> @@ -120,18 +120,27 @@ static void __flush_tlb_range(struct mm_struct *mm, unsigned long start,
>>   			      unsigned long size, unsigned long stride)
>>   {
>>   	struct flush_tlb_range_data ftd;
>> -	struct cpumask *cmask = mm_cpumask(mm);
>> -	unsigned int cpuid;
>> +	struct cpumask *cmask, full_cmask;
>>   	bool broadcast;
>>   
>> -	if (cpumask_empty(cmask))
>> -		return;
>> +	if (mm) {
>> +		unsigned int cpuid;
>> +
>> +		cmask = mm_cpumask(mm);
>> +		if (cpumask_empty(cmask))
>> +			return;
>> +
>> +		cpuid = get_cpu();
>> +		/* check if the tlbflush needs to be sent to other CPUs */
>> +		broadcast = cpumask_any_but(cmask, cpuid) < nr_cpu_ids;
>> +	} else {
>> +		cpumask_setall(&full_cmask);
>> +		cmask = &full_cmask;
>> +		broadcast = true;
>> +	}
>>   
>> -	cpuid = get_cpu();
>> -	/* check if the tlbflush needs to be sent to other CPUs */
>> -	broadcast = cpumask_any_but(cmask, cpuid) < nr_cpu_ids;
>>   	if (static_branch_unlikely(&use_asid_allocator)) {
>> -		unsigned long asid = atomic_long_read(&mm->context.id) & asid_mask;
>> +		unsigned long asid = mm ? atomic_long_read(&mm->context.id) & asid_mask : 0;
> I think the bug is here. Passing a value of 0 for the ASID is not the
> same as passing the ASID in register x0. Only in the latter case does
> the TLB flush apply to global mappings, which is what you need for
> flush_tlb_kernel_range().


Fantastic, thank you, I was miles away from finding this! Really nice 
catch, thanks again.

I'm fixing this and while doing so, I may be stepping a bit on your 
patchset (some code removal), sorry about that. I'll provide a new 
version quickly for Prabhakar to test, and we'll see how we'll rebase 
each other series.

Thanks again Samuel, well done!

Alex


> Regards,
> Samuel
>
>>   
>>   		if (broadcast) {
>>   			if (riscv_use_ipi_for_rfence()) {
>> @@ -165,7 +174,8 @@ static void __flush_tlb_range(struct mm_struct *mm, unsigned long start,
>>   		}
>>   	}
>>   
>> -	put_cpu();
>> +	if (mm)
>> +		put_cpu();
>>   }
>>   
>>   void flush_tlb_mm(struct mm_struct *mm)
>> @@ -196,6 +206,12 @@ void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
>>   
>>   	__flush_tlb_range(vma->vm_mm, start, end - start, stride_size);
>>   }
>> +
>> +void flush_tlb_kernel_range(unsigned long start, unsigned long end)
>> +{
>> +	__flush_tlb_range(NULL, start, end, PAGE_SIZE);
>> +}
>> +
>>   #ifdef CONFIG_TRANSPARENT_HUGEPAGE
>>   void flush_pmd_tlb_range(struct vm_area_struct *vma, unsigned long start,
>>   			unsigned long end)
>
> _______________________________________________
> linux-riscv mailing list
> linux-riscv@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-riscv


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

end of thread, other threads:[~2023-09-11  8:33 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-08-01  8:53 [PATCH v3 0/4] riscv: tlb flush improvements Alexandre Ghiti
2023-08-01  8:53 ` [PATCH v3 1/4] riscv: Improve flush_tlb() Alexandre Ghiti
2023-08-01  8:54 ` [PATCH v3 2/4] riscv: Improve flush_tlb_range() for hugetlb pages Alexandre Ghiti
2023-08-01  8:54 ` [PATCH v3 3/4] riscv: Make __flush_tlb_range() loop over pte instead of flushing the whole tlb Alexandre Ghiti
2023-08-01  8:54 ` [PATCH v3 4/4] riscv: Improve flush_tlb_kernel_range() Alexandre Ghiti
2023-09-06 11:48   ` Lad, Prabhakar
2023-09-06 12:01     ` Alexandre Ghiti
2023-09-06 12:08       ` Lad, Prabhakar
2023-09-06 12:18         ` Alexandre Ghiti
2023-09-06 12:23           ` Lad, Prabhakar
2023-09-06 12:43             ` Alexandre Ghiti
2023-09-06 13:16               ` Palmer Dabbelt
2023-09-06 13:54               ` Lad, Prabhakar
2023-09-07  9:05                 ` Alexandre Ghiti
2023-09-07 10:49                   ` Lad, Prabhakar
2023-09-08 12:34                     ` Alexandre Ghiti
2023-09-06 20:22     ` Nadav Amit
2023-09-07 13:47       ` Alexandre Ghiti
2023-09-09 19:00   ` Samuel Holland
2023-09-11  8:33     ` Alexandre Ghiti
2023-09-06 13:00 ` [PATCH v3 0/4] riscv: tlb flush improvements patchwork-bot+linux-riscv
2023-09-09 20:11 ` Samuel Holland

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