1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 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
/* SPDX-License-Identifier: GPL-2.0-or-later */ #include <asm/cpufeature.h> extern const struct raid6_calls raid6_mmxx1; extern const struct raid6_calls raid6_mmxx2; extern const struct raid6_calls raid6_sse1x1; extern const struct raid6_calls raid6_sse1x2; extern const struct raid6_calls raid6_sse2x1; extern const struct raid6_calls raid6_sse2x2; extern const struct raid6_calls raid6_sse2x4; extern const struct raid6_calls raid6_avx2x1; extern const struct raid6_calls raid6_avx2x2; extern const struct raid6_calls raid6_avx2x4; extern const struct raid6_calls raid6_avx512x1; extern const struct raid6_calls raid6_avx512x2; extern const struct raid6_calls raid6_avx512x4; extern const struct raid6_recov_calls raid6_recov_ssse3; extern const struct raid6_recov_calls raid6_recov_avx2; extern const struct raid6_recov_calls raid6_recov_avx512; static inline int raid6_has_avx512(void) { return boot_cpu_has(X86_FEATURE_AVX2) && boot_cpu_has(X86_FEATURE_AVX) && boot_cpu_has(X86_FEATURE_AVX512F) && boot_cpu_has(X86_FEATURE_AVX512BW) && boot_cpu_has(X86_FEATURE_AVX512VL) && boot_cpu_has(X86_FEATURE_AVX512DQ); } static inline bool raid6_has_avx2(void) { return boot_cpu_has(X86_FEATURE_AVX2) && boot_cpu_has(X86_FEATURE_AVX); } static inline bool raid6_has_ssse3(void) { return boot_cpu_has(X86_FEATURE_XMM) && boot_cpu_has(X86_FEATURE_XMM2) && boot_cpu_has(X86_FEATURE_SSSE3); } static inline bool raid6_has_sse2(void) { return boot_cpu_has(X86_FEATURE_MMX) && boot_cpu_has(X86_FEATURE_FXSR) && boot_cpu_has(X86_FEATURE_XMM) && boot_cpu_has(X86_FEATURE_XMM2); } static inline bool raid6_has_sse1_or_mmxext(void) { return boot_cpu_has(X86_FEATURE_MMX) && (boot_cpu_has(X86_FEATURE_XMM) || boot_cpu_has(X86_FEATURE_MMXEXT)); } static __always_inline void __init arch_raid6_init(void) { if (raid6_has_avx2()) { raid6_algo_add(&raid6_avx2x1); raid6_algo_add(&raid6_avx2x2); if (IS_ENABLED(CONFIG_X86_64)) raid6_algo_add(&raid6_avx2x4); if (raid6_has_avx512()) { raid6_algo_add(&raid6_avx512x1); raid6_algo_add(&raid6_avx512x2); if (IS_ENABLED(CONFIG_X86_64)) raid6_algo_add(&raid6_avx512x4); } } else if (IS_ENABLED(CONFIG_X86_64) || raid6_has_sse2()) { /* x86_64 can assume SSE2 as baseline */ raid6_algo_add(&raid6_sse2x1); raid6_algo_add(&raid6_sse2x2); if (IS_ENABLED(CONFIG_X86_64)) raid6_algo_add(&raid6_sse2x4); } else { raid6_algo_add_default(); if (raid6_has_sse1_or_mmxext()) { raid6_algo_add(&raid6_sse1x1); raid6_algo_add(&raid6_sse1x2); } else if (boot_cpu_has(X86_FEATURE_MMX)) { raid6_algo_add(&raid6_mmxx1); raid6_algo_add(&raid6_mmxx2); } } if (raid6_has_avx512()) raid6_recov_algo_add(&raid6_recov_avx512); else if (raid6_has_avx2()) raid6_recov_algo_add(&raid6_recov_avx2); else if (raid6_has_ssse3()) raid6_recov_algo_add(&raid6_recov_ssse3); }