Blame view
lib/raid6/algos.c
3.63 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 7 |
/* -*- linux-c -*- ------------------------------------------------------- * * * Copyright 2002 H. Peter Anvin - All Rights Reserved * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, Inc., 53 Temple Place Ste 330, |
93ed05e2a md: fix typo in F... |
8 |
* Boston MA 02111-1307, USA; either version 2 of the License, or |
1da177e4c Linux-2.6.12-rc2 |
9 10 11 12 13 |
* (at your option) any later version; incorporated herein by reference. * * ----------------------------------------------------------------------- */ /* |
a8e026c78 Further tidyup of... |
14 |
* raid6/algos.c |
1da177e4c Linux-2.6.12-rc2 |
15 16 17 |
* * Algorithm list and algorithm selection for RAID-6 */ |
f701d589a md/raid6: move ra... |
18 |
#include <linux/raid/pq.h> |
1da177e4c Linux-2.6.12-rc2 |
19 20 |
#ifndef __KERNEL__ #include <sys/mman.h> |
d7e70ba45 [PATCH] RAID6 Alt... |
21 |
#include <stdio.h> |
f701d589a md/raid6: move ra... |
22 |
#else |
d5302fe41 Make lib/raid6/te... |
23 |
#include <linux/gfp.h> |
f701d589a md/raid6: move ra... |
24 25 26 27 28 |
#if !RAID6_USE_EMPTY_ZERO_PAGE /* In .bss so it's zeroed */ const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256))); EXPORT_SYMBOL(raid6_empty_zero_page); #endif |
1da177e4c Linux-2.6.12-rc2 |
29 30 31 |
#endif struct raid6_calls raid6_call; |
f701d589a md/raid6: move ra... |
32 |
EXPORT_SYMBOL_GPL(raid6_call); |
1da177e4c Linux-2.6.12-rc2 |
33 |
|
1da177e4c Linux-2.6.12-rc2 |
34 35 36 37 38 39 40 41 42 |
const struct raid6_calls * const raid6_algos[] = { &raid6_intx1, &raid6_intx2, &raid6_intx4, &raid6_intx8, #if defined(__ia64__) &raid6_intx16, &raid6_intx32, #endif |
ca5cd877a x86 merge fallout... |
43 |
#if defined(__i386__) && !defined(__arch_um__) |
1da177e4c Linux-2.6.12-rc2 |
44 45 46 47 48 49 50 |
&raid6_mmxx1, &raid6_mmxx2, &raid6_sse1x1, &raid6_sse1x2, &raid6_sse2x1, &raid6_sse2x2, #endif |
ca5cd877a x86 merge fallout... |
51 |
#if defined(__x86_64__) && !defined(__arch_um__) |
1da177e4c Linux-2.6.12-rc2 |
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
&raid6_sse2x1, &raid6_sse2x2, &raid6_sse2x4, #endif #ifdef CONFIG_ALTIVEC &raid6_altivec1, &raid6_altivec2, &raid6_altivec4, &raid6_altivec8, #endif NULL }; #ifdef __KERNEL__ #define RAID6_TIME_JIFFIES_LG2 4 #else /* Need more time to be stable in userspace */ #define RAID6_TIME_JIFFIES_LG2 9 |
f701d589a md/raid6: move ra... |
70 |
#define time_before(x, y) ((x) < (y)) |
1da177e4c Linux-2.6.12-rc2 |
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 |
#endif /* Try to pick the best algorithm */ /* This code uses the gfmul table as convenient data set to abuse */ int __init raid6_select_algo(void) { const struct raid6_calls * const * algo; const struct raid6_calls * best; char *syndromes; void *dptrs[(65536/PAGE_SIZE)+2]; int i, disks; unsigned long perf, bestperf; int bestprefer; unsigned long j0, j1; disks = (65536/PAGE_SIZE)+2; for ( i = 0 ; i < disks-2 ; i++ ) { dptrs[i] = ((char *)raid6_gfmul) + PAGE_SIZE*i; } /* Normal code - use a 2-page allocation to avoid D$ conflict */ syndromes = (void *) __get_free_pages(GFP_KERNEL, 1); if ( !syndromes ) { printk("raid6: Yikes! No memory available. "); return -ENOMEM; } dptrs[disks-2] = syndromes; dptrs[disks-1] = syndromes + PAGE_SIZE; bestperf = 0; bestprefer = 0; best = NULL; for ( algo = raid6_algos ; *algo ; algo++ ) { if ( !(*algo)->valid || (*algo)->valid() ) { perf = 0; preempt_disable(); j0 = jiffies; while ( (j1 = jiffies) == j0 ) cpu_relax(); |
62b0559aa drivers/md: use t... |
114 115 |
while (time_before(jiffies, j1 + (1<<RAID6_TIME_JIFFIES_LG2))) { |
1da177e4c Linux-2.6.12-rc2 |
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
(*algo)->gen_syndrome(disks, PAGE_SIZE, dptrs); perf++; } preempt_enable(); if ( (*algo)->prefer > bestprefer || ((*algo)->prefer == bestprefer && perf > bestperf) ) { best = *algo; bestprefer = best->prefer; bestperf = perf; } printk("raid6: %-8s %5ld MB/s ", (*algo)->name, (perf*HZ) >> (20-16+RAID6_TIME_JIFFIES_LG2)); } } |
a5d6839b7 [PATCH] drivers/m... |
133 |
if (best) { |
1da177e4c Linux-2.6.12-rc2 |
134 135 136 137 |
printk("raid6: using algorithm %s (%ld MB/s) ", best->name, (bestperf*HZ) >> (20-16+RAID6_TIME_JIFFIES_LG2)); |
a5d6839b7 [PATCH] drivers/m... |
138 139 |
raid6_call = *best; } else |
1da177e4c Linux-2.6.12-rc2 |
140 141 |
printk("raid6: Yikes! No algorithm found! "); |
1da177e4c Linux-2.6.12-rc2 |
142 143 144 145 |
free_pages((unsigned long)syndromes, 1); return best ? 0 : -EINVAL; } |
f701d589a md/raid6: move ra... |
146 147 148 149 150 151 152 153 154 |
static void raid6_exit(void) { do { } while (0); } subsys_initcall(raid6_select_algo); module_exit(raid6_exit); MODULE_LICENSE("GPL"); |
0efb9e619 md: add MODULE_DE... |
155 |
MODULE_DESCRIPTION("RAID6 Q-syndrome calculations"); |