[PATCH] parisc: Reduce kernel size by packing alternative tables - variant 2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is the second variant to reduce the size of the alternative tables.
Basically it halves the size by reducing length, condition and replacement
fields.

bloat-o-meter shows a reduction of -0.01% by this change:
Total: Before=10254498, After=10253654, chg -0.01%

Since this patch introduces more changes without benefit, I won't
apply it for now, but want it to show up in patchwork.

Signed-off-by: Helge Deller <deller@xxxxxx>

diff --git a/arch/parisc/include/asm/alternative.h b/arch/parisc/include/asm/alternative.h
index 0ec54f43d6d2..1705abd97f5f 100644
--- a/arch/parisc/include/asm/alternative.h
+++ b/arch/parisc/include/asm/alternative.h
@@ -10,7 +10,9 @@
 #define ALT_COND_NO_IOC_FDC	0x10	/* if I/O cache does not need flushes */
 #define ALT_COND_RUN_ON_QEMU	0x20	/* if running on QEMU */

-#define INSN_PxTLB	0x02		/* modify pdtlb, pitlb */
+#define ALTCODE_PxTLB	0x01		/* add local flag to pdtlb & pitlb */
+#define ALTCODE_NOP	0x02		/* insert nops */
+
 #define INSN_NOP	0x08000240	/* nop */

 #ifndef __ASSEMBLY__
@@ -22,10 +24,10 @@

 struct alt_instr {
 	s32 orig_offset;	/* offset to original instructions */
-	s32 len;		/* end of original instructions */
-	u32 cond;		/* see ALT_COND_XXX */
-	u32 replacement;	/* replacement instruction or code */
-};
+	u16 len;		/* number of instructions */
+	u8 cond;		/* see ALT_COND_XXX condition */
+	u8 replacement;		/* see ALTCODE_XXX replacement instruction */
+} __packed;

 void set_kernel_text_rw(int enable_read_write);
 void apply_alternatives_all(void);
@@ -34,9 +36,11 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end,

 /* Alternative SMP implementation. */
 #define ALTERNATIVE(cond, replacement)		"!0:"	\
-	".section .altinstructions, \"aw\"	!"	\
-	".word (0b-4-.), 1, " __stringify(cond) ","	\
-		__stringify(replacement) "	!"	\
+	".section .altinstructions, \"aw\"	 !"	\
+	".word (0b-4) - .			 !"	\
+	".hword 1				 !"	\
+	".byte " __stringify(cond)		"!"	\
+	".byte " __stringify(replacement)	"!"	\
 	".previous"

 #else
@@ -44,15 +48,9 @@ void apply_alternatives(struct alt_instr *start, struct alt_instr *end,
 /* to replace one single instructions by a new instruction */
 #define ALTERNATIVE(from, to, cond, replacement)\
 	.section .altinstructions, "aw"	!	\
-	.word (from - .), (to - from)/4	!	\
-	.word cond, replacement		!	\
-	.previous
-
-/* to replace multiple instructions by new code */
-#define ALTERNATIVE_CODE(from, num_instructions, cond, new_instr_ptr)\
-	.section .altinstructions, "aw"	!	\
-	.word (from - .), -num_instructions !	\
-	.word cond, (new_instr_ptr - .)	!	\
+	.word from - .			!	\
+	.hword (to - from)/4		!	\
+	.byte cond, replacement		!	\
 	.previous

 #endif  /*  __ASSEMBLY__  */
diff --git a/arch/parisc/include/asm/barrier.h b/arch/parisc/include/asm/barrier.h
index c705decf2bed..f99bb8feff78 100644
--- a/arch/parisc/include/asm/barrier.h
+++ b/arch/parisc/include/asm/barrier.h
@@ -9,7 +9,7 @@
 /* The synchronize caches instruction executes as a nop on systems in
    which all memory references are performed in order. */
 #define synchronize_caches() asm volatile("sync" \
-	ALTERNATIVE(ALT_COND_NO_SMP, INSN_NOP) \
+	ALTERNATIVE(ALT_COND_NO_SMP, ALTCODE_NOP) \
 	: : : "memory")

 #if defined(CONFIG_SMP)
diff --git a/arch/parisc/include/asm/cache.h b/arch/parisc/include/asm/cache.h
index e23d06b51a20..41fa03e7efa1 100644
--- a/arch/parisc/include/asm/cache.h
+++ b/arch/parisc/include/asm/cache.h
@@ -40,20 +40,20 @@ extern struct pdc_cache_info cache_info;
 void parisc_setup_cache_timing(void);

 #define pdtlb(sr, addr)	asm volatile("pdtlb 0(%%sr%0,%1)" \
-			ALTERNATIVE(ALT_COND_NO_SMP, INSN_PxTLB) \
+			ALTERNATIVE(ALT_COND_NO_SMP, ALTCODE_PxTLB) \
 			: : "i"(sr), "r" (addr) : "memory")
 #define pitlb(sr, addr)	asm volatile("pitlb 0(%%sr%0,%1)" \
-			ALTERNATIVE(ALT_COND_NO_SMP, INSN_PxTLB) \
-			ALTERNATIVE(ALT_COND_NO_SPLIT_TLB, INSN_NOP) \
+			ALTERNATIVE(ALT_COND_NO_SMP, ALTCODE_PxTLB) \
+			ALTERNATIVE(ALT_COND_NO_SPLIT_TLB, ALTCODE_NOP) \
 			: : "i"(sr), "r" (addr) : "memory")

 #define asm_io_fdc(addr) asm volatile("fdc %%r0(%0)" \
-			ALTERNATIVE(ALT_COND_NO_DCACHE, INSN_NOP) \
-			ALTERNATIVE(ALT_COND_NO_IOC_FDC, INSN_NOP) \
+			ALTERNATIVE(ALT_COND_NO_DCACHE, ALTCODE_NOP) \
+			ALTERNATIVE(ALT_COND_NO_IOC_FDC, ALTCODE_NOP) \
 			: : "r" (addr) : "memory")
 #define asm_io_sync()	asm volatile("sync" \
-			ALTERNATIVE(ALT_COND_NO_DCACHE, INSN_NOP) \
-			ALTERNATIVE(ALT_COND_NO_IOC_FDC, INSN_NOP) :::"memory")
+			ALTERNATIVE(ALT_COND_NO_DCACHE, ALTCODE_NOP) \
+			ALTERNATIVE(ALT_COND_NO_IOC_FDC, ALTCODE_NOP) :::"memory")
 #define asm_syncdma()	asm volatile("syncdma" :::"memory")

 #endif /* ! __ASSEMBLY__ */
diff --git a/arch/parisc/kernel/alternative.c b/arch/parisc/kernel/alternative.c
index daa1e9047275..0c455ae13150 100644
--- a/arch/parisc/kernel/alternative.c
+++ b/arch/parisc/kernel/alternative.c
@@ -26,7 +26,7 @@ void __init_or_module apply_alternatives(struct alt_instr *start,
 	struct alt_instr *entry;
 	int index = 0, applied = 0;
 	int num_cpus = num_online_cpus();
-	u32 cond_check;
+	u8 cond_check;

 	cond_check = ALT_COND_ALWAYS |
 		((num_cpus == 1) ? ALT_COND_NO_SMP : 0) |
@@ -45,15 +45,19 @@ void __init_or_module apply_alternatives(struct alt_instr *start,

 	for (entry = start; entry < end; entry++, index++) {

-		u32 *from, cond, replacement;
-		s32 len;
+		u32 *from, replacement;
+		u8 cond;
+		u16 len;

 		from = (u32 *)((ulong)&entry->orig_offset + entry->orig_offset);
 		len = entry->len;
 		cond = entry->cond;
 		replacement = entry->replacement;

-		WARN_ON(!cond);
+		if (WARN_ON(!cond || !len))
+			continue;
+		if (WARN_ON(replacement != ALTCODE_PxTLB && replacement != ALTCODE_NOP))
+			continue;

 		if ((cond & ALT_COND_ALWAYS) == 0 && no_alternatives)
 			continue;
@@ -66,7 +70,7 @@ void __init_or_module apply_alternatives(struct alt_instr *start,
 			continue;

 		/* Want to replace pdtlb by a pdtlb,l instruction? */
-		if (replacement == INSN_PxTLB) {
+		if (replacement == ALTCODE_PxTLB) {
 			replacement = *from;
 			if (boot_cpu_data.cpu_type >= pcxu) /* >= pa2.0 ? */
 				replacement |= (1 << 10); /* set el bit */
@@ -76,21 +80,20 @@ void __init_or_module apply_alternatives(struct alt_instr *start,
 		 * Replace instruction with NOPs?
 		 * For long distance insert a branch instruction instead.
 		 */
-		if (replacement == INSN_NOP && len > 1)
-			replacement = 0xe8000002 + (len-2)*8; /* "b,n .+8" */
+		if (replacement == ALTCODE_NOP) {
+			if (len > 1)
+				replacement = 0xe8000002 + (len-2)*8; /* "b,n .+8" */
+			else
+				replacement = INSN_NOP;
+			len = 1;
+		}

 		pr_debug("ALTERNATIVE %3d: Cond %2x, Replace %2d instructions to 0x%08x @ 0x%px (%pS)\n",
 			index, cond, len, replacement, from, from);

-		if (len < 0) {
-			/* Replace multiple instruction by new code */
-			u32 *source;
-			len = -len;
-			source = (u32 *)((ulong)&entry->replacement + entry->replacement);
-			memcpy(from, source, 4 * len);
-		} else {
+		while (len--) {
 			/* Replace by one instruction */
-			*from = replacement;
+			*from++ = replacement;
 		}
 		applied++;
 	}
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S
index df8102fb435f..32167b276c26 100644
--- a/arch/parisc/kernel/entry.S
+++ b/arch/parisc/kernel/entry.S
@@ -407,7 +407,7 @@
 	bb,<,n		\pte,_PAGE_PRESENT_BIT,3f
 	b		\fault
 	stw		\spc,0(\tmp)
-99:	ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
+99:	ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, ALTCODE_NOP)
 #endif
 2:	LDREG		0(\ptp),\pte
 	bb,>=,n		\pte,_PAGE_PRESENT_BIT,\fault
@@ -424,7 +424,7 @@
 #ifdef CONFIG_TLB_PTLOCK
 98:	or,COND(=)	%r0,\spc,%r0
 	stw,ma		\spc,0(\tmp)
-99:	ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
+99:	ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, ALTCODE_NOP)
 #endif
 	.endm

@@ -433,7 +433,7 @@
 #ifdef CONFIG_TLB_PTLOCK
 98:	get_ptl		\tmp
 	ptl_unlock0	\spc,\tmp
-99:	ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, INSN_NOP)
+99:	ALTERNATIVE(98b, 99b, ALT_COND_NO_SMP, ALTCODE_NOP)
 #endif
 	.endm

diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S
index 9a0018f1f42c..038d876b0a92 100644
--- a/arch/parisc/kernel/pacache.S
+++ b/arch/parisc/kernel/pacache.S
@@ -103,7 +103,7 @@ fitonemiddle:					/* Loop if LOOP = 1 */
 	add		%r21, %r20, %r20		/* increment space */

 fitdone:
-	ALTERNATIVE(88b, fitdone, ALT_COND_NO_SPLIT_TLB, INSN_NOP)
+	ALTERNATIVE(88b, fitdone, ALT_COND_NO_SPLIT_TLB, ALTCODE_NOP)

 	/* Flush Data Tlb */

@@ -172,17 +172,16 @@ fdtdone:
 	rfi
 	nop

-2:      bv		%r0(%r2)
-	nop
+	bv,n		%r0(%r2)

 	/*
 	 * When running in qemu, drop whole flush_tlb_all_local function and
 	 * replace by one pdtlbe instruction, for which QEMU will drop all
 	 * local TLB entries.
 	 */
-3:	pdtlbe		%r0(%sr1,%r0)
-	bv,n		%r0(%r2)
-	ALTERNATIVE_CODE(flush_tlb_all_local, 2, ALT_COND_RUN_ON_QEMU, 3b)
+3:	ALTERNATIVE(flush_tlb_all_local, 3b, ALT_COND_RUN_ON_QEMU, ALTCODE_NOP)
+	bv		%r0(%r2)
+	pdtlbe		%r0(%sr1,%r0)
 ENDPROC_CFI(flush_tlb_all_local)

 	.import cache_info,data
@@ -241,7 +240,7 @@ fioneloop2:
 fisync:
 	sync
 	mtsm		%r22			/* restore I-bit */
-89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
+89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, ALTCODE_NOP)
 	bv		%r0(%r2)
 	nop
 ENDPROC_CFI(flush_instruction_cache_local)
@@ -302,7 +301,7 @@ fdoneloop2:
 fdsync:
 	sync
 	mtsm		%r22			/* restore I-bit */
-89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
+89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, ALTCODE_NOP)
 	bv		%r0(%r2)
 	nop
 ENDPROC_CFI(flush_data_cache_local)
@@ -545,8 +544,8 @@ ENTRY_CFI(copy_user_page_asm)
 #else
 0:	pdtlb		%r0(%r28)
 1:	pdtlb		%r0(%r29)
-	ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
-	ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, INSN_PxTLB)
+	ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, ALTCODE_PxTLB)
+	ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, ALTCODE_PxTLB)
 #endif

 #ifdef CONFIG_64BIT
@@ -674,7 +673,7 @@ ENTRY_CFI(clear_user_page_asm)
 	pdtlb,l		%r0(%r28)
 #else
 0:	pdtlb		%r0(%r28)
-	ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
+	ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, ALTCODE_PxTLB)
 #endif

 #ifdef CONFIG_64BIT
@@ -740,7 +739,7 @@ ENTRY_CFI(flush_dcache_page_asm)
 	pdtlb,l		%r0(%r28)
 #else
 0:	pdtlb		%r0(%r28)
-	ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
+	ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, ALTCODE_PxTLB)
 #endif

 88:	ldil		L%dcache_stride, %r1
@@ -772,7 +771,7 @@ ENTRY_CFI(flush_dcache_page_asm)
 	cmpb,COND(>>)	%r25, %r28, 1b /* predict taken */
 	fdc,m		r31(%r28)

-89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
+89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, ALTCODE_NOP)
 	sync
 	bv		%r0(%r2)
 	nop
@@ -789,7 +788,7 @@ ENTRY_CFI(purge_dcache_page_asm)
 	pdtlb,l		%r0(%r28)
 #else
 0:	pdtlb		%r0(%r28)
-	ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
+	ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, ALTCODE_PxTLB)
 #endif

 88:	ldil		L%dcache_stride, %r1
@@ -821,7 +820,7 @@ ENTRY_CFI(purge_dcache_page_asm)
 	cmpb,COND(>>)	%r25, %r28, 1b /* predict taken */
 	pdc,m		r31(%r28)

-89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
+89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, ALTCODE_NOP)
 	sync
 	bv		%r0(%r2)
 	nop
@@ -840,13 +839,13 @@ ENTRY_CFI(flush_icache_page_asm)
 #ifdef CONFIG_PA20
 	pdtlb,l		%r0(%r28)
 1:	pitlb,l         %r0(%sr4,%r28)
-	ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, INSN_NOP)
+	ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, ALTCODE_NOP)
 #else
 0:	pdtlb		%r0(%r28)
 1:	pitlb           %r0(%sr4,%r28)
-	ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, INSN_PxTLB)
-	ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, INSN_PxTLB)
-	ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, INSN_NOP)
+	ALTERNATIVE(0b, 0b+4, ALT_COND_NO_SMP, ALTCODE_PxTLB)
+	ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SMP, ALTCODE_PxTLB)
+	ALTERNATIVE(1b, 1b+4, ALT_COND_NO_SPLIT_TLB, ALTCODE_NOP)
 #endif

 88:	ldil		L%icache_stride, %r1
@@ -880,7 +879,7 @@ ENTRY_CFI(flush_icache_page_asm)
 	cmpb,COND(>>)	%r25, %r28, 1b /* predict taken */
 	fic,m		%r31(%sr4,%r28)

-89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, INSN_NOP)
+89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, ALTCODE_NOP)
 	sync
 	bv		%r0(%r2)
 	nop
@@ -916,7 +915,7 @@ 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)
+89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, ALTCODE_NOP)
 	sync
 	bv		%r0(%r2)
 	nop
@@ -952,7 +951,7 @@ 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)
+89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, ALTCODE_NOP)
 	sync
 	bv		%r0(%r2)
 	nop
@@ -993,7 +992,7 @@ 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)
+89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, ALTCODE_NOP)
 	sync
 	bv		%r0(%r2)
 	nop
@@ -1035,7 +1034,7 @@ ENTRY_CFI(flush_kernel_dcache_range_asm)
 	fdc,m		%r23(%r26)

 	sync
-89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
+89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, ALTCODE_NOP)
 	bv		%r0(%r2)
 	nop
 ENDPROC_CFI(flush_kernel_dcache_range_asm)
@@ -1076,7 +1075,7 @@ ENTRY_CFI(purge_kernel_dcache_range_asm)
 	pdc,m		%r23(%r26)

 	sync
-89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, INSN_NOP)
+89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_DCACHE, ALTCODE_NOP)
 	bv		%r0(%r2)
 	nop
 ENDPROC_CFI(purge_kernel_dcache_range_asm)
@@ -1116,7 +1115,7 @@ 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)
+89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, ALTCODE_NOP)
 	sync
 	bv		%r0(%r2)
 	nop
@@ -1153,7 +1152,7 @@ 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)
+89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, ALTCODE_NOP)
 	sync
 	bv		%r0(%r2)
 	nop
@@ -1194,7 +1193,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)
+89:	ALTERNATIVE(88b, 89b, ALT_COND_NO_ICACHE, ALTCODE_NOP)
 	sync
 	bv		%r0(%r2)
 	nop




[Index of Archives]     [Linux SoC]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux