diff options
Diffstat (limited to 'lib/raid6/algos.c')
| -rw-r--r-- | lib/raid6/algos.c | 41 |
1 files changed, 34 insertions, 7 deletions
diff --git a/lib/raid6/algos.c b/lib/raid6/algos.c index dbef2314901e..975c6e0434bd 100644 --- a/lib/raid6/algos.c +++ b/lib/raid6/algos.c | |||
| @@ -131,11 +131,12 @@ static inline const struct raid6_recov_calls *raid6_choose_recov(void) | |||
| 131 | static inline const struct raid6_calls *raid6_choose_gen( | 131 | static inline const struct raid6_calls *raid6_choose_gen( |
| 132 | void *(*const dptrs)[(65536/PAGE_SIZE)+2], const int disks) | 132 | void *(*const dptrs)[(65536/PAGE_SIZE)+2], const int disks) |
| 133 | { | 133 | { |
| 134 | unsigned long perf, bestperf, j0, j1; | 134 | unsigned long perf, bestgenperf, bestxorperf, j0, j1; |
| 135 | int start = (disks>>1)-1, stop = disks-3; /* work on the second half of the disks */ | ||
| 135 | const struct raid6_calls *const *algo; | 136 | const struct raid6_calls *const *algo; |
| 136 | const struct raid6_calls *best; | 137 | const struct raid6_calls *best; |
| 137 | 138 | ||
| 138 | for (bestperf = 0, best = NULL, algo = raid6_algos; *algo; algo++) { | 139 | for (bestgenperf = 0, bestxorperf = 0, best = NULL, algo = raid6_algos; *algo; algo++) { |
| 139 | if (!best || (*algo)->prefer >= best->prefer) { | 140 | if (!best || (*algo)->prefer >= best->prefer) { |
| 140 | if ((*algo)->valid && !(*algo)->valid()) | 141 | if ((*algo)->valid && !(*algo)->valid()) |
| 141 | continue; | 142 | continue; |
| @@ -153,19 +154,45 @@ static inline const struct raid6_calls *raid6_choose_gen( | |||
| 153 | } | 154 | } |
| 154 | preempt_enable(); | 155 | preempt_enable(); |
| 155 | 156 | ||
| 156 | if (perf > bestperf) { | 157 | if (perf > bestgenperf) { |
| 157 | bestperf = perf; | 158 | bestgenperf = perf; |
| 158 | best = *algo; | 159 | best = *algo; |
| 159 | } | 160 | } |
| 160 | pr_info("raid6: %-8s %5ld MB/s\n", (*algo)->name, | 161 | pr_info("raid6: %-8s gen() %5ld MB/s\n", (*algo)->name, |
| 161 | (perf*HZ) >> (20-16+RAID6_TIME_JIFFIES_LG2)); | 162 | (perf*HZ) >> (20-16+RAID6_TIME_JIFFIES_LG2)); |
| 163 | |||
| 164 | if (!(*algo)->xor_syndrome) | ||
| 165 | continue; | ||
| 166 | |||
| 167 | perf = 0; | ||
| 168 | |||
| 169 | preempt_disable(); | ||
| 170 | j0 = jiffies; | ||
| 171 | while ((j1 = jiffies) == j0) | ||
| 172 | cpu_relax(); | ||
| 173 | while (time_before(jiffies, | ||
| 174 | j1 + (1<<RAID6_TIME_JIFFIES_LG2))) { | ||
| 175 | (*algo)->xor_syndrome(disks, start, stop, | ||
| 176 | PAGE_SIZE, *dptrs); | ||
| 177 | perf++; | ||
| 178 | } | ||
| 179 | preempt_enable(); | ||
| 180 | |||
| 181 | if (best == *algo) | ||
| 182 | bestxorperf = perf; | ||
| 183 | |||
| 184 | pr_info("raid6: %-8s xor() %5ld MB/s\n", (*algo)->name, | ||
| 185 | (perf*HZ) >> (20-16+RAID6_TIME_JIFFIES_LG2+1)); | ||
| 162 | } | 186 | } |
| 163 | } | 187 | } |
| 164 | 188 | ||
| 165 | if (best) { | 189 | if (best) { |
| 166 | pr_info("raid6: using algorithm %s (%ld MB/s)\n", | 190 | pr_info("raid6: using algorithm %s gen() %ld MB/s\n", |
| 167 | best->name, | 191 | best->name, |
| 168 | (bestperf*HZ) >> (20-16+RAID6_TIME_JIFFIES_LG2)); | 192 | (bestgenperf*HZ) >> (20-16+RAID6_TIME_JIFFIES_LG2)); |
| 193 | if (best->xor_syndrome) | ||
| 194 | pr_info("raid6: .... xor() %ld MB/s, rmw enabled\n", | ||
| 195 | (bestxorperf*HZ) >> (20-16+RAID6_TIME_JIFFIES_LG2+1)); | ||
| 169 | raid6_call = *best; | 196 | raid6_call = *best; |
| 170 | } else | 197 | } else |
| 171 | pr_err("raid6: Yikes! No algorithm found!\n"); | 198 | pr_err("raid6: Yikes! No algorithm found!\n"); |
