|
@@ -131,11 +131,12 @@ static inline const struct raid6_recov_calls *raid6_choose_recov(void)
|
|
static inline const struct raid6_calls *raid6_choose_gen(
|
|
static inline const struct raid6_calls *raid6_choose_gen(
|
|
void *(*const dptrs)[(65536/PAGE_SIZE)+2], const int disks)
|
|
void *(*const dptrs)[(65536/PAGE_SIZE)+2], const int disks)
|
|
{
|
|
{
|
|
- unsigned long perf, bestperf, j0, j1;
|
|
|
|
|
|
+ unsigned long perf, bestgenperf, bestxorperf, j0, j1;
|
|
|
|
+ int start = (disks>>1)-1, stop = disks-3; /* work on the second half of the disks */
|
|
const struct raid6_calls *const *algo;
|
|
const struct raid6_calls *const *algo;
|
|
const struct raid6_calls *best;
|
|
const struct raid6_calls *best;
|
|
|
|
|
|
- for (bestperf = 0, best = NULL, algo = raid6_algos; *algo; algo++) {
|
|
|
|
|
|
+ for (bestgenperf = 0, bestxorperf = 0, best = NULL, algo = raid6_algos; *algo; algo++) {
|
|
if (!best || (*algo)->prefer >= best->prefer) {
|
|
if (!best || (*algo)->prefer >= best->prefer) {
|
|
if ((*algo)->valid && !(*algo)->valid())
|
|
if ((*algo)->valid && !(*algo)->valid())
|
|
continue;
|
|
continue;
|
|
@@ -153,19 +154,45 @@ static inline const struct raid6_calls *raid6_choose_gen(
|
|
}
|
|
}
|
|
preempt_enable();
|
|
preempt_enable();
|
|
|
|
|
|
- if (perf > bestperf) {
|
|
|
|
- bestperf = perf;
|
|
|
|
|
|
+ if (perf > bestgenperf) {
|
|
|
|
+ bestgenperf = perf;
|
|
best = *algo;
|
|
best = *algo;
|
|
}
|
|
}
|
|
- pr_info("raid6: %-8s %5ld MB/s\n", (*algo)->name,
|
|
|
|
|
|
+ pr_info("raid6: %-8s gen() %5ld MB/s\n", (*algo)->name,
|
|
(perf*HZ) >> (20-16+RAID6_TIME_JIFFIES_LG2));
|
|
(perf*HZ) >> (20-16+RAID6_TIME_JIFFIES_LG2));
|
|
|
|
+
|
|
|
|
+ if (!(*algo)->xor_syndrome)
|
|
|
|
+ continue;
|
|
|
|
+
|
|
|
|
+ perf = 0;
|
|
|
|
+
|
|
|
|
+ preempt_disable();
|
|
|
|
+ j0 = jiffies;
|
|
|
|
+ while ((j1 = jiffies) == j0)
|
|
|
|
+ cpu_relax();
|
|
|
|
+ while (time_before(jiffies,
|
|
|
|
+ j1 + (1<<RAID6_TIME_JIFFIES_LG2))) {
|
|
|
|
+ (*algo)->xor_syndrome(disks, start, stop,
|
|
|
|
+ PAGE_SIZE, *dptrs);
|
|
|
|
+ perf++;
|
|
|
|
+ }
|
|
|
|
+ preempt_enable();
|
|
|
|
+
|
|
|
|
+ if (best == *algo)
|
|
|
|
+ bestxorperf = perf;
|
|
|
|
+
|
|
|
|
+ pr_info("raid6: %-8s xor() %5ld MB/s\n", (*algo)->name,
|
|
|
|
+ (perf*HZ) >> (20-16+RAID6_TIME_JIFFIES_LG2+1));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (best) {
|
|
if (best) {
|
|
- pr_info("raid6: using algorithm %s (%ld MB/s)\n",
|
|
|
|
|
|
+ pr_info("raid6: using algorithm %s gen() %ld MB/s\n",
|
|
best->name,
|
|
best->name,
|
|
- (bestperf*HZ) >> (20-16+RAID6_TIME_JIFFIES_LG2));
|
|
|
|
|
|
+ (bestgenperf*HZ) >> (20-16+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));
|
|
raid6_call = *best;
|
|
raid6_call = *best;
|
|
} else
|
|
} else
|
|
pr_err("raid6: Yikes! No algorithm found!\n");
|
|
pr_err("raid6: Yikes! No algorithm found!\n");
|