summaryrefslogtreecommitdiff
path: root/raid6-default-algo.patch
blob: 98bfd54a185659d890539d9dc71ac2dd79c1ef2e (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
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -10,6 +10,23 @@ menu "Library routines"
 config RAID6_PQ
 	tristate
 
+config RAID6_PQ_DEFAULT_ALG_BOOL
+	bool "Default RAID6 PQ algorithm"
+	default n
+	depends on RAID6_PQ
+	help
+	  Allow for specifying a default algorithm via the kernel
+	  parameter "raid6_pq_default_alg", which forces the performance
+	  tests to be skipped. This can save between 500ms to 2s
+	  during boot.
+
+config RAID6_PQ_DEFAULT_ALG
+	string "Default RAID6 PQ algorithm name"
+	default ""
+	depends on RAID6_PQ_DEFAULT_ALG_BOOL
+	help
+	  The default algorithm name to be used by default.
+
 config BITREVERSE
 	tristate
 
diff --git a/lib/raid6/algos.c b/lib/raid6/algos.c
index d3b16f43c39f..480cbfbe293f 100644
--- a/lib/raid6/algos.c
+++ b/lib/raid6/algos.c
@@ -30,6 +30,12 @@ EXPORT_SYMBOL(raid6_empty_zero_page);
 #endif
 #endif
 
+#ifdef CONFIG_RAID6_PQ_DEFAULT_ALG_BOOL
+static char raid6_pq_default_alg[32] = CONFIG_RAID6_PQ_DEFAULT_ALG;
+module_param_string(raid6_pq_default_alg, raid6_pq_default_alg, sizeof(raid6_pq_default_alg), 0444);
+MODULE_PARM_DESC(raid6_pq_default_alg, "Default gen/xor() algorithm");
+#endif
+
 struct raid6_calls raid6_call;
 EXPORT_SYMBOL_GPL(raid6_call);
 
@@ -157,6 +163,26 @@ static inline const struct raid6_calls *raid6_choose_gen(
 	const struct raid6_calls *const *algo;
 	const struct raid6_calls *best;
 
+#ifdef CONFIG_RAID6_PQ_DEFAULT_ALG_BOOL
+	if (strlen(raid6_pq_default_alg)) {
+		for (algo = raid6_algos; *algo; algo++) {
+			if (!strncmp(raid6_pq_default_alg, (*algo)->name, sizeof(raid6_pq_default_alg))) {
+				if ((*algo)->valid && !(*algo)->valid()) {
+					pr_info("raid6: default alg \"%s\" is invalid.\n",
+						raid6_pq_default_alg);
+					continue;
+				}
+				pr_info("raid6: using default algorithm %s gen() without performace tests.\n",
+					(*algo)->name);
+				raid6_call = **algo;
+				return *algo;
+			}
+		}
+		pr_info("raid6: default alg \"%s\" not found. Choosing the best alg as fallback...\n",
+			raid6_pq_default_alg);
+	}
+#endif
+
 	for (bestgenperf = 0, bestxorperf = 0, best = NULL, algo = raid6_algos; *algo; algo++) {
 		if (!best || (*algo)->prefer >= best->prefer) {
 			/* 2 ^ (RAID6_TIME_JIFFIES_LG2 - 0.5) */