riscv: jump_label: Optimize the code size with compressed instruction
Subsystems (3)
PATCH v4 1/1 riscv: jump_label: Optimize the code size with compressed instruction
From: Guo Ren <[email protected]>
Reduce the size of the static branch instruction and prevent atomic update problems when CONFIG_RISCV_ISA_C=y. It also reduces the jump range from 1MB to 4KB, but 4KB is enough for the current riscv requirement.
Signed-off-by Guo Ren <[email protected]>
Signed-off-by Guo Ren <[email protected]>
---
Changelog
v4:
- Rebase on palmer/for-next (20230324)
- Separate from "riscv: jump_label: Fixup & Optimization"
v3:
https://lore.kernel.org/linux-riscv/[email protected]/
v2:
https://lore.kernel.org/linux-riscv/[email protected]/
v1:
https://lore.kernel.org/linux-riscv/[email protected]/
--- arch/riscv/include/asm/jump_label.h | 16 +++++++++++---- arch/riscv/kernel/jump_label.c | 30 +++++++++++++++++++++++++++-- 2 files changed, 40 insertions(+), 6 deletions(-)
arch/riscv/include/asm/jump_label.h +12 -4
@@ -12,17 +12,23 @@#include <linux/types.h> #include <asm/asm.h> +#ifdef CONFIG_RISCV_ISA_C +#define JUMP_LABEL_NOP_SIZE 2 +#else #define JUMP_LABEL_NOP_SIZE 4 +#endif static __always_inline bool arch_static_branch(struct static_key * const key,const bool branch) {asm_volatile_goto ( -" .align 2 \n\t" " .option push \n\t" " .option norelax \n\t" -" .option norvc \n\t" +#ifdef CONFIG_RISCV_ISA_C + "1: c.nop \n\t" +#else"1: nop \n\t" +#endif" .option pop \n\t" " .pushsection __jump_table, \"aw\" \n\t" " .align " RISCV_LGPTR " \n\t"
@@ -40,11 +46,13 @@ static __always_inline bool arch_static_branch_jump(struct static_key * const ke const bool branch) {asm_volatile_goto ( -" .align 2 \n\t" " .option push \n\t" " .option norelax \n\t" -" .option norvc \n\t" +#ifdef CONFIG_RISCV_ISA_C + "1: c.j %l[label] \n\t" +#else"1: jal zero, %l[label] \n\t" +#endif" .option pop \n\t" " .pushsection __jump_table, \"aw\" \n\t" " .align " RISCV_LGPTR " \n\t"
arch/riscv/kernel/jump_label.c +28 -2
@@ -11,26 +11,52 @@#include <asm/bug.h> #include <asm/patch.h> +#ifdef CONFIG_RISCV_ISA_C +#define RISCV_INSN_NOP 0x0001U +#define RISCV_INSN_C_J 0xa001U +#else #define RISCV_INSN_NOP 0x00000013U#define RISCV_INSN_JAL 0x0000006fU +#endif void arch_jump_label_transform (struct jump_entry *entry,enum jump_label_type type) {void *addr = (void *)jump_entry_code (entry); +#ifdef CONFIG_RISCV_ISA_C +u16 insn; +#else u32 insn; +#endif if (type ==JUMP_LABEL_JMP ) {long offset =jump_entry_target (entry) -jump_entry_code (entry); - -if (WARN_ON (offset &1 || offset <-524288 || offset >=524288 )) +if (WARN_ON (offset &1 || offset <-2048 || offset >=2048 ))return ; +#ifdef CONFIG_RISCV_ISA_C +/* +* 001 | imm[11|4|9:8|10|6|7|3:1|5] 01 - C.J +*/ + insn =RISCV_INSN_C_J | + (((u16 )offset &GENMASK (5 ,5 )) >> (5 -2 )) | + (((u16 )offset &GENMASK (3 ,1 )) << (3 -1 )) | + (((u16 )offset &GENMASK (7 ,7 )) >> (7 -6 )) | + (((u16 )offset &GENMASK (6 ,6 )) << (7 -6 )) | + (((u16 )offset &GENMASK (10 ,10 )) >> (10 -8 )) | + (((u16 )offset &GENMASK (9 ,8 )) << (9 -8 )) | + (((u16 )offset &GENMASK (4 ,4 )) << (11 -4 )) | + (((u16 )offset &GENMASK (11 ,11 )) << (12 -11 )); +#else +/* +* imm[20|10:1|11|19:12] | rd | 1101111 - JAL +*/ insn =RISCV_INSN_JAL | (((u32 )offset &GENMASK (19 ,12 )) << (12 -12 )) | (((u32 )offset &GENMASK (11 ,11 )) << (20 -11 )) | (((u32 )offset &GENMASK (10 ,1 )) << (21 -1 )) | (((u32 )offset &GENMASK (20 ,20 )) << (31 -20 )); +#endif }else { insn =RISCV_INSN_NOP ; }
Signature · 1 line
2.36.1