* [PATCH] parisc: Optimize sync instruction and D/I-cache flushes on UP kernel
@ 2018-11-09 21:39 Helge Deller
2018-11-11 15:31 ` John David Anglin
0 siblings, 1 reply; 2+ messages in thread
From: Helge Deller @ 2018-11-09 21:39 UTC (permalink / raw)
To: linux-parisc, James Bottomley, John David Anglin
Utilize the alternative coding to return early from D/I-flush functions
with the bv,n instruction when machine has no D- or I-caches. Up to now
the coding was replaced with a long branch instruction to the end of the
functions.
Additionally replace the sync instruction on UP kernel with nop.
Signed-off-by: Helge Deller <deller@gmx.de>
diff --git a/arch/parisc/include/asm/alternative.h b/arch/parisc/include/asm/alternative.h
index a3630442111d..754988ef4e8d 100644
--- a/arch/parisc/include/asm/alternative.h
+++ b/arch/parisc/include/asm/alternative.h
@@ -12,6 +12,7 @@
#define INSN_PxTLB 0x02 /* modify pdtlb, pitlb */
#define INSN_LDI_CPUs 0x34000000 /* ldi val,%reg */
#define INSN_NOP 0x08000240 /* nop */
+#define INSN_RETURN 0xe840c002 /* bv,n r0(rp) */
#ifndef __ASSEMBLY__
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
index 187f032c9dd8..1ea832b256fa 100644
--- a/arch/parisc/kernel/pacache.S
+++ b/arch/parisc/kernel/pacache.S
@@ -41,6 +41,12 @@
#include <linux/linkage.h>
#include <linux/init.h>
+ /* sync instruction, replaced by nop on UP kernel */
+ .macro asm_sync
+77: sync
+ ALTERNATIVE(77b, 77b+4, ALT_COND_NO_SMP, INSN_NOP)
+ .endm
+
.section .text.hot
.align 16
@@ -192,6 +198,7 @@ ENDPROC_CFI(flush_tlb_all_local)
ENTRY_CFI(flush_instruction_cache_local)
88: load32 cache_info, %r1
+ ALTERNATIVE(88b, 88b+4, ALT_COND_NO_ICACHE, INSN_RETURN)
/* Flush Instruction Cache */
@@ -242,9 +249,8 @@ fioneloop2:
fice,m %arg1(%sr1, %arg0) /* Fice for one loop */
fisync:
- sync
+ asm_sync
mtsm %r22 /* restore I-bit */
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
bv %r0(%r2)
nop
ENDPROC_CFI(flush_instruction_cache_local)
@@ -253,6 +259,7 @@ ENDPROC_CFI(flush_instruction_cache_local)
.import cache_info, data
ENTRY_CFI(flush_data_cache_local)
88: load32 cache_info, %r1
+ ALTERNATIVE(88b, 88b+4, ALT_COND_NO_DCACHE, INSN_RETURN)
/* Flush Data Cache */
@@ -304,9 +311,8 @@ fdoneloop2:
fdsync:
syncdma
- sync
+ asm_sync
mtsm %r22 /* restore I-bit */
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
bv %r0(%r2)
nop
ENDPROC_CFI(flush_data_cache_local)
@@ -857,7 +863,7 @@ ENTRY_CFI(flush_dcache_page_asm)
fdc,m r31(%r28)
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
- sync
+ asm_sync
bv %r0(%r2)
nop
ENDPROC_CFI(flush_dcache_page_asm)
@@ -918,7 +924,7 @@ ENTRY_CFI(purge_dcache_page_asm)
pdc,m r31(%r28)
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
- sync
+ asm_sync
bv %r0(%r2)
nop
ENDPROC_CFI(purge_dcache_page_asm)
@@ -989,13 +995,14 @@ ENTRY_CFI(flush_icache_page_asm)
fic,m %r31(%sr4,%r28)
89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
- sync
+ asm_sync
bv %r0(%r2)
nop
ENDPROC_CFI(flush_icache_page_asm)
ENTRY_CFI(flush_kernel_dcache_page_asm)
88: ldil L%dcache_stride, %r1
+ ALTERNATIVE(88b, 88b+4, ALT_COND_NO_DCACHE, INSN_RETURN)
ldw R%dcache_stride(%r1), %r23
#ifdef CONFIG_64BIT
@@ -1024,14 +1031,14 @@ ENTRY_CFI(flush_kernel_dcache_page_asm)
cmpb,COND(>>) %r25, %r26, 1b /* predict taken */
fdc,m %r23(%r26)
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
- sync
+ asm_sync
bv %r0(%r2)
nop
ENDPROC_CFI(flush_kernel_dcache_page_asm)
ENTRY_CFI(purge_kernel_dcache_page_asm)
88: ldil L%dcache_stride, %r1
+ ALTERNATIVE(88b, 88b+4, ALT_COND_NO_DCACHE, INSN_RETURN)
ldw R%dcache_stride(%r1), %r23
#ifdef CONFIG_64BIT
@@ -1060,14 +1067,14 @@ ENTRY_CFI(purge_kernel_dcache_page_asm)
cmpb,COND(>>) %r25, %r26, 1b /* predict taken */
pdc,m %r23(%r26)
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
- sync
+ asm_sync
bv %r0(%r2)
nop
ENDPROC_CFI(purge_kernel_dcache_page_asm)
ENTRY_CFI(flush_user_dcache_range_asm)
88: ldil L%dcache_stride, %r1
+ ALTERNATIVE(88b, 88b+4, ALT_COND_NO_DCACHE, INSN_RETURN)
ldw R%dcache_stride(%r1), %r23
ldo -1(%r23), %r21
ANDCM %r26, %r21, %r26
@@ -1101,14 +1108,14 @@ ENTRY_CFI(flush_user_dcache_range_asm)
2: cmpb,COND(>>),n %r25, %r26, 2b
fdc,m %r23(%sr3, %r26)
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
- sync
+ asm_sync
bv %r0(%r2)
nop
ENDPROC_CFI(flush_user_dcache_range_asm)
ENTRY_CFI(flush_kernel_dcache_range_asm)
88: ldil L%dcache_stride, %r1
+ ALTERNATIVE(88b, 88b+4, ALT_COND_NO_DCACHE, INSN_RETURN)
ldw R%dcache_stride(%r1), %r23
ldo -1(%r23), %r21
ANDCM %r26, %r21, %r26
@@ -1142,8 +1149,7 @@ ENTRY_CFI(flush_kernel_dcache_range_asm)
2: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */
fdc,m %r23(%r26)
- sync
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
+ asm_sync
syncdma
bv %r0(%r2)
nop
@@ -1151,6 +1157,7 @@ ENDPROC_CFI(flush_kernel_dcache_range_asm)
ENTRY_CFI(purge_kernel_dcache_range_asm)
88: ldil L%dcache_stride, %r1
+ ALTERNATIVE(88b, 88b+4, ALT_COND_NO_DCACHE, INSN_RETURN)
ldw R%dcache_stride(%r1), %r23
ldo -1(%r23), %r21
ANDCM %r26, %r21, %r26
@@ -1184,8 +1191,7 @@ ENTRY_CFI(purge_kernel_dcache_range_asm)
2: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */
pdc,m %r23(%r26)
- sync
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
+ asm_sync
syncdma
bv %r0(%r2)
nop
@@ -1193,6 +1199,7 @@ ENDPROC_CFI(purge_kernel_dcache_range_asm)
ENTRY_CFI(flush_user_icache_range_asm)
88: ldil L%icache_stride, %r1
+ ALTERNATIVE(88b, 88b+4, ALT_COND_NO_ICACHE, INSN_RETURN)
ldw R%icache_stride(%r1), %r23
ldo -1(%r23), %r21
ANDCM %r26, %r21, %r26
@@ -1226,14 +1233,14 @@ ENTRY_CFI(flush_user_icache_range_asm)
2: cmpb,COND(>>),n %r25, %r26, 2b
fic,m %r23(%sr3, %r26)
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
- sync
+ asm_sync
bv %r0(%r2)
nop
ENDPROC_CFI(flush_user_icache_range_asm)
ENTRY_CFI(flush_kernel_icache_page)
88: ldil L%icache_stride, %r1
+ ALTERNATIVE(88b, 88b+4, ALT_COND_NO_ICACHE, INSN_RETURN)
ldw R%icache_stride(%r1), %r23
#ifdef CONFIG_64BIT
@@ -1263,14 +1270,14 @@ ENTRY_CFI(flush_kernel_icache_page)
cmpb,COND(>>) %r25, %r26, 1b /* predict taken */
fic,m %r23(%sr4, %r26)
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
- sync
+ asm_sync
bv %r0(%r2)
nop
ENDPROC_CFI(flush_kernel_icache_page)
ENTRY_CFI(flush_kernel_icache_range_asm)
88: ldil L%icache_stride, %r1
+ ALTERNATIVE(88b, 88b+4, ALT_COND_NO_ICACHE, INSN_RETURN)
ldw R%icache_stride(%r1), %r23
ldo -1(%r23), %r21
ANDCM %r26, %r21, %r26
@@ -1304,8 +1311,7 @@ ENTRY_CFI(flush_kernel_icache_range_asm)
2: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */
fic,m %r23(%sr4, %r26)
-89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
- sync
+ asm_sync
bv %r0(%r2)
nop
ENDPROC_CFI(flush_kernel_icache_range_asm)
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH] parisc: Optimize sync instruction and D/I-cache flushes on UP kernel
2018-11-09 21:39 [PATCH] parisc: Optimize sync instruction and D/I-cache flushes on UP kernel Helge Deller
@ 2018-11-11 15:31 ` John David Anglin
0 siblings, 0 replies; 2+ messages in thread
From: John David Anglin @ 2018-11-11 15:31 UTC (permalink / raw)
To: Helge Deller, linux-parisc, James Bottomley
On 2018-11-09 4:39 p.m., Helge Deller wrote:
> Utilize the alternative coding to return early from D/I-flush functions
> with the bv,n instruction when machine has no D- or I-caches. Up to now
> the coding was replaced with a long branch instruction to the end of the
> functions.
> Additionally replace the sync instruction on UP kernel with nop.
I don't believe this change is correct. Flush and purge data cache
instructions are deferred.
The sync instructions in the flush and purge routines ensure that cache
lines are flushed
to memory. This has nothing directly to do with UP. It is needed for
example on machines with
separate I and D caches, or multiple combined caches that aren't coherent.
>
> Signed-off-by: Helge Deller <deller@gmx.de>
>
> diff --git a/arch/parisc/include/asm/alternative.h b/arch/parisc/include/asm/alternative.h
> index a3630442111d..754988ef4e8d 100644
> --- a/arch/parisc/include/asm/alternative.h
> +++ b/arch/parisc/include/asm/alternative.h
> @@ -12,6 +12,7 @@
> #define INSN_PxTLB 0x02 /* modify pdtlb, pitlb */
> #define INSN_LDI_CPUs 0x34000000 /* ldi val,%reg */
> #define INSN_NOP 0x08000240 /* nop */
> +#define INSN_RETURN 0xe840c002 /* bv,n r0(rp) */
>
> #ifndef __ASSEMBLY__
>
> diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
> index 187f032c9dd8..1ea832b256fa 100644
> --- a/arch/parisc/kernel/pacache.S
> +++ b/arch/parisc/kernel/pacache.S
> @@ -41,6 +41,12 @@
> #include <linux/linkage.h>
> #include <linux/init.h>
>
> + /* sync instruction, replaced by nop on UP kernel */
> + .macro asm_sync
> +77: sync
> + ALTERNATIVE(77b, 77b+4, ALT_COND_NO_SMP, INSN_NOP)
> + .endm
> +
> .section .text.hot
> .align 16
>
> @@ -192,6 +198,7 @@ ENDPROC_CFI(flush_tlb_all_local)
>
> ENTRY_CFI(flush_instruction_cache_local)
> 88: load32 cache_info, %r1
> + ALTERNATIVE(88b, 88b+4, ALT_COND_NO_ICACHE, INSN_RETURN)
>
> /* Flush Instruction Cache */
>
> @@ -242,9 +249,8 @@ fioneloop2:
> fice,m %arg1(%sr1, %arg0) /* Fice for one loop */
>
> fisync:
> - sync
> + asm_sync
> mtsm %r22 /* restore I-bit */
> -89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
> bv %r0(%r2)
> nop
> ENDPROC_CFI(flush_instruction_cache_local)
> @@ -253,6 +259,7 @@ ENDPROC_CFI(flush_instruction_cache_local)
> .import cache_info, data
> ENTRY_CFI(flush_data_cache_local)
> 88: load32 cache_info, %r1
> + ALTERNATIVE(88b, 88b+4, ALT_COND_NO_DCACHE, INSN_RETURN)
>
> /* Flush Data Cache */
>
> @@ -304,9 +311,8 @@ fdoneloop2:
>
> fdsync:
> syncdma
> - sync
> + asm_sync
> mtsm %r22 /* restore I-bit */
> -89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
> bv %r0(%r2)
> nop
> ENDPROC_CFI(flush_data_cache_local)
> @@ -857,7 +863,7 @@ ENTRY_CFI(flush_dcache_page_asm)
> fdc,m r31(%r28)
>
> 89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
> - sync
> + asm_sync
> bv %r0(%r2)
> nop
> ENDPROC_CFI(flush_dcache_page_asm)
> @@ -918,7 +924,7 @@ ENTRY_CFI(purge_dcache_page_asm)
> pdc,m r31(%r28)
>
> 89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
> - sync
> + asm_sync
> bv %r0(%r2)
> nop
> ENDPROC_CFI(purge_dcache_page_asm)
> @@ -989,13 +995,14 @@ ENTRY_CFI(flush_icache_page_asm)
> fic,m %r31(%sr4,%r28)
>
> 89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
> - sync
> + asm_sync
> bv %r0(%r2)
> nop
> ENDPROC_CFI(flush_icache_page_asm)
>
> ENTRY_CFI(flush_kernel_dcache_page_asm)
> 88: ldil L%dcache_stride, %r1
> + ALTERNATIVE(88b, 88b+4, ALT_COND_NO_DCACHE, INSN_RETURN)
> ldw R%dcache_stride(%r1), %r23
>
> #ifdef CONFIG_64BIT
> @@ -1024,14 +1031,14 @@ ENTRY_CFI(flush_kernel_dcache_page_asm)
> cmpb,COND(>>) %r25, %r26, 1b /* predict taken */
> fdc,m %r23(%r26)
>
> -89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
> - sync
> + asm_sync
> bv %r0(%r2)
> nop
> ENDPROC_CFI(flush_kernel_dcache_page_asm)
>
> ENTRY_CFI(purge_kernel_dcache_page_asm)
> 88: ldil L%dcache_stride, %r1
> + ALTERNATIVE(88b, 88b+4, ALT_COND_NO_DCACHE, INSN_RETURN)
> ldw R%dcache_stride(%r1), %r23
>
> #ifdef CONFIG_64BIT
> @@ -1060,14 +1067,14 @@ ENTRY_CFI(purge_kernel_dcache_page_asm)
> cmpb,COND(>>) %r25, %r26, 1b /* predict taken */
> pdc,m %r23(%r26)
>
> -89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
> - sync
> + asm_sync
> bv %r0(%r2)
> nop
> ENDPROC_CFI(purge_kernel_dcache_page_asm)
>
> ENTRY_CFI(flush_user_dcache_range_asm)
> 88: ldil L%dcache_stride, %r1
> + ALTERNATIVE(88b, 88b+4, ALT_COND_NO_DCACHE, INSN_RETURN)
> ldw R%dcache_stride(%r1), %r23
> ldo -1(%r23), %r21
> ANDCM %r26, %r21, %r26
> @@ -1101,14 +1108,14 @@ ENTRY_CFI(flush_user_dcache_range_asm)
> 2: cmpb,COND(>>),n %r25, %r26, 2b
> fdc,m %r23(%sr3, %r26)
>
> -89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
> - sync
> + asm_sync
> bv %r0(%r2)
> nop
> ENDPROC_CFI(flush_user_dcache_range_asm)
>
> ENTRY_CFI(flush_kernel_dcache_range_asm)
> 88: ldil L%dcache_stride, %r1
> + ALTERNATIVE(88b, 88b+4, ALT_COND_NO_DCACHE, INSN_RETURN)
> ldw R%dcache_stride(%r1), %r23
> ldo -1(%r23), %r21
> ANDCM %r26, %r21, %r26
> @@ -1142,8 +1149,7 @@ ENTRY_CFI(flush_kernel_dcache_range_asm)
> 2: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */
> fdc,m %r23(%r26)
>
> - sync
> -89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
> + asm_sync
> syncdma
> bv %r0(%r2)
> nop
> @@ -1151,6 +1157,7 @@ ENDPROC_CFI(flush_kernel_dcache_range_asm)
>
> ENTRY_CFI(purge_kernel_dcache_range_asm)
> 88: ldil L%dcache_stride, %r1
> + ALTERNATIVE(88b, 88b+4, ALT_COND_NO_DCACHE, INSN_RETURN)
> ldw R%dcache_stride(%r1), %r23
> ldo -1(%r23), %r21
> ANDCM %r26, %r21, %r26
> @@ -1184,8 +1191,7 @@ ENTRY_CFI(purge_kernel_dcache_range_asm)
> 2: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */
> pdc,m %r23(%r26)
>
> - sync
> -89: ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
> + asm_sync
> syncdma
> bv %r0(%r2)
> nop
> @@ -1193,6 +1199,7 @@ ENDPROC_CFI(purge_kernel_dcache_range_asm)
>
> ENTRY_CFI(flush_user_icache_range_asm)
> 88: ldil L%icache_stride, %r1
> + ALTERNATIVE(88b, 88b+4, ALT_COND_NO_ICACHE, INSN_RETURN)
> ldw R%icache_stride(%r1), %r23
> ldo -1(%r23), %r21
> ANDCM %r26, %r21, %r26
> @@ -1226,14 +1233,14 @@ ENTRY_CFI(flush_user_icache_range_asm)
> 2: cmpb,COND(>>),n %r25, %r26, 2b
> fic,m %r23(%sr3, %r26)
>
> -89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
> - sync
> + asm_sync
> bv %r0(%r2)
> nop
> ENDPROC_CFI(flush_user_icache_range_asm)
>
> ENTRY_CFI(flush_kernel_icache_page)
> 88: ldil L%icache_stride, %r1
> + ALTERNATIVE(88b, 88b+4, ALT_COND_NO_ICACHE, INSN_RETURN)
> ldw R%icache_stride(%r1), %r23
>
> #ifdef CONFIG_64BIT
> @@ -1263,14 +1270,14 @@ ENTRY_CFI(flush_kernel_icache_page)
> cmpb,COND(>>) %r25, %r26, 1b /* predict taken */
> fic,m %r23(%sr4, %r26)
>
> -89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
> - sync
> + asm_sync
> bv %r0(%r2)
> nop
> ENDPROC_CFI(flush_kernel_icache_page)
>
> ENTRY_CFI(flush_kernel_icache_range_asm)
> 88: ldil L%icache_stride, %r1
> + ALTERNATIVE(88b, 88b+4, ALT_COND_NO_ICACHE, INSN_RETURN)
> ldw R%icache_stride(%r1), %r23
> ldo -1(%r23), %r21
> ANDCM %r26, %r21, %r26
> @@ -1304,8 +1311,7 @@ ENTRY_CFI(flush_kernel_icache_range_asm)
> 2: cmpb,COND(>>),n %r25, %r26, 2b /* predict taken */
> fic,m %r23(%sr4, %r26)
>
> -89: ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
> - sync
> + asm_sync
> bv %r0(%r2)
> nop
> ENDPROC_CFI(flush_kernel_icache_range_asm)
>
--
John David Anglin dave.anglin@bell.net
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2018-11-11 15:31 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-11-09 21:39 [PATCH] parisc: Optimize sync instruction and D/I-cache flushes on UP kernel Helge Deller
2018-11-11 15:31 ` John David Anglin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).