[PATCH] md/raid6: fix algorithm choice under larger PAGE_SIZE

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



For raid6, we need at least 4 disks to calculate the best algorithm.
But, currently we assume we are always under 4k PAGE_SIZE, when come
to larger page size, such as 64K, we may get a wrong xor() and gen().

This patch tries to fix the problem by supporting arbitrarily page size.

Signed-off-by: Zhengyuan Liu <liuzhengyuan@xxxxxxxxxx>
---
 lib/raid6/algos.c | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/lib/raid6/algos.c b/lib/raid6/algos.c
index 17417ee..0df7d99 100644
--- a/lib/raid6/algos.c
+++ b/lib/raid6/algos.c
@@ -118,6 +118,7 @@ const struct raid6_recov_calls *const raid6_recov_algos[] = {
 
 #ifdef __KERNEL__
 #define RAID6_TIME_JIFFIES_LG2	4
+#define RAID6_DATA_BLOCK_LEN	4096
 #else
 /* Need more time to be stable in userspace */
 #define RAID6_TIME_JIFFIES_LG2	9
@@ -146,7 +147,7 @@ static inline const struct raid6_recov_calls *raid6_choose_recov(void)
 }
 
 static inline const struct raid6_calls *raid6_choose_gen(
-	void *(*const dptrs)[(65536/PAGE_SIZE)+2], const int disks)
+	void *(*const dptrs)[(65536/RAID6_DATA_BLOCK_LEN)+2], const int disks)
 {
 	unsigned long perf, bestgenperf, bestxorperf, j0, j1;
 	int start = (disks>>1)-1, stop = disks-3;	/* work on the second half of the disks */
@@ -171,7 +172,7 @@ static inline const struct raid6_calls *raid6_choose_gen(
 				cpu_relax();
 			while (time_before(jiffies,
 					    j1 + (1<<RAID6_TIME_JIFFIES_LG2))) {
-				(*algo)->gen_syndrome(disks, PAGE_SIZE, *dptrs);
+				(*algo)->gen_syndrome(disks, RAID6_DATA_BLOCK_LEN, *dptrs);
 				perf++;
 			}
 			preempt_enable();
@@ -181,7 +182,8 @@ static inline const struct raid6_calls *raid6_choose_gen(
 				best = *algo;
 			}
 			pr_info("raid6: %-8s gen() %5ld MB/s\n", (*algo)->name,
-			       (perf*HZ) >> (20-16+RAID6_TIME_JIFFIES_LG2));
+			       (perf*HZ*RAID6_DATA_BLOCK_LEN*(disks-2)) >> \
+						(20+RAID6_TIME_JIFFIES_LG2));
 
 			if (!(*algo)->xor_syndrome)
 				continue;
@@ -195,7 +197,7 @@ static inline const struct raid6_calls *raid6_choose_gen(
 			while (time_before(jiffies,
 					    j1 + (1<<RAID6_TIME_JIFFIES_LG2))) {
 				(*algo)->xor_syndrome(disks, start, stop,
-						      PAGE_SIZE, *dptrs);
+						      RAID6_DATA_BLOCK_LEN, *dptrs);
 				perf++;
 			}
 			preempt_enable();
@@ -204,17 +206,20 @@ static inline const struct raid6_calls *raid6_choose_gen(
 				bestxorperf = perf;
 
 			pr_info("raid6: %-8s xor() %5ld MB/s\n", (*algo)->name,
-				(perf*HZ) >> (20-16+RAID6_TIME_JIFFIES_LG2+1));
+				(perf*HZ*RAID6_DATA_BLOCK_LEN*(disks-2)) >> \
+						(20+RAID6_TIME_JIFFIES_LG2+1));
 		}
 	}
 
 	if (best) {
 		pr_info("raid6: using algorithm %s gen() %ld MB/s\n",
 		       best->name,
-		       (bestgenperf*HZ) >> (20-16+RAID6_TIME_JIFFIES_LG2));
+		       (bestgenperf*HZ*RAID6_DATA_BLOCK_LEN*(disks-2)) >> \
+						(20+RAID6_TIME_JIFFIES_LG2));
 		if (best->xor_syndrome)
 			pr_info("raid6: .... xor() %ld MB/s, rmw enabled\n",
-			       (bestxorperf*HZ) >> (20-16+RAID6_TIME_JIFFIES_LG2+1));
+			       (bestxorperf*HZ*RAID6_DATA_BLOCK_LEN*(disks-2)) \
+						>> (20+RAID6_TIME_JIFFIES_LG2+1));
 		raid6_call = *best;
 	} else
 		pr_err("raid6: Yikes!  No algorithm found!\n");
@@ -228,16 +233,16 @@ static inline const struct raid6_calls *raid6_choose_gen(
 
 int __init raid6_select_algo(void)
 {
-	const int disks = (65536/PAGE_SIZE)+2;
+	const int disks = (65536/RAID6_DATA_BLOCK_LEN)+2;
 
 	const struct raid6_calls *gen_best;
 	const struct raid6_recov_calls *rec_best;
 	char *syndromes;
-	void *dptrs[(65536/PAGE_SIZE)+2];
+	void *dptrs[(65536/RAID6_DATA_BLOCK_LEN)+2];
 	int i;
 
 	for (i = 0; i < disks-2; i++)
-		dptrs[i] = ((char *)raid6_gfmul) + PAGE_SIZE*i;
+		dptrs[i] = ((char *)raid6_gfmul) + RAID6_DATA_BLOCK_LEN*i;
 
 	/* Normal code - use a 2-page allocation to avoid D$ conflict */
 	syndromes = (void *) __get_free_pages(GFP_KERNEL, 1);
-- 
2.7.4






[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux