All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] parisc: fixes for CONFIG_PREEMPT
@ 2021-10-09 18:24 Sven Schnelle
  2021-10-09 18:24 ` [PATCH v2 1/5] parisc: disable preemption during local tlb flush Sven Schnelle
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Sven Schnelle @ 2021-10-09 18:24 UTC (permalink / raw)
  To: Helge Deller; +Cc: linux-parisc

Out of curiosity i enabled CONFIG_PREEMPT on my c8000. The kernel didn't
even compile. After fixing compilation i noticed a lot of segmentation
faults - usually a few processes crashed already at boot, with sshd the
most notable one. Most of the time the processes where crashing with a
DTLB or ITLB miss.

With these fixes, i was able to compile a linux kernel on the c8000
with preemption enabled without crashes.

Changes in v2:
- also fix flush_cache_range(), also extend the preemption-disabled
  region to the end of the function, as there's also a tlb flush in
  the last for loop
- add patch to deduplicate code a bit

Sven Schnelle (5):
  parisc: disable preemption during local tlb flush
  parisc: deduplicate code in flush_cache_mm() and flush_cache_range()
  parisc: fix preempt_count() check in entry.S
  parisc: disable preemption in send_IPI_allbutself()
  parisc: fix warning in flush_tlb_all

 arch/parisc/kernel/cache.c | 87 ++++++++++++++++----------------------
 arch/parisc/kernel/entry.S |  4 +-
 arch/parisc/kernel/smp.c   |  4 +-
 arch/parisc/mm/init.c      |  4 +-
 4 files changed, 43 insertions(+), 56 deletions(-)

-- 
2.33.0


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

* [PATCH v2 1/5] parisc: disable preemption during local tlb flush
  2021-10-09 18:24 [PATCH v2 0/5] parisc: fixes for CONFIG_PREEMPT Sven Schnelle
@ 2021-10-09 18:24 ` Sven Schnelle
  2021-10-09 18:24 ` [PATCH v2 2/5] parisc: deduplicate code in flush_cache_mm() and flush_cache_range() Sven Schnelle
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Sven Schnelle @ 2021-10-09 18:24 UTC (permalink / raw)
  To: Helge Deller; +Cc: linux-parisc

flush_cache_mm() and flush_cache_range() fetch %sr3 via mfsp().
If it matches mm->context, they flush caches and the TLB. However,
the TLB is cpu-local, so if the code gets preempted shortly after
the mfsp(), and later resumed on another CPU, the wrong TLB is flushed.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
 arch/parisc/kernel/cache.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index 39e02227e231..a1a7e2b0812f 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -558,6 +558,7 @@ void flush_cache_mm(struct mm_struct *mm)
 		return;
 	}
 
+	preempt_disable();
 	if (mm->context == mfsp(3)) {
 		for (vma = mm->mmap; vma; vma = vma->vm_next) {
 			flush_user_dcache_range_asm(vma->vm_start, vma->vm_end);
@@ -565,6 +566,7 @@ void flush_cache_mm(struct mm_struct *mm)
 				flush_user_icache_range_asm(vma->vm_start, vma->vm_end);
 			flush_tlb_range(vma, vma->vm_start, vma->vm_end);
 		}
+		preempt_enable();
 		return;
 	}
 
@@ -589,6 +591,7 @@ void flush_cache_mm(struct mm_struct *mm)
 			}
 		}
 	}
+	preempt_enable();
 }
 
 void flush_cache_range(struct vm_area_struct *vma,
@@ -605,11 +608,13 @@ void flush_cache_range(struct vm_area_struct *vma,
 		return;
 	}
 
+	preempt_disable();
 	if (vma->vm_mm->context == mfsp(3)) {
 		flush_user_dcache_range_asm(start, end);
 		if (vma->vm_flags & VM_EXEC)
 			flush_user_icache_range_asm(start, end);
 		flush_tlb_range(vma, start, end);
+		preempt_enable();
 		return;
 	}
 
@@ -629,6 +634,7 @@ void flush_cache_range(struct vm_area_struct *vma,
 			}
 		}
 	}
+	preempt_enable();
 }
 
 void
-- 
2.33.0


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

* [PATCH v2 2/5] parisc: deduplicate code in flush_cache_mm() and flush_cache_range()
  2021-10-09 18:24 [PATCH v2 0/5] parisc: fixes for CONFIG_PREEMPT Sven Schnelle
  2021-10-09 18:24 ` [PATCH v2 1/5] parisc: disable preemption during local tlb flush Sven Schnelle
@ 2021-10-09 18:24 ` Sven Schnelle
  2021-10-11 15:06   ` Rolf Eike Beer
  2021-10-09 18:24 ` [PATCH v2 3/5] parisc: fix preempt_count() check in entry.S Sven Schnelle
                   ` (3 subsequent siblings)
  5 siblings, 1 reply; 8+ messages in thread
From: Sven Schnelle @ 2021-10-09 18:24 UTC (permalink / raw)
  To: Helge Deller; +Cc: linux-parisc

Parts of both functions are the same, so deduplicate them. No functional
change.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
 arch/parisc/kernel/cache.c | 81 ++++++++++++++------------------------
 1 file changed, 30 insertions(+), 51 deletions(-)

diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index a1a7e2b0812f..c61827e4928a 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -543,10 +543,33 @@ static inline pte_t *get_ptep(pgd_t *pgd, unsigned long addr)
 	return ptep;
 }
 
+static void flush_cache_pages(struct vm_area_struct *vma, struct mm_struct *mm,
+			      unsigned long start, unsigned long end)
+{
+	unsigned long addr, pfn;
+	pte_t *ptep;
+
+	for (addr = start; addr < end; addr += PAGE_SIZE) {
+		ptep = get_ptep(mm->pgd, addr);
+		if (ptep) {
+			pfn = pte_pfn(*ptep);
+			flush_cache_page(vma, addr, pfn);
+		}
+	}
+}
+
+static void flush_user_cache_tlb(struct vm_area_struct *vma,
+				 unsigned long start, unsigned long end)
+{
+	flush_user_dcache_range_asm(start, end);
+	if (vma->vm_flags & VM_EXEC)
+		flush_user_icache_range_asm(start, end);
+	flush_tlb_range(vma, start, end);
+}
+
 void flush_cache_mm(struct mm_struct *mm)
 {
 	struct vm_area_struct *vma;
-	pgd_t *pgd;
 
 	/* Flushing the whole cache on each cpu takes forever on
 	   rp3440, etc.  So, avoid it if the mm isn't too big.  */
@@ -560,46 +583,20 @@ void flush_cache_mm(struct mm_struct *mm)
 
 	preempt_disable();
 	if (mm->context == mfsp(3)) {
-		for (vma = mm->mmap; vma; vma = vma->vm_next) {
-			flush_user_dcache_range_asm(vma->vm_start, vma->vm_end);
-			if (vma->vm_flags & VM_EXEC)
-				flush_user_icache_range_asm(vma->vm_start, vma->vm_end);
-			flush_tlb_range(vma, vma->vm_start, vma->vm_end);
-		}
+		for (vma = mm->mmap; vma; vma = vma->vm_next)
+			flush_user_cache_tlb(vma, vma->vm_start, vma->vm_end);
 		preempt_enable();
 		return;
 	}
 
-	pgd = mm->pgd;
-	for (vma = mm->mmap; vma; vma = vma->vm_next) {
-		unsigned long addr;
-
-		for (addr = vma->vm_start; addr < vma->vm_end;
-		     addr += PAGE_SIZE) {
-			unsigned long pfn;
-			pte_t *ptep = get_ptep(pgd, addr);
-			if (!ptep)
-				continue;
-			pfn = pte_pfn(*ptep);
-			if (!pfn_valid(pfn))
-				continue;
-			if (unlikely(mm->context)) {
-				flush_tlb_page(vma, addr);
-				__flush_cache_page(vma, addr, PFN_PHYS(pfn));
-			} else {
-				__purge_cache_page(vma, addr, PFN_PHYS(pfn));
-			}
-		}
-	}
+	for (vma = mm->mmap; vma; vma = vma->vm_next)
+		flush_cache_pages(vma, mm, vma->vm_start, vma->vm_end);
 	preempt_enable();
 }
 
 void flush_cache_range(struct vm_area_struct *vma,
 		unsigned long start, unsigned long end)
 {
-	pgd_t *pgd;
-	unsigned long addr;
-
 	if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
 	    end - start >= parisc_cache_flush_threshold) {
 		if (vma->vm_mm->context)
@@ -610,30 +607,12 @@ void flush_cache_range(struct vm_area_struct *vma,
 
 	preempt_disable();
 	if (vma->vm_mm->context == mfsp(3)) {
-		flush_user_dcache_range_asm(start, end);
-		if (vma->vm_flags & VM_EXEC)
-			flush_user_icache_range_asm(start, end);
-		flush_tlb_range(vma, start, end);
+		flush_user_cache_tlb(vma, start, end);
 		preempt_enable();
 		return;
 	}
 
-	pgd = vma->vm_mm->pgd;
-	for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) {
-		unsigned long pfn;
-		pte_t *ptep = get_ptep(pgd, addr);
-		if (!ptep)
-			continue;
-		pfn = pte_pfn(*ptep);
-		if (pfn_valid(pfn)) {
-			if (unlikely(vma->vm_mm->context)) {
-				flush_tlb_page(vma, addr);
-				__flush_cache_page(vma, addr, PFN_PHYS(pfn));
-			} else {
-				__purge_cache_page(vma, addr, PFN_PHYS(pfn));
-			}
-		}
-	}
+	flush_cache_pages(vma, vma->vm_mm, vma->vm_start, vma->vm_end);
 	preempt_enable();
 }
 
-- 
2.33.0


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

* [PATCH v2 3/5] parisc: fix preempt_count() check in entry.S
  2021-10-09 18:24 [PATCH v2 0/5] parisc: fixes for CONFIG_PREEMPT Sven Schnelle
  2021-10-09 18:24 ` [PATCH v2 1/5] parisc: disable preemption during local tlb flush Sven Schnelle
  2021-10-09 18:24 ` [PATCH v2 2/5] parisc: deduplicate code in flush_cache_mm() and flush_cache_range() Sven Schnelle
@ 2021-10-09 18:24 ` Sven Schnelle
  2021-10-09 18:24 ` [PATCH v2 4/5] parisc: disable preemption in send_IPI_allbutself() Sven Schnelle
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Sven Schnelle @ 2021-10-09 18:24 UTC (permalink / raw)
  To: Helge Deller; +Cc: linux-parisc

preempt_count in struct thread_info is unsigned int,
but the entry.S code used LDREG, which generates a 64 bit
load when compiled for 64 bit. Fix this to use an ldw and
also change the condition in the compare one line below
to only compares 32 bits, although ldw zero extends, and
that should work with a 64 bit compare.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
 arch/parisc/kernel/entry.S | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index 9f939afe6b88..e9e598c18cb0 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -974,8 +974,8 @@ intr_do_preempt:
 
 	/* current_thread_info()->preempt_count */
 	mfctl	%cr30, %r1
-	LDREG	TI_PRE_COUNT(%r1), %r19
-	cmpib,COND(<>)	0, %r19, intr_restore	/* if preempt_count > 0 */
+	ldw	TI_PRE_COUNT(%r1), %r19
+	cmpib,<>	0, %r19, intr_restore	/* if preempt_count > 0 */
 	nop				/* prev insn branched backwards */
 
 	/* check if we interrupted a critical path */
-- 
2.33.0


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

* [PATCH v2 4/5] parisc: disable preemption in send_IPI_allbutself()
  2021-10-09 18:24 [PATCH v2 0/5] parisc: fixes for CONFIG_PREEMPT Sven Schnelle
                   ` (2 preceding siblings ...)
  2021-10-09 18:24 ` [PATCH v2 3/5] parisc: fix preempt_count() check in entry.S Sven Schnelle
@ 2021-10-09 18:24 ` Sven Schnelle
  2021-10-09 18:24 ` [PATCH v2 5/5] parisc: fix warning in flush_tlb_all Sven Schnelle
  2021-10-09 20:38 ` [PATCH v2 0/5] parisc: fixes for CONFIG_PREEMPT Helge Deller
  5 siblings, 0 replies; 8+ messages in thread
From: Sven Schnelle @ 2021-10-09 18:24 UTC (permalink / raw)
  To: Helge Deller; +Cc: linux-parisc

Otherwise we might not stop all other CPUs.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
 arch/parisc/kernel/smp.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/parisc/kernel/smp.c b/arch/parisc/kernel/smp.c
index 1405b603b91b..3413e6949c87 100644
--- a/arch/parisc/kernel/smp.c
+++ b/arch/parisc/kernel/smp.c
@@ -219,11 +219,13 @@ static inline void
 send_IPI_allbutself(enum ipi_message_type op)
 {
 	int i;
-	
+
+	preempt_disable();
 	for_each_online_cpu(i) {
 		if (i != smp_processor_id())
 			send_IPI_single(i, op);
 	}
+	preempt_enable();
 }
 
 
-- 
2.33.0


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

* [PATCH v2 5/5] parisc: fix warning in flush_tlb_all
  2021-10-09 18:24 [PATCH v2 0/5] parisc: fixes for CONFIG_PREEMPT Sven Schnelle
                   ` (3 preceding siblings ...)
  2021-10-09 18:24 ` [PATCH v2 4/5] parisc: disable preemption in send_IPI_allbutself() Sven Schnelle
@ 2021-10-09 18:24 ` Sven Schnelle
  2021-10-09 20:38 ` [PATCH v2 0/5] parisc: fixes for CONFIG_PREEMPT Helge Deller
  5 siblings, 0 replies; 8+ messages in thread
From: Sven Schnelle @ 2021-10-09 18:24 UTC (permalink / raw)
  To: Helge Deller; +Cc: linux-parisc

I've got the following splat after enabling preemption:

[    3.724721] BUG: using __this_cpu_add() in preemptible [00000000] code: swapper/0/1
[    3.734630] caller is __this_cpu_preempt_check+0x38/0x50
[    3.740635] CPU: 1 PID: 1 Comm: swapper/0 Not tainted 5.15.0-rc4-64bit+ #324
[    3.744605] Hardware name: 9000/785/C8000
[    3.744605] Backtrace:
[    3.744605]  [<00000000401d9d58>] show_stack+0x74/0xb0
[    3.744605]  [<0000000040c27bd4>] dump_stack_lvl+0x10c/0x188
[    3.744605]  [<0000000040c27c84>] dump_stack+0x34/0x48
[    3.744605]  [<0000000040c33438>] check_preemption_disabled+0x178/0x1b0
[    3.744605]  [<0000000040c334f8>] __this_cpu_preempt_check+0x38/0x50
[    3.744605]  [<00000000401d632c>] flush_tlb_all+0x58/0x2e0
[    3.744605]  [<00000000401075c0>] 0x401075c0
[    3.744605]  [<000000004010b8fc>] 0x4010b8fc
[    3.744605]  [<00000000401080fc>] 0x401080fc
[    3.744605]  [<00000000401d5224>] do_one_initcall+0x128/0x378
[    3.744605]  [<0000000040102de8>] 0x40102de8
[    3.744605]  [<0000000040c33864>] kernel_init+0x60/0x3a8
[    3.744605]  [<00000000401d1020>] ret_from_kernel_thread+0x20/0x28
[    3.744605]

Fix this by moving the __inc_irq_stat() into the locked section.

Signed-off-by: Sven Schnelle <svens@stackframe.org>
---
 arch/parisc/mm/init.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c
index 3f7d6d5b56ac..65f50f072a87 100644
--- a/arch/parisc/mm/init.c
+++ b/arch/parisc/mm/init.c
@@ -842,9 +842,9 @@ void flush_tlb_all(void)
 {
 	int do_recycle;
 
-	__inc_irq_stat(irq_tlb_count);
 	do_recycle = 0;
 	spin_lock(&sid_lock);
+	__inc_irq_stat(irq_tlb_count);
 	if (dirty_space_ids > RECYCLE_THRESHOLD) {
 	    BUG_ON(recycle_inuse);  /* FIXME: Use a semaphore/wait queue here */
 	    get_dirty_sids(&recycle_ndirty,recycle_dirty_array);
@@ -863,8 +863,8 @@ void flush_tlb_all(void)
 #else
 void flush_tlb_all(void)
 {
-	__inc_irq_stat(irq_tlb_count);
 	spin_lock(&sid_lock);
+	__inc_irq_stat(irq_tlb_count);
 	flush_tlb_all_local(NULL);
 	recycle_sids();
 	spin_unlock(&sid_lock);
-- 
2.33.0


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

* Re: [PATCH v2 0/5] parisc: fixes for CONFIG_PREEMPT
  2021-10-09 18:24 [PATCH v2 0/5] parisc: fixes for CONFIG_PREEMPT Sven Schnelle
                   ` (4 preceding siblings ...)
  2021-10-09 18:24 ` [PATCH v2 5/5] parisc: fix warning in flush_tlb_all Sven Schnelle
@ 2021-10-09 20:38 ` Helge Deller
  5 siblings, 0 replies; 8+ messages in thread
From: Helge Deller @ 2021-10-09 20:38 UTC (permalink / raw)
  To: Sven Schnelle; +Cc: linux-parisc

On 10/9/21 20:24, Sven Schnelle wrote:
> Out of curiosity i enabled CONFIG_PREEMPT on my c8000. The kernel didn't
> even compile. After fixing compilation i noticed a lot of segmentation
> faults - usually a few processes crashed already at boot, with sshd the
> most notable one. Most of the time the processes where crashing with a
> DTLB or ITLB miss.
>
> With these fixes, i was able to compile a linux kernel on the c8000
> with preemption enabled without crashes.

Thank you Sven.
I've merged this series into my for-next-v5.15 branch:
https://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux.git/log/?h=for-next-v5.15

Helge



> Changes in v2:
> - also fix flush_cache_range(), also extend the preemption-disabled
>   region to the end of the function, as there's also a tlb flush in
>   the last for loop
> - add patch to deduplicate code a bit
>
> Sven Schnelle (5):
>   parisc: disable preemption during local tlb flush
>   parisc: deduplicate code in flush_cache_mm() and flush_cache_range()
>   parisc: fix preempt_count() check in entry.S
>   parisc: disable preemption in send_IPI_allbutself()
>   parisc: fix warning in flush_tlb_all
>
>  arch/parisc/kernel/cache.c | 87 ++++++++++++++++----------------------
>  arch/parisc/kernel/entry.S |  4 +-
>  arch/parisc/kernel/smp.c   |  4 +-
>  arch/parisc/mm/init.c      |  4 +-
>  4 files changed, 43 insertions(+), 56 deletions(-)
>


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

* Re: [PATCH v2 2/5] parisc: deduplicate code in flush_cache_mm() and flush_cache_range()
  2021-10-09 18:24 ` [PATCH v2 2/5] parisc: deduplicate code in flush_cache_mm() and flush_cache_range() Sven Schnelle
@ 2021-10-11 15:06   ` Rolf Eike Beer
  0 siblings, 0 replies; 8+ messages in thread
From: Rolf Eike Beer @ 2021-10-11 15:06 UTC (permalink / raw)
  To: Helge Deller, Sven Schnelle; +Cc: linux-parisc

[-- Attachment #1: Type: text/plain, Size: 4225 bytes --]

Am Samstag, 9. Oktober 2021, 20:24:36 CEST schrieb Sven Schnelle:
> Parts of both functions are the same, so deduplicate them. No functional
> change.
> 
> Signed-off-by: Sven Schnelle <svens@stackframe.org>
> ---
>  arch/parisc/kernel/cache.c | 81 ++++++++++++++------------------------
>  1 file changed, 30 insertions(+), 51 deletions(-)
> 
> diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
> index a1a7e2b0812f..c61827e4928a 100644
> --- a/arch/parisc/kernel/cache.c
> +++ b/arch/parisc/kernel/cache.c
> @@ -543,10 +543,33 @@ static inline pte_t *get_ptep(pgd_t *pgd, unsigned
> long addr) return ptep;
>  }
> 
> +static void flush_cache_pages(struct vm_area_struct *vma, struct mm_struct
> *mm, +			      unsigned long start, unsigned long end)
> +{
> +	unsigned long addr, pfn;
> +	pte_t *ptep;
> +
> +	for (addr = start; addr < end; addr += PAGE_SIZE) {
> +		ptep = get_ptep(mm->pgd, addr);
> +		if (ptep) {
> +			pfn = pte_pfn(*ptep);
> +			flush_cache_page(vma, addr, pfn);
> +		}
> +	}
> +}
> +
> +static void flush_user_cache_tlb(struct vm_area_struct *vma,
> +				 unsigned long start, unsigned 
long end)
> +{
> +	flush_user_dcache_range_asm(start, end);
> +	if (vma->vm_flags & VM_EXEC)
> +		flush_user_icache_range_asm(start, end);
> +	flush_tlb_range(vma, start, end);
> +}

What you add here is less than what you removed below. If that is intentional 
I would welcome a description on why it is correct in the commit message.

>  void flush_cache_mm(struct mm_struct *mm)
>  {
>  	struct vm_area_struct *vma;
> -	pgd_t *pgd;
> 
>  	/* Flushing the whole cache on each cpu takes forever on
>  	   rp3440, etc.  So, avoid it if the mm isn't too big.  */
> @@ -560,46 +583,20 @@ void flush_cache_mm(struct mm_struct *mm)
> 
>  	preempt_disable();
>  	if (mm->context == mfsp(3)) {
> -		for (vma = mm->mmap; vma; vma = vma->vm_next) {
> -			flush_user_dcache_range_asm(vma->vm_start, 
vma->vm_end);
> -			if (vma->vm_flags & VM_EXEC)
> -				flush_user_icache_range_asm(vma-
>vm_start, vma->vm_end);
> -			flush_tlb_range(vma, vma->vm_start, vma-
>vm_end);
> -		}
> +		for (vma = mm->mmap; vma; vma = vma->vm_next)
> +			flush_user_cache_tlb(vma, vma->vm_start, vma-
>vm_end);
>  		preempt_enable();
>  		return;
>  	}
> 
> -	pgd = mm->pgd;
> -	for (vma = mm->mmap; vma; vma = vma->vm_next) {
> -		unsigned long addr;
> -
> -		for (addr = vma->vm_start; addr < vma->vm_end;
> -		     addr += PAGE_SIZE) {
> -			unsigned long pfn;
> -			pte_t *ptep = get_ptep(pgd, addr);
> -			if (!ptep)
> -				continue;
> -			pfn = pte_pfn(*ptep);
> -			if (!pfn_valid(pfn))
> -				continue;
> -			if (unlikely(mm->context)) {
> -				flush_tlb_page(vma, addr);
> -				__flush_cache_page(vma, addr, 
PFN_PHYS(pfn));
> -			} else {
> -				__purge_cache_page(vma, addr, 
PFN_PHYS(pfn));
> -			}
> -		}
> -	}
> +	for (vma = mm->mmap; vma; vma = vma->vm_next)
> +		flush_cache_pages(vma, mm, vma->vm_start, vma->vm_end);
>  	preempt_enable();
>  }
> 
>  void flush_cache_range(struct vm_area_struct *vma,
>  		unsigned long start, unsigned long end)
>  {
> -	pgd_t *pgd;
> -	unsigned long addr;
> -
>  	if ((!IS_ENABLED(CONFIG_SMP) || !arch_irqs_disabled()) &&
>  	    end - start >= parisc_cache_flush_threshold) {
>  		if (vma->vm_mm->context)
> @@ -610,30 +607,12 @@ void flush_cache_range(struct vm_area_struct *vma,
> 
>  	preempt_disable();
>  	if (vma->vm_mm->context == mfsp(3)) {
> -		flush_user_dcache_range_asm(start, end);
> -		if (vma->vm_flags & VM_EXEC)
> -			flush_user_icache_range_asm(start, end);
> -		flush_tlb_range(vma, start, end);
> +		flush_user_cache_tlb(vma, start, end);
>  		preempt_enable();
>  		return;
>  	}
> 
> -	pgd = vma->vm_mm->pgd;
> -	for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) 
{
> -		unsigned long pfn;
> -		pte_t *ptep = get_ptep(pgd, addr);
> -		if (!ptep)
> -			continue;
> -		pfn = pte_pfn(*ptep);
> -		if (pfn_valid(pfn)) {
> -			if (unlikely(vma->vm_mm->context)) {
> -				flush_tlb_page(vma, addr);
> -				__flush_cache_page(vma, addr, 
PFN_PHYS(pfn));
> -			} else {
> -				__purge_cache_page(vma, addr, 
PFN_PHYS(pfn));
> -			}
> -		}
> -	}
> +	flush_cache_pages(vma, vma->vm_mm, vma->vm_start, vma->vm_end);
>  	preempt_enable();
>  }


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

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

end of thread, other threads:[~2021-10-11 15:06 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-10-09 18:24 [PATCH v2 0/5] parisc: fixes for CONFIG_PREEMPT Sven Schnelle
2021-10-09 18:24 ` [PATCH v2 1/5] parisc: disable preemption during local tlb flush Sven Schnelle
2021-10-09 18:24 ` [PATCH v2 2/5] parisc: deduplicate code in flush_cache_mm() and flush_cache_range() Sven Schnelle
2021-10-11 15:06   ` Rolf Eike Beer
2021-10-09 18:24 ` [PATCH v2 3/5] parisc: fix preempt_count() check in entry.S Sven Schnelle
2021-10-09 18:24 ` [PATCH v2 4/5] parisc: disable preemption in send_IPI_allbutself() Sven Schnelle
2021-10-09 18:24 ` [PATCH v2 5/5] parisc: fix warning in flush_tlb_all Sven Schnelle
2021-10-09 20:38 ` [PATCH v2 0/5] parisc: fixes for CONFIG_PREEMPT Helge Deller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.