diff --git a/.gitmodules b/.gitmodules index 464b58b136d..acd9d513d14 100644 --- a/.gitmodules +++ b/.gitmodules @@ -14,7 +14,7 @@ [submodule "src/erasure-code/jerasure/gf-complete"] path = src/erasure-code/jerasure/gf-complete url = https://github.com/ceph/gf-complete.git - branch = v1-ceph + branch = v2-ceph [submodule "src/rocksdb"] path = src/rocksdb url = git://github.com/ceph/rocksdb diff --git a/configure.ac b/configure.ac index 4770e206771..72c7fe0c035 100644 --- a/configure.ac +++ b/configure.ac @@ -143,9 +143,6 @@ AC_DEFUN([AC_CHECK_CC_FLAG], AC_CHECK_CC_FLAG([-Wtype-limits], [WARN_TYPE_LIMITS]) AC_CHECK_CC_FLAG([-Wignored-qualifiers], [WARN_IGNORED_QUALIFIERS]) -# Checks for architecture stuff -AM_CONDITIONAL([ENABLE_FPU_NEON], [case $target_cpu in arm*) true;; *) false;; esac]) - # Check for compiler VTA support AX_CHECK_COMPILE_FLAG([-fvar-tracking-assignments], [HAS_VTA_SUPPORT=1], [HAS_VTA_SUPPORT=0]) AM_CONDITIONAL(COMPILER_HAS_VTA, [test "$HAS_VTA_SUPPORT" = 1]) @@ -545,8 +542,12 @@ AC_LANG_PUSH([C++]) AC_CHECK_HEADER([leveldb/filter_policy.h], [AC_DEFINE([HAVE_LEVELDB_FILTER_POLICY], [1], [Defined if LevelDB supports bloom filters ])]) AC_LANG_POP([C++]) -# Find supported SIMD / SSE extensions supported by the compiler +# Find supported SIMD / NEON / SSE extensions supported by the compiler +AX_ARM_FEATURES() +AM_CONDITIONAL(HAVE_NEON, [ test "x$ax_cv_support_neon_ext" = "xyes"]) AX_INTEL_FEATURES() +AM_CONDITIONAL(HAVE_SSSE3, [ test "x$ax_cv_support_ssse3_ext" = "xyes"]) +AM_CONDITIONAL(HAVE_SSE4_PCLMUL, [ test "x$ax_cv_support_pclmuldq_ext" = "xyes"]) # kinetic osd backend? AC_ARG_WITH([kinetic], diff --git a/m4/ax_arm.m4 b/m4/ax_arm.m4 new file mode 100644 index 00000000000..2ccc9a977f8 --- /dev/null +++ b/m4/ax_arm.m4 @@ -0,0 +1,27 @@ +AC_DEFUN([AX_ARM_FEATURES], +[ + AC_REQUIRE([AC_CANONICAL_HOST]) + + case $target_cpu in + arm*) + AX_CHECK_COMPILE_FLAG(-mfpu=neon, ax_cv_support_neon_ext=yes, []) + if test x"$ax_cv_support_neon_ext" = x"yes"; then + ARM_NEON_FLAGS="-mfpu=neon -DARM_NEON" + AC_SUBST(ARM_NEON_FLAGS) + ARM_FLAGS="$ARM_FLAGS $ARM_NEON_FLAGS" + AC_DEFINE(HAVE_NEON,,[Support NEON instructions]) + fi + ;; + aarch64*) + AX_CHECK_COMPILE_FLAG(-march=armv8-a+simd, ax_cv_support_neon_ext=yes, []) + if test x"$ax_cv_support_neon_ext" = x"yes"; then + ARM_NEON_FLAGS="-march=armv8-a+simd -DARCH_AARCH64 -DARM_NEON" + AC_SUBST(ARM_NEON_FLAGS) + ARM_FLAGS="$ARM_FLAGS $ARM_NEON_FLAGS" + AC_DEFINE(HAVE_NEON,,[Support NEON instructions]) + fi + ;; + esac + + AC_SUBST(ARM_FLAGS) +]) diff --git a/src/arch/neon.c b/src/arch/neon.c index 6dad7e6e13e..f059080b96b 100644 --- a/src/arch/neon.c +++ b/src/arch/neon.c @@ -10,7 +10,7 @@ int ceph_arch_neon = 0; #include #include // ElfW macro -#if __arm__ +#if __arm__ || __aarch64__ #include #endif // __arm__ @@ -45,6 +45,8 @@ int ceph_arch_neon_probe(void) { #if __arm__ && __linux__ ceph_arch_neon = (get_hwcap() & HWCAP_NEON) == HWCAP_NEON; +#elif __aarch64__ && __linux__ + ceph_arch_neon = (get_hwcap() & HWCAP_ASIMD) == HWCAP_ASIMD; #else if (0) get_hwcap(); // make compiler shut up diff --git a/src/erasure-code/jerasure/ErasureCodePluginSelectJerasure.cc b/src/erasure-code/jerasure/ErasureCodePluginSelectJerasure.cc index 53c70266a9b..32560b40fcb 100644 --- a/src/erasure-code/jerasure/ErasureCodePluginSelectJerasure.cc +++ b/src/erasure-code/jerasure/ErasureCodePluginSelectJerasure.cc @@ -19,6 +19,7 @@ #include "common/debug.h" #include "arch/probe.h" #include "arch/intel.h" +#include "arch/neon.h" #include "erasure-code/ErasureCodePlugin.h" #define dout_subsys ceph_subsys_osd @@ -44,6 +45,8 @@ static string get_variant() { ceph_arch_intel_sse3 && ceph_arch_intel_sse2) { return "sse3"; + } else if (ceph_arch_neon) { + return "neon"; } else { return "generic"; } diff --git a/src/erasure-code/jerasure/Makefile.am b/src/erasure-code/jerasure/Makefile.am index 86763af9d11..9ca4fbb35d7 100644 --- a/src/erasure-code/jerasure/Makefile.am +++ b/src/erasure-code/jerasure/Makefile.am @@ -1,15 +1,20 @@ # jerasure plugin noinst_HEADERS += \ + erasure-code/jerasure/gf-complete/include/gf_complete.h \ + erasure-code/jerasure/gf-complete/include/gf_general.h \ + erasure-code/jerasure/gf-complete/include/gf_int.h \ + erasure-code/jerasure/gf-complete/include/gf_method.h \ + erasure-code/jerasure/gf-complete/include/gf_rand.h \ + erasure-code/jerasure/gf-complete/include/gf_w16.h \ + erasure-code/jerasure/gf-complete/include/gf_w32.h \ + erasure-code/jerasure/gf-complete/include/gf_w4.h \ + erasure-code/jerasure/gf-complete/include/gf_w64.h \ + erasure-code/jerasure/gf-complete/include/gf_w8.h \ erasure-code/jerasure/jerasure/include/cauchy.h \ erasure-code/jerasure/jerasure/include/galois.h \ erasure-code/jerasure/jerasure/include/jerasure.h \ erasure-code/jerasure/jerasure/include/liberation.h \ erasure-code/jerasure/jerasure/include/reed_sol.h \ - erasure-code/jerasure/gf-complete/include/gf_int.h \ - erasure-code/jerasure/gf-complete/include/gf_complete.h \ - erasure-code/jerasure/gf-complete/include/gf_rand.h \ - erasure-code/jerasure/gf-complete/include/gf_method.h \ - erasure-code/jerasure/gf-complete/include/gf_general.h \ erasure-code/jerasure/ErasureCodeJerasure.h jerasure_sources = \ @@ -50,6 +55,30 @@ endif erasure_codelib_LTLIBRARIES += libec_jerasure_generic.la +libec_jerasure_neon_la_SOURCES = ${jerasure_sources} \ + erasure-code/jerasure/gf-complete/src/neon/gf_w4_neon.c \ + erasure-code/jerasure/gf-complete/src/neon/gf_w8_neon.c \ + erasure-code/jerasure/gf-complete/src/neon/gf_w16_neon.c \ + erasure-code/jerasure/gf-complete/src/neon/gf_w32_neon.c \ + erasure-code/jerasure/gf-complete/src/neon/gf_w64_neon.c +libec_jerasure_neon_la_CFLAGS = ${AM_CFLAGS} \ + ${ARM_NEON_FLAGS} \ + -I$(srcdir)/erasure-code/jerasure/gf-complete/include \ + -I$(srcdir)/erasure-code/jerasure/jerasure/include +libec_jerasure_neon_la_CXXFLAGS= ${AM_CXXFLAGS} \ + ${ARM_NEON_FLAGS} \ + -I$(srcdir)/erasure-code/jerasure/gf-complete/include \ + -I$(srcdir)/erasure-code/jerasure/jerasure/include +libec_jerasure_neon_la_LIBADD = $(LIBCRUSH) $(PTHREAD_LIBS) $(EXTRALIBS) +libec_jerasure_neon_la_LDFLAGS = ${AM_LDFLAGS} -version-info 2:0:0 +if LINUX +libec_jerasure_neon_la_LDFLAGS += -export-symbols-regex '.*__erasure_code_.*' +endif + +if HAVE_NEON +erasure_codelib_LTLIBRARIES += libec_jerasure_neon.la +endif + libec_jerasure_sse3_la_SOURCES = ${jerasure_sources} libec_jerasure_sse3_la_CFLAGS = ${AM_CFLAGS} \ ${INTEL_SSE_FLAGS} \ @@ -71,7 +100,9 @@ if LINUX libec_jerasure_sse3_la_LDFLAGS += -export-symbols-regex '.*__erasure_code_.*' endif +if HAVE_SSSE3 erasure_codelib_LTLIBRARIES += libec_jerasure_sse3.la +endif libec_jerasure_sse4_la_SOURCES = ${jerasure_sources} libec_jerasure_sse4_la_CFLAGS = ${AM_CFLAGS} \ @@ -98,7 +129,9 @@ if LINUX libec_jerasure_sse4_la_LDFLAGS += -export-symbols-regex '.*__erasure_code_.*' endif +if HAVE_SSE4_PCLMUL erasure_codelib_LTLIBRARIES += libec_jerasure_sse4.la +endif libec_jerasure_la_SOURCES = \ erasure-code/jerasure/ErasureCodePluginSelectJerasure.cc diff --git a/src/erasure-code/jerasure/gf-complete b/src/erasure-code/jerasure/gf-complete index 191e7105b2b..70dd94ae38f 160000 --- a/src/erasure-code/jerasure/gf-complete +++ b/src/erasure-code/jerasure/gf-complete @@ -1 +1 @@ -Subproject commit 191e7105b2b75f7f48ef23dfab9ae72275363168 +Subproject commit 70dd94ae38f2d20dd78532a6dfd1310fdfb4a884 diff --git a/src/test/erasure-code/Makefile.am b/src/test/erasure-code/Makefile.am index 723ebe34d76..08fe9e965f5 100644 --- a/src/test/erasure-code/Makefile.am +++ b/src/test/erasure-code/Makefile.am @@ -78,6 +78,14 @@ libec_fail_to_register_la_LIBADD = $(PTHREAD_LIBS) $(EXTRALIBS) libec_fail_to_register_la_LDFLAGS = ${AM_LDFLAGS} -export-symbols-regex '.*__erasure_code_.*' erasure_codelib_LTLIBRARIES += libec_fail_to_register.la +libec_test_jerasure_neon_la_SOURCES = test/erasure-code/TestJerasurePluginNEON.cc +test/erasure-code/TestJerasurePluginNEON.cc: ./ceph_ver.h +libec_test_jerasure_neon_la_CFLAGS = ${AM_CFLAGS} +libec_test_jerasure_neon_la_CXXFLAGS= ${AM_CXXFLAGS} +libec_test_jerasure_neon_la_LIBADD = $(PTHREAD_LIBS) $(EXTRALIBS) +libec_test_jerasure_neon_la_LDFLAGS = ${AM_LDFLAGS} -export-symbols-regex '.*__erasure_code_.*' +erasure_codelib_LTLIBRARIES += libec_test_jerasure_neon.la + libec_test_jerasure_sse4_la_SOURCES = test/erasure-code/TestJerasurePluginSSE4.cc test/erasure-code/TestJerasurePluginSSE4.cc: ./ceph_ver.h libec_test_jerasure_sse4_la_CFLAGS = ${AM_CFLAGS} diff --git a/src/test/erasure-code/TestErasureCodePluginJerasure.cc b/src/test/erasure-code/TestErasureCodePluginJerasure.cc index e6cb4c4458b..e8128a8bdee 100644 --- a/src/test/erasure-code/TestErasureCodePluginJerasure.cc +++ b/src/test/erasure-code/TestErasureCodePluginJerasure.cc @@ -4,6 +4,7 @@ * Ceph distributed storage system * * Copyright (C) 2013,2014 Cloudwatt + * Copyright (C) 2014 Red Hat * * Author: Loic Dachary * @@ -17,6 +18,7 @@ #include #include "arch/probe.h" #include "arch/intel.h" +#include "arch/neon.h" #include "global/global_init.h" #include "erasure-code/ErasureCodePlugin.h" #include "common/ceph_argparse.h" @@ -65,6 +67,7 @@ TEST(ErasureCodePlugin, select) int arch_intel_ssse3 = ceph_arch_intel_ssse3; int arch_intel_sse3 = ceph_arch_intel_sse3; int arch_intel_sse2 = ceph_arch_intel_sse2; + int arch_neon = ceph_arch_neon; ErasureCodePluginRegistry &instance = ErasureCodePluginRegistry::instance(); map parameters; @@ -82,6 +85,7 @@ TEST(ErasureCodePlugin, select) ceph_arch_intel_ssse3 = 1; ceph_arch_intel_sse3 = 1; ceph_arch_intel_sse2 = 1; + ceph_arch_neon = 0; ErasureCodeInterfaceRef erasure_code; int sse4_side_effect = -444; @@ -96,6 +100,7 @@ TEST(ErasureCodePlugin, select) ceph_arch_intel_ssse3 = 1; ceph_arch_intel_sse3 = 1; ceph_arch_intel_sse2 = 1; + ceph_arch_neon = 0; ErasureCodeInterfaceRef erasure_code; int sse3_side_effect = -333; @@ -110,11 +115,27 @@ TEST(ErasureCodePlugin, select) ceph_arch_intel_ssse3 = 1; ceph_arch_intel_sse3 = 0; ceph_arch_intel_sse2 = 1; + ceph_arch_neon = 0; ErasureCodeInterfaceRef erasure_code; int generic_side_effect = -111; EXPECT_EQ(generic_side_effect, instance.factory("jerasure", parameters, - &erasure_code, cerr)); + &erasure_code, cerr)); + } + // neon is set, load the neon plugin + { + ceph_arch_intel_pclmul = 0; + ceph_arch_intel_sse42 = 0; + ceph_arch_intel_sse41 = 0; + ceph_arch_intel_ssse3 = 0; + ceph_arch_intel_sse3 = 0; + ceph_arch_intel_sse2 = 0; + ceph_arch_neon = 1; + + ErasureCodeInterfaceRef erasure_code; + int generic_side_effect = -555; + EXPECT_EQ(generic_side_effect, instance.factory("jerasure", parameters, + &erasure_code, cerr)); } @@ -125,6 +146,7 @@ TEST(ErasureCodePlugin, select) ceph_arch_intel_ssse3 = arch_intel_ssse3; ceph_arch_intel_sse3 = arch_intel_sse3; ceph_arch_intel_sse2 = arch_intel_sse2; + ceph_arch_neon = arch_neon; } TEST(ErasureCodePlugin, sse) diff --git a/src/test/erasure-code/TestJerasurePluginNEON.cc b/src/test/erasure-code/TestJerasurePluginNEON.cc new file mode 100644 index 00000000000..cd38ccbd1e8 --- /dev/null +++ b/src/test/erasure-code/TestJerasurePluginNEON.cc @@ -0,0 +1,25 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph distributed storage system + * + * Copyright (C) 2014 Cloudwatt + * Copyright (C) 2014 Red Hat + * + * Author: Loic Dachary + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + */ + +#include "ceph_ver.h" + +extern "C" const char *__erasure_code_version() { return CEPH_GIT_NICE_VER; } + +extern "C" int __erasure_code_init(char *plugin_name, char *directory) +{ + return -555; +}