blob: e4e4fccd4018cb3e71c0a4298d8dcf63704a7c21 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
|
This patch is an adaptation of a clearlinux patch by Jim Kukunas
You can find the original at https://github.com/clearlinux-pkgs/linux/blob/master/0109-raid6-add-Kconfig-option-to-skip-raid6-benchmarking.patch
diff --git a/lib/Kconfig b/lib/Kconfig
index 3321d04df..e4343fa05 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 000000000..a2e91531a
--- /dev/null
+++ b/lib/raid6/Kconfig
@@ -0,0 +1,18 @@
+menu "RAID6"
+
+config RAID6_PQ
+ tristate
+
+config RAID6_FORCE_NEON
+ bool "Always use NEON RAID6 recovery Algorithm"
+ default n
+ depends on ARM64
+ 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.
+
+endmenu
diff --git a/lib/raid6/algos.c b/lib/raid6/algos.c
index 17417eee0..8fc6b3672 100644
--- a/lib/raid6/algos.c
+++ b/lib/raid6/algos.c
@@ -124,6 +124,33 @@ const struct raid6_recov_calls *const raid6_recov_algos[] = {
#define time_before(x, y) ((x) < (y))
#endif
+#ifdef CONFIG_RAID6_FORCE_NEON
+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;
+
+ gen_fallback = &raid6_neonx8;
+ recov_algo = &raid6_recov_neon;
+ gen_algo = &raid6_neonx8;
+
+ 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 +287,7 @@ int __init raid6_select_algo(void)
return gen_best && rec_best ? 0 : -EINVAL;
}
+#endif
static void raid6_exit(void)
{
|