md/raid6: move raid6 data processing to raid6_pq.ko
authorDan Williams <dan.j.williams@intel.com>
Tue, 31 Mar 2009 04:09:39 +0000 (15:09 +1100)
committerNeilBrown <neilb@suse.de>
Tue, 31 Mar 2009 04:09:39 +0000 (15:09 +1100)
Move the raid6 data processing routines into a standalone module
(raid6_pq) to prepare them to be called from async_tx wrappers and other
non-md drivers/modules.  This precludes a circular dependency of raid456
needing the async modules for data processing while those modules in
turn depend on raid456 for the base level synchronous raid6 routines.

To support this move:
1/ The exportable definitions in raid6.h move to include/linux/raid/pq.h
2/ The raid6_call, recovery calls, and table symbols are exported
3/ Extra #ifdef __KERNEL__ statements to enable the userspace raid6test to
   compile

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: NeilBrown <neilb@suse.de>
16 files changed:
drivers/md/Kconfig
drivers/md/Makefile
drivers/md/mktables.c
drivers/md/raid5.c
drivers/md/raid5.h
drivers/md/raid6.h [deleted file]
drivers/md/raid6algos.c
drivers/md/raid6altivec.uc
drivers/md/raid6int.uc
drivers/md/raid6mmx.c
drivers/md/raid6recov.c
drivers/md/raid6sse1.c
drivers/md/raid6sse2.c
drivers/md/raid6test/Makefile
drivers/md/raid6test/test.c
include/linux/raid/pq.h [new file with mode: 0644]

index 2281b5098e95455cd1a6d60af7354f7728888185..449d0b9cac14679eb46d266065ab3f7722830857 100644 (file)
@@ -121,6 +121,7 @@ config MD_RAID10
 config MD_RAID456
        tristate "RAID-4/RAID-5/RAID-6 mode"
        depends on BLK_DEV_MD
+       select MD_RAID6_PQ
        select ASYNC_MEMCPY
        select ASYNC_XOR
        ---help---
@@ -180,6 +181,9 @@ config MD_RAID5_RESHAPE
 
          If unsure, say Y.
 
+config MD_RAID6_PQ
+       tristate
+
 config MD_MULTIPATH
        tristate "Multipath I/O support"
        depends on BLK_DEV_MD
index 3b118da575ee59fb780f56daf70e9b6f8579330d..45cc5951d9287030df73363a20659482aa55414d 100644 (file)
@@ -9,7 +9,8 @@ dm-snapshot-y   += dm-snap.o dm-exception-store.o dm-snap-transient.o \
                    dm-snap-persistent.o
 dm-mirror-y    += dm-raid1.o
 md-mod-y       += md.o bitmap.o
-raid456-y      += raid5.o raid6algos.o raid6recov.o raid6tables.o \
+raid456-y      += raid5.o
+raid6_pq-y     += raid6algos.o raid6recov.o raid6tables.o \
                   raid6int1.o raid6int2.o raid6int4.o \
                   raid6int8.o raid6int16.o raid6int32.o \
                   raid6altivec1.o raid6altivec2.o raid6altivec4.o \
@@ -26,6 +27,7 @@ obj-$(CONFIG_MD_LINEAR)               += linear.o
 obj-$(CONFIG_MD_RAID0)         += raid0.o
 obj-$(CONFIG_MD_RAID1)         += raid1.o
 obj-$(CONFIG_MD_RAID10)                += raid10.o
+obj-$(CONFIG_MD_RAID6_PQ)      += raid6_pq.o
 obj-$(CONFIG_MD_RAID456)       += raid456.o
 obj-$(CONFIG_MD_MULTIPATH)     += multipath.o
 obj-$(CONFIG_MD_FAULTY)                += faulty.o
index b61d5767aae7c61c3960a09e16c26becb3a1712f..3b1500843bbac2dfa85daaeb85058480294080d4 100644 (file)
@@ -59,7 +59,7 @@ int main(int argc, char *argv[])
        uint8_t v;
        uint8_t exptbl[256], invtbl[256];
 
-       printf("#include \"raid6.h\"\n");
+       printf("#include <linux/raid/pq.h>\n");
 
        /* Compute multiplication table */
        printf("\nconst u8  __attribute__((aligned(256)))\n"
@@ -76,6 +76,9 @@ int main(int argc, char *argv[])
                printf("\t},\n");
        }
        printf("};\n");
+       printf("#ifdef __KERNEL__\n");
+       printf("EXPORT_SYMBOL(raid6_gfmul);\n");
+       printf("#endif\n");
 
        /* Compute power-of-2 table (exponent) */
        v = 1;
@@ -92,6 +95,9 @@ int main(int argc, char *argv[])
                }
        }
        printf("};\n");
+       printf("#ifdef __KERNEL__\n");
+       printf("EXPORT_SYMBOL(raid6_gfexp);\n");
+       printf("#endif\n");
 
        /* Compute inverse table x^-1 == x^254 */
        printf("\nconst u8 __attribute__((aligned(256)))\n"
@@ -104,6 +110,9 @@ int main(int argc, char *argv[])
                }
        }
        printf("};\n");
+       printf("#ifdef __KERNEL__\n");
+       printf("EXPORT_SYMBOL(raid6_gfinv);\n");
+       printf("#endif\n");
 
        /* Compute inv(2^x + 1) (exponent-xor-inverse) table */
        printf("\nconst u8 __attribute__((aligned(256)))\n"
@@ -115,6 +124,9 @@ int main(int argc, char *argv[])
                               (j == 7) ? '\n' : ' ');
        }
        printf("};\n");
+       printf("#ifdef __KERNEL__\n");
+       printf("EXPORT_SYMBOL(raid6_gfexi);\n");
+       printf("#endif\n");
 
        return 0;
 }
index e1ee181b79bb784688e065cae55138461cea64d2..1f1b054ff0b67d5427d55d1f7f9209ba4adbece4 100644 (file)
 
 #include <linux/blkdev.h>
 #include <linux/kthread.h>
+#include <linux/raid/pq.h>
 #include <linux/async_tx.h>
 #include <linux/seq_file.h>
 #include "md.h"
 #include "raid5.h"
-#include "raid6.h"
 #include "bitmap.h"
 
 /*
 
 #define printk_rl(args...) ((void) (printk_ratelimit() && printk(args)))
 
-#if !RAID6_USE_EMPTY_ZERO_PAGE
-/* In .bss so it's zeroed */
-const char raid6_empty_zero_page[PAGE_SIZE] __attribute__((aligned(256)));
-#endif
-
 /*
  * We maintain a biased count of active stripes in the bottom 16 bits of
  * bi_phys_segments, and a count of processed stripes in the upper 16 bits
@@ -5153,11 +5148,6 @@ static struct mdk_personality raid4_personality =
 
 static int __init raid5_init(void)
 {
-       int e;
-
-       e = raid6_select_algo();
-       if ( e )
-               return e;
        register_md_personality(&raid6_personality);
        register_md_personality(&raid5_personality);
        register_md_personality(&raid4_personality);
index c172371481c7a6dc814950e69b7dcaf47f5e76cd..2934ee0a39c6d3e420e8418c7f59fd6abe88eb0a 100644 (file)
@@ -269,6 +269,8 @@ struct r6_state {
 #define READ_MODIFY_WRITE      2
 /* not a write method, but a compute_parity mode */
 #define        CHECK_PARITY            3
+/* Additional compute_parity mode -- updates the parity w/o LOCKING */
+#define UPDATE_PARITY          4
 
 /*
  * Stripe state
diff --git a/drivers/md/raid6.h b/drivers/md/raid6.h
deleted file mode 100644 (file)
index 8a9c823..0000000
+++ /dev/null
@@ -1,126 +0,0 @@
-/* -*- linux-c -*- ------------------------------------------------------- *
- *
- *   Copyright 2003 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,
- *   Boston MA 02111-1307, USA; either version 2 of the License, or
- *   (at your option) any later version; incorporated herein by reference.
- *
- * ----------------------------------------------------------------------- */
-
-#ifndef LINUX_RAID_RAID6_H
-#define LINUX_RAID_RAID6_H
-
-#ifdef __KERNEL__
-
-/* Set to 1 to use kernel-wide empty_zero_page */
-#define RAID6_USE_EMPTY_ZERO_PAGE 0
-#include <linux/blkdev.h>
-
-/* Additional compute_parity mode -- updates the parity w/o LOCKING */
-#define UPDATE_PARITY  4
-
-/* We need a pre-zeroed page... if we don't want to use the kernel-provided
-   one define it here */
-#if RAID6_USE_EMPTY_ZERO_PAGE
-# define raid6_empty_zero_page empty_zero_page
-#else
-extern const char raid6_empty_zero_page[PAGE_SIZE];
-#endif
-
-#else /* ! __KERNEL__ */
-/* Used for testing in user space */
-
-#include <errno.h>
-#include <inttypes.h>
-#include <limits.h>
-#include <stddef.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-
-/* Not standard, but glibc defines it */
-#define BITS_PER_LONG __WORDSIZE
-
-typedef uint8_t  u8;
-typedef uint16_t u16;
-typedef uint32_t u32;
-typedef uint64_t u64;
-
-#ifndef PAGE_SIZE
-# define PAGE_SIZE 4096
-#endif
-extern const char raid6_empty_zero_page[PAGE_SIZE];
-
-#define __init
-#define __exit
-#define __attribute_const__ __attribute__((const))
-#define noinline __attribute__((noinline))
-
-#define preempt_enable()
-#define preempt_disable()
-#define cpu_has_feature(x) 1
-#define enable_kernel_altivec()
-#define disable_kernel_altivec()
-
-#endif /* __KERNEL__ */
-
-/* Routine choices */
-struct raid6_calls {
-       void (*gen_syndrome)(int, size_t, void **);
-       int  (*valid)(void);    /* Returns 1 if this routine set is usable */
-       const char *name;       /* Name of this routine set */
-       int prefer;             /* Has special performance attribute */
-};
-
-/* Selected algorithm */
-extern struct raid6_calls raid6_call;
-
-/* Algorithm list */
-extern const struct raid6_calls * const raid6_algos[];
-int raid6_select_algo(void);
-
-/* Return values from chk_syndrome */
-#define RAID6_OK       0
-#define RAID6_P_BAD    1
-#define RAID6_Q_BAD    2
-#define RAID6_PQ_BAD   3
-
-/* Galois field tables */
-extern const u8 raid6_gfmul[256][256] __attribute__((aligned(256)));
-extern const u8 raid6_gfexp[256]      __attribute__((aligned(256)));
-extern const u8 raid6_gfinv[256]      __attribute__((aligned(256)));
-extern const u8 raid6_gfexi[256]      __attribute__((aligned(256)));
-
-/* Recovery routines */
-void raid6_2data_recov(int disks, size_t bytes, int faila, int failb, void **ptrs);
-void raid6_datap_recov(int disks, size_t bytes, int faila, void **ptrs);
-void raid6_dual_recov(int disks, size_t bytes, int faila, int failb, void **ptrs);
-
-/* Some definitions to allow code to be compiled for testing in userspace */
-#ifndef __KERNEL__
-
-# define jiffies       raid6_jiffies()
-# define printk        printf
-# define GFP_KERNEL    0
-# define __get_free_pages(x,y) ((unsigned long)mmap(NULL, PAGE_SIZE << (y), PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, 0, 0))
-# define free_pages(x,y)       munmap((void *)(x), (y)*PAGE_SIZE)
-
-static inline void cpu_relax(void)
-{
-       /* Nothing */
-}
-
-#undef  HZ
-#define HZ 1000
-static inline uint32_t raid6_jiffies(void)
-{
-       struct timeval tv;
-       gettimeofday(&tv, NULL);
-       return tv.tv_sec*1000 + tv.tv_usec/1000;
-}
-
-#endif /* ! __KERNEL__ */
-
-#endif /* LINUX_RAID_RAID6_H */
index 1f6a3c82ee0c66bcc04073b80b91f411c6bc6503..866215ac7f2554f86733cc900f4b902b3f60bc76 100644 (file)
  * Algorithm list and algorithm selection for RAID-6
  */
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 #ifndef __KERNEL__
 #include <sys/mman.h>
 #include <stdio.h>
+#else
+#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
 #endif
 
 struct raid6_calls raid6_call;
+EXPORT_SYMBOL_GPL(raid6_call);
 
 /* Various routine sets */
 extern const struct raid6_calls raid6_intx1;
@@ -79,6 +86,7 @@ const struct raid6_calls * const raid6_algos[] = {
 #else
 /* Need more time to be stable in userspace */
 #define RAID6_TIME_JIFFIES_LG2 9
+#define time_before(x, y) ((x) < (y))
 #endif
 
 /* Try to pick the best algorithm */
@@ -152,3 +160,12 @@ int __init raid6_select_algo(void)
 
        return best ? 0 : -EINVAL;
 }
+
+static void raid6_exit(void)
+{
+       do { } while (0);
+}
+
+subsys_initcall(raid6_select_algo);
+module_exit(raid6_exit);
+MODULE_LICENSE("GPL");
index 217580667e0cbcecd040e75a9a704991c5b81c5b..699dfeee494459afdd1ba2ff3b7a7e90c063b12f 100644 (file)
@@ -22,7 +22,7 @@
  * bracked this with preempt_disable/enable or in a lock)
  */
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 
 #ifdef CONFIG_ALTIVEC
 
index 32a0bac3eb3d5e5dc7b8f4806fd52f192bec9421..f9bf9cba357fd1202b6bef088a7e26b49fed6ab2 100644 (file)
@@ -18,7 +18,7 @@
  * This file is postprocessed using unroll.pl
  */
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 
 /*
  * This is the C data type to use
index 804cb50ecc19a7172f1f18e088307d28c5f9e65d..e7f6c13132bfd12e2f145a337ed954659198d971 100644 (file)
@@ -18,7 +18,7 @@
 
 #if defined(__i386__) && !defined(__arch_um__)
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 #include "raid6x86.h"
 
 /* Shared with raid6sse1.c */
index 7a98b8652582dd1f47fe578d9810d141db546b1e..2609f00e0d61ed8c5b80347704c4bf6d9fbae29f 100644 (file)
@@ -18,7 +18,7 @@
  * the syndrome.)
  */
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 
 /* Recover two failed data blocks. */
 void raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
@@ -63,9 +63,7 @@ void raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
                p++; q++;
        }
 }
-
-
-
+EXPORT_SYMBOL_GPL(raid6_2data_recov);
 
 /* Recover failure of one data block plus the P block */
 void raid6_datap_recov(int disks, size_t bytes, int faila, void **ptrs)
@@ -97,9 +95,10 @@ void raid6_datap_recov(int disks, size_t bytes, int faila, void **ptrs)
                q++; dq++;
        }
 }
+EXPORT_SYMBOL_GPL(raid6_datap_recov);
 
-
-#ifndef __KERNEL__             /* Testing only */
+#ifndef __KERNEL__
+/* Testing only */
 
 /* Recover two failed blocks. */
 void raid6_dual_recov(int disks, size_t bytes, int faila, int failb, void **ptrs)
index 15c588905225a7969e45a009e2be952188410dc4..b274dd5eab8f1a39aa3706e0d012bfeb8cef92f2 100644 (file)
@@ -23,7 +23,7 @@
 
 #if defined(__i386__) && !defined(__arch_um__)
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 #include "raid6x86.h"
 
 /* Defined in raid6mmx.c */
index 2e92e96275be748634b9eae1cd0b8bb3540b6ebe..6ed6c6c0389f47aef453c8708defd7f01e4d1c8f 100644 (file)
@@ -19,7 +19,7 @@
 
 #if (defined(__i386__) || defined(__x86_64__)) && !defined(__arch_um__)
 
-#include "raid6.h"
+#include <linux/raid/pq.h>
 #include "raid6x86.h"
 
 static const struct raid6_sse_constants {
index 78e0396adf2ac28ab8cc23f0427303b10d2207b2..58ffdf4f51619caa05253d5d42abb520ae5c8e20 100644 (file)
@@ -5,7 +5,7 @@
 
 CC      = gcc
 OPTFLAGS = -O2                 # Adjust as desired
-CFLAGS  = -I.. -g $(OPTFLAGS)
+CFLAGS  = -I.. -I ../../../include -g $(OPTFLAGS)
 LD      = ld
 PERL    = perl
 AR      = ar
index 559cc41b258566d4b0437241559156fbbc574721..7a930318b17d60c406bb1d421ba406c0f3bcb139 100644 (file)
@@ -17,7 +17,7 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <string.h>
-#include "raid6.h"
+#include <linux/raid/pq.h>
 
 #define NDISKS         16      /* Including P and Q */
 
diff --git a/include/linux/raid/pq.h b/include/linux/raid/pq.h
new file mode 100644 (file)
index 0000000..d92480f
--- /dev/null
@@ -0,0 +1,132 @@
+/* -*- linux-c -*- ------------------------------------------------------- *
+ *
+ *   Copyright 2003 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,
+ *   Boston MA 02111-1307, USA; either version 2 of the License, or
+ *   (at your option) any later version; incorporated herein by reference.
+ *
+ * ----------------------------------------------------------------------- */
+
+#ifndef LINUX_RAID_RAID6_H
+#define LINUX_RAID_RAID6_H
+
+#ifdef __KERNEL__
+
+/* Set to 1 to use kernel-wide empty_zero_page */
+#define RAID6_USE_EMPTY_ZERO_PAGE 0
+#include <linux/blkdev.h>
+
+/* We need a pre-zeroed page... if we don't want to use the kernel-provided
+   one define it here */
+#if RAID6_USE_EMPTY_ZERO_PAGE
+# define raid6_empty_zero_page empty_zero_page
+#else
+extern const char raid6_empty_zero_page[PAGE_SIZE];
+#endif
+
+#else /* ! __KERNEL__ */
+/* Used for testing in user space */
+
+#include <errno.h>
+#include <inttypes.h>
+#include <limits.h>
+#include <stddef.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+
+/* Not standard, but glibc defines it */
+#define BITS_PER_LONG __WORDSIZE
+
+typedef uint8_t  u8;
+typedef uint16_t u16;
+typedef uint32_t u32;
+typedef uint64_t u64;
+
+#ifndef PAGE_SIZE
+# define PAGE_SIZE 4096
+#endif
+extern const char raid6_empty_zero_page[PAGE_SIZE];
+
+#define __init
+#define __exit
+#define __attribute_const__ __attribute__((const))
+#define noinline __attribute__((noinline))
+
+#define preempt_enable()
+#define preempt_disable()
+#define cpu_has_feature(x) 1
+#define enable_kernel_altivec()
+#define disable_kernel_altivec()
+
+#define EXPORT_SYMBOL(sym)
+#define MODULE_LICENSE(licence)
+#define subsys_initcall(x)
+#define module_exit(x)
+#endif /* __KERNEL__ */
+
+/* Routine choices */
+struct raid6_calls {
+       void (*gen_syndrome)(int, size_t, void **);
+       int  (*valid)(void);    /* Returns 1 if this routine set is usable */
+       const char *name;       /* Name of this routine set */
+       int prefer;             /* Has special performance attribute */
+};
+
+/* Selected algorithm */
+extern struct raid6_calls raid6_call;
+
+/* Algorithm list */
+extern const struct raid6_calls * const raid6_algos[];
+int raid6_select_algo(void);
+
+/* Return values from chk_syndrome */
+#define RAID6_OK       0
+#define RAID6_P_BAD    1
+#define RAID6_Q_BAD    2
+#define RAID6_PQ_BAD   3
+
+/* Galois field tables */
+extern const u8 raid6_gfmul[256][256] __attribute__((aligned(256)));
+extern const u8 raid6_gfexp[256]      __attribute__((aligned(256)));
+extern const u8 raid6_gfinv[256]      __attribute__((aligned(256)));
+extern const u8 raid6_gfexi[256]      __attribute__((aligned(256)));
+
+/* Recovery routines */
+void raid6_2data_recov(int disks, size_t bytes, int faila, int failb,
+                      void **ptrs);
+void raid6_datap_recov(int disks, size_t bytes, int faila, void **ptrs);
+void raid6_dual_recov(int disks, size_t bytes, int faila, int failb,
+                     void **ptrs);
+
+/* Some definitions to allow code to be compiled for testing in userspace */
+#ifndef __KERNEL__
+
+# define jiffies       raid6_jiffies()
+# define printk        printf
+# define GFP_KERNEL    0
+# define __get_free_pages(x, y)        ((unsigned long)mmap(NULL, PAGE_SIZE << (y), \
+                                                    PROT_READ|PROT_WRITE,   \
+                                                    MAP_PRIVATE|MAP_ANONYMOUS,\
+                                                    0, 0))
+# define free_pages(x, y)      munmap((void *)(x), (y)*PAGE_SIZE)
+
+static inline void cpu_relax(void)
+{
+       /* Nothing */
+}
+
+#undef  HZ
+#define HZ 1000
+static inline uint32_t raid6_jiffies(void)
+{
+       struct timeval tv;
+       gettimeofday(&tv, NULL);
+       return tv.tv_sec*1000 + tv.tv_usec/1000;
+}
+
+#endif /* ! __KERNEL__ */
+
+#endif /* LINUX_RAID_RAID6_H */