Message ID | 20181109213900.GA12384@ls3530.dellerweb.de (mailing list archive) |
---|---|
State | Rejected |
Headers | show |
Series | parisc: Optimize sync instruction and D/I-cache flushes on UP kernel | expand |
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) >
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)
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>