[PATCH 25/25] xor: use static_call for xor_gen
Christoph Hellwig <[email protected]>
| Newsgroups | gmane.linux.uml.devel,gmane.linux.ports.alpha,gmane.linux.kernel,gmane.linux.ports.arm.kernel,gmane.linux.ports.ppc64.devel,gmane.linux.ports.riscv,gmane.linux.ports.sparc,gmane.linux.kernel.cryptoapi,gmane.comp.file-systems.btrfs,gmane.linux.kernel.cross-arch,gmane.linux.raid |
|---|---|
| Message-ID | <[email protected]> |
Avoid the indirect call for xor_generation by using a static_call. Signed-off-by: Christoph Hellwig <[email protected]> --- lib/raid/xor/xor-32regs.c | 2 +- lib/raid/xor/xor-core.c | 29 ++++++++++++++--------------- lib/raid/xor/xor_impl.h | 4 ++++ 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/lib/raid/xor/xor-32regs.c b/lib/raid/xor/xor-32regs.c index acb4a10d1e95..759a31f76414 100644 --- a/lib/raid/xor/xor-32regs.c +++ b/lib/raid/xor/xor-32regs.c @@ -209,7 +209,7 @@ xor_32regs_5(unsigned long bytes, unsigned long * __restrict p1, } while (--lines > 0); } -DO_XOR_BLOCKS(32regs, xor_32regs_2, xor_32regs_3, xor_32regs_4, xor_32regs_5); +__DO_XOR_BLOCKS(32regs, xor_32regs_2, xor_32regs_3, xor_32regs_4, xor_32regs_5); struct xor_block_template xor_block_32regs = { .name = "32regs", diff --git a/lib/raid/xor/xor-core.c b/lib/raid/xor/xor-core.c index f18dcc57004b..2ab03dd294bf 100644 --- a/lib/raid/xor/xor-core.c +++ b/lib/raid/xor/xor-core.c @@ -11,10 +11,14 @@ #include <linux/raid/xor.h> #include <linux/jiffies.h> #include <linux/preempt.h> +#include <linux/static_call.h> #include "xor_impl.h" -/* The xor routine to use. */ -static struct xor_block_template *active_template; +/* + * Provide a temporary default until the fastest or forced implementation is + * picked. + */ +DEFINE_STATIC_CALL(xor_gen_impl, xor_gen_32regs); /** * xor_gen - generate RAID-style XOR information @@ -32,13 +36,13 @@ static struct xor_block_template *active_template; void xor_gen(void *dest, void **srcs, unsigned int src_cnt, unsigned int bytes) { WARN_ON_ONCE(in_interrupt()); - active_template->xor_gen(dest, srcs, src_cnt, bytes); + static_call(xor_gen_impl)(dest, srcs, src_cnt, bytes); } EXPORT_SYMBOL(xor_gen); /* Set of all registered templates. */ static struct xor_block_template *__initdata template_list; -static int __initdata xor_forced = false; +static struct xor_block_template *forced_template; /** * xor_register - register a XOR template @@ -64,7 +68,7 @@ void __init xor_register(struct xor_block_template *tmpl) */ void __init xor_force(struct xor_block_template *tmpl) { - active_template = tmpl; + forced_template = tmpl; } #define BENCH_SIZE 4096 @@ -106,7 +110,7 @@ static int __init calibrate_xor_blocks(void) void *b1, *b2; struct xor_block_template *f, *fastest; - if (xor_forced) + if (forced_template) return 0; b1 = (void *) __get_free_pages(GFP_KERNEL, 2); @@ -123,7 +127,7 @@ static int __init calibrate_xor_blocks(void) if (f->speed > fastest->speed) fastest = f; } - active_template = fastest; + static_call_update(xor_gen_impl, fastest->xor_gen); pr_info("xor: using function: %s (%d MB/sec)\n", fastest->name, fastest->speed); @@ -151,21 +155,16 @@ static int __init xor_init(void) * If this arch/cpu has a short-circuited selection, don't loop through * all the possible functions, just use the best one. */ - if (active_template) { + if (forced_template) { pr_info("xor: automatically using best checksumming function %-10s\n", - active_template->name); - xor_forced = true; + forced_template->name); + static_call_update(xor_gen_impl, forced_template->xor_gen); return 0; } #ifdef MODULE return calibrate_xor_blocks(); #else - /* - * Pick the first template as the temporary default until calibration - * happens. - */ - active_template = template_list; return 0; #endif } diff --git a/lib/raid/xor/xor_impl.h b/lib/raid/xor/xor_impl.h index 968dd07df627..f11910162b08 100644 --- a/lib/raid/xor/xor_impl.h +++ b/lib/raid/xor/xor_impl.h @@ -50,6 +50,10 @@ extern struct xor_block_template xor_block_32regs; extern struct xor_block_template xor_block_8regs_p; extern struct xor_block_template xor_block_32regs_p; +/* default call until updated */ +void xor_gen_32regs(void *dest, void **srcs, unsigned int src_cnt, + unsigned int bytes); + void __init xor_register(struct xor_block_template *tmpl); void __init xor_force(struct xor_block_template *tmpl); -- 2.47.3