From b0209c2d4d771eb1c728549483244a63e11a818e Mon Sep 17 00:00:00 2001 From: Shaun Tancheff Date: Sun, 10 May 2020 15:14:54 -0500 Subject: [PATCH] LU-13485 build: Enable 2 stage configure tests This idea was implemented by OpenZFS a while ago. This is heavily inspired by the OpenZFS work. Here we enable splitting tests compile tests into two distinct parts that share an internal unique name. The source half can then be built in parallel and the results can be determined based on the build artifacts. Tests which depend on order of execution and/or the result of a previous test are not well suited for being converted. However the majority of lustre compile tests can be run in parallel. Signed-off-by: Shaun Tancheff Change-Id: If01ccdfdf4810ecc2d616da3fa6b7ca786fe760f Reviewed-on: https://review.whamcloud.com/38347 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Petros Koutoupis Reviewed-by: James Simmons Reviewed-by: Oleg Drokin --- config/lustre-build-ldiskfs.m4 | 4 + config/lustre-build-linux.m4 | 179 +++++++++++++++++++++++++++++++++++++++ config/lustre-build.m4 | 14 +++ libcfs/autoconf/lustre-libcfs.m4 | 2 + lnet/autoconf/lustre-lnet.m4 | 8 ++ lustre/autoconf/lustre-core.m4 | 15 ++++ 6 files changed, 222 insertions(+) diff --git a/config/lustre-build-ldiskfs.m4 b/config/lustre-build-ldiskfs.m4 index 88aaed7..6358dbf 100644 --- a/config/lustre-build-ldiskfs.m4 +++ b/config/lustre-build-ldiskfs.m4 @@ -427,6 +427,10 @@ AC_MSG_RESULT([$enable_ldiskfs]) AM_CONDITIONAL([LDISKFS_ENABLED], [test x$enable_ldiskfs = xyes]) ]) # LB_CONFIG_LDISKFS + +AC_DEFUN([LB_EXT4_SRC_DIR_SRC], []) +AC_DEFUN([LB_EXT4_SRC_DIR_RESULTS], []) + # # LB_VALIDATE_EXT4_SRC_DIR # diff --git a/config/lustre-build-linux.m4 b/config/lustre-build-linux.m4 index 53dc3a6..b8a5c2e 100644 --- a/config/lustre-build-linux.m4 +++ b/config/lustre-build-linux.m4 @@ -638,3 +638,182 @@ AC_CACHE_CHECK([for $1], lb_header, [ AS_VAR_IF([lb_header], [yes], [$2], [$3])[]dnl AS_VAR_POPDEF([lb_header])dnl ]) # LB_CHECK_LINUX_HEADER + +# ------------------------------------------------------------------------------ +# Support 2 stage: parallel compile then checked test results +# Heavily inspired by OpenZFS + +AC_DEFUN([LB2_LINUX_CONFTEST_C], [ +test -d ${TEST_DIR}/$2 || mkdir -p ${TEST_DIR}/$2 +cat confdefs.h - <<_EOF >${TEST_DIR}/$2/$2.c +$1 +_EOF +]) + +# +# LB2_LINUX_CONFTEST_MAKEFILE +# +# $1 - *unique* test case name +# $2 - additional build flags (ccflags) +# $3 - external kernel includes for lnet o2ib|gni +# +AC_DEFUN([LB2_LINUX_CONFTEST_MAKEFILE], [ + test -d ${TEST_DIR} || mkdir -p ${TEST_DIR} + test -d ${TEST_DIR}/$1 || mkdir -p ${TEST_DIR}/$1 + + file=${TEST_DIR}/$1/Makefile + EXT_INCLUDE="$3" + + cat - <<_EOF >$file +# Example command line to manually build source +# make modules -C $LINUX_OBJ $ARCH_UM M=${TEST_DIR}/$1 + +${LD:+LD="$LD"} +CC=$CC +ZINC=${ZFS} +SINC=${SPL} +ZOBJ=${ZFS_OBJ} +SOBJ=${SPL_OBJ} + +LINUXINCLUDE = $EXT_INCLUDE +LINUXINCLUDE += -I$LINUX/arch/$SUBARCH/include +LINUXINCLUDE += -Iinclude -Iarch/$SUBARCH/include/generated +LINUXINCLUDE += -I$LINUX/include +LINUXINCLUDE += -Iinclude2 +LINUXINCLUDE += -I$LINUX/include/uapi +LINUXINCLUDE += -Iinclude/generated +LINUXINCLUDE += -I$LINUX/arch/$SUBARCH/include/uapi +LINUXINCLUDE += -Iarch/$SUBARCH/include/generated/uapi +LINUXINCLUDE += -I$LINUX/include/uapi -Iinclude/generated/uapi +ifneq (\$(SOBJ),) +LINUXINCLUDE += -include \$(SOBJ)/spl_config.h +endif +ifneq (\$(ZOBJ),) +LINUXINCLUDE += -include \$(ZOBJ)/zfs_config.h +endif +ifneq (\$(SINC),) +LINUXINCLUDE += -I\$(SINC)/include +endif +ifneq (\$(ZINC),) +LINUXINCLUDE += -I\$(ZINC) -I\$(ZINC)/include +ifneq (\$(SINC),) +LINUXINCLUDE += -I\$(SINC) +else +LINUXINCLUDE += -I\$(ZINC)/include/spl +endif +endif +LINUXINCLUDE += -include $CONFIG_INCLUDE +KBUILD_EXTRA_SYMBOLS=${ZFS_OBJ:+$ZFS_OBJ/Module.symvers} + +ccflags-y := -Werror-implicit-function-declaration +_EOF + + # Additional custom CFLAGS as requested. + m4_ifval($2, [echo "ccflags-y += $2" >>$file], []) + + # Test case source + echo "obj-m := $1.o" >>$file + echo "obj-m += $1/" >>${TEST_DIR}/Makefile +]) + + +# +# LB2_LINUX_COMPILE +# +# $1 - build dir +# $2 - test command +# $3 - pass command +# $4 - fail command +# +# Used internally by LB2_LINUX_TEST_COMPILE +# +AC_DEFUN([LB2_LINUX_COMPILE], [ + AC_TRY_COMMAND([ + KBUILD_MODPOST_NOFINAL="yes" + make modules -k -j$TEST_JOBS -C $LINUX_OBJ $ARCH_UM + M=$1 >$1/build.log 2>&1]) + AS_IF([AC_TRY_COMMAND([$2])], [$3], [$4]) +]) + +# +# LB2_LINUX_TEST_COMPILE +# +# Perform a full compile excluding the final modpost phase. +# $1 - flavor +# $2 - dirname +# +AC_DEFUN([LB2_LINUX_TEST_COMPILE], [ + LB2_LINUX_COMPILE([$2], [test -f $2/build.log], [ + mv $2/Makefile $2/Makefile.compile.$1 + mv $2/build.log $2/build.log.$1 + ],[ + AC_MSG_ERROR([ + *** Unable to compile test source to determine kernel interfaces.]) + ]) +]) + +# +# Perform the compilation of the test cases in two phases. +# +# Phase 1) attempt to build the object files for all of the tests +# defined by the LB2_LINUX_TEST_SRC macro. +# +# Phase 2) disable all tests which failed the initial compilation. +# +# This allows us efficiently build the test cases in parallel while +# remaining resilient to build failures which are expected when +# detecting the available kernel interfaces. +# +# The maximum allowed parallelism can be controlled by setting the +# TEST_JOBS environment variable which defaults to $(nproc). +# +AC_DEFUN([LB2_LINUX_TEST_COMPILE_ALL], [ + # Phase 1 - Compilation only, final linking is skipped. + LB2_LINUX_TEST_COMPILE([$1], [${TEST_DIR}]) + + for dir in $(awk '/^obj-m/ { print [$]3 }' \ + ${TEST_DIR}/Makefile.compile.$1); do + name=${dir%/} + AS_IF([test -f ${TEST_DIR}/$name/$name.o], [ + touch ${TEST_DIR}/$name/$name.ko + ]) + done +]) + +# +# LB2_LINUX_TEST_SRC +# +# $1 - *unique* name +# $2 - global +# $3 - source +# $4 - extra cflags +# $5 - external include paths +# +# NOTICE as all of the test cases are compiled in parallel tests may not +# depend on the results other tests. +# Each test needs resolve any external dependencies at the time the program +# source is generated. +# +AC_DEFUN([LB2_LINUX_TEST_SRC], [ + LB2_LINUX_CONFTEST_C([LB_LANG_PROGRAM([[$2]], [[$3]])], [$1]) + LB2_LINUX_CONFTEST_MAKEFILE([$1], [$4], [$5]) +]) + +# +# LB2_LINUX_TEST_RESULT +# +# $1 - *unique* name matching the LB2_LINUX_TEST_SRC macro +# $2 - run on success (valid .ko generated) +# $3 - run on failure (unable to compile) +# +AC_DEFUN([LB2_LINUX_TEST_RESULT], [ + AS_IF([test -d ${TEST_DIR}/$1], [ + AS_IF([test -f ${TEST_DIR}/$1/$1.ko], [$2], [$3]) + ], [ + AC_MSG_ERROR([ + *** No matching source for the "$1" test, check that + *** both the test source and result macros refer to the same name. + ]) + ]) +]) + diff --git a/config/lustre-build.m4 b/config/lustre-build.m4 index 4b9f9d1..2f6a98c 100644 --- a/config/lustre-build.m4 +++ b/config/lustre-build.m4 @@ -157,11 +157,25 @@ AC_MSG_RESULT([$enable_modules ($target_os)]) AS_IF([test "x$enable_modules" = xyes], [ AS_CASE([$target_os], [linux*], [ + # Run serial tests LB_PROG_LINUX LIBCFS_PROG_LINUX LN_PROG_LINUX AS_IF([test "x$enable_server" != xno], [LB_EXT4_SRC_DIR]) LC_PROG_LINUX + + # Run any parallel compile tests + LIBCFS_PROG_LINUX_SRC + LN_PROG_LINUX_SRC + AS_IF([test "x$enable_server" != xno], [LB_EXT4_SRC_DIR_SRC]) + LC_PROG_LINUX_SRC + + # Collect parallel compile tests results + LIBCFS_PROG_LINUX_RESULTS + LN_PROG_LINUX_RESULTS + AS_IF([test "x$enable_server" != xno], [LB_EXT4_SRC_DIR_RESULTS]) + LC_PROG_LINUX_RESULTS + ], [*], [ # This is strange - Lustre supports a target we don't AC_MSG_ERROR([Modules are not supported on $target_os]) diff --git a/libcfs/autoconf/lustre-libcfs.m4 b/libcfs/autoconf/lustre-libcfs.m4 index e933bc6..c3efe06 100644 --- a/libcfs/autoconf/lustre-libcfs.m4 +++ b/libcfs/autoconf/lustre-libcfs.m4 @@ -1259,6 +1259,8 @@ Lustre requires that CONFIG_CRYPTO_CRC32 is enabled in your kernel. ])]) ]) # LIBCFS_CONFIG_CRYPTO_CRC32 +AC_DEFUN([LIBCFS_PROG_LINUX_SRC], [] ) +AC_DEFUN([LIBCFS_PROG_LINUX_RESULTS], []) # # LIBCFS_PROG_LINUX diff --git a/lnet/autoconf/lustre-lnet.m4 b/lnet/autoconf/lustre-lnet.m4 index 961808b..139ce1c 100644 --- a/lnet/autoconf/lustre-lnet.m4 +++ b/lnet/autoconf/lustre-lnet.m4 @@ -102,6 +102,8 @@ esac AS_IF([test $ENABLEO2IB = "no"], [ AC_MSG_RESULT([no]) + AC_DEFUN([LN_CONFIG_O2IB_SRC], []) + AC_DEFUN([LN_CONFIG_O2IB_RESULTS], []) ], [ o2ib_found=false for O2IBPATH in $O2IBPATHS; do @@ -521,6 +523,8 @@ AS_IF([test $ENABLEO2IB != "no"], [ LN_IB_SG_DMA_ADDRESS_EXISTS EXTRA_CHECK_INCLUDE="" + AC_DEFUN([LN_CONFIG_O2IB_SRC], []) + AC_DEFUN([LN_CONFIG_O2IB_RESULTS], []) ]) # ENABLEO2IB != "no" ]) # LN_CONFIG_O2IB @@ -767,6 +771,10 @@ AC_COMPILE_IFELSE([AC_LANG_SOURCE([ ]) ]) # LN_USR_RDMA + +AC_DEFUN([LN_PROG_LINUX_SRC], []) +AC_DEFUN([LN_PROG_LINUX_RESULTS], []) + # # LN_PROG_LINUX # diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index b3242f7..4eec916 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -285,6 +285,18 @@ AC_ARG_ENABLE([gss], [], [enable_gss="auto"]) AC_MSG_RESULT([$enable_gss]) +AC_ARG_VAR([TEST_JOBS], + [simultaneous jobs during configure (defaults to $(nproc))]) +if test "x$ac_cv_env_TEST_JOBS_set" != "xset"; then + TEST_JOBS=${TEST_JOBS:-$(nproc)} +fi +AC_SUBST(TEST_JOBS) + +AC_ARG_VAR([TEST_DIR], + [location of temporary parallel configure tests (defaults to $PWD/lb2)]) + TEST_DIR=${TEST_DIR:-$PWD/_lpb} +AC_SUBST(TEST_DIR) + AS_IF([test "x$enable_gss" != xno], [ LC_CONFIG_GSS_KEYRING LC_KEY_TYPE_INSTANTIATE_2ARGS @@ -2189,6 +2201,9 @@ lock_manager_ops_lm_compare_owner, [ EXTRA_KCFLAGS="$tmp_flags" ]) # LC_LM_COMPARE_OWNER_EXISTS +AC_DEFUN([LC_PROG_LINUX_SRC], []) +AC_DEFUN([LC_PROG_LINUX_RESULTS], []) + # # LC_FSCRYPT_SUPPORT # -- 1.8.3.1