summaryrefslogtreecommitdiffstats
path: root/lib/raid6
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-07 15:08:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-07 15:08:19 -0400
commit49a695ba723224875df50e327bd7b0b65dd9a56b (patch)
tree02372931e3e751106ca16bae14567d990bf22ad8 /lib/raid6
parent299f89d53e61c0b17479cc7d6f3b5382d5e83f28 (diff)
parentc1b25a17d24925b0961c319cfc3fd7e1dc778914 (diff)
Merge tag 'powerpc-4.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc updates from Michael Ellerman: "Notable changes: - Support for 4PB user address space on 64-bit, opt-in via mmap(). - Removal of POWER4 support, which was accidentally broken in 2016 and no one noticed, and blocked use of some modern instructions. - Workarounds so that the hypervisor can enable Transactional Memory on Power9. - A series to disable the DAWR (Data Address Watchpoint Register) on Power9. - More information displayed in the meltdown/spectre_v1/v2 sysfs files. - A vpermxor (Power8 Altivec) implementation for the raid6 Q Syndrome. - A big series to make the allocation of our pacas (per cpu area), kernel page tables, and per-cpu stacks NUMA aware when using the Radix MMU on Power9. And as usual many fixes, reworks and cleanups. Thanks to: Aaro Koskinen, Alexandre Belloni, Alexey Kardashevskiy, Alistair Popple, Andy Shevchenko, Aneesh Kumar K.V, Anshuman Khandual, Balbir Singh, Benjamin Herrenschmidt, Christophe Leroy, Christophe Lombard, Cyril Bur, Daniel Axtens, Dave Young, Finn Thain, Frederic Barrat, Gustavo Romero, Horia Geantă, Jonathan Neuschäfer, Kees Cook, Larry Finger, Laurent Dufour, Laurent Vivier, Logan Gunthorpe, Madhavan Srinivasan, Mark Greer, Mark Hairgrove, Markus Elfring, Mathieu Malaterre, Matt Brown, Matt Evans, Mauricio Faria de Oliveira, Michael Neuling, Naveen N. Rao, Nicholas Piggin, Paul Mackerras, Philippe Bergheaud, Ram Pai, Rob Herring, Sam Bobroff, Segher Boessenkool, Simon Guo, Simon Horman, Stewart Smith, Sukadev Bhattiprolu, Suraj Jitindar Singh, Thiago Jung Bauermann, Vaibhav Jain, Vaidyanathan Srinivasan, Vasant Hegde, Wei Yongjun" * tag 'powerpc-4.17-1' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: (207 commits) powerpc/64s/idle: Fix restore of AMOR on POWER9 after deep sleep powerpc/64s: Fix POWER9 DD2.2 and above in cputable features powerpc/64s: Fix pkey support in dt_cpu_ftrs, add CPU_FTR_PKEY bit powerpc/64s: Fix dt_cpu_ftrs to have restore_cpu clear unwanted LPCR bits Revert "powerpc/64s/idle: POWER9 ESL=0 stop avoid save/restore overhead" powerpc: iomap.c: introduce io{read|write}64_{lo_hi|hi_lo} powerpc: io.h: move iomap.h include so that it can use readq/writeq defs cxl: Fix possible deadlock when processing page faults from cxllib powerpc/hw_breakpoint: Only disable hw breakpoint if cpu supports it powerpc/mm/radix: Update command line parsing for disable_radix powerpc/mm/radix: Parse disable_radix commandline correctly. powerpc/mm/hugetlb: initialize the pagetable cache correctly for hugetlb powerpc/mm/radix: Update pte fragment count from 16 to 256 on radix powerpc/mm/keys: Update documentation and remove unnecessary check powerpc/64s/idle: POWER9 ESL=0 stop avoid save/restore overhead powerpc/64s/idle: Consolidate power9_offline_stop()/power9_idle_stop() powerpc/powernv: Always stop secondaries before reboot/shutdown powerpc: hard disable irqs in smp_send_stop loop powerpc: use NMI IPI for smp_send_stop powerpc/powernv: Fix SMT4 forcing idle code ...
Diffstat (limited to 'lib/raid6')
-rw-r--r--lib/raid6/.gitignore1
-rw-r--r--lib/raid6/Makefile27
-rw-r--r--lib/raid6/algos.c4
-rw-r--r--lib/raid6/altivec.uc3
-rw-r--r--lib/raid6/test/Makefile22
-rw-r--r--lib/raid6/vpermxor.uc105
6 files changed, 157 insertions, 5 deletions
diff --git a/lib/raid6/.gitignore b/lib/raid6/.gitignore
index f01b1cb04f91..3de0d8921286 100644
--- a/lib/raid6/.gitignore
+++ b/lib/raid6/.gitignore
@@ -4,3 +4,4 @@ int*.c
4tables.c 4tables.c
5neon?.c 5neon?.c
6s390vx?.c 6s390vx?.c
7vpermxor*.c
diff --git a/lib/raid6/Makefile b/lib/raid6/Makefile
index 44d6b46df051..2f8b61dfd9b0 100644
--- a/lib/raid6/Makefile
+++ b/lib/raid6/Makefile
@@ -5,7 +5,8 @@ raid6_pq-y += algos.o recov.o tables.o int1.o int2.o int4.o \
5 int8.o int16.o int32.o 5 int8.o int16.o int32.o
6 6
7raid6_pq-$(CONFIG_X86) += recov_ssse3.o recov_avx2.o mmx.o sse1.o sse2.o avx2.o avx512.o recov_avx512.o 7raid6_pq-$(CONFIG_X86) += recov_ssse3.o recov_avx2.o mmx.o sse1.o sse2.o avx2.o avx512.o recov_avx512.o
8raid6_pq-$(CONFIG_ALTIVEC) += altivec1.o altivec2.o altivec4.o altivec8.o 8raid6_pq-$(CONFIG_ALTIVEC) += altivec1.o altivec2.o altivec4.o altivec8.o \
9 vpermxor1.o vpermxor2.o vpermxor4.o vpermxor8.o
9raid6_pq-$(CONFIG_KERNEL_MODE_NEON) += neon.o neon1.o neon2.o neon4.o neon8.o recov_neon.o recov_neon_inner.o 10raid6_pq-$(CONFIG_KERNEL_MODE_NEON) += neon.o neon1.o neon2.o neon4.o neon8.o recov_neon.o recov_neon_inner.o
10raid6_pq-$(CONFIG_S390) += s390vx8.o recov_s390xc.o 11raid6_pq-$(CONFIG_S390) += s390vx8.o recov_s390xc.o
11 12
@@ -90,6 +91,30 @@ $(obj)/altivec8.c: UNROLL := 8
90$(obj)/altivec8.c: $(src)/altivec.uc $(src)/unroll.awk FORCE 91$(obj)/altivec8.c: $(src)/altivec.uc $(src)/unroll.awk FORCE
91 $(call if_changed,unroll) 92 $(call if_changed,unroll)
92 93
94CFLAGS_vpermxor1.o += $(altivec_flags)
95targets += vpermxor1.c
96$(obj)/vpermxor1.c: UNROLL := 1
97$(obj)/vpermxor1.c: $(src)/vpermxor.uc $(src)/unroll.awk FORCE
98 $(call if_changed,unroll)
99
100CFLAGS_vpermxor2.o += $(altivec_flags)
101targets += vpermxor2.c
102$(obj)/vpermxor2.c: UNROLL := 2
103$(obj)/vpermxor2.c: $(src)/vpermxor.uc $(src)/unroll.awk FORCE
104 $(call if_changed,unroll)
105
106CFLAGS_vpermxor4.o += $(altivec_flags)
107targets += vpermxor4.c
108$(obj)/vpermxor4.c: UNROLL := 4
109$(obj)/vpermxor4.c: $(src)/vpermxor.uc $(src)/unroll.awk FORCE
110 $(call if_changed,unroll)
111
112CFLAGS_vpermxor8.o += $(altivec_flags)
113targets += vpermxor8.c
114$(obj)/vpermxor8.c: UNROLL := 8
115$(obj)/vpermxor8.c: $(src)/vpermxor.uc $(src)/unroll.awk FORCE
116 $(call if_changed,unroll)
117
93CFLAGS_neon1.o += $(NEON_FLAGS) 118CFLAGS_neon1.o += $(NEON_FLAGS)
94targets += neon1.c 119targets += neon1.c
95$(obj)/neon1.c: UNROLL := 1 120$(obj)/neon1.c: UNROLL := 1
diff --git a/lib/raid6/algos.c b/lib/raid6/algos.c
index c65aa80d67ed..5065b1e7e327 100644
--- a/lib/raid6/algos.c
+++ b/lib/raid6/algos.c
@@ -74,6 +74,10 @@ const struct raid6_calls * const raid6_algos[] = {
74 &raid6_altivec2, 74 &raid6_altivec2,
75 &raid6_altivec4, 75 &raid6_altivec4,
76 &raid6_altivec8, 76 &raid6_altivec8,
77 &raid6_vpermxor1,
78 &raid6_vpermxor2,
79 &raid6_vpermxor4,
80 &raid6_vpermxor8,
77#endif 81#endif
78#if defined(CONFIG_S390) 82#if defined(CONFIG_S390)
79 &raid6_s390vx8, 83 &raid6_s390vx8,
diff --git a/lib/raid6/altivec.uc b/lib/raid6/altivec.uc
index 682aae8a1fef..d20ed0d11411 100644
--- a/lib/raid6/altivec.uc
+++ b/lib/raid6/altivec.uc
@@ -24,10 +24,13 @@
24 24
25#include <linux/raid/pq.h> 25#include <linux/raid/pq.h>
26 26
27#ifdef CONFIG_ALTIVEC
28
27#include <altivec.h> 29#include <altivec.h>
28#ifdef __KERNEL__ 30#ifdef __KERNEL__
29# include <asm/cputable.h> 31# include <asm/cputable.h>
30# include <asm/switch_to.h> 32# include <asm/switch_to.h>
33#endif /* __KERNEL__ */
31 34
32/* 35/*
33 * This is the C data type to use. We use a vector of 36 * This is the C data type to use. We use a vector of
diff --git a/lib/raid6/test/Makefile b/lib/raid6/test/Makefile
index fabc477b1417..5d73f5cb4d8a 100644
--- a/lib/raid6/test/Makefile
+++ b/lib/raid6/test/Makefile
@@ -45,10 +45,12 @@ else ifeq ($(HAS_NEON),yes)
45 CFLAGS += -DCONFIG_KERNEL_MODE_NEON=1 45 CFLAGS += -DCONFIG_KERNEL_MODE_NEON=1
46else 46else
47 HAS_ALTIVEC := $(shell printf '\#include <altivec.h>\nvector int a;\n' |\ 47 HAS_ALTIVEC := $(shell printf '\#include <altivec.h>\nvector int a;\n' |\
48 gcc -c -x c - >&/dev/null && \ 48 gcc -c -x c - >/dev/null && rm ./-.o && echo yes)
49 rm ./-.o && echo yes)
50 ifeq ($(HAS_ALTIVEC),yes) 49 ifeq ($(HAS_ALTIVEC),yes)
51 OBJS += altivec1.o altivec2.o altivec4.o altivec8.o 50 CFLAGS += -I../../../arch/powerpc/include
51 CFLAGS += -DCONFIG_ALTIVEC
52 OBJS += altivec1.o altivec2.o altivec4.o altivec8.o \
53 vpermxor1.o vpermxor2.o vpermxor4.o vpermxor8.o
52 endif 54 endif
53endif 55endif
54 56
@@ -95,6 +97,18 @@ altivec4.c: altivec.uc ../unroll.awk
95altivec8.c: altivec.uc ../unroll.awk 97altivec8.c: altivec.uc ../unroll.awk
96 $(AWK) ../unroll.awk -vN=8 < altivec.uc > $@ 98 $(AWK) ../unroll.awk -vN=8 < altivec.uc > $@
97 99
100vpermxor1.c: vpermxor.uc ../unroll.awk
101 $(AWK) ../unroll.awk -vN=1 < vpermxor.uc > $@
102
103vpermxor2.c: vpermxor.uc ../unroll.awk
104 $(AWK) ../unroll.awk -vN=2 < vpermxor.uc > $@
105
106vpermxor4.c: vpermxor.uc ../unroll.awk
107 $(AWK) ../unroll.awk -vN=4 < vpermxor.uc > $@
108
109vpermxor8.c: vpermxor.uc ../unroll.awk
110 $(AWK) ../unroll.awk -vN=8 < vpermxor.uc > $@
111
98int1.c: int.uc ../unroll.awk 112int1.c: int.uc ../unroll.awk
99 $(AWK) ../unroll.awk -vN=1 < int.uc > $@ 113 $(AWK) ../unroll.awk -vN=1 < int.uc > $@
100 114
@@ -117,7 +131,7 @@ tables.c: mktables
117 ./mktables > tables.c 131 ./mktables > tables.c
118 132
119clean: 133clean:
120 rm -f *.o *.a mktables mktables.c *.uc int*.c altivec*.c neon*.c tables.c raid6test 134 rm -f *.o *.a mktables mktables.c *.uc int*.c altivec*.c vpermxor*.c neon*.c tables.c raid6test
121 135
122spotless: clean 136spotless: clean
123 rm -f *~ 137 rm -f *~
diff --git a/lib/raid6/vpermxor.uc b/lib/raid6/vpermxor.uc
new file mode 100644
index 000000000000..10475dc423c1
--- /dev/null
+++ b/lib/raid6/vpermxor.uc
@@ -0,0 +1,105 @@
1/*
2 * Copyright 2017, Matt Brown, IBM Corp.
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License
6 * as published by the Free Software Foundation; either version
7 * 2 of the License, or (at your option) any later version.
8 *
9 * vpermxor$#.c
10 *
11 * Based on H. Peter Anvin's paper - The mathematics of RAID-6
12 *
13 * $#-way unrolled portable integer math RAID-6 instruction set
14 * This file is postprocessed using unroll.awk
15 *
16 * vpermxor$#.c makes use of the vpermxor instruction to optimise the RAID6 Q
17 * syndrome calculations.
18 * This can be run on systems which have both Altivec and vpermxor instruction.
19 *
20 * This instruction was introduced in POWER8 - ISA v2.07.
21 */
22
23#include <linux/raid/pq.h>
24#ifdef CONFIG_ALTIVEC
25
26#include <altivec.h>
27#ifdef __KERNEL__
28#include <asm/cputable.h>
29#include <asm/ppc-opcode.h>
30#include <asm/switch_to.h>
31#endif
32
33typedef vector unsigned char unative_t;
34#define NSIZE sizeof(unative_t)
35
36static const vector unsigned char gf_low = {0x1e, 0x1c, 0x1a, 0x18, 0x16, 0x14,
37 0x12, 0x10, 0x0e, 0x0c, 0x0a, 0x08,
38 0x06, 0x04, 0x02,0x00};
39static const vector unsigned char gf_high = {0xfd, 0xdd, 0xbd, 0x9d, 0x7d, 0x5d,
40 0x3d, 0x1d, 0xe0, 0xc0, 0xa0, 0x80,
41 0x60, 0x40, 0x20, 0x00};
42
43static void noinline raid6_vpermxor$#_gen_syndrome_real(int disks, size_t bytes,
44 void **ptrs)
45{
46 u8 **dptr = (u8 **)ptrs;
47 u8 *p, *q;
48 int d, z, z0;
49 unative_t wp$$, wq$$, wd$$;
50
51 z0 = disks - 3; /* Highest data disk */
52 p = dptr[z0+1]; /* XOR parity */
53 q = dptr[z0+2]; /* RS syndrome */
54
55 for (d = 0; d < bytes; d += NSIZE*$#) {
56 wp$$ = wq$$ = *(unative_t *)&dptr[z0][d+$$*NSIZE];
57
58 for (z = z0-1; z>=0; z--) {
59 wd$$ = *(unative_t *)&dptr[z][d+$$*NSIZE];
60 /* P syndrome */
61 wp$$ = vec_xor(wp$$, wd$$);
62
63 /* Q syndrome */
64 asm(VPERMXOR(%0,%1,%2,%3):"=v"(wq$$):"v"(gf_high), "v"(gf_low), "v"(wq$$));
65 wq$$ = vec_xor(wq$$, wd$$);
66 }
67 *(unative_t *)&p[d+NSIZE*$$] = wp$$;
68 *(unative_t *)&q[d+NSIZE*$$] = wq$$;
69 }
70}
71
72static void raid6_vpermxor$#_gen_syndrome(int disks, size_t bytes, void **ptrs)
73{
74 preempt_disable();
75 enable_kernel_altivec();
76
77 raid6_vpermxor$#_gen_syndrome_real(disks, bytes, ptrs);
78
79 disable_kernel_altivec();
80 preempt_enable();
81}
82
83int raid6_have_altivec_vpermxor(void);
84#if $# == 1
85int raid6_have_altivec_vpermxor(void)
86{
87 /* Check if arch has both altivec and the vpermxor instructions */
88# ifdef __KERNEL__
89 return (cpu_has_feature(CPU_FTR_ALTIVEC_COMP) &&
90 cpu_has_feature(CPU_FTR_ARCH_207S));
91# else
92 return 1;
93#endif
94
95}
96#endif
97
98const struct raid6_calls raid6_vpermxor$# = {
99 raid6_vpermxor$#_gen_syndrome,
100 NULL,
101 raid6_have_altivec_vpermxor,
102 "vpermxor$#",
103 0
104};
105#endif