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 | olio-linux-3.10-048a8b8c89dc427dd7a58527c8923224b1e66d83.tar.xz olio-linux-3.10-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 f6a0f789916..5a7f8022be1 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;  }  |