Skip to content
Permalink
Browse files
raid6: add Kconfig option to skip raid6 benchmarking
Adds CONFIG_RAID6_FORCE_ALGO, which causes the kernel to not benchmark
each raid recovery and syndrome generation algorithm, and instead use
the version selected via Kconfig (CONFIG_RAID6_FORCE_{INT,SSSE3,AVX2}).
In the case, the selected algorithm is not supported by the processor at
runtime, a fallback is used.

Signed-off-by: Jim Kukunas <james.t.kukunas@linux.intel.com>
  • Loading branch information
jtkukunas authored and heftig committed Feb 15, 2021
1 parent e8530db commit 8bca7b9c84942da91c8dbf901dbafac503567545
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 2 deletions.
@@ -8,8 +8,7 @@ config BINARY_PRINTF

menu "Library routines"

config RAID6_PQ
tristate
source "lib/raid6/Kconfig"

config RAID6_PQ_BENCHMARK
bool "Automatically choose fastest RAID6 PQ functions"
@@ -0,0 +1,38 @@
menu "RAID 6"

config RAID6_PQ
tristate

config RAID6_FORCE_ALGO
bool "Always use specified recovery algorithm"
default n
depends on RAID6_PQ
help
If this option is not set, on every boot the kernel will
benchmark each optimized version of the RAID6 recovery and
syndrome generation algorithms and will select the one that
performs best. Microbenchmarking each version negatively
affects boot time.

Enabling this option skips the benchmark at boot, and
instead always uses the algorithm selected. The only exception
is if the selected algorithm relies on a cpu feature not
supported at runtime. In this case, one of the lower performance
fallbacks are used.

choice
prompt "RAID6 Recovery Algorithm"
default RAID6_FORCE_INT
depends on RAID6_FORCE_ALGO
help
Select the RAID6 recovery algorithm to unconditionally use

config RAID6_FORCE_INT
bool "Reference Implementation"
config RAID6_FORCE_SSSE3
bool "SSSE3"
config RAID6_FORCE_AVX2
bool "AVX2"
endchoice

endmenu
@@ -121,6 +121,63 @@ const struct raid6_recov_calls *const raid6_recov_algos[] = {
#define RAID6_TEST_DISKS 8
#define RAID6_TEST_DISKS_ORDER 3

#ifdef CONFIG_RAID6_FORCE_ALGO
/* TODO don't compile in algos that will never be used */
int __init raid6_select_algo(void)
{
const struct raid6_recov_calls *recov_fallback = &raid6_recov_intx1;
const struct raid6_recov_calls *recov_algo;
const struct raid6_calls *gen_fallback;
const struct raid6_calls *gen_algo;

#if defined(__i386__)
gen_fallback = &raid6_intx32;
#elif defined(__x86_64__)
gen_fallback = &raid6_sse2x2;
#else
# error "TODO"
#endif

#if defined(CONFIG_RAID6_FORCE_INT)
recov_algo = &raid6_recov_intx1;
gen_algo = &raid6_intx32;

#elif defined(CONFIG_RAID6_FORCE_SSSE3)
recov_algo = &raid6_recov_ssse3;
#if defined(__i386__)
gen_algo = &raid6_sse2x2;
#else
gen_algo = &raid6_sse2x4;
#endif

#elif defined(CONFIG_RAID6_FORCE_AVX2)
recov_algo = &raid6_recov_avx2;

#if defined(__i386__)
gen_algo = &raid6_avx2x2;
#else
gen_algo = &raid6_avx2x4;
#endif

#else
#error "RAID6 Forced Recov Algo: Unsupported selection"
#endif

if (recov_algo->valid != NULL && recov_algo->valid() == 0)
recov_algo = recov_fallback;

pr_info("raid6: Forced to use recovery algorithm %s\n", recov_algo->name);

raid6_2data_recov = recov_algo->data2;
raid6_datap_recov = recov_algo->datap;

pr_info("raid6: Forced gen() algo %s\n", gen_algo->name);

raid6_call = *gen_algo;

return gen_algo && recov_algo ? 0 : -EINVAL;
}
#else
static inline const struct raid6_recov_calls *raid6_choose_recov(void)
{
const struct raid6_recov_calls *const *algo;
@@ -271,6 +328,7 @@ int __init raid6_select_algo(void)

return gen_best && rec_best ? 0 : -EINVAL;
}
#endif

static void raid6_exit(void)
{

0 comments on commit 8bca7b9

Please sign in to comment.