提交 685784aa 编写于 作者: D Dan Williams

xor: make 'xor_blocks' a library routine for use with async_tx

The async_tx api tries to use a dma engine for an operation, but will fall
back to an optimized software routine otherwise.  Xor support is
implemented using the raid5 xor routines.  For organizational purposes this
routine is moved to a common area.

The following fixes are also made:
* rename xor_block => xor_blocks, suggested by Adrian Bunk
* ensure that xor.o initializes before md.o in the built-in case
* checkpatch.pl fixes
* mark calibrate_xor_blocks __init, Adrian Bunk

Cc: Adrian Bunk <bunk@stusta.de>
Cc: NeilBrown <neilb@suse.de>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: NDan Williams <dan.j.williams@intel.com>
上级 d379b01e
#
# Generic algorithms support
#
config XOR_BLOCKS
tristate
# #
# Cryptographic API Configuration # Cryptographic API Configuration
# #
......
...@@ -50,3 +50,9 @@ obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o ...@@ -50,3 +50,9 @@ obj-$(CONFIG_CRYPTO_MICHAEL_MIC) += michael_mic.o
obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o obj-$(CONFIG_CRYPTO_CRC32C) += crc32c.o
obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o
#
# generic algorithms and the async_tx api
#
obj-$(CONFIG_XOR_BLOCKS) += xor.o
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
static struct xor_block_template *active_template; static struct xor_block_template *active_template;
void void
xor_block(unsigned int count, unsigned int bytes, void **ptr) xor_blocks(unsigned int count, unsigned int bytes, void **ptr)
{ {
unsigned long *p0, *p1, *p2, *p3, *p4; unsigned long *p0, *p1, *p2, *p3, *p4;
...@@ -52,6 +52,7 @@ xor_block(unsigned int count, unsigned int bytes, void **ptr) ...@@ -52,6 +52,7 @@ xor_block(unsigned int count, unsigned int bytes, void **ptr)
p4 = (unsigned long *) ptr[4]; p4 = (unsigned long *) ptr[4];
active_template->do_5(bytes, p0, p1, p2, p3, p4); active_template->do_5(bytes, p0, p1, p2, p3, p4);
} }
EXPORT_SYMBOL(xor_blocks);
/* Set of all registered templates. */ /* Set of all registered templates. */
static struct xor_block_template *template_list; static struct xor_block_template *template_list;
...@@ -78,7 +79,7 @@ do_xor_speed(struct xor_block_template *tmpl, void *b1, void *b2) ...@@ -78,7 +79,7 @@ do_xor_speed(struct xor_block_template *tmpl, void *b1, void *b2)
now = jiffies; now = jiffies;
count = 0; count = 0;
while (jiffies == now) { while (jiffies == now) {
mb(); mb(); /* prevent loop optimzation */
tmpl->do_2(BENCH_SIZE, b1, b2); tmpl->do_2(BENCH_SIZE, b1, b2);
mb(); mb();
count++; count++;
...@@ -91,26 +92,26 @@ do_xor_speed(struct xor_block_template *tmpl, void *b1, void *b2) ...@@ -91,26 +92,26 @@ do_xor_speed(struct xor_block_template *tmpl, void *b1, void *b2)
speed = max * (HZ * BENCH_SIZE / 1024); speed = max * (HZ * BENCH_SIZE / 1024);
tmpl->speed = speed; tmpl->speed = speed;
printk(" %-10s: %5d.%03d MB/sec\n", tmpl->name, printk(KERN_INFO " %-10s: %5d.%03d MB/sec\n", tmpl->name,
speed / 1000, speed % 1000); speed / 1000, speed % 1000);
} }
static int static int __init
calibrate_xor_block(void) calibrate_xor_blocks(void)
{ {
void *b1, *b2; void *b1, *b2;
struct xor_block_template *f, *fastest; struct xor_block_template *f, *fastest;
b1 = (void *) __get_free_pages(GFP_KERNEL, 2); b1 = (void *) __get_free_pages(GFP_KERNEL, 2);
if (! b1) { if (!b1) {
printk("raid5: Yikes! No memory available.\n"); printk(KERN_WARNING "xor: Yikes! No memory available.\n");
return -ENOMEM; return -ENOMEM;
} }
b2 = b1 + 2*PAGE_SIZE + BENCH_SIZE; b2 = b1 + 2*PAGE_SIZE + BENCH_SIZE;
/* /*
* If this arch/cpu has a short-circuited selection, don't loop through all * If this arch/cpu has a short-circuited selection, don't loop through
* the possible functions, just test the best one * all the possible functions, just test the best one
*/ */
fastest = NULL; fastest = NULL;
...@@ -122,11 +123,12 @@ calibrate_xor_block(void) ...@@ -122,11 +123,12 @@ calibrate_xor_block(void)
#define xor_speed(templ) do_xor_speed((templ), b1, b2) #define xor_speed(templ) do_xor_speed((templ), b1, b2)
if (fastest) { if (fastest) {
printk(KERN_INFO "raid5: automatically using best checksumming function: %s\n", printk(KERN_INFO "xor: automatically using best "
"checksumming function: %s\n",
fastest->name); fastest->name);
xor_speed(fastest); xor_speed(fastest);
} else { } else {
printk(KERN_INFO "raid5: measuring checksumming speed\n"); printk(KERN_INFO "xor: measuring checksumming speed\n");
XOR_TRY_TEMPLATES; XOR_TRY_TEMPLATES;
fastest = template_list; fastest = template_list;
for (f = fastest; f; f = f->next) for (f = fastest; f; f = f->next)
...@@ -134,7 +136,7 @@ calibrate_xor_block(void) ...@@ -134,7 +136,7 @@ calibrate_xor_block(void)
fastest = f; fastest = f;
} }
printk("raid5: using function: %s (%d.%03d MB/sec)\n", printk(KERN_INFO "xor: using function: %s (%d.%03d MB/sec)\n",
fastest->name, fastest->speed / 1000, fastest->speed % 1000); fastest->name, fastest->speed / 1000, fastest->speed % 1000);
#undef xor_speed #undef xor_speed
...@@ -147,8 +149,8 @@ calibrate_xor_block(void) ...@@ -147,8 +149,8 @@ calibrate_xor_block(void)
static __exit void xor_exit(void) { } static __exit void xor_exit(void) { }
EXPORT_SYMBOL(xor_block);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
module_init(calibrate_xor_block); /* when built-in xor.o must initialize before drivers/md/md.o */
core_initcall(calibrate_xor_blocks);
module_exit(xor_exit); module_exit(xor_exit);
...@@ -109,6 +109,7 @@ config MD_RAID10 ...@@ -109,6 +109,7 @@ config MD_RAID10
config MD_RAID456 config MD_RAID456
tristate "RAID-4/RAID-5/RAID-6 mode" tristate "RAID-4/RAID-5/RAID-6 mode"
depends on BLK_DEV_MD depends on BLK_DEV_MD
select XOR_BLOCKS
---help--- ---help---
A RAID-5 set of N drives with a capacity of C MB per drive provides A RAID-5 set of N drives with a capacity of C MB per drive provides
the capacity of C * (N - 1) MB, and protects against a failure the capacity of C * (N - 1) MB, and protects against a failure
......
...@@ -17,7 +17,7 @@ raid456-objs := raid5.o raid6algos.o raid6recov.o raid6tables.o \ ...@@ -17,7 +17,7 @@ raid456-objs := raid5.o raid6algos.o raid6recov.o raid6tables.o \
hostprogs-y := mktables hostprogs-y := mktables
# Note: link order is important. All raid personalities # Note: link order is important. All raid personalities
# and xor.o must come before md.o, as they each initialise # and must come before md.o, as they each initialise
# themselves, and md.o may use the personalities when it # themselves, and md.o may use the personalities when it
# auto-initialised. # auto-initialised.
...@@ -25,7 +25,7 @@ obj-$(CONFIG_MD_LINEAR) += linear.o ...@@ -25,7 +25,7 @@ obj-$(CONFIG_MD_LINEAR) += linear.o
obj-$(CONFIG_MD_RAID0) += raid0.o obj-$(CONFIG_MD_RAID0) += raid0.o
obj-$(CONFIG_MD_RAID1) += raid1.o obj-$(CONFIG_MD_RAID1) += raid1.o
obj-$(CONFIG_MD_RAID10) += raid10.o obj-$(CONFIG_MD_RAID10) += raid10.o
obj-$(CONFIG_MD_RAID456) += raid456.o xor.o obj-$(CONFIG_MD_RAID456) += raid456.o
obj-$(CONFIG_MD_MULTIPATH) += multipath.o obj-$(CONFIG_MD_MULTIPATH) += multipath.o
obj-$(CONFIG_MD_FAULTY) += faulty.o obj-$(CONFIG_MD_FAULTY) += faulty.o
obj-$(CONFIG_BLK_DEV_MD) += md-mod.o obj-$(CONFIG_BLK_DEV_MD) += md-mod.o
......
...@@ -5814,7 +5814,7 @@ static __exit void md_exit(void) ...@@ -5814,7 +5814,7 @@ static __exit void md_exit(void)
} }
} }
module_init(md_init) subsys_initcall(md_init);
module_exit(md_exit) module_exit(md_exit)
static int get_ro(char *buffer, struct kernel_param *kp) static int get_ro(char *buffer, struct kernel_param *kp)
......
...@@ -918,7 +918,7 @@ static void copy_data(int frombio, struct bio *bio, ...@@ -918,7 +918,7 @@ static void copy_data(int frombio, struct bio *bio,
#define check_xor() do { \ #define check_xor() do { \
if (count == MAX_XOR_BLOCKS) { \ if (count == MAX_XOR_BLOCKS) { \
xor_block(count, STRIPE_SIZE, ptr); \ xor_blocks(count, STRIPE_SIZE, ptr); \
count = 1; \ count = 1; \
} \ } \
} while(0) } while(0)
...@@ -949,7 +949,7 @@ static void compute_block(struct stripe_head *sh, int dd_idx) ...@@ -949,7 +949,7 @@ static void compute_block(struct stripe_head *sh, int dd_idx)
check_xor(); check_xor();
} }
if (count != 1) if (count != 1)
xor_block(count, STRIPE_SIZE, ptr); xor_blocks(count, STRIPE_SIZE, ptr);
set_bit(R5_UPTODATE, &sh->dev[dd_idx].flags); set_bit(R5_UPTODATE, &sh->dev[dd_idx].flags);
} }
...@@ -1004,7 +1004,7 @@ static void compute_parity5(struct stripe_head *sh, int method) ...@@ -1004,7 +1004,7 @@ static void compute_parity5(struct stripe_head *sh, int method)
break; break;
} }
if (count>1) { if (count>1) {
xor_block(count, STRIPE_SIZE, ptr); xor_blocks(count, STRIPE_SIZE, ptr);
count = 1; count = 1;
} }
...@@ -1038,7 +1038,7 @@ static void compute_parity5(struct stripe_head *sh, int method) ...@@ -1038,7 +1038,7 @@ static void compute_parity5(struct stripe_head *sh, int method)
} }
} }
if (count != 1) if (count != 1)
xor_block(count, STRIPE_SIZE, ptr); xor_blocks(count, STRIPE_SIZE, ptr);
if (method != CHECK_PARITY) { if (method != CHECK_PARITY) {
set_bit(R5_UPTODATE, &sh->dev[pd_idx].flags); set_bit(R5_UPTODATE, &sh->dev[pd_idx].flags);
...@@ -1160,7 +1160,7 @@ static void compute_block_1(struct stripe_head *sh, int dd_idx, int nozero) ...@@ -1160,7 +1160,7 @@ static void compute_block_1(struct stripe_head *sh, int dd_idx, int nozero)
check_xor(); check_xor();
} }
if (count != 1) if (count != 1)
xor_block(count, STRIPE_SIZE, ptr); xor_blocks(count, STRIPE_SIZE, ptr);
if (!nozero) set_bit(R5_UPTODATE, &sh->dev[dd_idx].flags); if (!nozero) set_bit(R5_UPTODATE, &sh->dev[dd_idx].flags);
else clear_bit(R5_UPTODATE, &sh->dev[dd_idx].flags); else clear_bit(R5_UPTODATE, &sh->dev[dd_idx].flags);
} }
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#define MAX_XOR_BLOCKS 5 #define MAX_XOR_BLOCKS 5
extern void xor_block(unsigned int count, unsigned int bytes, void **ptr); extern void xor_blocks(unsigned int count, unsigned int bytes, void **ptr);
struct xor_block_template { struct xor_block_template {
struct xor_block_template *next; struct xor_block_template *next;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册