gentoo-overlay/sys-kernel/hardened-kernel/files/linux-5.4/9109_0109-raid6-add-Kconfig...

157 lines
4.3 KiB
Diff

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jim Kukunas <james.t.kukunas@linux.intel.com>
Date: Fri, 27 May 2016 09:26:51 -0400
Subject: [PATCH] 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>
---
lib/Kconfig | 3 +--
lib/raid6/Kconfig | 38 +++++++++++++++++++++++++++++++
lib/raid6/algos.c | 58 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 97 insertions(+), 2 deletions(-)
create mode 100644 lib/raid6/Kconfig
diff --git a/lib/Kconfig b/lib/Kconfig
index 3321d04dfa5a..e4343fa05964 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -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"
diff --git a/lib/raid6/Kconfig b/lib/raid6/Kconfig
new file mode 100644
index 000000000000..d881d6be89bb
--- /dev/null
+++ b/lib/raid6/Kconfig
@@ -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
diff --git a/lib/raid6/algos.c b/lib/raid6/algos.c
index 17417eee0866..8af3d7c737c1 100644
--- a/lib/raid6/algos.c
+++ b/lib/raid6/algos.c
@@ -124,6 +124,63 @@ const struct raid6_recov_calls *const raid6_recov_algos[] = {
#define time_before(x, y) ((x) < (y))
#endif
+#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;
@@ -260,6 +317,7 @@ int __init raid6_select_algo(void)
return gen_best && rec_best ? 0 : -EINVAL;
}
+#endif
static void raid6_exit(void)
{
--
https://clearlinux.org