diff options
author | Jim Kukunas <james.t.kukunas@linux.intel.com> | 2012-05-22 13:54:18 +1000 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2012-05-22 13:54:18 +1000 |
commit | 048a8b8c89dc427dd7a58527c8923224b1e66d83 (patch) | |
tree | c8e09964537839f3848d0ad0e25ee40e873c3d09 /lib/raid6/algos.c | |
parent | f674ef7b43881b2ac11f98d6ba2dc5d9dd0dd118 (diff) | |
download | lwn-048a8b8c89dc427dd7a58527c8923224b1e66d83.tar.gz lwn-048a8b8c89dc427dd7a58527c8923224b1e66d83.zip |
lib/raid6: Add SSSE3 optimized recovery functions
Add SSSE3 optimized recovery functions, as well as a system
for selecting the most appropriate recovery functions to use.
Originally-by: H. Peter Anvin <hpa@zytor.com>
Signed-off-by: Jim Kukunas <james.t.kukunas@linux.intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'lib/raid6/algos.c')
-rw-r--r-- | lib/raid6/algos.c | 37 |
1 files changed, 37 insertions, 0 deletions
diff --git a/lib/raid6/algos.c b/lib/raid6/algos.c index f6a0f7899163..5a7f8022be13 100644 --- a/lib/raid6/algos.c +++ b/lib/raid6/algos.c @@ -64,6 +64,20 @@ const struct raid6_calls * const raid6_algos[] = { NULL }; +void (*raid6_2data_recov)(int, size_t, int, int, void **); +EXPORT_SYMBOL_GPL(raid6_2data_recov); + +void (*raid6_datap_recov)(int, size_t, int, void **); +EXPORT_SYMBOL_GPL(raid6_datap_recov); + +const struct raid6_recov_calls *const raid6_recov_algos[] = { +#if (defined(__i386__) || defined(__x86_64__)) && !defined(__arch_um__) + &raid6_recov_ssse3, +#endif + &raid6_recov_intx1, + NULL +}; + #ifdef __KERNEL__ #define RAID6_TIME_JIFFIES_LG2 4 #else @@ -72,6 +86,26 @@ const struct raid6_calls * const raid6_algos[] = { #define time_before(x, y) ((x) < (y)) #endif +static inline void raid6_choose_recov(void) +{ + const struct raid6_recov_calls *const *algo; + const struct raid6_recov_calls *best; + + for (best = NULL, algo = raid6_recov_algos; *algo; algo++) + if (!best || (*algo)->priority > best->priority) + if (!(*algo)->valid || (*algo)->valid()) + best = *algo; + + if (best) { + raid6_2data_recov = best->data2; + raid6_datap_recov = best->datap; + + printk("raid6: using %s recovery algorithm\n", best->name); + } else + printk("raid6: Yikes! No recovery algorithm found!\n"); +} + + /* Try to pick the best algorithm */ /* This code uses the gfmul table as convenient data set to abuse */ @@ -141,6 +175,9 @@ int __init raid6_select_algo(void) free_pages((unsigned long)syndromes, 1); + /* select raid recover functions */ + raid6_choose_recov(); + return best ? 0 : -EINVAL; } |