^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * linux/lib/raid6/neon.c - RAID6 syndrome calculation using ARM NEON intrinsics
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/raid/pq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #ifdef __KERNEL__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <asm/neon.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #define kernel_neon_begin()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #define kernel_neon_end()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define cpu_has_neon() (1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * There are 2 reasons these wrappers are kept in a separate compilation unit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * from the actual implementations in neonN.c (generated from neon.uc by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * unroll.awk):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * - the actual implementations use NEON intrinsics, and the GCC support header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * (arm_neon.h) is not fully compatible (type wise) with the kernel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * - the neonN.c files are compiled with -mfpu=neon and optimization enabled,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * and we have to make sure that we never use *any* NEON/VFP instructions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * outside a kernel_neon_begin()/kernel_neon_end() pair.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define RAID6_NEON_WRAPPER(_n) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) static void raid6_neon ## _n ## _gen_syndrome(int disks, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) size_t bytes, void **ptrs) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) void raid6_neon ## _n ## _gen_syndrome_real(int, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) unsigned long, void**); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) kernel_neon_begin(); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) raid6_neon ## _n ## _gen_syndrome_real(disks, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) (unsigned long)bytes, ptrs); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) kernel_neon_end(); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static void raid6_neon ## _n ## _xor_syndrome(int disks, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) int start, int stop, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) size_t bytes, void **ptrs) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) void raid6_neon ## _n ## _xor_syndrome_real(int, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) int, int, unsigned long, void**); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) kernel_neon_begin(); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) raid6_neon ## _n ## _xor_syndrome_real(disks, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) start, stop, (unsigned long)bytes, ptrs); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) kernel_neon_end(); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) } \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) struct raid6_calls const raid6_neonx ## _n = { \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) raid6_neon ## _n ## _gen_syndrome, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) raid6_neon ## _n ## _xor_syndrome, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) raid6_have_neon, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) "neonx" #_n, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) 0 \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static int raid6_have_neon(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return cpu_has_neon();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) RAID6_NEON_WRAPPER(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) RAID6_NEON_WRAPPER(2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) RAID6_NEON_WRAPPER(4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) RAID6_NEON_WRAPPER(8);