| From: Kuan-Wei Chiu <visitorckw@gmail.com> |
| Subject: riscv: optimize gcd() performance on RISC-V without Zbb extension |
| Date: Fri, 6 Jun 2025 21:47:58 +0800 |
| |
| The binary GCD implementation uses FFS (find first set), which benefits |
| from hardware support for the ctz instruction, provided by the Zbb |
| extension on RISC-V. Without Zbb, this results in slower |
| software-emulated behavior. |
| |
| Previously, RISC-V always used the binary GCD, regardless of actual |
| hardware support. This patch improves runtime efficiency by disabling the |
| efficient_ffs_key static branch when Zbb is either not enabled in the |
| kernel (config) or not supported on the executing CPU. This selects the |
| odd-even GCD implementation, which is faster in the absence of efficient |
| FFS. |
| |
| This change ensures the most suitable GCD algorithm is chosen dynamically |
| based on actual hardware capabilities. |
| |
| Link: https://lkml.kernel.org/r/20250606134758.1308400-4-visitorckw@gmail.com |
| Co-developed-by: Yu-Chun Lin <eleanor15x@gmail.com> |
| Signed-off-by: Yu-Chun Lin <eleanor15x@gmail.com> |
| Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com> |
| Acked-by: Alexandre Ghiti <alexghiti@rivosinc.com> |
| Cc: Albert Ou <aou@eecs.berkeley.edu> |
| Cc: Ching-Chun (Jim) Huang <jserv@ccns.ncku.edu.tw> |
| Cc: Palmer Dabbelt <palmer@dabbelt.com> |
| Cc: Paul Walmsley <paul.walmsley@sifive.com> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| --- |
| |
| arch/riscv/kernel/setup.c | 5 +++++ |
| 1 file changed, 5 insertions(+) |
| |
| --- a/arch/riscv/kernel/setup.c~riscv-optimize-gcd-performance-on-risc-v-without-zbb-extension |
| +++ a/arch/riscv/kernel/setup.c |
| @@ -21,6 +21,8 @@ |
| #include <linux/efi.h> |
| #include <linux/crash_dump.h> |
| #include <linux/panic_notifier.h> |
| +#include <linux/jump_label.h> |
| +#include <linux/gcd.h> |
| |
| #include <asm/acpi.h> |
| #include <asm/alternative.h> |
| @@ -362,6 +364,9 @@ void __init setup_arch(char **cmdline_p) |
| |
| riscv_user_isa_enable(); |
| riscv_spinlock_init(); |
| + |
| + if (!IS_ENABLED(CONFIG_RISCV_ISA_ZBB) || !riscv_isa_extension_available(NULL, ZBB)) |
| + static_branch_disable(&efficient_ffs_key); |
| } |
| |
| bool arch_cpu_is_hotpluggable(int cpu) |
| _ |