diff options
| author | chenmiao <chenmiao.ku@gmail.com> | 2025-09-05 18:12:58 +0000 |
|---|---|---|
| committer | Stafford Horne <shorne@gmail.com> | 2025-09-11 11:27:59 +0100 |
| commit | 8c30b0018f9d93391573e091960d257fd9de120a (patch) | |
| tree | 4640531e83b421b427d1e99db65d768da91078e1 /arch/openrisc/include | |
| parent | openrisc: Regenerate defconfigs. (diff) | |
| download | linux-8c30b0018f9d93391573e091960d257fd9de120a.tar.gz linux-8c30b0018f9d93391573e091960d257fd9de120a.zip | |
openrisc: Add jump label support
Supported a complete jump_label implementation based on the ARM64 and
RV64 version and add the CONFIG_JUMP_LABEL=y to the defconfig.
Testing was conducted using a dedicated test module jump-label-test,
provided in the link below. For detailed steps, please refer to the
README also at the provided link.
Link: https://github.com/ChenMiaoi/GSoC-2025-Final-Report/tree/main/tests/jump-label-test
Test Environment:
- Hardware: QEMU emulated OR1K
- Kernel Version: 6.17.0-rc3-dirty
- Configs: CONFIG_MODULES=y,CONFIG_MODULE_UNLOAD=y
- Toolchain: or1k-none-linux-musl-gcc 15.1.0
Test Results:
$ insmod jump_label_test.ko
[ 32.590000] Jump label performance test module loaded
[ 35.250000] Normal branch time: 1241327150 ns (124 ns per iteration)
[ 35.250000] Jump label (false) time: 706422700 ns (70 ns per iteration)
[ 35.250000] Jump label (true) time: 708913450 ns (70 ns per iteration)
$ rmmod jump_label_test.ko
[ 72.210000] Jump label test module unloaded
The results show approximately 43% improvement in branch performance
when using jump labels compared to traditional branches.
Link: https://lore.kernel.org/openrisc/aLsZ9S3X0OpKy1RM@antec/T/#u
Signed-off-by: chenmiao <chenmiao.ku@gmail.com>
Signed-off-by: Stafford Horne <shorne@gmail.com>
Diffstat (limited to 'arch/openrisc/include')
| -rw-r--r-- | arch/openrisc/include/asm/insn-def.h | 3 | ||||
| -rw-r--r-- | arch/openrisc/include/asm/jump_label.h | 72 |
2 files changed, 75 insertions, 0 deletions
diff --git a/arch/openrisc/include/asm/insn-def.h b/arch/openrisc/include/asm/insn-def.h index e28a9a9604fc..1e0c028a5b95 100644 --- a/arch/openrisc/include/asm/insn-def.h +++ b/arch/openrisc/include/asm/insn-def.h @@ -9,4 +9,7 @@ /* or1k instructions are always 32 bits. */ #define OPENRISC_INSN_SIZE 4 +/* or1k nop instruction code */ +#define OPENRISC_INSN_NOP 0x15000000U + #endif /* __ASM_OPENRISC_INSN_DEF_H */ diff --git a/arch/openrisc/include/asm/jump_label.h b/arch/openrisc/include/asm/jump_label.h new file mode 100644 index 000000000000..3ec0f4e19f9c --- /dev/null +++ b/arch/openrisc/include/asm/jump_label.h @@ -0,0 +1,72 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2025 Chen Miao + * + * Based on arch/arm/include/asm/jump_label.h + */ +#ifndef __ASM_OPENRISC_JUMP_LABEL_H +#define __ASM_OPENRISC_JUMP_LABEL_H + +#ifndef __ASSEMBLER__ + +#include <linux/types.h> +#include <asm/insn-def.h> + +#define HAVE_JUMP_LABEL_BATCH + +#define JUMP_LABEL_NOP_SIZE OPENRISC_INSN_SIZE + +/** + * JUMP_TABLE_ENTRY - Create a jump table entry + * @key: Jump key identifier (typically a symbol address) + * @label: Target label address + * + * This macro creates a jump table entry in the dedicated kernel section (__jump_table). + * Each entry contains the following information: + * Offset from current instruction to jump instruction (1b - .) + * Offset from current instruction to target label (label - .) + * Offset from current instruction to key identifier (key - .) + */ +#define JUMP_TABLE_ENTRY(key, label) \ + ".pushsection __jump_table, \"aw\" \n\t" \ + ".align 4 \n\t" \ + ".long 1b - ., " label " - . \n\t" \ + ".long " key " - . \n\t" \ + ".popsection \n\t" + +#define ARCH_STATIC_BRANCH_ASM(key, label) \ + ".align 4 \n\t" \ + "1: l.nop \n\t" \ + " l.nop \n\t" \ + JUMP_TABLE_ENTRY(key, label) + +static __always_inline bool arch_static_branch(struct static_key *const key, + const bool branch) +{ + asm goto (ARCH_STATIC_BRANCH_ASM("%0", "%l[l_yes]") + ::"i"(&((char *)key)[branch])::l_yes); + + return false; +l_yes: + return true; +} + +#define ARCH_STATIC_BRANCH_JUMP_ASM(key, label) \ + ".align 4 \n\t" \ + "1: l.j " label " \n\t" \ + " l.nop \n\t" \ + JUMP_TABLE_ENTRY(key, label) + +static __always_inline bool +arch_static_branch_jump(struct static_key *const key, const bool branch) +{ + asm goto (ARCH_STATIC_BRANCH_JUMP_ASM("%0", "%l[l_yes]") + ::"i"(&((char *)key)[branch])::l_yes); + + return false; +l_yes: + return true; +} + +#endif /* __ASSEMBLER__ */ +#endif /* __ASM_OPENRISC_JUMP_LABEL_H */ |
