Starting from Kevin and Bruce idea of using libabigail, here is an alternate approach to implement ABI checks. By default, those checks are disabled and enabling them requires a manual step that generates the ABI dumps on a reference version for a set of configurations. Those checks are enabled in the CI by default for the default meson options on x86 and aarch64 so that proposed patches are validated. A cache of the ABI is stored in travis jobs. Checks can be only informational by setting ABI_CHECKS_WARN_ONLY when breaking the ABI in a future release. For advanced developers and maintainers, the contributing guide details the higher level scripts that are quite close to the existing devtools scripts. Signed-off-by: David Marchand <david.marchand@redhat.com> --- .ci/linux-build.sh | 43 +++++++++++++++++++++++++++ .travis.yml | 20 +++++++++++-- devtools/check-abi-dump.sh | 46 +++++++++++++++++++++++++++++ devtools/check-abi-reference.sh | 27 +++++++++++++++++ devtools/dpdk.abignore | 2 ++ devtools/gen-abi-dump.sh | 29 ++++++++++++++++++ devtools/gen-abi-reference.sh | 24 +++++++++++++++ devtools/test-build.sh | 13 ++++++-- devtools/test-meson-builds.sh | 6 ++++ doc/guides/contributing/patches.rst | 25 ++++++++++++++++ 10 files changed, 230 insertions(+), 5 deletions(-) create mode 100755 devtools/check-abi-dump.sh create mode 100755 devtools/check-abi-reference.sh create mode 100644 devtools/dpdk.abignore create mode 100755 devtools/gen-abi-dump.sh create mode 100755 devtools/gen-abi-reference.sh diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh index ccc3a7ccd..345dba264 100755 --- a/.ci/linux-build.sh +++ b/.ci/linux-build.sh @@ -30,8 +30,51 @@ fi OPTS="$OPTS --default-library=$DEF_LIB" meson build --werror -Dexamples=all $OPTS + +if [ "$ABI_CHECKS" = "1" ]; then + git remote add ref ${REF_GIT_REPO:-https://dpdk.org/git/dpdk} + git fetch --tags ref ${REF_GIT_BRANCH:-master} + + head=$(git describe --all) + tag=$(git describe --abbrev=0) + + if [ "$(cat reference/VERSION 2>/dev/null)" != "$tag" ]; then + rm -rf reference + fi + + if [ ! -d reference ]; then + gen_abi_dump=$(mktemp -t gen-abi-dump-XXX.sh) + cp -a devtools/gen-abi-dump.sh $gen_abi_dump + + git checkout -qf $tag + ninja -C build + $gen_abi_dump build reference + + if [ "$AARCH64" != "1" ]; then + mkdir -p reference/app + cp -a build/app/dpdk-testpmd reference/app/ + + export LD_LIBRARY_PATH=$(pwd)/build/lib:$(pwd)/build/drivers + devtools/test-null.sh reference/app/dpdk-testpmd + unset LD_LIBRARY_PATH + fi + echo $tag > reference/VERSION + + git checkout -qf $head + fi +fi + ninja -C build +if [ "$ABI_CHECKS" = "1" ]; then + devtools/check-abi-dump.sh build reference ${ABI_CHECKS_WARN_ONLY:-} + if [ "$AARCH64" != "1" ]; then + export LD_LIBRARY_PATH=$(pwd)/build/lib:$(pwd)/build/drivers + devtools/test-null.sh reference/app/dpdk-testpmd + unset LD_LIBRARY_PATH + fi +fi + if [ "$AARCH64" != "1" ]; then devtools/test-null.sh fi diff --git a/.travis.yml b/.travis.yml index 8f90d06f2..bbb060fa2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,8 @@ language: c -cache: ccache +cache: + ccache: true + directories: + - reference compiler: - gcc - clang @@ -21,7 +24,7 @@ aarch64_packages: &aarch64_packages extra_packages: &extra_packages - *required_packages - - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4] + - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4, abigail-tools] build_32b_packages: &build_32b_packages - *required_packages @@ -59,6 +62,13 @@ matrix: apt: packages: - *aarch64_packages + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1 AARCH64=1 + compiler: gcc + addons: + apt: + packages: + - *aarch64_packages + - *extra_packages - env: DEF_LIB="static" EXTRA_PACKAGES=1 compiler: gcc addons: @@ -72,6 +82,12 @@ matrix: packages: - *extra_packages - *doc_packages + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1 + compiler: gcc + addons: + apt: + packages: + - *extra_packages - env: DEF_LIB="static" OPTS="-Denable_kmods=false" EXTRA_PACKAGES=1 compiler: gcc addons: diff --git a/devtools/check-abi-dump.sh b/devtools/check-abi-dump.sh new file mode 100755 index 000000000..f48a2ae7e --- /dev/null +++ b/devtools/check-abi-dump.sh @@ -0,0 +1,46 @@ +#!/bin/sh -e +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2019 Red Hat, Inc. + +if [ $# != 2 ] && [ $# != 3 ]; then + echo "Usage: $0 builddir dumpdir [warnonly]" + exit 1 +fi + +builddir=$1 +dumpdir=$2 +warnonly=${3:-} +if [ ! -d $builddir ]; then + echo "Error: build directory '$builddir' does not exist." + exit 1 +fi +if [ ! -d $dumpdir ]; then + echo "Error: dump directory '$dumpdir' does not exist." + exit 1 +fi + +ABIDIFF_OPTIONS="--suppr $(dirname $0)/dpdk.abignore" +for dump in $(find $dumpdir -name "*.dump"); do + libname=$(basename $dump) + libname=${libname%.dump} + result= + for f in $(find $builddir -name "$libname.so.*"); do + if test -L $f || [ "$f" != "${f%%.symbols}" ]; then + continue + fi + result=found + + if ! abidiff $ABIDIFF_OPTIONS $dump $f; then + if [ -z "$warnonly" ]; then + echo "Error: ABI issue reported for $dump, $f" + exit 1 + fi + echo "Warning: ABI issue reported for $dump, $f" + fi + break + done + if [ "$result" != "found" ]; then + echo "Error: can't find a library for dump file $dump" + exit 1 + fi +done diff --git a/devtools/check-abi-reference.sh b/devtools/check-abi-reference.sh new file mode 100755 index 000000000..7addb094e --- /dev/null +++ b/devtools/check-abi-reference.sh @@ -0,0 +1,27 @@ +#!/bin/sh -e +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2019 Red Hat, Inc. + +devtools_dir=$(dirname $(readlink -f $0)) +. $devtools_dir/load-devel-config + +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference} +builds_dir=${DPDK_BUILD_TEST_DIR:-.} + +for dir in $abi_ref_build_dir/*; do + if [ "$dir" = "$abi_ref_build_dir" ]; then + exit 1 + fi + if [ ! -d $dir/dump ]; then + echo "Skipping $dir" + continue + fi + target=$(basename $dir) + if [ -d $builds_dir/$target/install ]; then + libdir=$builds_dir/$target/install + else + libdir=$builds_dir/$target + fi + echo "Checking ABI between $libdir and $dir/dump" + $devtools_dir/check-abi-dump.sh $libdir $dir/dump +done diff --git a/devtools/dpdk.abignore b/devtools/dpdk.abignore new file mode 100644 index 000000000..b866b7f26 --- /dev/null +++ b/devtools/dpdk.abignore @@ -0,0 +1,2 @@ +[suppress_function] + symbol_version = EXPERIMENTAL diff --git a/devtools/gen-abi-dump.sh b/devtools/gen-abi-dump.sh new file mode 100755 index 000000000..4e38d751f --- /dev/null +++ b/devtools/gen-abi-dump.sh @@ -0,0 +1,29 @@ +#!/bin/sh -e +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2019 Red Hat, Inc. + +if [ $# != 2 ]; then + echo "Usage: $0 builddir dumpdir" + exit 1 +fi + +builddir=$1 +dumpdir=$2 +if [ ! -d $builddir ]; then + echo "Error: build directory '$builddir' does not exist." + exit 1 +fi +if [ -d $dumpdir ]; then + echo "Error: dump directory '$dumpdir' already exists." + exit 1 +fi + +mkdir -p $dumpdir +for f in $(find $builddir -name "*.so.*"); do + if test -L $f || [ "$f" != "${f%%.symbols}" ]; then + continue + fi + + libname=$(basename $f) + abidw --out-file $dumpdir/${libname%.so.*}.dump $f +done diff --git a/devtools/gen-abi-reference.sh b/devtools/gen-abi-reference.sh new file mode 100755 index 000000000..f41d7fadc --- /dev/null +++ b/devtools/gen-abi-reference.sh @@ -0,0 +1,24 @@ +#!/bin/sh -e +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2019 Red Hat, Inc. + +devtools_dir=$(dirname $(readlink -f $0)) +. $devtools_dir/load-devel-config + +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference} +for dir in $abi_ref_build_dir/*; do + if [ "$dir" = "$abi_ref_build_dir" ]; then + exit 1 + fi + if [ -d $dir/dump ]; then + echo "Skipping $dir" + continue + fi + if [ -d $dir/install ]; then + libdir=$dir/install + else + libdir=$dir + fi + echo "Dumping libraries from $libdir in $dir/dump" + $devtools_dir/gen-abi-dump.sh $libdir $dir/dump +done diff --git a/devtools/test-build.sh b/devtools/test-build.sh index 52305fbb8..8cb5b56fb 100755 --- a/devtools/test-build.sh +++ b/devtools/test-build.sh @@ -30,7 +30,8 @@ default_path=$PATH # - LIBSSO_SNOW3G_PATH # - LIBSSO_KASUMI_PATH # - LIBSSO_ZUC_PATH -. $(dirname $(readlink -f $0))/load-devel-config +devtools_dir=$(dirname $(readlink -f $0)) +. $devtools_dir/load-devel-config print_usage () { echo "usage: $(basename $0) [-h] [-jX] [-s] [config1 [config2] ...]]" @@ -64,6 +65,7 @@ print_help () { [ -z $MAKE ] && echo "Cannot find make or gmake" && exit 1 J=$DPDK_MAKE_JOBS +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference} builds_dir=${DPDK_BUILD_TEST_DIR:-.} short=false unset verbose @@ -97,7 +99,7 @@ trap "signal=INT ; trap - INT ; kill -INT $$" INT # notify result on exit trap on_exit EXIT -cd $(dirname $(readlink -f $0))/.. +cd $devtools_dir/.. reset_env () { @@ -233,7 +235,7 @@ for conf in $configs ; do # reload config with DPDK_TARGET set DPDK_TARGET=$target reset_env - . $(dirname $(readlink -f $0))/load-devel-config + . $devtools_dir/load-devel-config options=$(echo $conf | sed 's,[^~+]*,,') dir=$builds_dir/$conf @@ -246,6 +248,11 @@ for conf in $configs ; do export RTE_TARGET=$target rm -rf $dir/install ${MAKE} install O=$dir DESTDIR=$dir/install prefix= + if [ -d $abi_ref_build_dir/$conf/dump ]; then + echo "================== Check ABI $conf" + $devtools_dir/check-abi-dump.sh $dir/install \ + $abi_ref_build_dir/$conf/dump + fi echo "================== Build examples for $conf" export RTE_SDK=$(readlink -f $dir)/install/share/dpdk ln -sTf $(pwd)/lib $RTE_SDK/lib # workaround for vm_power_manager diff --git a/devtools/test-meson-builds.sh b/devtools/test-meson-builds.sh index 688567714..aaefa38a2 100755 --- a/devtools/test-meson-builds.sh +++ b/devtools/test-meson-builds.sh @@ -16,6 +16,7 @@ srcdir=$(dirname $(readlink -f $0))/.. MESON=${MESON:-meson} use_shared="--default-library=shared" +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference} builds_dir=${DPDK_BUILD_TEST_DIR:-.} if command -v gmake >/dev/null 2>&1 ; then @@ -88,6 +89,11 @@ build () # <directory> <target compiler> <meson options> echo "$ninja_cmd -C $builddir" $ninja_cmd -C $builddir fi + + if [ -d $abi_ref_build_dir/$1/dump ]; then + $srcdir/devtools/check-abi-dump.sh $builddir + $abi_ref_build_dir/$1/dump + fi } if [ "$1" = "-vv" ] ; then diff --git a/doc/guides/contributing/patches.rst b/doc/guides/contributing/patches.rst index 0686450e4..de3dff145 100644 --- a/doc/guides/contributing/patches.rst +++ b/doc/guides/contributing/patches.rst @@ -513,6 +513,31 @@ in a single subfolder called "__builds" created in the current directory. Setting ``DPDK_BUILD_TEST_DIR`` to an absolute directory path e.g. ``/tmp`` is also supported. +Checking ABI compatibility +-------------------------- + +The first thing is to build reference binaries for the latest release your +patches are built on top of. + +Either you are in a git tree and an easy way to identify this is to run:: + + git checkout $(git describe --abbrev=0) + +Or you use a tarball and you extract the sources in a director of your choice. + +Next is building those sources, refer to the previous paragraph. +You can set ``DPDK_BUILD_TEST_DIR=reference``, so that the builds occur in this +directory. + +Finally, the ABI dump files are generated with the +``devtools/gen-abi-reference.sh`` script. This script will look for builds in +the current sub directory ``reference``. But you can set the environment +variable ``DPDK_ABI_REF_BUILD_DIR`` to a different location. + +Once done, you can check your current binaries ABI with this reference with the +``devtools/check-abi-reference.sh`` script. + + Sending Patches --------------- -- 2.23.0
> -----Original Message-----
> From: David Marchand <david.marchand@redhat.com>
> Sent: Friday, December 20, 2019 3:21 PM
> To: dev@dpdk.org
> Cc: thomas@monjalon.net; Richardson, Bruce <bruce.richardson@intel.com>;
> Laatz, Kevin <kevin.laatz@intel.com>; aconole@redhat.com;
> nhorman@tuxdriver.com; Michael Santana <maicolgabriel@hotmail.com>;
> Mcnamara, John <john.mcnamara@intel.com>; Kovacevic, Marko
> <marko.kovacevic@intel.com>
> Subject: [PATCH] add ABI checks
>
> Starting from Kevin and Bruce idea of using libabigail, here is an
> alternate approach to implement ABI checks.
>
> By default, those checks are disabled and enabling them requires a manual
> step that generates the ABI dumps on a reference version for a set of
> configurations.
>
> Those checks are enabled in the CI by default for the default meson
> options on x86 and aarch64 so that proposed patches are validated.
> A cache of the ABI is stored in travis jobs.
> Checks can be only informational by setting ABI_CHECKS_WARN_ONLY when
> breaking the ABI in a future release.
>
> For advanced developers and maintainers, the contributing guide details
> the higher level scripts that are quite close to the existing devtools
> scripts.
>
> Signed-off-by: David Marchand <david.marchand@redhat.com>
> ---
> .ci/linux-build.sh | 43 +++++++++++++++++++++++++++
> .travis.yml | 20 +++++++++++--
> devtools/check-abi-dump.sh | 46 +++++++++++++++++++++++++++++
> devtools/check-abi-reference.sh | 27 +++++++++++++++++
> devtools/dpdk.abignore | 2 ++
> devtools/gen-abi-dump.sh | 29 ++++++++++++++++++
> devtools/gen-abi-reference.sh | 24 +++++++++++++++
> devtools/test-build.sh | 13 ++++++--
> devtools/test-meson-builds.sh | 6 ++++
> doc/guides/contributing/patches.rst | 25 ++++++++++++++++
> 10 files changed, 230 insertions(+), 5 deletions(-) create mode 100755
> devtools/check-abi-dump.sh create mode 100755 devtools/check-abi-
> reference.sh create mode 100644 devtools/dpdk.abignore create mode
> 100755 devtools/gen-abi-dump.sh create mode 100755 devtools/gen-abi-
> reference.sh
>
> diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh index
> ccc3a7ccd..345dba264 100755
> --- a/.ci/linux-build.sh
> +++ b/.ci/linux-build.sh
> @@ -30,8 +30,51 @@ fi
>
> OPTS="$OPTS --default-library=$DEF_LIB"
> meson build --werror -Dexamples=all $OPTS
> +
> +if [ "$ABI_CHECKS" = "1" ]; then
> + git remote add ref ${REF_GIT_REPO:-https://dpdk.org/git/dpdk}
> + git fetch --tags ref ${REF_GIT_BRANCH:-master}
> +
> + head=$(git describe --all)
> + tag=$(git describe --abbrev=0)
> +
> + if [ "$(cat reference/VERSION 2>/dev/null)" != "$tag" ]; then
> + rm -rf reference
> + fi
> +
> + if [ ! -d reference ]; then
> + gen_abi_dump=$(mktemp -t gen-abi-dump-XXX.sh)
> + cp -a devtools/gen-abi-dump.sh $gen_abi_dump
> +
> + git checkout -qf $tag
> + ninja -C build
> + $gen_abi_dump build reference
> +
> + if [ "$AARCH64" != "1" ]; then
> + mkdir -p reference/app
> + cp -a build/app/dpdk-testpmd reference/app/
> +
> + export LD_LIBRARY_PATH=$(pwd)/build/lib:$(pwd)/build/drivers
> + devtools/test-null.sh reference/app/dpdk-testpmd
> + unset LD_LIBRARY_PATH
> + fi
> + echo $tag > reference/VERSION
> +
> + git checkout -qf $head
> + fi
> +fi
> +
> ninja -C build
>
> +if [ "$ABI_CHECKS" = "1" ]; then
> + devtools/check-abi-dump.sh build reference ${ABI_CHECKS_WARN_ONLY:-}
> + if [ "$AARCH64" != "1" ]; then
> + export LD_LIBRARY_PATH=$(pwd)/build/lib:$(pwd)/build/drivers
> + devtools/test-null.sh reference/app/dpdk-testpmd
> + unset LD_LIBRARY_PATH
> + fi
> +fi
> +
> if [ "$AARCH64" != "1" ]; then
> devtools/test-null.sh
> fi
> diff --git a/.travis.yml b/.travis.yml
> index 8f90d06f2..bbb060fa2 100644
> --- a/.travis.yml
> +++ b/.travis.yml
> @@ -1,5 +1,8 @@
> language: c
> -cache: ccache
> +cache:
> + ccache: true
> + directories:
> + - reference
> compiler:
> - gcc
> - clang
> @@ -21,7 +24,7 @@ aarch64_packages: &aarch64_packages
>
> extra_packages: &extra_packages
> - *required_packages
> - - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4]
> + - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4,
> + abigail-tools]
>
> build_32b_packages: &build_32b_packages
> - *required_packages
> @@ -59,6 +62,13 @@ matrix:
> apt:
> packages:
> - *aarch64_packages
> + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1 AARCH64=1
> + compiler: gcc
> + addons:
> + apt:
> + packages:
> + - *aarch64_packages
> + - *extra_packages
> - env: DEF_LIB="static" EXTRA_PACKAGES=1
> compiler: gcc
> addons:
> @@ -72,6 +82,12 @@ matrix:
> packages:
> - *extra_packages
> - *doc_packages
> + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1
> + compiler: gcc
> + addons:
> + apt:
> + packages:
> + - *extra_packages
> - env: DEF_LIB="static" OPTS="-Denable_kmods=false" EXTRA_PACKAGES=1
> compiler: gcc
> addons:
> diff --git a/devtools/check-abi-dump.sh b/devtools/check-abi-dump.sh new
> file mode 100755 index 000000000..f48a2ae7e
> --- /dev/null
> +++ b/devtools/check-abi-dump.sh
> @@ -0,0 +1,46 @@
> +#!/bin/sh -e
> +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red Hat,
> +Inc.
> +
> +if [ $# != 2 ] && [ $# != 3 ]; then
> + echo "Usage: $0 builddir dumpdir [warnonly]"
> + exit 1
> +fi
> +
> +builddir=$1
> +dumpdir=$2
> +warnonly=${3:-}
> +if [ ! -d $builddir ]; then
> + echo "Error: build directory '$builddir' does not exist."
> + exit 1
> +fi
> +if [ ! -d $dumpdir ]; then
> + echo "Error: dump directory '$dumpdir' does not exist."
> + exit 1
> +fi
> +
> +ABIDIFF_OPTIONS="--suppr $(dirname $0)/dpdk.abignore"
> +for dump in $(find $dumpdir -name "*.dump"); do
> + libname=$(basename $dump)
> + libname=${libname%.dump}
> + result=
> + for f in $(find $builddir -name "$libname.so.*"); do
> + if test -L $f || [ "$f" != "${f%%.symbols}" ]; then
> + continue
> + fi
> + result=found
> +
> + if ! abidiff $ABIDIFF_OPTIONS $dump $f; then
> + if [ -z "$warnonly" ]; then
> + echo "Error: ABI issue reported for $dump, $f"
> + exit 1
> + fi
> + echo "Warning: ABI issue reported for $dump, $f"
> + fi
> + break
> + done
> + if [ "$result" != "found" ]; then
> + echo "Error: can't find a library for dump file $dump"
> + exit 1
> + fi
> +done
> diff --git a/devtools/check-abi-reference.sh b/devtools/check-abi-
> reference.sh new file mode 100755 index 000000000..7addb094e
> --- /dev/null
> +++ b/devtools/check-abi-reference.sh
> @@ -0,0 +1,27 @@
> +#!/bin/sh -e
> +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red Hat,
> +Inc.
> +
> +devtools_dir=$(dirname $(readlink -f $0)) .
> +$devtools_dir/load-devel-config
> +
> +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference}
> +builds_dir=${DPDK_BUILD_TEST_DIR:-.}
> +
> +for dir in $abi_ref_build_dir/*; do
> + if [ "$dir" = "$abi_ref_build_dir" ]; then
> + exit 1
> + fi
> + if [ ! -d $dir/dump ]; then
> + echo "Skipping $dir"
> + continue
> + fi
> + target=$(basename $dir)
> + if [ -d $builds_dir/$target/install ]; then
> + libdir=$builds_dir/$target/install
> + else
> + libdir=$builds_dir/$target
> + fi
> + echo "Checking ABI between $libdir and $dir/dump"
> + $devtools_dir/check-abi-dump.sh $libdir $dir/dump done
> diff --git a/devtools/dpdk.abignore b/devtools/dpdk.abignore new file mode
> 100644 index 000000000..b866b7f26
> --- /dev/null
> +++ b/devtools/dpdk.abignore
> @@ -0,0 +1,2 @@
> +[suppress_function]
> + symbol_version = EXPERIMENTAL
> diff --git a/devtools/gen-abi-dump.sh b/devtools/gen-abi-dump.sh new file
> mode 100755 index 000000000..4e38d751f
> --- /dev/null
> +++ b/devtools/gen-abi-dump.sh
> @@ -0,0 +1,29 @@
> +#!/bin/sh -e
> +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red Hat,
> +Inc.
> +
> +if [ $# != 2 ]; then
> + echo "Usage: $0 builddir dumpdir"
> + exit 1
> +fi
> +
> +builddir=$1
> +dumpdir=$2
> +if [ ! -d $builddir ]; then
> + echo "Error: build directory '$builddir' does not exist."
> + exit 1
> +fi
> +if [ -d $dumpdir ]; then
> + echo "Error: dump directory '$dumpdir' already exists."
> + exit 1
> +fi
> +
> +mkdir -p $dumpdir
> +for f in $(find $builddir -name "*.so.*"); do
> + if test -L $f || [ "$f" != "${f%%.symbols}" ]; then
> + continue
> + fi
> +
> + libname=$(basename $f)
> + abidw --out-file $dumpdir/${libname%.so.*}.dump $f done
> diff --git a/devtools/gen-abi-reference.sh b/devtools/gen-abi-reference.sh
> new file mode 100755 index 000000000..f41d7fadc
> --- /dev/null
> +++ b/devtools/gen-abi-reference.sh
> @@ -0,0 +1,24 @@
> +#!/bin/sh -e
> +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red Hat,
> +Inc.
> +
> +devtools_dir=$(dirname $(readlink -f $0)) .
> +$devtools_dir/load-devel-config
> +
> +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference}
> +for dir in $abi_ref_build_dir/*; do
> + if [ "$dir" = "$abi_ref_build_dir" ]; then
> + exit 1
> + fi
> + if [ -d $dir/dump ]; then
> + echo "Skipping $dir"
> + continue
> + fi
> + if [ -d $dir/install ]; then
> + libdir=$dir/install
> + else
> + libdir=$dir
> + fi
> + echo "Dumping libraries from $libdir in $dir/dump"
> + $devtools_dir/gen-abi-dump.sh $libdir $dir/dump done
> diff --git a/devtools/test-build.sh b/devtools/test-build.sh index
> 52305fbb8..8cb5b56fb 100755
> --- a/devtools/test-build.sh
> +++ b/devtools/test-build.sh
> @@ -30,7 +30,8 @@ default_path=$PATH
> # - LIBSSO_SNOW3G_PATH
> # - LIBSSO_KASUMI_PATH
> # - LIBSSO_ZUC_PATH
> -. $(dirname $(readlink -f $0))/load-devel-config
> +devtools_dir=$(dirname $(readlink -f $0)) .
> +$devtools_dir/load-devel-config
>
> print_usage () {
> echo "usage: $(basename $0) [-h] [-jX] [-s] [config1 [config2]
> ...]]"
> @@ -64,6 +65,7 @@ print_help () {
> [ -z $MAKE ] && echo "Cannot find make or gmake" && exit 1
>
> J=$DPDK_MAKE_JOBS
> +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference}
> builds_dir=${DPDK_BUILD_TEST_DIR:-.}
> short=false
> unset verbose
> @@ -97,7 +99,7 @@ trap "signal=INT ; trap - INT ; kill -INT $$" INT #
> notify result on exit trap on_exit EXIT
>
> -cd $(dirname $(readlink -f $0))/..
> +cd $devtools_dir/..
>
> reset_env ()
> {
> @@ -233,7 +235,7 @@ for conf in $configs ; do
> # reload config with DPDK_TARGET set
> DPDK_TARGET=$target
> reset_env
> - . $(dirname $(readlink -f $0))/load-devel-config
> + . $devtools_dir/load-devel-config
>
> options=$(echo $conf | sed 's,[^~+]*,,')
> dir=$builds_dir/$conf
> @@ -246,6 +248,11 @@ for conf in $configs ; do
> export RTE_TARGET=$target
> rm -rf $dir/install
> ${MAKE} install O=$dir DESTDIR=$dir/install prefix=
> + if [ -d $abi_ref_build_dir/$conf/dump ]; then
> + echo "================== Check ABI $conf"
> + $devtools_dir/check-abi-dump.sh $dir/install \
> + $abi_ref_build_dir/$conf/dump
> + fi
> echo "================== Build examples for $conf"
> export RTE_SDK=$(readlink -f $dir)/install/share/dpdk
> ln -sTf $(pwd)/lib $RTE_SDK/lib # workaround for vm_power_manager
> diff --git a/devtools/test-meson-builds.sh b/devtools/test-meson-builds.sh
> index 688567714..aaefa38a2 100755
> --- a/devtools/test-meson-builds.sh
> +++ b/devtools/test-meson-builds.sh
> @@ -16,6 +16,7 @@ srcdir=$(dirname $(readlink -f $0))/..
>
> MESON=${MESON:-meson}
> use_shared="--default-library=shared"
> +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference}
> builds_dir=${DPDK_BUILD_TEST_DIR:-.}
>
> if command -v gmake >/dev/null 2>&1 ; then @@ -88,6 +89,11 @@ build () #
> <directory> <target compiler> <meson options>
> echo "$ninja_cmd -C $builddir"
> $ninja_cmd -C $builddir
> fi
> +
> + if [ -d $abi_ref_build_dir/$1/dump ]; then
> + $srcdir/devtools/check-abi-dump.sh $builddir
> + $abi_ref_build_dir/$1/dump
> + fi
> }
>
> if [ "$1" = "-vv" ] ; then
> diff --git a/doc/guides/contributing/patches.rst
> b/doc/guides/contributing/patches.rst
> index 0686450e4..de3dff145 100644
> --- a/doc/guides/contributing/patches.rst
> +++ b/doc/guides/contributing/patches.rst
> @@ -513,6 +513,31 @@ in a single subfolder called "__builds" created in
> the current directory.
> Setting ``DPDK_BUILD_TEST_DIR`` to an absolute directory path e.g.
> ``/tmp`` is also supported.
>
>
> +Checking ABI compatibility
> +--------------------------
> +
> +The first thing is to build reference binaries for the latest release
> +your patches are built on top of.
> +
> +Either you are in a git tree and an easy way to identify this is to run::
> +
> + git checkout $(git describe --abbrev=0)
> +
> +Or you use a tarball and you extract the sources in a director of your
> choice.
> +
> +Next is building those sources, refer to the previous paragraph.
> +You can set ``DPDK_BUILD_TEST_DIR=reference``, so that the builds occur
> +in this directory.
> +
> +Finally, the ABI dump files are generated with the
> +``devtools/gen-abi-reference.sh`` script. This script will look for
> +builds in the current sub directory ``reference``. But you can set the
> +environment variable ``DPDK_ABI_REF_BUILD_DIR`` to a different location.
> +
> +Once done, you can check your current binaries ABI with this reference
> +with the ``devtools/check-abi-reference.sh`` script.
> +
> +
> Sending Patches
> ---------------
>
> --
> 2.23.0
I still very much dislike forcing the user to generate his own reference version
to compare the ABI against. These should be archived and the user should just
be able to pull them down via git or http or otherwise. Two reasons for this:
1. Less error prone, since there is no chance of the user having an incorrect
build for whatever reason.
2. Less effort for the user than asking them to do extra builds. The more steps
the user has to follow, the less likely they are to attempt the process.
Regards,
/Bruce
> -----Original Message-----
> From: Richardson, Bruce <bruce.richardson@intel.com>
> Sent: Friday 20 December 2019 15:32
> To: David Marchand <david.marchand@redhat.com>; dev@dpdk.org
> Cc: thomas@monjalon.net; Laatz, Kevin <kevin.laatz@intel.com>;
> aconole@redhat.com; nhorman@tuxdriver.com; Michael Santana
> <maicolgabriel@hotmail.com>; Mcnamara, John <john.mcnamara@intel.com>;
> Kovacevic, Marko <marko.kovacevic@intel.com>; Kinsella, Ray
> <ray.kinsella@intel.com>
> Subject: RE: [PATCH] add ABI checks
>
>
>
> > -----Original Message-----
> > From: David Marchand <david.marchand@redhat.com>
> > Sent: Friday, December 20, 2019 3:21 PM
> > To: dev@dpdk.org
> > Cc: thomas@monjalon.net; Richardson, Bruce
> > <bruce.richardson@intel.com>; Laatz, Kevin <kevin.laatz@intel.com>;
> > aconole@redhat.com; nhorman@tuxdriver.com; Michael Santana
> > <maicolgabriel@hotmail.com>; Mcnamara, John
> <john.mcnamara@intel.com>;
> > Kovacevic, Marko <marko.kovacevic@intel.com>
> > Subject: [PATCH] add ABI checks
> >
> > Starting from Kevin and Bruce idea of using libabigail, here is an
> > alternate approach to implement ABI checks.
> >
> > By default, those checks are disabled and enabling them requires a
> > manual step that generates the ABI dumps on a reference version for a
> > set of configurations.
> >
> > Those checks are enabled in the CI by default for the default meson
> > options on x86 and aarch64 so that proposed patches are validated.
> > A cache of the ABI is stored in travis jobs.
> > Checks can be only informational by setting ABI_CHECKS_WARN_ONLY when
> > breaking the ABI in a future release.
> >
> > For advanced developers and maintainers, the contributing guide
> > details the higher level scripts that are quite close to the existing
> > devtools scripts.
> >
> > Signed-off-by: David Marchand <david.marchand@redhat.com>
> > ---
> > .ci/linux-build.sh | 43 +++++++++++++++++++++++++++
> > .travis.yml | 20 +++++++++++--
> > devtools/check-abi-dump.sh | 46
> +++++++++++++++++++++++++++++
> > devtools/check-abi-reference.sh | 27 +++++++++++++++++
> > devtools/dpdk.abignore | 2 ++
> > devtools/gen-abi-dump.sh | 29 ++++++++++++++++++
> > devtools/gen-abi-reference.sh | 24 +++++++++++++++
> > devtools/test-build.sh | 13 ++++++--
> > devtools/test-meson-builds.sh | 6 ++++
> > doc/guides/contributing/patches.rst | 25 ++++++++++++++++
> > 10 files changed, 230 insertions(+), 5 deletions(-) create mode
> > 100755 devtools/check-abi-dump.sh create mode 100755
> > devtools/check-abi- reference.sh create mode 100644
> > devtools/dpdk.abignore create mode
> > 100755 devtools/gen-abi-dump.sh create mode 100755 devtools/gen-abi-
> > reference.sh
> >
> > diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh index
> > ccc3a7ccd..345dba264 100755
> > --- a/.ci/linux-build.sh
> > +++ b/.ci/linux-build.sh
> > @@ -30,8 +30,51 @@ fi
> >
> > OPTS="$OPTS --default-library=$DEF_LIB"
> > meson build --werror -Dexamples=all $OPTS
> > +
> > +if [ "$ABI_CHECKS" = "1" ]; then
> > + git remote add ref ${REF_GIT_REPO:-https://dpdk.org/git/dpdk}
> > + git fetch --tags ref ${REF_GIT_BRANCH:-master}
> > +
> > + head=$(git describe --all)
> > + tag=$(git describe --abbrev=0)
> > +
> > + if [ "$(cat reference/VERSION 2>/dev/null)" != "$tag" ]; then
> > + rm -rf reference
> > + fi
> > +
> > + if [ ! -d reference ]; then
> > + gen_abi_dump=$(mktemp -t gen-abi-dump-XXX.sh)
> > + cp -a devtools/gen-abi-dump.sh $gen_abi_dump
> > +
> > + git checkout -qf $tag
> > + ninja -C build
> > + $gen_abi_dump build reference
> > +
> > + if [ "$AARCH64" != "1" ]; then
> > + mkdir -p reference/app
> > + cp -a build/app/dpdk-testpmd reference/app/
> > +
> > + export
> LD_LIBRARY_PATH=$(pwd)/build/lib:$(pwd)/build/drivers
> > + devtools/test-null.sh reference/app/dpdk-testpmd
> > + unset LD_LIBRARY_PATH
> > + fi
> > + echo $tag > reference/VERSION
> > +
> > + git checkout -qf $head
> > + fi
> > +fi
> > +
> > ninja -C build
> >
> > +if [ "$ABI_CHECKS" = "1" ]; then
> > + devtools/check-abi-dump.sh build reference
> ${ABI_CHECKS_WARN_ONLY:-}
> > + if [ "$AARCH64" != "1" ]; then
> > + export LD_LIBRARY_PATH=$(pwd)/build/lib:$(pwd)/build/drivers
> > + devtools/test-null.sh reference/app/dpdk-testpmd
> > + unset LD_LIBRARY_PATH
> > + fi
> > +fi
> > +
> > if [ "$AARCH64" != "1" ]; then
> > devtools/test-null.sh
> > fi
> > diff --git a/.travis.yml b/.travis.yml index 8f90d06f2..bbb060fa2
> > 100644
> > --- a/.travis.yml
> > +++ b/.travis.yml
> > @@ -1,5 +1,8 @@
> > language: c
> > -cache: ccache
> > +cache:
> > + ccache: true
> > + directories:
> > + - reference
> > compiler:
> > - gcc
> > - clang
> > @@ -21,7 +24,7 @@ aarch64_packages: &aarch64_packages
> >
> > extra_packages: &extra_packages
> > - *required_packages
> > - - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4]
> > + - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4,
> > + abigail-tools]
> >
> > build_32b_packages: &build_32b_packages
> > - *required_packages
> > @@ -59,6 +62,13 @@ matrix:
> > apt:
> > packages:
> > - *aarch64_packages
> > + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1 AARCH64=1
> > + compiler: gcc
> > + addons:
> > + apt:
> > + packages:
> > + - *aarch64_packages
> > + - *extra_packages
> > - env: DEF_LIB="static" EXTRA_PACKAGES=1
> > compiler: gcc
> > addons:
> > @@ -72,6 +82,12 @@ matrix:
> > packages:
> > - *extra_packages
> > - *doc_packages
> > + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1
> > + compiler: gcc
> > + addons:
> > + apt:
> > + packages:
> > + - *extra_packages
> > - env: DEF_LIB="static" OPTS="-Denable_kmods=false"
> EXTRA_PACKAGES=1
> > compiler: gcc
> > addons:
> > diff --git a/devtools/check-abi-dump.sh b/devtools/check-abi-dump.sh
> > new file mode 100755 index 000000000..f48a2ae7e
> > --- /dev/null
> > +++ b/devtools/check-abi-dump.sh
> > @@ -0,0 +1,46 @@
> > +#!/bin/sh -e
> > +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red
> Hat,
> > +Inc.
> > +
> > +if [ $# != 2 ] && [ $# != 3 ]; then
> > + echo "Usage: $0 builddir dumpdir [warnonly]"
> > + exit 1
> > +fi
> > +
> > +builddir=$1
> > +dumpdir=$2
> > +warnonly=${3:-}
> > +if [ ! -d $builddir ]; then
> > + echo "Error: build directory '$builddir' does not exist."
> > + exit 1
> > +fi
> > +if [ ! -d $dumpdir ]; then
> > + echo "Error: dump directory '$dumpdir' does not exist."
> > + exit 1
> > +fi
> > +
> > +ABIDIFF_OPTIONS="--suppr $(dirname $0)/dpdk.abignore"
> > +for dump in $(find $dumpdir -name "*.dump"); do
> > + libname=$(basename $dump)
> > + libname=${libname%.dump}
> > + result=
> > + for f in $(find $builddir -name "$libname.so.*"); do
> > + if test -L $f || [ "$f" != "${f%%.symbols}" ]; then
> > + continue
> > + fi
> > + result=found
> > +
> > + if ! abidiff $ABIDIFF_OPTIONS $dump $f; then
> > + if [ -z "$warnonly" ]; then
> > + echo "Error: ABI issue reported for $dump, $f"
> > + exit 1
> > + fi
> > + echo "Warning: ABI issue reported for $dump, $f"
> > + fi
> > + break
> > + done
> > + if [ "$result" != "found" ]; then
> > + echo "Error: can't find a library for dump file $dump"
> > + exit 1
> > + fi
> > +done
> > diff --git a/devtools/check-abi-reference.sh b/devtools/check-abi-
> > reference.sh new file mode 100755 index 000000000..7addb094e
> > --- /dev/null
> > +++ b/devtools/check-abi-reference.sh
> > @@ -0,0 +1,27 @@
> > +#!/bin/sh -e
> > +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red
> Hat,
> > +Inc.
> > +
> > +devtools_dir=$(dirname $(readlink -f $0)) .
> > +$devtools_dir/load-devel-config
> > +
> > +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference}
> > +builds_dir=${DPDK_BUILD_TEST_DIR:-.}
> > +
> > +for dir in $abi_ref_build_dir/*; do
> > + if [ "$dir" = "$abi_ref_build_dir" ]; then
> > + exit 1
> > + fi
> > + if [ ! -d $dir/dump ]; then
> > + echo "Skipping $dir"
> > + continue
> > + fi
> > + target=$(basename $dir)
> > + if [ -d $builds_dir/$target/install ]; then
> > + libdir=$builds_dir/$target/install
> > + else
> > + libdir=$builds_dir/$target
> > + fi
> > + echo "Checking ABI between $libdir and $dir/dump"
> > + $devtools_dir/check-abi-dump.sh $libdir $dir/dump done
> > diff --git a/devtools/dpdk.abignore b/devtools/dpdk.abignore new file
> > mode
> > 100644 index 000000000..b866b7f26
> > --- /dev/null
> > +++ b/devtools/dpdk.abignore
> > @@ -0,0 +1,2 @@
> > +[suppress_function]
> > + symbol_version = EXPERIMENTAL
> > diff --git a/devtools/gen-abi-dump.sh b/devtools/gen-abi-dump.sh new
> > file mode 100755 index 000000000..4e38d751f
> > --- /dev/null
> > +++ b/devtools/gen-abi-dump.sh
> > @@ -0,0 +1,29 @@
> > +#!/bin/sh -e
> > +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red
> Hat,
> > +Inc.
> > +
> > +if [ $# != 2 ]; then
> > + echo "Usage: $0 builddir dumpdir"
> > + exit 1
> > +fi
> > +
> > +builddir=$1
> > +dumpdir=$2
> > +if [ ! -d $builddir ]; then
> > + echo "Error: build directory '$builddir' does not exist."
> > + exit 1
> > +fi
> > +if [ -d $dumpdir ]; then
> > + echo "Error: dump directory '$dumpdir' already exists."
> > + exit 1
> > +fi
> > +
> > +mkdir -p $dumpdir
> > +for f in $(find $builddir -name "*.so.*"); do
> > + if test -L $f || [ "$f" != "${f%%.symbols}" ]; then
> > + continue
> > + fi
> > +
> > + libname=$(basename $f)
> > + abidw --out-file $dumpdir/${libname%.so.*}.dump $f done
> > diff --git a/devtools/gen-abi-reference.sh
> > b/devtools/gen-abi-reference.sh new file mode 100755 index
> > 000000000..f41d7fadc
> > --- /dev/null
> > +++ b/devtools/gen-abi-reference.sh
> > @@ -0,0 +1,24 @@
> > +#!/bin/sh -e
> > +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red
> Hat,
> > +Inc.
> > +
> > +devtools_dir=$(dirname $(readlink -f $0)) .
> > +$devtools_dir/load-devel-config
> > +
> > +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference}
> > +for dir in $abi_ref_build_dir/*; do
> > + if [ "$dir" = "$abi_ref_build_dir" ]; then
> > + exit 1
> > + fi
> > + if [ -d $dir/dump ]; then
> > + echo "Skipping $dir"
> > + continue
> > + fi
> > + if [ -d $dir/install ]; then
> > + libdir=$dir/install
> > + else
> > + libdir=$dir
> > + fi
> > + echo "Dumping libraries from $libdir in $dir/dump"
> > + $devtools_dir/gen-abi-dump.sh $libdir $dir/dump done
> > diff --git a/devtools/test-build.sh b/devtools/test-build.sh index
> > 52305fbb8..8cb5b56fb 100755
> > --- a/devtools/test-build.sh
> > +++ b/devtools/test-build.sh
> > @@ -30,7 +30,8 @@ default_path=$PATH
> > # - LIBSSO_SNOW3G_PATH
> > # - LIBSSO_KASUMI_PATH
> > # - LIBSSO_ZUC_PATH
> > -. $(dirname $(readlink -f $0))/load-devel-config
> > +devtools_dir=$(dirname $(readlink -f $0)) .
> > +$devtools_dir/load-devel-config
> >
> > print_usage () {
> > echo "usage: $(basename $0) [-h] [-jX] [-s] [config1 [config2]
> > ...]]"
> > @@ -64,6 +65,7 @@ print_help () {
> > [ -z $MAKE ] && echo "Cannot find make or gmake" && exit 1
> >
> > J=$DPDK_MAKE_JOBS
> > +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference}
> > builds_dir=${DPDK_BUILD_TEST_DIR:-.}
> > short=false
> > unset verbose
> > @@ -97,7 +99,7 @@ trap "signal=INT ; trap - INT ; kill -INT $$" INT
> #
> > notify result on exit trap on_exit EXIT
> >
> > -cd $(dirname $(readlink -f $0))/..
> > +cd $devtools_dir/..
> >
> > reset_env ()
> > {
> > @@ -233,7 +235,7 @@ for conf in $configs ; do
> > # reload config with DPDK_TARGET set
> > DPDK_TARGET=$target
> > reset_env
> > - . $(dirname $(readlink -f $0))/load-devel-config
> > + . $devtools_dir/load-devel-config
> >
> > options=$(echo $conf | sed 's,[^~+]*,,')
> > dir=$builds_dir/$conf
> > @@ -246,6 +248,11 @@ for conf in $configs ; do
> > export RTE_TARGET=$target
> > rm -rf $dir/install
> > ${MAKE} install O=$dir DESTDIR=$dir/install prefix=
> > + if [ -d $abi_ref_build_dir/$conf/dump ]; then
> > + echo "================== Check ABI $conf"
> > + $devtools_dir/check-abi-dump.sh $dir/install \
> > + $abi_ref_build_dir/$conf/dump
> > + fi
> > echo "================== Build examples for $conf"
> > export RTE_SDK=$(readlink -f $dir)/install/share/dpdk
> > ln -sTf $(pwd)/lib $RTE_SDK/lib # workaround for vm_power_manager
> > diff --git a/devtools/test-meson-builds.sh
> > b/devtools/test-meson-builds.sh index 688567714..aaefa38a2 100755
> > --- a/devtools/test-meson-builds.sh
> > +++ b/devtools/test-meson-builds.sh
> > @@ -16,6 +16,7 @@ srcdir=$(dirname $(readlink -f $0))/..
> >
> > MESON=${MESON:-meson}
> > use_shared="--default-library=shared"
> > +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference}
> > builds_dir=${DPDK_BUILD_TEST_DIR:-.}
> >
> > if command -v gmake >/dev/null 2>&1 ; then @@ -88,6 +89,11 @@ build
> > () # <directory> <target compiler> <meson options>
> > echo "$ninja_cmd -C $builddir"
> > $ninja_cmd -C $builddir
> > fi
> > +
> > + if [ -d $abi_ref_build_dir/$1/dump ]; then
> > + $srcdir/devtools/check-abi-dump.sh $builddir
> > + $abi_ref_build_dir/$1/dump
> > + fi
> > }
> >
> > if [ "$1" = "-vv" ] ; then
> > diff --git a/doc/guides/contributing/patches.rst
> > b/doc/guides/contributing/patches.rst
> > index 0686450e4..de3dff145 100644
> > --- a/doc/guides/contributing/patches.rst
> > +++ b/doc/guides/contributing/patches.rst
> > @@ -513,6 +513,31 @@ in a single subfolder called "__builds" created
> > in the current directory.
> > Setting ``DPDK_BUILD_TEST_DIR`` to an absolute directory path e.g.
> > ``/tmp`` is also supported.
> >
> >
> > +Checking ABI compatibility
> > +--------------------------
> > +
> > +The first thing is to build reference binaries for the latest
> release
> > +your patches are built on top of.
> > +
> > +Either you are in a git tree and an easy way to identify this is to
> run::
> > +
> > + git checkout $(git describe --abbrev=0)
> > +
> > +Or you use a tarball and you extract the sources in a director of
> > +your
> > choice.
> > +
> > +Next is building those sources, refer to the previous paragraph.
> > +You can set ``DPDK_BUILD_TEST_DIR=reference``, so that the builds
> > +occur in this directory.
> > +
> > +Finally, the ABI dump files are generated with the
> > +``devtools/gen-abi-reference.sh`` script. This script will look for
> > +builds in the current sub directory ``reference``. But you can set
> > +the environment variable ``DPDK_ABI_REF_BUILD_DIR`` to a different
> location.
> > +
> > +Once done, you can check your current binaries ABI with this
> > +reference with the ``devtools/check-abi-reference.sh`` script.
> > +
> > +
> > Sending Patches
> > ---------------
> >
> > --
> > 2.23.0
>
> I still very much dislike forcing the user to generate his own
> reference version to compare the ABI against. These should be archived
> and the user should just be able to pull them down via git or http or
> otherwise. Two reasons for this:
>
> 1. Less error prone, since there is no chance of the user having an
> incorrect build for whatever reason.
>
> 2. Less effort for the user than asking them to do extra builds. The
> more steps the user has to follow, the less likely they are to attempt
> the process.
>
> Regards,
> /Bruce
>
+1 ... 100% agree with this.
Many people won't know or understand what the reference is,
or why they to generate it.
Ray K
On Fri, Dec 20, 2019 at 04:20:58PM +0100, David Marchand wrote: > Starting from Kevin and Bruce idea of using libabigail, here is an > alternate approach to implement ABI checks. > > By default, those checks are disabled and enabling them requires a > manual step that generates the ABI dumps on a reference version for a > set of configurations. > > Those checks are enabled in the CI by default for the default meson > options on x86 and aarch64 so that proposed patches are validated. > A cache of the ABI is stored in travis jobs. Are they? I'm looking here: https://travis-ci.com/DPDK/dpdk And can't for the life of me see where those cached ABI files are pulled from, or where the checks are encoded at all. Am I missing something (which is the far greater likelyhood). assuming they are there, and I'm just not seeing them, do we have external access to them? Could we download them as part of the abi check process on local trees? Neil > Checks can be only informational by setting ABI_CHECKS_WARN_ONLY when > breaking the ABI in a future release. > > For advanced developers and maintainers, the contributing guide details > the higher level scripts that are quite close to the existing devtools > scripts. > > Signed-off-by: David Marchand <david.marchand@redhat.com> > --- > .ci/linux-build.sh | 43 +++++++++++++++++++++++++++ > .travis.yml | 20 +++++++++++-- > devtools/check-abi-dump.sh | 46 +++++++++++++++++++++++++++++ > devtools/check-abi-reference.sh | 27 +++++++++++++++++ > devtools/dpdk.abignore | 2 ++ > devtools/gen-abi-dump.sh | 29 ++++++++++++++++++ > devtools/gen-abi-reference.sh | 24 +++++++++++++++ > devtools/test-build.sh | 13 ++++++-- > devtools/test-meson-builds.sh | 6 ++++ > doc/guides/contributing/patches.rst | 25 ++++++++++++++++ > 10 files changed, 230 insertions(+), 5 deletions(-) > create mode 100755 devtools/check-abi-dump.sh > create mode 100755 devtools/check-abi-reference.sh > create mode 100644 devtools/dpdk.abignore > create mode 100755 devtools/gen-abi-dump.sh > create mode 100755 devtools/gen-abi-reference.sh > > diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh > index ccc3a7ccd..345dba264 100755 > --- a/.ci/linux-build.sh > +++ b/.ci/linux-build.sh > @@ -30,8 +30,51 @@ fi > > OPTS="$OPTS --default-library=$DEF_LIB" > meson build --werror -Dexamples=all $OPTS > + > +if [ "$ABI_CHECKS" = "1" ]; then > + git remote add ref ${REF_GIT_REPO:-https://dpdk.org/git/dpdk} > + git fetch --tags ref ${REF_GIT_BRANCH:-master} > + > + head=$(git describe --all) > + tag=$(git describe --abbrev=0) > + > + if [ "$(cat reference/VERSION 2>/dev/null)" != "$tag" ]; then > + rm -rf reference > + fi > + > + if [ ! -d reference ]; then > + gen_abi_dump=$(mktemp -t gen-abi-dump-XXX.sh) > + cp -a devtools/gen-abi-dump.sh $gen_abi_dump > + > + git checkout -qf $tag > + ninja -C build > + $gen_abi_dump build reference > + > + if [ "$AARCH64" != "1" ]; then > + mkdir -p reference/app > + cp -a build/app/dpdk-testpmd reference/app/ > + > + export LD_LIBRARY_PATH=$(pwd)/build/lib:$(pwd)/build/drivers > + devtools/test-null.sh reference/app/dpdk-testpmd > + unset LD_LIBRARY_PATH > + fi > + echo $tag > reference/VERSION > + > + git checkout -qf $head > + fi > +fi > + > ninja -C build > > +if [ "$ABI_CHECKS" = "1" ]; then > + devtools/check-abi-dump.sh build reference ${ABI_CHECKS_WARN_ONLY:-} > + if [ "$AARCH64" != "1" ]; then > + export LD_LIBRARY_PATH=$(pwd)/build/lib:$(pwd)/build/drivers > + devtools/test-null.sh reference/app/dpdk-testpmd > + unset LD_LIBRARY_PATH > + fi > +fi > + > if [ "$AARCH64" != "1" ]; then > devtools/test-null.sh > fi > diff --git a/.travis.yml b/.travis.yml > index 8f90d06f2..bbb060fa2 100644 > --- a/.travis.yml > +++ b/.travis.yml > @@ -1,5 +1,8 @@ > language: c > -cache: ccache > +cache: > + ccache: true > + directories: > + - reference > compiler: > - gcc > - clang > @@ -21,7 +24,7 @@ aarch64_packages: &aarch64_packages > > extra_packages: &extra_packages > - *required_packages > - - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4] > + - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4, abigail-tools] > > build_32b_packages: &build_32b_packages > - *required_packages > @@ -59,6 +62,13 @@ matrix: > apt: > packages: > - *aarch64_packages > + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1 AARCH64=1 > + compiler: gcc > + addons: > + apt: > + packages: > + - *aarch64_packages > + - *extra_packages > - env: DEF_LIB="static" EXTRA_PACKAGES=1 > compiler: gcc > addons: > @@ -72,6 +82,12 @@ matrix: > packages: > - *extra_packages > - *doc_packages > + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1 > + compiler: gcc > + addons: > + apt: > + packages: > + - *extra_packages > - env: DEF_LIB="static" OPTS="-Denable_kmods=false" EXTRA_PACKAGES=1 > compiler: gcc > addons: > diff --git a/devtools/check-abi-dump.sh b/devtools/check-abi-dump.sh > new file mode 100755 > index 000000000..f48a2ae7e > --- /dev/null > +++ b/devtools/check-abi-dump.sh > @@ -0,0 +1,46 @@ > +#!/bin/sh -e > +# SPDX-License-Identifier: BSD-3-Clause > +# Copyright (c) 2019 Red Hat, Inc. > + > +if [ $# != 2 ] && [ $# != 3 ]; then > + echo "Usage: $0 builddir dumpdir [warnonly]" > + exit 1 > +fi > + > +builddir=$1 > +dumpdir=$2 > +warnonly=${3:-} > +if [ ! -d $builddir ]; then > + echo "Error: build directory '$builddir' does not exist." > + exit 1 > +fi > +if [ ! -d $dumpdir ]; then > + echo "Error: dump directory '$dumpdir' does not exist." > + exit 1 > +fi > + > +ABIDIFF_OPTIONS="--suppr $(dirname $0)/dpdk.abignore" > +for dump in $(find $dumpdir -name "*.dump"); do > + libname=$(basename $dump) > + libname=${libname%.dump} > + result= > + for f in $(find $builddir -name "$libname.so.*"); do > + if test -L $f || [ "$f" != "${f%%.symbols}" ]; then > + continue > + fi > + result=found > + > + if ! abidiff $ABIDIFF_OPTIONS $dump $f; then > + if [ -z "$warnonly" ]; then > + echo "Error: ABI issue reported for $dump, $f" > + exit 1 > + fi > + echo "Warning: ABI issue reported for $dump, $f" > + fi > + break > + done > + if [ "$result" != "found" ]; then > + echo "Error: can't find a library for dump file $dump" > + exit 1 > + fi > +done > diff --git a/devtools/check-abi-reference.sh b/devtools/check-abi-reference.sh > new file mode 100755 > index 000000000..7addb094e > --- /dev/null > +++ b/devtools/check-abi-reference.sh > @@ -0,0 +1,27 @@ > +#!/bin/sh -e > +# SPDX-License-Identifier: BSD-3-Clause > +# Copyright (c) 2019 Red Hat, Inc. > + > +devtools_dir=$(dirname $(readlink -f $0)) > +. $devtools_dir/load-devel-config > + > +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference} > +builds_dir=${DPDK_BUILD_TEST_DIR:-.} > + > +for dir in $abi_ref_build_dir/*; do > + if [ "$dir" = "$abi_ref_build_dir" ]; then > + exit 1 > + fi > + if [ ! -d $dir/dump ]; then > + echo "Skipping $dir" > + continue > + fi > + target=$(basename $dir) > + if [ -d $builds_dir/$target/install ]; then > + libdir=$builds_dir/$target/install > + else > + libdir=$builds_dir/$target > + fi > + echo "Checking ABI between $libdir and $dir/dump" > + $devtools_dir/check-abi-dump.sh $libdir $dir/dump > +done > diff --git a/devtools/dpdk.abignore b/devtools/dpdk.abignore > new file mode 100644 > index 000000000..b866b7f26 > --- /dev/null > +++ b/devtools/dpdk.abignore > @@ -0,0 +1,2 @@ > +[suppress_function] > + symbol_version = EXPERIMENTAL > diff --git a/devtools/gen-abi-dump.sh b/devtools/gen-abi-dump.sh > new file mode 100755 > index 000000000..4e38d751f > --- /dev/null > +++ b/devtools/gen-abi-dump.sh > @@ -0,0 +1,29 @@ > +#!/bin/sh -e > +# SPDX-License-Identifier: BSD-3-Clause > +# Copyright (c) 2019 Red Hat, Inc. > + > +if [ $# != 2 ]; then > + echo "Usage: $0 builddir dumpdir" > + exit 1 > +fi > + > +builddir=$1 > +dumpdir=$2 > +if [ ! -d $builddir ]; then > + echo "Error: build directory '$builddir' does not exist." > + exit 1 > +fi > +if [ -d $dumpdir ]; then > + echo "Error: dump directory '$dumpdir' already exists." > + exit 1 > +fi > + > +mkdir -p $dumpdir > +for f in $(find $builddir -name "*.so.*"); do > + if test -L $f || [ "$f" != "${f%%.symbols}" ]; then > + continue > + fi > + > + libname=$(basename $f) > + abidw --out-file $dumpdir/${libname%.so.*}.dump $f > +done > diff --git a/devtools/gen-abi-reference.sh b/devtools/gen-abi-reference.sh > new file mode 100755 > index 000000000..f41d7fadc > --- /dev/null > +++ b/devtools/gen-abi-reference.sh > @@ -0,0 +1,24 @@ > +#!/bin/sh -e > +# SPDX-License-Identifier: BSD-3-Clause > +# Copyright (c) 2019 Red Hat, Inc. > + > +devtools_dir=$(dirname $(readlink -f $0)) > +. $devtools_dir/load-devel-config > + > +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference} > +for dir in $abi_ref_build_dir/*; do > + if [ "$dir" = "$abi_ref_build_dir" ]; then > + exit 1 > + fi > + if [ -d $dir/dump ]; then > + echo "Skipping $dir" > + continue > + fi > + if [ -d $dir/install ]; then > + libdir=$dir/install > + else > + libdir=$dir > + fi > + echo "Dumping libraries from $libdir in $dir/dump" > + $devtools_dir/gen-abi-dump.sh $libdir $dir/dump > +done > diff --git a/devtools/test-build.sh b/devtools/test-build.sh > index 52305fbb8..8cb5b56fb 100755 > --- a/devtools/test-build.sh > +++ b/devtools/test-build.sh > @@ -30,7 +30,8 @@ default_path=$PATH > # - LIBSSO_SNOW3G_PATH > # - LIBSSO_KASUMI_PATH > # - LIBSSO_ZUC_PATH > -. $(dirname $(readlink -f $0))/load-devel-config > +devtools_dir=$(dirname $(readlink -f $0)) > +. $devtools_dir/load-devel-config > > print_usage () { > echo "usage: $(basename $0) [-h] [-jX] [-s] [config1 [config2] ...]]" > @@ -64,6 +65,7 @@ print_help () { > [ -z $MAKE ] && echo "Cannot find make or gmake" && exit 1 > > J=$DPDK_MAKE_JOBS > +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference} > builds_dir=${DPDK_BUILD_TEST_DIR:-.} > short=false > unset verbose > @@ -97,7 +99,7 @@ trap "signal=INT ; trap - INT ; kill -INT $$" INT > # notify result on exit > trap on_exit EXIT > > -cd $(dirname $(readlink -f $0))/.. > +cd $devtools_dir/.. > > reset_env () > { > @@ -233,7 +235,7 @@ for conf in $configs ; do > # reload config with DPDK_TARGET set > DPDK_TARGET=$target > reset_env > - . $(dirname $(readlink -f $0))/load-devel-config > + . $devtools_dir/load-devel-config > > options=$(echo $conf | sed 's,[^~+]*,,') > dir=$builds_dir/$conf > @@ -246,6 +248,11 @@ for conf in $configs ; do > export RTE_TARGET=$target > rm -rf $dir/install > ${MAKE} install O=$dir DESTDIR=$dir/install prefix= > + if [ -d $abi_ref_build_dir/$conf/dump ]; then > + echo "================== Check ABI $conf" > + $devtools_dir/check-abi-dump.sh $dir/install \ > + $abi_ref_build_dir/$conf/dump > + fi > echo "================== Build examples for $conf" > export RTE_SDK=$(readlink -f $dir)/install/share/dpdk > ln -sTf $(pwd)/lib $RTE_SDK/lib # workaround for vm_power_manager > diff --git a/devtools/test-meson-builds.sh b/devtools/test-meson-builds.sh > index 688567714..aaefa38a2 100755 > --- a/devtools/test-meson-builds.sh > +++ b/devtools/test-meson-builds.sh > @@ -16,6 +16,7 @@ srcdir=$(dirname $(readlink -f $0))/.. > > MESON=${MESON:-meson} > use_shared="--default-library=shared" > +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference} > builds_dir=${DPDK_BUILD_TEST_DIR:-.} > > if command -v gmake >/dev/null 2>&1 ; then > @@ -88,6 +89,11 @@ build () # <directory> <target compiler> <meson options> > echo "$ninja_cmd -C $builddir" > $ninja_cmd -C $builddir > fi > + > + if [ -d $abi_ref_build_dir/$1/dump ]; then > + $srcdir/devtools/check-abi-dump.sh $builddir > + $abi_ref_build_dir/$1/dump > + fi > } > > if [ "$1" = "-vv" ] ; then > diff --git a/doc/guides/contributing/patches.rst b/doc/guides/contributing/patches.rst > index 0686450e4..de3dff145 100644 > --- a/doc/guides/contributing/patches.rst > +++ b/doc/guides/contributing/patches.rst > @@ -513,6 +513,31 @@ in a single subfolder called "__builds" created in the current directory. > Setting ``DPDK_BUILD_TEST_DIR`` to an absolute directory path e.g. ``/tmp`` is also supported. > > > +Checking ABI compatibility > +-------------------------- > + > +The first thing is to build reference binaries for the latest release your > +patches are built on top of. > + > +Either you are in a git tree and an easy way to identify this is to run:: > + > + git checkout $(git describe --abbrev=0) > + > +Or you use a tarball and you extract the sources in a director of your choice. > + > +Next is building those sources, refer to the previous paragraph. > +You can set ``DPDK_BUILD_TEST_DIR=reference``, so that the builds occur in this > +directory. > + > +Finally, the ABI dump files are generated with the > +``devtools/gen-abi-reference.sh`` script. This script will look for builds in > +the current sub directory ``reference``. But you can set the environment > +variable ``DPDK_ABI_REF_BUILD_DIR`` to a different location. > + > +Once done, you can check your current binaries ABI with this reference with the > +``devtools/check-abi-reference.sh`` script. > + > + > Sending Patches > --------------- > > -- > 2.23.0 > >
20/12/2019 17:20, Kinsella, Ray:
> > -----Original Message-----
> > From: Richardson, Bruce <bruce.richardson@intel.com>
> > Sent: Friday 20 December 2019 15:32
> > To: David Marchand <david.marchand@redhat.com>; dev@dpdk.org
> > Cc: thomas@monjalon.net; Laatz, Kevin <kevin.laatz@intel.com>;
> > aconole@redhat.com; nhorman@tuxdriver.com; Michael Santana
> > <maicolgabriel@hotmail.com>; Mcnamara, John <john.mcnamara@intel.com>;
> > Kovacevic, Marko <marko.kovacevic@intel.com>; Kinsella, Ray
> > <ray.kinsella@intel.com>
> > Subject: RE: [PATCH] add ABI checks
> >
> >
> >
> > > -----Original Message-----
> > > From: David Marchand <david.marchand@redhat.com>
> > > Sent: Friday, December 20, 2019 3:21 PM
> > > To: dev@dpdk.org
> > > Cc: thomas@monjalon.net; Richardson, Bruce
> > > <bruce.richardson@intel.com>; Laatz, Kevin <kevin.laatz@intel.com>;
> > > aconole@redhat.com; nhorman@tuxdriver.com; Michael Santana
> > > <maicolgabriel@hotmail.com>; Mcnamara, John
> > <john.mcnamara@intel.com>;
> > > Kovacevic, Marko <marko.kovacevic@intel.com>
> > > Subject: [PATCH] add ABI checks
> > >
> > > Starting from Kevin and Bruce idea of using libabigail, here is an
> > > alternate approach to implement ABI checks.
> > >
> > > By default, those checks are disabled and enabling them requires a
> > > manual step that generates the ABI dumps on a reference version for a
> > > set of configurations.
> > >
> > > Those checks are enabled in the CI by default for the default meson
> > > options on x86 and aarch64 so that proposed patches are validated.
> > > A cache of the ABI is stored in travis jobs.
> > > Checks can be only informational by setting ABI_CHECKS_WARN_ONLY when
> > > breaking the ABI in a future release.
> > >
> > > For advanced developers and maintainers, the contributing guide
> > > details the higher level scripts that are quite close to the existing
> > > devtools scripts.
> > >
> > > Signed-off-by: David Marchand <david.marchand@redhat.com>
> > > ---
> > > .ci/linux-build.sh | 43 +++++++++++++++++++++++++++
> > > .travis.yml | 20 +++++++++++--
> > > devtools/check-abi-dump.sh | 46
> > +++++++++++++++++++++++++++++
> > > devtools/check-abi-reference.sh | 27 +++++++++++++++++
> > > devtools/dpdk.abignore | 2 ++
> > > devtools/gen-abi-dump.sh | 29 ++++++++++++++++++
> > > devtools/gen-abi-reference.sh | 24 +++++++++++++++
> > > devtools/test-build.sh | 13 ++++++--
> > > devtools/test-meson-builds.sh | 6 ++++
> > > doc/guides/contributing/patches.rst | 25 ++++++++++++++++
> > > 10 files changed, 230 insertions(+), 5 deletions(-) create mode
> > > 100755 devtools/check-abi-dump.sh create mode 100755
> > > devtools/check-abi- reference.sh create mode 100644
> > > devtools/dpdk.abignore create mode
> > > 100755 devtools/gen-abi-dump.sh create mode 100755 devtools/gen-abi-
> > > reference.sh
> > >
> > > diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh index
> > > ccc3a7ccd..345dba264 100755
> > > --- a/.ci/linux-build.sh
> > > +++ b/.ci/linux-build.sh
> > > @@ -30,8 +30,51 @@ fi
> > >
> > > OPTS="$OPTS --default-library=$DEF_LIB"
> > > meson build --werror -Dexamples=all $OPTS
> > > +
> > > +if [ "$ABI_CHECKS" = "1" ]; then
> > > + git remote add ref ${REF_GIT_REPO:-https://dpdk.org/git/dpdk}
> > > + git fetch --tags ref ${REF_GIT_BRANCH:-master}
> > > +
> > > + head=$(git describe --all)
> > > + tag=$(git describe --abbrev=0)
> > > +
> > > + if [ "$(cat reference/VERSION 2>/dev/null)" != "$tag" ]; then
> > > + rm -rf reference
> > > + fi
> > > +
> > > + if [ ! -d reference ]; then
> > > + gen_abi_dump=$(mktemp -t gen-abi-dump-XXX.sh)
> > > + cp -a devtools/gen-abi-dump.sh $gen_abi_dump
> > > +
> > > + git checkout -qf $tag
> > > + ninja -C build
> > > + $gen_abi_dump build reference
> > > +
> > > + if [ "$AARCH64" != "1" ]; then
> > > + mkdir -p reference/app
> > > + cp -a build/app/dpdk-testpmd reference/app/
> > > +
> > > + export
> > LD_LIBRARY_PATH=$(pwd)/build/lib:$(pwd)/build/drivers
> > > + devtools/test-null.sh reference/app/dpdk-testpmd
> > > + unset LD_LIBRARY_PATH
> > > + fi
> > > + echo $tag > reference/VERSION
> > > +
> > > + git checkout -qf $head
> > > + fi
> > > +fi
> > > +
> > > ninja -C build
> > >
> > > +if [ "$ABI_CHECKS" = "1" ]; then
> > > + devtools/check-abi-dump.sh build reference
> > ${ABI_CHECKS_WARN_ONLY:-}
> > > + if [ "$AARCH64" != "1" ]; then
> > > + export LD_LIBRARY_PATH=$(pwd)/build/lib:$(pwd)/build/drivers
> > > + devtools/test-null.sh reference/app/dpdk-testpmd
> > > + unset LD_LIBRARY_PATH
> > > + fi
> > > +fi
> > > +
> > > if [ "$AARCH64" != "1" ]; then
> > > devtools/test-null.sh
> > > fi
> > > diff --git a/.travis.yml b/.travis.yml index 8f90d06f2..bbb060fa2
> > > 100644
> > > --- a/.travis.yml
> > > +++ b/.travis.yml
> > > @@ -1,5 +1,8 @@
> > > language: c
> > > -cache: ccache
> > > +cache:
> > > + ccache: true
> > > + directories:
> > > + - reference
> > > compiler:
> > > - gcc
> > > - clang
> > > @@ -21,7 +24,7 @@ aarch64_packages: &aarch64_packages
> > >
> > > extra_packages: &extra_packages
> > > - *required_packages
> > > - - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4]
> > > + - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4,
> > > + abigail-tools]
> > >
> > > build_32b_packages: &build_32b_packages
> > > - *required_packages
> > > @@ -59,6 +62,13 @@ matrix:
> > > apt:
> > > packages:
> > > - *aarch64_packages
> > > + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1 AARCH64=1
> > > + compiler: gcc
> > > + addons:
> > > + apt:
> > > + packages:
> > > + - *aarch64_packages
> > > + - *extra_packages
> > > - env: DEF_LIB="static" EXTRA_PACKAGES=1
> > > compiler: gcc
> > > addons:
> > > @@ -72,6 +82,12 @@ matrix:
> > > packages:
> > > - *extra_packages
> > > - *doc_packages
> > > + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1
> > > + compiler: gcc
> > > + addons:
> > > + apt:
> > > + packages:
> > > + - *extra_packages
> > > - env: DEF_LIB="static" OPTS="-Denable_kmods=false"
> > EXTRA_PACKAGES=1
> > > compiler: gcc
> > > addons:
> > > diff --git a/devtools/check-abi-dump.sh b/devtools/check-abi-dump.sh
> > > new file mode 100755 index 000000000..f48a2ae7e
> > > --- /dev/null
> > > +++ b/devtools/check-abi-dump.sh
> > > @@ -0,0 +1,46 @@
> > > +#!/bin/sh -e
> > > +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red
> > Hat,
> > > +Inc.
> > > +
> > > +if [ $# != 2 ] && [ $# != 3 ]; then
> > > + echo "Usage: $0 builddir dumpdir [warnonly]"
> > > + exit 1
> > > +fi
> > > +
> > > +builddir=$1
> > > +dumpdir=$2
> > > +warnonly=${3:-}
> > > +if [ ! -d $builddir ]; then
> > > + echo "Error: build directory '$builddir' does not exist."
> > > + exit 1
> > > +fi
> > > +if [ ! -d $dumpdir ]; then
> > > + echo "Error: dump directory '$dumpdir' does not exist."
> > > + exit 1
> > > +fi
> > > +
> > > +ABIDIFF_OPTIONS="--suppr $(dirname $0)/dpdk.abignore"
> > > +for dump in $(find $dumpdir -name "*.dump"); do
> > > + libname=$(basename $dump)
> > > + libname=${libname%.dump}
> > > + result=
> > > + for f in $(find $builddir -name "$libname.so.*"); do
> > > + if test -L $f || [ "$f" != "${f%%.symbols}" ]; then
> > > + continue
> > > + fi
> > > + result=found
> > > +
> > > + if ! abidiff $ABIDIFF_OPTIONS $dump $f; then
> > > + if [ -z "$warnonly" ]; then
> > > + echo "Error: ABI issue reported for $dump, $f"
> > > + exit 1
> > > + fi
> > > + echo "Warning: ABI issue reported for $dump, $f"
> > > + fi
> > > + break
> > > + done
> > > + if [ "$result" != "found" ]; then
> > > + echo "Error: can't find a library for dump file $dump"
> > > + exit 1
> > > + fi
> > > +done
> > > diff --git a/devtools/check-abi-reference.sh b/devtools/check-abi-
> > > reference.sh new file mode 100755 index 000000000..7addb094e
> > > --- /dev/null
> > > +++ b/devtools/check-abi-reference.sh
> > > @@ -0,0 +1,27 @@
> > > +#!/bin/sh -e
> > > +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red
> > Hat,
> > > +Inc.
> > > +
> > > +devtools_dir=$(dirname $(readlink -f $0)) .
> > > +$devtools_dir/load-devel-config
> > > +
> > > +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference}
> > > +builds_dir=${DPDK_BUILD_TEST_DIR:-.}
> > > +
> > > +for dir in $abi_ref_build_dir/*; do
> > > + if [ "$dir" = "$abi_ref_build_dir" ]; then
> > > + exit 1
> > > + fi
> > > + if [ ! -d $dir/dump ]; then
> > > + echo "Skipping $dir"
> > > + continue
> > > + fi
> > > + target=$(basename $dir)
> > > + if [ -d $builds_dir/$target/install ]; then
> > > + libdir=$builds_dir/$target/install
> > > + else
> > > + libdir=$builds_dir/$target
> > > + fi
> > > + echo "Checking ABI between $libdir and $dir/dump"
> > > + $devtools_dir/check-abi-dump.sh $libdir $dir/dump done
> > > diff --git a/devtools/dpdk.abignore b/devtools/dpdk.abignore new file
> > > mode
> > > 100644 index 000000000..b866b7f26
> > > --- /dev/null
> > > +++ b/devtools/dpdk.abignore
> > > @@ -0,0 +1,2 @@
> > > +[suppress_function]
> > > + symbol_version = EXPERIMENTAL
> > > diff --git a/devtools/gen-abi-dump.sh b/devtools/gen-abi-dump.sh new
> > > file mode 100755 index 000000000..4e38d751f
> > > --- /dev/null
> > > +++ b/devtools/gen-abi-dump.sh
> > > @@ -0,0 +1,29 @@
> > > +#!/bin/sh -e
> > > +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red
> > Hat,
> > > +Inc.
> > > +
> > > +if [ $# != 2 ]; then
> > > + echo "Usage: $0 builddir dumpdir"
> > > + exit 1
> > > +fi
> > > +
> > > +builddir=$1
> > > +dumpdir=$2
> > > +if [ ! -d $builddir ]; then
> > > + echo "Error: build directory '$builddir' does not exist."
> > > + exit 1
> > > +fi
> > > +if [ -d $dumpdir ]; then
> > > + echo "Error: dump directory '$dumpdir' already exists."
> > > + exit 1
> > > +fi
> > > +
> > > +mkdir -p $dumpdir
> > > +for f in $(find $builddir -name "*.so.*"); do
> > > + if test -L $f || [ "$f" != "${f%%.symbols}" ]; then
> > > + continue
> > > + fi
> > > +
> > > + libname=$(basename $f)
> > > + abidw --out-file $dumpdir/${libname%.so.*}.dump $f done
> > > diff --git a/devtools/gen-abi-reference.sh
> > > b/devtools/gen-abi-reference.sh new file mode 100755 index
> > > 000000000..f41d7fadc
> > > --- /dev/null
> > > +++ b/devtools/gen-abi-reference.sh
> > > @@ -0,0 +1,24 @@
> > > +#!/bin/sh -e
> > > +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red
> > Hat,
> > > +Inc.
> > > +
> > > +devtools_dir=$(dirname $(readlink -f $0)) .
> > > +$devtools_dir/load-devel-config
> > > +
> > > +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference}
> > > +for dir in $abi_ref_build_dir/*; do
> > > + if [ "$dir" = "$abi_ref_build_dir" ]; then
> > > + exit 1
> > > + fi
> > > + if [ -d $dir/dump ]; then
> > > + echo "Skipping $dir"
> > > + continue
> > > + fi
> > > + if [ -d $dir/install ]; then
> > > + libdir=$dir/install
> > > + else
> > > + libdir=$dir
> > > + fi
> > > + echo "Dumping libraries from $libdir in $dir/dump"
> > > + $devtools_dir/gen-abi-dump.sh $libdir $dir/dump done
> > > diff --git a/devtools/test-build.sh b/devtools/test-build.sh index
> > > 52305fbb8..8cb5b56fb 100755
> > > --- a/devtools/test-build.sh
> > > +++ b/devtools/test-build.sh
> > > @@ -30,7 +30,8 @@ default_path=$PATH
> > > # - LIBSSO_SNOW3G_PATH
> > > # - LIBSSO_KASUMI_PATH
> > > # - LIBSSO_ZUC_PATH
> > > -. $(dirname $(readlink -f $0))/load-devel-config
> > > +devtools_dir=$(dirname $(readlink -f $0)) .
> > > +$devtools_dir/load-devel-config
> > >
> > > print_usage () {
> > > echo "usage: $(basename $0) [-h] [-jX] [-s] [config1 [config2]
> > > ...]]"
> > > @@ -64,6 +65,7 @@ print_help () {
> > > [ -z $MAKE ] && echo "Cannot find make or gmake" && exit 1
> > >
> > > J=$DPDK_MAKE_JOBS
> > > +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference}
> > > builds_dir=${DPDK_BUILD_TEST_DIR:-.}
> > > short=false
> > > unset verbose
> > > @@ -97,7 +99,7 @@ trap "signal=INT ; trap - INT ; kill -INT $$" INT
> > #
> > > notify result on exit trap on_exit EXIT
> > >
> > > -cd $(dirname $(readlink -f $0))/..
> > > +cd $devtools_dir/..
> > >
> > > reset_env ()
> > > {
> > > @@ -233,7 +235,7 @@ for conf in $configs ; do
> > > # reload config with DPDK_TARGET set
> > > DPDK_TARGET=$target
> > > reset_env
> > > - . $(dirname $(readlink -f $0))/load-devel-config
> > > + . $devtools_dir/load-devel-config
> > >
> > > options=$(echo $conf | sed 's,[^~+]*,,')
> > > dir=$builds_dir/$conf
> > > @@ -246,6 +248,11 @@ for conf in $configs ; do
> > > export RTE_TARGET=$target
> > > rm -rf $dir/install
> > > ${MAKE} install O=$dir DESTDIR=$dir/install prefix=
> > > + if [ -d $abi_ref_build_dir/$conf/dump ]; then
> > > + echo "================== Check ABI $conf"
> > > + $devtools_dir/check-abi-dump.sh $dir/install \
> > > + $abi_ref_build_dir/$conf/dump
> > > + fi
> > > echo "================== Build examples for $conf"
> > > export RTE_SDK=$(readlink -f $dir)/install/share/dpdk
> > > ln -sTf $(pwd)/lib $RTE_SDK/lib # workaround for vm_power_manager
> > > diff --git a/devtools/test-meson-builds.sh
> > > b/devtools/test-meson-builds.sh index 688567714..aaefa38a2 100755
> > > --- a/devtools/test-meson-builds.sh
> > > +++ b/devtools/test-meson-builds.sh
> > > @@ -16,6 +16,7 @@ srcdir=$(dirname $(readlink -f $0))/..
> > >
> > > MESON=${MESON:-meson}
> > > use_shared="--default-library=shared"
> > > +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference}
> > > builds_dir=${DPDK_BUILD_TEST_DIR:-.}
> > >
> > > if command -v gmake >/dev/null 2>&1 ; then @@ -88,6 +89,11 @@ build
> > > () # <directory> <target compiler> <meson options>
> > > echo "$ninja_cmd -C $builddir"
> > > $ninja_cmd -C $builddir
> > > fi
> > > +
> > > + if [ -d $abi_ref_build_dir/$1/dump ]; then
> > > + $srcdir/devtools/check-abi-dump.sh $builddir
> > > + $abi_ref_build_dir/$1/dump
> > > + fi
> > > }
> > >
> > > if [ "$1" = "-vv" ] ; then
> > > diff --git a/doc/guides/contributing/patches.rst
> > > b/doc/guides/contributing/patches.rst
> > > index 0686450e4..de3dff145 100644
> > > --- a/doc/guides/contributing/patches.rst
> > > +++ b/doc/guides/contributing/patches.rst
> > > @@ -513,6 +513,31 @@ in a single subfolder called "__builds" created
> > > in the current directory.
> > > Setting ``DPDK_BUILD_TEST_DIR`` to an absolute directory path e.g.
> > > ``/tmp`` is also supported.
> > >
> > >
> > > +Checking ABI compatibility
> > > +--------------------------
> > > +
> > > +The first thing is to build reference binaries for the latest
> > release
> > > +your patches are built on top of.
> > > +
> > > +Either you are in a git tree and an easy way to identify this is to
> > run::
> > > +
> > > + git checkout $(git describe --abbrev=0)
> > > +
> > > +Or you use a tarball and you extract the sources in a director of
> > > +your
> > > choice.
> > > +
> > > +Next is building those sources, refer to the previous paragraph.
> > > +You can set ``DPDK_BUILD_TEST_DIR=reference``, so that the builds
> > > +occur in this directory.
> > > +
> > > +Finally, the ABI dump files are generated with the
> > > +``devtools/gen-abi-reference.sh`` script. This script will look for
> > > +builds in the current sub directory ``reference``. But you can set
> > > +the environment variable ``DPDK_ABI_REF_BUILD_DIR`` to a different
> > location.
> > > +
> > > +Once done, you can check your current binaries ABI with this
> > > +reference with the ``devtools/check-abi-reference.sh`` script.
> > > +
> > > +
> > > Sending Patches
> > > ---------------
> > >
> > > --
> > > 2.23.0
> >
> > I still very much dislike forcing the user to generate his own
> > reference version to compare the ABI against. These should be archived
> > and the user should just be able to pull them down via git or http or
> > otherwise. Two reasons for this:
> >
> > 1. Less error prone, since there is no chance of the user having an
> > incorrect build for whatever reason.
> >
> > 2. Less effort for the user than asking them to do extra builds. The
> > more steps the user has to follow, the less likely they are to attempt
> > the process.
> >
> > Regards,
> > /Bruce
> >
>
> +1 ... 100% agree with this.
>
> Many people won't know or understand what the reference is,
> or why they to generate it.
Many people won't run the test at all and will rely on the automatic CI tests.
Thomas Monjalon <thomas@monjalon.net> writes: > 20/12/2019 17:20, Kinsella, Ray: >> > -----Original Message----- >> > From: Richardson, Bruce <bruce.richardson@intel.com> >> > Sent: Friday 20 December 2019 15:32 >> > To: David Marchand <david.marchand@redhat.com>; dev@dpdk.org >> > Cc: thomas@monjalon.net; Laatz, Kevin <kevin.laatz@intel.com>; >> > aconole@redhat.com; nhorman@tuxdriver.com; Michael Santana >> > <maicolgabriel@hotmail.com>; Mcnamara, John <john.mcnamara@intel.com>; >> > Kovacevic, Marko <marko.kovacevic@intel.com>; Kinsella, Ray >> > <ray.kinsella@intel.com> >> > Subject: RE: [PATCH] add ABI checks >> > >> > >> > >> > > -----Original Message----- >> > > From: David Marchand <david.marchand@redhat.com> >> > > Sent: Friday, December 20, 2019 3:21 PM >> > > To: dev@dpdk.org >> > > Cc: thomas@monjalon.net; Richardson, Bruce >> > > <bruce.richardson@intel.com>; Laatz, Kevin <kevin.laatz@intel.com>; >> > > aconole@redhat.com; nhorman@tuxdriver.com; Michael Santana >> > > <maicolgabriel@hotmail.com>; Mcnamara, John >> > <john.mcnamara@intel.com>; >> > > Kovacevic, Marko <marko.kovacevic@intel.com> >> > > Subject: [PATCH] add ABI checks >> > > >> > > Starting from Kevin and Bruce idea of using libabigail, here is an >> > > alternate approach to implement ABI checks. >> > > >> > > By default, those checks are disabled and enabling them requires a >> > > manual step that generates the ABI dumps on a reference version for a >> > > set of configurations. >> > > >> > > Those checks are enabled in the CI by default for the default meson >> > > options on x86 and aarch64 so that proposed patches are validated. >> > > A cache of the ABI is stored in travis jobs. >> > > Checks can be only informational by setting ABI_CHECKS_WARN_ONLY when >> > > breaking the ABI in a future release. >> > > >> > > For advanced developers and maintainers, the contributing guide >> > > details the higher level scripts that are quite close to the existing >> > > devtools scripts. >> > > >> > > Signed-off-by: David Marchand <david.marchand@redhat.com> >> > > --- >> > > .ci/linux-build.sh | 43 +++++++++++++++++++++++++++ >> > > .travis.yml | 20 +++++++++++-- >> > > devtools/check-abi-dump.sh | 46 >> > +++++++++++++++++++++++++++++ >> > > devtools/check-abi-reference.sh | 27 +++++++++++++++++ >> > > devtools/dpdk.abignore | 2 ++ >> > > devtools/gen-abi-dump.sh | 29 ++++++++++++++++++ >> > > devtools/gen-abi-reference.sh | 24 +++++++++++++++ >> > > devtools/test-build.sh | 13 ++++++-- >> > > devtools/test-meson-builds.sh | 6 ++++ >> > > doc/guides/contributing/patches.rst | 25 ++++++++++++++++ >> > > 10 files changed, 230 insertions(+), 5 deletions(-) create mode >> > > 100755 devtools/check-abi-dump.sh create mode 100755 >> > > devtools/check-abi- reference.sh create mode 100644 >> > > devtools/dpdk.abignore create mode >> > > 100755 devtools/gen-abi-dump.sh create mode 100755 devtools/gen-abi- >> > > reference.sh >> > > >> > > diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh index >> > > ccc3a7ccd..345dba264 100755 >> > > --- a/.ci/linux-build.sh >> > > +++ b/.ci/linux-build.sh >> > > @@ -30,8 +30,51 @@ fi >> > > >> > > OPTS="$OPTS --default-library=$DEF_LIB" >> > > meson build --werror -Dexamples=all $OPTS >> > > + >> > > +if [ "$ABI_CHECKS" = "1" ]; then >> > > + git remote add ref ${REF_GIT_REPO:-https://dpdk.org/git/dpdk} >> > > + git fetch --tags ref ${REF_GIT_BRANCH:-master} >> > > + >> > > + head=$(git describe --all) >> > > + tag=$(git describe --abbrev=0) >> > > + >> > > + if [ "$(cat reference/VERSION 2>/dev/null)" != "$tag" ]; then >> > > + rm -rf reference >> > > + fi >> > > + >> > > + if [ ! -d reference ]; then >> > > + gen_abi_dump=$(mktemp -t gen-abi-dump-XXX.sh) >> > > + cp -a devtools/gen-abi-dump.sh $gen_abi_dump >> > > + >> > > + git checkout -qf $tag >> > > + ninja -C build >> > > + $gen_abi_dump build reference >> > > + >> > > + if [ "$AARCH64" != "1" ]; then >> > > + mkdir -p reference/app >> > > + cp -a build/app/dpdk-testpmd reference/app/ >> > > + >> > > + export >> > LD_LIBRARY_PATH=$(pwd)/build/lib:$(pwd)/build/drivers >> > > + devtools/test-null.sh reference/app/dpdk-testpmd >> > > + unset LD_LIBRARY_PATH >> > > + fi >> > > + echo $tag > reference/VERSION >> > > + >> > > + git checkout -qf $head >> > > + fi >> > > +fi >> > > + >> > > ninja -C build >> > > >> > > +if [ "$ABI_CHECKS" = "1" ]; then >> > > + devtools/check-abi-dump.sh build reference >> > ${ABI_CHECKS_WARN_ONLY:-} >> > > + if [ "$AARCH64" != "1" ]; then >> > > + export LD_LIBRARY_PATH=$(pwd)/build/lib:$(pwd)/build/drivers >> > > + devtools/test-null.sh reference/app/dpdk-testpmd >> > > + unset LD_LIBRARY_PATH >> > > + fi >> > > +fi >> > > + >> > > if [ "$AARCH64" != "1" ]; then >> > > devtools/test-null.sh >> > > fi >> > > diff --git a/.travis.yml b/.travis.yml index 8f90d06f2..bbb060fa2 >> > > 100644 >> > > --- a/.travis.yml >> > > +++ b/.travis.yml >> > > @@ -1,5 +1,8 @@ >> > > language: c >> > > -cache: ccache >> > > +cache: >> > > + ccache: true >> > > + directories: >> > > + - reference >> > > compiler: >> > > - gcc >> > > - clang >> > > @@ -21,7 +24,7 @@ aarch64_packages: &aarch64_packages >> > > >> > > extra_packages: &extra_packages >> > > - *required_packages >> > > - - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4] >> > > + - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4, >> > > + abigail-tools] >> > > >> > > build_32b_packages: &build_32b_packages >> > > - *required_packages >> > > @@ -59,6 +62,13 @@ matrix: >> > > apt: >> > > packages: >> > > - *aarch64_packages >> > > + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1 AARCH64=1 >> > > + compiler: gcc >> > > + addons: >> > > + apt: >> > > + packages: >> > > + - *aarch64_packages >> > > + - *extra_packages >> > > - env: DEF_LIB="static" EXTRA_PACKAGES=1 >> > > compiler: gcc >> > > addons: >> > > @@ -72,6 +82,12 @@ matrix: >> > > packages: >> > > - *extra_packages >> > > - *doc_packages >> > > + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1 >> > > + compiler: gcc >> > > + addons: >> > > + apt: >> > > + packages: >> > > + - *extra_packages >> > > - env: DEF_LIB="static" OPTS="-Denable_kmods=false" >> > EXTRA_PACKAGES=1 >> > > compiler: gcc >> > > addons: >> > > diff --git a/devtools/check-abi-dump.sh b/devtools/check-abi-dump.sh >> > > new file mode 100755 index 000000000..f48a2ae7e >> > > --- /dev/null >> > > +++ b/devtools/check-abi-dump.sh >> > > @@ -0,0 +1,46 @@ >> > > +#!/bin/sh -e >> > > +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red >> > Hat, >> > > +Inc. >> > > + >> > > +if [ $# != 2 ] && [ $# != 3 ]; then >> > > + echo "Usage: $0 builddir dumpdir [warnonly]" >> > > + exit 1 >> > > +fi >> > > + >> > > +builddir=$1 >> > > +dumpdir=$2 >> > > +warnonly=${3:-} >> > > +if [ ! -d $builddir ]; then >> > > + echo "Error: build directory '$builddir' does not exist." >> > > + exit 1 >> > > +fi >> > > +if [ ! -d $dumpdir ]; then >> > > + echo "Error: dump directory '$dumpdir' does not exist." >> > > + exit 1 >> > > +fi >> > > + >> > > +ABIDIFF_OPTIONS="--suppr $(dirname $0)/dpdk.abignore" >> > > +for dump in $(find $dumpdir -name "*.dump"); do >> > > + libname=$(basename $dump) >> > > + libname=${libname%.dump} >> > > + result= >> > > + for f in $(find $builddir -name "$libname.so.*"); do >> > > + if test -L $f || [ "$f" != "${f%%.symbols}" ]; then >> > > + continue >> > > + fi >> > > + result=found >> > > + >> > > + if ! abidiff $ABIDIFF_OPTIONS $dump $f; then >> > > + if [ -z "$warnonly" ]; then >> > > + echo "Error: ABI issue reported for $dump, $f" >> > > + exit 1 >> > > + fi >> > > + echo "Warning: ABI issue reported for $dump, $f" >> > > + fi >> > > + break >> > > + done >> > > + if [ "$result" != "found" ]; then >> > > + echo "Error: can't find a library for dump file $dump" >> > > + exit 1 >> > > + fi >> > > +done >> > > diff --git a/devtools/check-abi-reference.sh b/devtools/check-abi- >> > > reference.sh new file mode 100755 index 000000000..7addb094e >> > > --- /dev/null >> > > +++ b/devtools/check-abi-reference.sh >> > > @@ -0,0 +1,27 @@ >> > > +#!/bin/sh -e >> > > +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red >> > Hat, >> > > +Inc. >> > > + >> > > +devtools_dir=$(dirname $(readlink -f $0)) . >> > > +$devtools_dir/load-devel-config >> > > + >> > > +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference} >> > > +builds_dir=${DPDK_BUILD_TEST_DIR:-.} >> > > + >> > > +for dir in $abi_ref_build_dir/*; do >> > > + if [ "$dir" = "$abi_ref_build_dir" ]; then >> > > + exit 1 >> > > + fi >> > > + if [ ! -d $dir/dump ]; then >> > > + echo "Skipping $dir" >> > > + continue >> > > + fi >> > > + target=$(basename $dir) >> > > + if [ -d $builds_dir/$target/install ]; then >> > > + libdir=$builds_dir/$target/install >> > > + else >> > > + libdir=$builds_dir/$target >> > > + fi >> > > + echo "Checking ABI between $libdir and $dir/dump" >> > > + $devtools_dir/check-abi-dump.sh $libdir $dir/dump done >> > > diff --git a/devtools/dpdk.abignore b/devtools/dpdk.abignore new file >> > > mode >> > > 100644 index 000000000..b866b7f26 >> > > --- /dev/null >> > > +++ b/devtools/dpdk.abignore >> > > @@ -0,0 +1,2 @@ >> > > +[suppress_function] >> > > + symbol_version = EXPERIMENTAL >> > > diff --git a/devtools/gen-abi-dump.sh b/devtools/gen-abi-dump.sh new >> > > file mode 100755 index 000000000..4e38d751f >> > > --- /dev/null >> > > +++ b/devtools/gen-abi-dump.sh >> > > @@ -0,0 +1,29 @@ >> > > +#!/bin/sh -e >> > > +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red >> > Hat, >> > > +Inc. >> > > + >> > > +if [ $# != 2 ]; then >> > > + echo "Usage: $0 builddir dumpdir" >> > > + exit 1 >> > > +fi >> > > + >> > > +builddir=$1 >> > > +dumpdir=$2 >> > > +if [ ! -d $builddir ]; then >> > > + echo "Error: build directory '$builddir' does not exist." >> > > + exit 1 >> > > +fi >> > > +if [ -d $dumpdir ]; then >> > > + echo "Error: dump directory '$dumpdir' already exists." >> > > + exit 1 >> > > +fi >> > > + >> > > +mkdir -p $dumpdir >> > > +for f in $(find $builddir -name "*.so.*"); do >> > > + if test -L $f || [ "$f" != "${f%%.symbols}" ]; then >> > > + continue >> > > + fi >> > > + >> > > + libname=$(basename $f) >> > > + abidw --out-file $dumpdir/${libname%.so.*}.dump $f done >> > > diff --git a/devtools/gen-abi-reference.sh >> > > b/devtools/gen-abi-reference.sh new file mode 100755 index >> > > 000000000..f41d7fadc >> > > --- /dev/null >> > > +++ b/devtools/gen-abi-reference.sh >> > > @@ -0,0 +1,24 @@ >> > > +#!/bin/sh -e >> > > +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red >> > Hat, >> > > +Inc. >> > > + >> > > +devtools_dir=$(dirname $(readlink -f $0)) . >> > > +$devtools_dir/load-devel-config >> > > + >> > > +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference} >> > > +for dir in $abi_ref_build_dir/*; do >> > > + if [ "$dir" = "$abi_ref_build_dir" ]; then >> > > + exit 1 >> > > + fi >> > > + if [ -d $dir/dump ]; then >> > > + echo "Skipping $dir" >> > > + continue >> > > + fi >> > > + if [ -d $dir/install ]; then >> > > + libdir=$dir/install >> > > + else >> > > + libdir=$dir >> > > + fi >> > > + echo "Dumping libraries from $libdir in $dir/dump" >> > > + $devtools_dir/gen-abi-dump.sh $libdir $dir/dump done >> > > diff --git a/devtools/test-build.sh b/devtools/test-build.sh index >> > > 52305fbb8..8cb5b56fb 100755 >> > > --- a/devtools/test-build.sh >> > > +++ b/devtools/test-build.sh >> > > @@ -30,7 +30,8 @@ default_path=$PATH >> > > # - LIBSSO_SNOW3G_PATH >> > > # - LIBSSO_KASUMI_PATH >> > > # - LIBSSO_ZUC_PATH >> > > -. $(dirname $(readlink -f $0))/load-devel-config >> > > +devtools_dir=$(dirname $(readlink -f $0)) . >> > > +$devtools_dir/load-devel-config >> > > >> > > print_usage () { >> > > echo "usage: $(basename $0) [-h] [-jX] [-s] [config1 [config2] >> > > ...]]" >> > > @@ -64,6 +65,7 @@ print_help () { >> > > [ -z $MAKE ] && echo "Cannot find make or gmake" && exit 1 >> > > >> > > J=$DPDK_MAKE_JOBS >> > > +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference} >> > > builds_dir=${DPDK_BUILD_TEST_DIR:-.} >> > > short=false >> > > unset verbose >> > > @@ -97,7 +99,7 @@ trap "signal=INT ; trap - INT ; kill -INT $$" INT >> > # >> > > notify result on exit trap on_exit EXIT >> > > >> > > -cd $(dirname $(readlink -f $0))/.. >> > > +cd $devtools_dir/.. >> > > >> > > reset_env () >> > > { >> > > @@ -233,7 +235,7 @@ for conf in $configs ; do >> > > # reload config with DPDK_TARGET set >> > > DPDK_TARGET=$target >> > > reset_env >> > > - . $(dirname $(readlink -f $0))/load-devel-config >> > > + . $devtools_dir/load-devel-config >> > > >> > > options=$(echo $conf | sed 's,[^~+]*,,') >> > > dir=$builds_dir/$conf >> > > @@ -246,6 +248,11 @@ for conf in $configs ; do >> > > export RTE_TARGET=$target >> > > rm -rf $dir/install >> > > ${MAKE} install O=$dir DESTDIR=$dir/install prefix= >> > > + if [ -d $abi_ref_build_dir/$conf/dump ]; then >> > > + echo "================== Check ABI $conf" >> > > + $devtools_dir/check-abi-dump.sh $dir/install \ >> > > + $abi_ref_build_dir/$conf/dump >> > > + fi >> > > echo "================== Build examples for $conf" >> > > export RTE_SDK=$(readlink -f $dir)/install/share/dpdk >> > > ln -sTf $(pwd)/lib $RTE_SDK/lib # workaround for vm_power_manager >> > > diff --git a/devtools/test-meson-builds.sh >> > > b/devtools/test-meson-builds.sh index 688567714..aaefa38a2 100755 >> > > --- a/devtools/test-meson-builds.sh >> > > +++ b/devtools/test-meson-builds.sh >> > > @@ -16,6 +16,7 @@ srcdir=$(dirname $(readlink -f $0))/.. >> > > >> > > MESON=${MESON:-meson} >> > > use_shared="--default-library=shared" >> > > +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference} >> > > builds_dir=${DPDK_BUILD_TEST_DIR:-.} >> > > >> > > if command -v gmake >/dev/null 2>&1 ; then @@ -88,6 +89,11 @@ build >> > > () # <directory> <target compiler> <meson options> >> > > echo "$ninja_cmd -C $builddir" >> > > $ninja_cmd -C $builddir >> > > fi >> > > + >> > > + if [ -d $abi_ref_build_dir/$1/dump ]; then >> > > + $srcdir/devtools/check-abi-dump.sh $builddir >> > > + $abi_ref_build_dir/$1/dump >> > > + fi >> > > } >> > > >> > > if [ "$1" = "-vv" ] ; then >> > > diff --git a/doc/guides/contributing/patches.rst >> > > b/doc/guides/contributing/patches.rst >> > > index 0686450e4..de3dff145 100644 >> > > --- a/doc/guides/contributing/patches.rst >> > > +++ b/doc/guides/contributing/patches.rst >> > > @@ -513,6 +513,31 @@ in a single subfolder called "__builds" created >> > > in the current directory. >> > > Setting ``DPDK_BUILD_TEST_DIR`` to an absolute directory path e.g. >> > > ``/tmp`` is also supported. >> > > >> > > >> > > +Checking ABI compatibility >> > > +-------------------------- >> > > + >> > > +The first thing is to build reference binaries for the latest >> > release >> > > +your patches are built on top of. >> > > + >> > > +Either you are in a git tree and an easy way to identify this is to >> > run:: >> > > + >> > > + git checkout $(git describe --abbrev=0) >> > > + >> > > +Or you use a tarball and you extract the sources in a director of >> > > +your >> > > choice. >> > > + >> > > +Next is building those sources, refer to the previous paragraph. >> > > +You can set ``DPDK_BUILD_TEST_DIR=reference``, so that the builds >> > > +occur in this directory. >> > > + >> > > +Finally, the ABI dump files are generated with the >> > > +``devtools/gen-abi-reference.sh`` script. This script will look for >> > > +builds in the current sub directory ``reference``. But you can set >> > > +the environment variable ``DPDK_ABI_REF_BUILD_DIR`` to a different >> > location. >> > > + >> > > +Once done, you can check your current binaries ABI with this >> > > +reference with the ``devtools/check-abi-reference.sh`` script. >> > > + >> > > + >> > > Sending Patches >> > > --------------- >> > > >> > > -- >> > > 2.23.0 >> > >> > I still very much dislike forcing the user to generate his own >> > reference version to compare the ABI against. These should be archived >> > and the user should just be able to pull them down via git or http or >> > otherwise. Two reasons for this: >> > >> > 1. Less error prone, since there is no chance of the user having an >> > incorrect build for whatever reason. It's more error prone I think. There are issues with archived versions of ABI dumps, or bad content delivery networks. Working from the git repository is *guaranteed* to generate a correct ABI dump. Anything else allows your CDN / other to break. >> > 2. Less effort for the user than asking them to do extra builds. The >> > more steps the user has to follow, the less likely they are to attempt >> > the process. It's important to remember that (as far as I'm aware) the vast majority of DPDK users don't make many code changes or even compile it. And those who do typically don't even run the unit tests. I think it's good to document a process for people to follow, but such process shouldn't assume that developers can't run basic git commands or execute scripts. >> > Regards, >> > /Bruce >> > >> >> +1 ... 100% agree with this. >> >> Many people won't know or understand what the reference is, >> or why they to generate it. > > Many people won't run the test at all and will rely on the automatic CI tests. +1 to this. It's good for the robot's travis build to validate the ABI for patches, since it will alert us anyway.
20/12/2019 17:20, Kinsella, Ray:
> From: Richardson, Bruce <bruce.richardson@intel.com>
> > From: David Marchand <david.marchand@redhat.com>
> > > +Checking ABI compatibility
> > > +--------------------------
> > > +
> > > +The first thing is to build reference binaries for the latest
> > release
> > > +your patches are built on top of.
> > > +
> > > +Either you are in a git tree and an easy way to identify this is to
> > run::
> > > +
> > > + git checkout $(git describe --abbrev=0)
> > > +
> > > +Or you use a tarball and you extract the sources in a director of
> > > +your
> > > choice.
> > > +
> > > +Next is building those sources, refer to the previous paragraph.
> > > +You can set ``DPDK_BUILD_TEST_DIR=reference``, so that the builds
> > > +occur in this directory.
> > > +
> > > +Finally, the ABI dump files are generated with the
> > > +``devtools/gen-abi-reference.sh`` script. This script will look for
> > > +builds in the current sub directory ``reference``. But you can set
> > > +the environment variable ``DPDK_ABI_REF_BUILD_DIR`` to a different
> > location.
> > > +
> > > +Once done, you can check your current binaries ABI with this
> > > +reference with the ``devtools/check-abi-reference.sh`` script.
> > >
> >
> > I still very much dislike forcing the user to generate his own
> > reference version to compare the ABI against. These should be archived
> > and the user should just be able to pull them down via git or http or
> > otherwise. Two reasons for this:
> >
> > 1. Less error prone, since there is no chance of the user having an
> > incorrect build for whatever reason.
> >
> > 2. Less effort for the user than asking them to do extra builds. The
> > more steps the user has to follow, the less likely they are to attempt
> > the process.
>
> +1 ... 100% agree with this.
>
> Many people won't know or understand what the reference is,
> or why they to generate it.
I don't want to generate and save the reference in git for each arch.
We can make reference build more automatic with a command like this:
git clone --branch v19.11 . $DPDK_BUILD_TEST_DIR/abiref-19.11
Also I don't like mixing build and check steps.
I believe the compilation should be simple and right to the point.
This approach, from David, does not prevent from saving the dumps later
if we really feel a strong need.
That's why I suggest going with this patch.
On Wed, Jan 15, 2020 at 12:19:30AM +0100, Thomas Monjalon wrote: > 20/12/2019 17:20, Kinsella, Ray: > > From: Richardson, Bruce <bruce.richardson@intel.com> > > > From: David Marchand <david.marchand@redhat.com> > > > > +Checking ABI compatibility > > > > +-------------------------- > > > > + > > > > +The first thing is to build reference binaries for the latest > > > release > > > > +your patches are built on top of. > > > > + > > > > +Either you are in a git tree and an easy way to identify this is to > > > run:: > > > > + > > > > + git checkout $(git describe --abbrev=0) > > > > + > > > > +Or you use a tarball and you extract the sources in a director of > > > > +your > > > > choice. > > > > + > > > > +Next is building those sources, refer to the previous paragraph. > > > > +You can set ``DPDK_BUILD_TEST_DIR=reference``, so that the builds > > > > +occur in this directory. > > > > + > > > > +Finally, the ABI dump files are generated with the > > > > +``devtools/gen-abi-reference.sh`` script. This script will look for > > > > +builds in the current sub directory ``reference``. But you can set > > > > +the environment variable ``DPDK_ABI_REF_BUILD_DIR`` to a different > > > location. > > > > + > > > > +Once done, you can check your current binaries ABI with this > > > > +reference with the ``devtools/check-abi-reference.sh`` script. > > > > > > > > > > I still very much dislike forcing the user to generate his own > > > reference version to compare the ABI against. These should be archived > > > and the user should just be able to pull them down via git or http or > > > otherwise. Two reasons for this: > > > > > > 1. Less error prone, since there is no chance of the user having an > > > incorrect build for whatever reason. > > > > > > 2. Less effort for the user than asking them to do extra builds. The > > > more steps the user has to follow, the less likely they are to attempt > > > the process. > > > > +1 ... 100% agree with this. > > > > Many people won't know or understand what the reference is, > > or why they to generate it. > > I don't want to generate and save the reference in git for each arch. > Can I ask what your reluctance is? Is it related to not wanting to have to save all this information that is otherwise not used for building purposes? If so I might suggest saving the dumps in a separate git tree and pulling them in as a git submodule when the check is performed I really like the idea of caching the results so everyone is working from a known ABI baseline. Neil > We can make reference build more automatic with a command like this: > git clone --branch v19.11 . $DPDK_BUILD_TEST_DIR/abiref-19.11 > > Also I don't like mixing build and check steps. > I believe the compilation should be simple and right to the point. > > This approach, from David, does not prevent from saving the dumps later > if we really feel a strong need. > > That's why I suggest going with this patch. > > >
15/01/2020 12:33, Neil Horman: > On Wed, Jan 15, 2020 at 12:19:30AM +0100, Thomas Monjalon wrote: > > 20/12/2019 17:20, Kinsella, Ray: > > > From: Richardson, Bruce <bruce.richardson@intel.com> > > > > From: David Marchand <david.marchand@redhat.com> > > > > > +Checking ABI compatibility > > > > > +-------------------------- > > > > > + > > > > > +The first thing is to build reference binaries for the latest > > > > release > > > > > +your patches are built on top of. > > > > > + > > > > > +Either you are in a git tree and an easy way to identify this is to > > > > run:: > > > > > + > > > > > + git checkout $(git describe --abbrev=0) > > > > > + > > > > > +Or you use a tarball and you extract the sources in a director of > > > > > +your > > > > > choice. > > > > > + > > > > > +Next is building those sources, refer to the previous paragraph. > > > > > +You can set ``DPDK_BUILD_TEST_DIR=reference``, so that the builds > > > > > +occur in this directory. > > > > > + > > > > > +Finally, the ABI dump files are generated with the > > > > > +``devtools/gen-abi-reference.sh`` script. This script will look for > > > > > +builds in the current sub directory ``reference``. But you can set > > > > > +the environment variable ``DPDK_ABI_REF_BUILD_DIR`` to a different > > > > location. > > > > > + > > > > > +Once done, you can check your current binaries ABI with this > > > > > +reference with the ``devtools/check-abi-reference.sh`` script. > > > > > > > > > > > > > I still very much dislike forcing the user to generate his own > > > > reference version to compare the ABI against. These should be archived > > > > and the user should just be able to pull them down via git or http or > > > > otherwise. Two reasons for this: > > > > > > > > 1. Less error prone, since there is no chance of the user having an > > > > incorrect build for whatever reason. > > > > > > > > 2. Less effort for the user than asking them to do extra builds. The > > > > more steps the user has to follow, the less likely they are to attempt > > > > the process. > > > > > > +1 ... 100% agree with this. > > > > > > Many people won't know or understand what the reference is, > > > or why they to generate it. > > > > I don't want to generate and save the reference in git for each arch. > > > Can I ask what your reluctance is? Is it related to not wanting to have to save > all this information that is otherwise not used for building purposes? Yes I prefer keeping only the sources in the repository. And these dumps are big. And last but not the least, there is no ready-to-use environment to build and dump all libs for all archs. > If so I might suggest saving the dumps in a separate git tree and pulling them > in as a git submodule when the check is performed > > I really like the idea of caching the results so everyone is working from a > known ABI baseline. You don't trust the result of the build made from tagged sources? > > We can make reference build more automatic with a command like this: > > git clone --branch v19.11 . $DPDK_BUILD_TEST_DIR/abiref-19.11 > > > > Also I don't like mixing build and check steps. > > I believe the compilation should be simple and right to the point. > > > > This approach, from David, does not prevent from saving the dumps later > > if we really feel a strong need. > > > > That's why I suggest going with this patch.
On 06-Jan-20 1:17 PM, Aaron Conole wrote: > Thomas Monjalon <thomas@monjalon.net> writes: > >> 20/12/2019 17:20, Kinsella, Ray: >>>> -----Original Message----- >>>> From: Richardson, Bruce <bruce.richardson@intel.com> >>>> Sent: Friday 20 December 2019 15:32 >>>> To: David Marchand <david.marchand@redhat.com>; dev@dpdk.org >>>> Cc: thomas@monjalon.net; Laatz, Kevin <kevin.laatz@intel.com>; >>>> aconole@redhat.com; nhorman@tuxdriver.com; Michael Santana >>>> <maicolgabriel@hotmail.com>; Mcnamara, John <john.mcnamara@intel.com>; >>>> Kovacevic, Marko <marko.kovacevic@intel.com>; Kinsella, Ray >>>> <ray.kinsella@intel.com> >>>> Subject: RE: [PATCH] add ABI checks >>>> >>>> >>>> >>>>> -----Original Message----- >>>>> From: David Marchand <david.marchand@redhat.com> >>>>> Sent: Friday, December 20, 2019 3:21 PM >>>>> To: dev@dpdk.org >>>>> Cc: thomas@monjalon.net; Richardson, Bruce >>>>> <bruce.richardson@intel.com>; Laatz, Kevin <kevin.laatz@intel.com>; >>>>> aconole@redhat.com; nhorman@tuxdriver.com; Michael Santana >>>>> <maicolgabriel@hotmail.com>; Mcnamara, John >>>> <john.mcnamara@intel.com>; >>>>> Kovacevic, Marko <marko.kovacevic@intel.com> >>>>> Subject: [PATCH] add ABI checks >>>>> >>>>> Starting from Kevin and Bruce idea of using libabigail, here is an >>>>> alternate approach to implement ABI checks. >>>>> >>>>> By default, those checks are disabled and enabling them requires a >>>>> manual step that generates the ABI dumps on a reference version for a >>>>> set of configurations. >>>>> >>>>> Those checks are enabled in the CI by default for the default meson >>>>> options on x86 and aarch64 so that proposed patches are validated. >>>>> A cache of the ABI is stored in travis jobs. >>>>> Checks can be only informational by setting ABI_CHECKS_WARN_ONLY when >>>>> breaking the ABI in a future release. >>>>> >>>>> For advanced developers and maintainers, the contributing guide >>>>> details the higher level scripts that are quite close to the existing >>>>> devtools scripts. >>>>> >>>>> Signed-off-by: David Marchand <david.marchand@redhat.com> >>>>> --- >>>>> .ci/linux-build.sh | 43 +++++++++++++++++++++++++++ >>>>> .travis.yml | 20 +++++++++++-- >>>>> devtools/check-abi-dump.sh | 46 >>>> +++++++++++++++++++++++++++++ >>>>> devtools/check-abi-reference.sh | 27 +++++++++++++++++ >>>>> devtools/dpdk.abignore | 2 ++ >>>>> devtools/gen-abi-dump.sh | 29 ++++++++++++++++++ >>>>> devtools/gen-abi-reference.sh | 24 +++++++++++++++ >>>>> devtools/test-build.sh | 13 ++++++-- >>>>> devtools/test-meson-builds.sh | 6 ++++ >>>>> doc/guides/contributing/patches.rst | 25 ++++++++++++++++ >>>>> 10 files changed, 230 insertions(+), 5 deletions(-) create mode >>>>> 100755 devtools/check-abi-dump.sh create mode 100755 >>>>> devtools/check-abi- reference.sh create mode 100644 >>>>> devtools/dpdk.abignore create mode >>>>> 100755 devtools/gen-abi-dump.sh create mode 100755 devtools/gen-abi- >>>>> reference.sh >>>>> >>>>> diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh index >>>>> ccc3a7ccd..345dba264 100755 >>>>> --- a/.ci/linux-build.sh >>>>> +++ b/.ci/linux-build.sh >>>>> @@ -30,8 +30,51 @@ fi >>>>> >>>>> OPTS="$OPTS --default-library=$DEF_LIB" >>>>> meson build --werror -Dexamples=all $OPTS >>>>> + >>>>> +if [ "$ABI_CHECKS" = "1" ]; then >>>>> + git remote add ref ${REF_GIT_REPO:-https://dpdk.org/git/dpdk} >>>>> + git fetch --tags ref ${REF_GIT_BRANCH:-master} >>>>> + >>>>> + head=$(git describe --all) >>>>> + tag=$(git describe --abbrev=0) >>>>> + >>>>> + if [ "$(cat reference/VERSION 2>/dev/null)" != "$tag" ]; then >>>>> + rm -rf reference >>>>> + fi >>>>> + >>>>> + if [ ! -d reference ]; then >>>>> + gen_abi_dump=$(mktemp -t gen-abi-dump-XXX.sh) >>>>> + cp -a devtools/gen-abi-dump.sh $gen_abi_dump >>>>> + >>>>> + git checkout -qf $tag >>>>> + ninja -C build >>>>> + $gen_abi_dump build reference >>>>> + >>>>> + if [ "$AARCH64" != "1" ]; then >>>>> + mkdir -p reference/app >>>>> + cp -a build/app/dpdk-testpmd reference/app/ >>>>> + >>>>> + export >>>> LD_LIBRARY_PATH=$(pwd)/build/lib:$(pwd)/build/drivers >>>>> + devtools/test-null.sh reference/app/dpdk-testpmd >>>>> + unset LD_LIBRARY_PATH >>>>> + fi >>>>> + echo $tag > reference/VERSION >>>>> + >>>>> + git checkout -qf $head >>>>> + fi >>>>> +fi >>>>> + >>>>> ninja -C build >>>>> >>>>> +if [ "$ABI_CHECKS" = "1" ]; then >>>>> + devtools/check-abi-dump.sh build reference >>>> ${ABI_CHECKS_WARN_ONLY:-} >>>>> + if [ "$AARCH64" != "1" ]; then >>>>> + export LD_LIBRARY_PATH=$(pwd)/build/lib:$(pwd)/build/drivers >>>>> + devtools/test-null.sh reference/app/dpdk-testpmd >>>>> + unset LD_LIBRARY_PATH >>>>> + fi >>>>> +fi >>>>> + >>>>> if [ "$AARCH64" != "1" ]; then >>>>> devtools/test-null.sh >>>>> fi >>>>> diff --git a/.travis.yml b/.travis.yml index 8f90d06f2..bbb060fa2 >>>>> 100644 >>>>> --- a/.travis.yml >>>>> +++ b/.travis.yml >>>>> @@ -1,5 +1,8 @@ >>>>> language: c >>>>> -cache: ccache >>>>> +cache: >>>>> + ccache: true >>>>> + directories: >>>>> + - reference >>>>> compiler: >>>>> - gcc >>>>> - clang >>>>> @@ -21,7 +24,7 @@ aarch64_packages: &aarch64_packages >>>>> >>>>> extra_packages: &extra_packages >>>>> - *required_packages >>>>> - - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4] >>>>> + - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4, >>>>> + abigail-tools] >>>>> >>>>> build_32b_packages: &build_32b_packages >>>>> - *required_packages >>>>> @@ -59,6 +62,13 @@ matrix: >>>>> apt: >>>>> packages: >>>>> - *aarch64_packages >>>>> + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1 AARCH64=1 >>>>> + compiler: gcc >>>>> + addons: >>>>> + apt: >>>>> + packages: >>>>> + - *aarch64_packages >>>>> + - *extra_packages >>>>> - env: DEF_LIB="static" EXTRA_PACKAGES=1 >>>>> compiler: gcc >>>>> addons: >>>>> @@ -72,6 +82,12 @@ matrix: >>>>> packages: >>>>> - *extra_packages >>>>> - *doc_packages >>>>> + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1 >>>>> + compiler: gcc >>>>> + addons: >>>>> + apt: >>>>> + packages: >>>>> + - *extra_packages >>>>> - env: DEF_LIB="static" OPTS="-Denable_kmods=false" >>>> EXTRA_PACKAGES=1 >>>>> compiler: gcc >>>>> addons: >>>>> diff --git a/devtools/check-abi-dump.sh b/devtools/check-abi-dump.sh >>>>> new file mode 100755 index 000000000..f48a2ae7e >>>>> --- /dev/null >>>>> +++ b/devtools/check-abi-dump.sh >>>>> @@ -0,0 +1,46 @@ >>>>> +#!/bin/sh -e >>>>> +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red >>>> Hat, >>>>> +Inc. >>>>> + >>>>> +if [ $# != 2 ] && [ $# != 3 ]; then >>>>> + echo "Usage: $0 builddir dumpdir [warnonly]" >>>>> + exit 1 >>>>> +fi >>>>> + >>>>> +builddir=$1 >>>>> +dumpdir=$2 >>>>> +warnonly=${3:-} >>>>> +if [ ! -d $builddir ]; then >>>>> + echo "Error: build directory '$builddir' does not exist." >>>>> + exit 1 >>>>> +fi >>>>> +if [ ! -d $dumpdir ]; then >>>>> + echo "Error: dump directory '$dumpdir' does not exist." >>>>> + exit 1 >>>>> +fi >>>>> + >>>>> +ABIDIFF_OPTIONS="--suppr $(dirname $0)/dpdk.abignore" >>>>> +for dump in $(find $dumpdir -name "*.dump"); do >>>>> + libname=$(basename $dump) >>>>> + libname=${libname%.dump} >>>>> + result= >>>>> + for f in $(find $builddir -name "$libname.so.*"); do >>>>> + if test -L $f || [ "$f" != "${f%%.symbols}" ]; then >>>>> + continue >>>>> + fi >>>>> + result=found >>>>> + >>>>> + if ! abidiff $ABIDIFF_OPTIONS $dump $f; then >>>>> + if [ -z "$warnonly" ]; then >>>>> + echo "Error: ABI issue reported for $dump, $f" >>>>> + exit 1 >>>>> + fi >>>>> + echo "Warning: ABI issue reported for $dump, $f" >>>>> + fi >>>>> + break >>>>> + done >>>>> + if [ "$result" != "found" ]; then >>>>> + echo "Error: can't find a library for dump file $dump" >>>>> + exit 1 >>>>> + fi >>>>> +done >>>>> diff --git a/devtools/check-abi-reference.sh b/devtools/check-abi- >>>>> reference.sh new file mode 100755 index 000000000..7addb094e >>>>> --- /dev/null >>>>> +++ b/devtools/check-abi-reference.sh >>>>> @@ -0,0 +1,27 @@ >>>>> +#!/bin/sh -e >>>>> +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red >>>> Hat, >>>>> +Inc. >>>>> + >>>>> +devtools_dir=$(dirname $(readlink -f $0)) . >>>>> +$devtools_dir/load-devel-config >>>>> + >>>>> +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference} >>>>> +builds_dir=${DPDK_BUILD_TEST_DIR:-.} >>>>> + >>>>> +for dir in $abi_ref_build_dir/*; do >>>>> + if [ "$dir" = "$abi_ref_build_dir" ]; then >>>>> + exit 1 >>>>> + fi >>>>> + if [ ! -d $dir/dump ]; then >>>>> + echo "Skipping $dir" >>>>> + continue >>>>> + fi >>>>> + target=$(basename $dir) >>>>> + if [ -d $builds_dir/$target/install ]; then >>>>> + libdir=$builds_dir/$target/install >>>>> + else >>>>> + libdir=$builds_dir/$target >>>>> + fi >>>>> + echo "Checking ABI between $libdir and $dir/dump" >>>>> + $devtools_dir/check-abi-dump.sh $libdir $dir/dump done >>>>> diff --git a/devtools/dpdk.abignore b/devtools/dpdk.abignore new file >>>>> mode >>>>> 100644 index 000000000..b866b7f26 >>>>> --- /dev/null >>>>> +++ b/devtools/dpdk.abignore >>>>> @@ -0,0 +1,2 @@ >>>>> +[suppress_function] >>>>> + symbol_version = EXPERIMENTAL >>>>> diff --git a/devtools/gen-abi-dump.sh b/devtools/gen-abi-dump.sh new >>>>> file mode 100755 index 000000000..4e38d751f >>>>> --- /dev/null >>>>> +++ b/devtools/gen-abi-dump.sh >>>>> @@ -0,0 +1,29 @@ >>>>> +#!/bin/sh -e >>>>> +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red >>>> Hat, >>>>> +Inc. >>>>> + >>>>> +if [ $# != 2 ]; then >>>>> + echo "Usage: $0 builddir dumpdir" >>>>> + exit 1 >>>>> +fi >>>>> + >>>>> +builddir=$1 >>>>> +dumpdir=$2 >>>>> +if [ ! -d $builddir ]; then >>>>> + echo "Error: build directory '$builddir' does not exist." >>>>> + exit 1 >>>>> +fi >>>>> +if [ -d $dumpdir ]; then >>>>> + echo "Error: dump directory '$dumpdir' already exists." >>>>> + exit 1 >>>>> +fi >>>>> + >>>>> +mkdir -p $dumpdir >>>>> +for f in $(find $builddir -name "*.so.*"); do >>>>> + if test -L $f || [ "$f" != "${f%%.symbols}" ]; then >>>>> + continue >>>>> + fi >>>>> + >>>>> + libname=$(basename $f) >>>>> + abidw --out-file $dumpdir/${libname%.so.*}.dump $f done >>>>> diff --git a/devtools/gen-abi-reference.sh >>>>> b/devtools/gen-abi-reference.sh new file mode 100755 index >>>>> 000000000..f41d7fadc >>>>> --- /dev/null >>>>> +++ b/devtools/gen-abi-reference.sh >>>>> @@ -0,0 +1,24 @@ >>>>> +#!/bin/sh -e >>>>> +# SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2019 Red >>>> Hat, >>>>> +Inc. >>>>> + >>>>> +devtools_dir=$(dirname $(readlink -f $0)) . >>>>> +$devtools_dir/load-devel-config >>>>> + >>>>> +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference} >>>>> +for dir in $abi_ref_build_dir/*; do >>>>> + if [ "$dir" = "$abi_ref_build_dir" ]; then >>>>> + exit 1 >>>>> + fi >>>>> + if [ -d $dir/dump ]; then >>>>> + echo "Skipping $dir" >>>>> + continue >>>>> + fi >>>>> + if [ -d $dir/install ]; then >>>>> + libdir=$dir/install >>>>> + else >>>>> + libdir=$dir >>>>> + fi >>>>> + echo "Dumping libraries from $libdir in $dir/dump" >>>>> + $devtools_dir/gen-abi-dump.sh $libdir $dir/dump done >>>>> diff --git a/devtools/test-build.sh b/devtools/test-build.sh index >>>>> 52305fbb8..8cb5b56fb 100755 >>>>> --- a/devtools/test-build.sh >>>>> +++ b/devtools/test-build.sh >>>>> @@ -30,7 +30,8 @@ default_path=$PATH >>>>> # - LIBSSO_SNOW3G_PATH >>>>> # - LIBSSO_KASUMI_PATH >>>>> # - LIBSSO_ZUC_PATH >>>>> -. $(dirname $(readlink -f $0))/load-devel-config >>>>> +devtools_dir=$(dirname $(readlink -f $0)) . >>>>> +$devtools_dir/load-devel-config >>>>> >>>>> print_usage () { >>>>> echo "usage: $(basename $0) [-h] [-jX] [-s] [config1 [config2] >>>>> ...]]" >>>>> @@ -64,6 +65,7 @@ print_help () { >>>>> [ -z $MAKE ] && echo "Cannot find make or gmake" && exit 1 >>>>> >>>>> J=$DPDK_MAKE_JOBS >>>>> +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference} >>>>> builds_dir=${DPDK_BUILD_TEST_DIR:-.} >>>>> short=false >>>>> unset verbose >>>>> @@ -97,7 +99,7 @@ trap "signal=INT ; trap - INT ; kill -INT $$" INT >>>> # >>>>> notify result on exit trap on_exit EXIT >>>>> >>>>> -cd $(dirname $(readlink -f $0))/.. >>>>> +cd $devtools_dir/.. >>>>> >>>>> reset_env () >>>>> { >>>>> @@ -233,7 +235,7 @@ for conf in $configs ; do >>>>> # reload config with DPDK_TARGET set >>>>> DPDK_TARGET=$target >>>>> reset_env >>>>> - . $(dirname $(readlink -f $0))/load-devel-config >>>>> + . $devtools_dir/load-devel-config >>>>> >>>>> options=$(echo $conf | sed 's,[^~+]*,,') >>>>> dir=$builds_dir/$conf >>>>> @@ -246,6 +248,11 @@ for conf in $configs ; do >>>>> export RTE_TARGET=$target >>>>> rm -rf $dir/install >>>>> ${MAKE} install O=$dir DESTDIR=$dir/install prefix= >>>>> + if [ -d $abi_ref_build_dir/$conf/dump ]; then >>>>> + echo "================== Check ABI $conf" >>>>> + $devtools_dir/check-abi-dump.sh $dir/install \ >>>>> + $abi_ref_build_dir/$conf/dump >>>>> + fi >>>>> echo "================== Build examples for $conf" >>>>> export RTE_SDK=$(readlink -f $dir)/install/share/dpdk >>>>> ln -sTf $(pwd)/lib $RTE_SDK/lib # workaround for vm_power_manager >>>>> diff --git a/devtools/test-meson-builds.sh >>>>> b/devtools/test-meson-builds.sh index 688567714..aaefa38a2 100755 >>>>> --- a/devtools/test-meson-builds.sh >>>>> +++ b/devtools/test-meson-builds.sh >>>>> @@ -16,6 +16,7 @@ srcdir=$(dirname $(readlink -f $0))/.. >>>>> >>>>> MESON=${MESON:-meson} >>>>> use_shared="--default-library=shared" >>>>> +abi_ref_build_dir=${DPDK_ABI_REF_BUILD_DIR:-reference} >>>>> builds_dir=${DPDK_BUILD_TEST_DIR:-.} >>>>> >>>>> if command -v gmake >/dev/null 2>&1 ; then @@ -88,6 +89,11 @@ build >>>>> () # <directory> <target compiler> <meson options> >>>>> echo "$ninja_cmd -C $builddir" >>>>> $ninja_cmd -C $builddir >>>>> fi >>>>> + >>>>> + if [ -d $abi_ref_build_dir/$1/dump ]; then >>>>> + $srcdir/devtools/check-abi-dump.sh $builddir >>>>> + $abi_ref_build_dir/$1/dump >>>>> + fi >>>>> } >>>>> >>>>> if [ "$1" = "-vv" ] ; then >>>>> diff --git a/doc/guides/contributing/patches.rst >>>>> b/doc/guides/contributing/patches.rst >>>>> index 0686450e4..de3dff145 100644 >>>>> --- a/doc/guides/contributing/patches.rst >>>>> +++ b/doc/guides/contributing/patches.rst >>>>> @@ -513,6 +513,31 @@ in a single subfolder called "__builds" created >>>>> in the current directory. >>>>> Setting ``DPDK_BUILD_TEST_DIR`` to an absolute directory path e.g. >>>>> ``/tmp`` is also supported. >>>>> >>>>> >>>>> +Checking ABI compatibility >>>>> +-------------------------- >>>>> + >>>>> +The first thing is to build reference binaries for the latest >>>> release >>>>> +your patches are built on top of. >>>>> + >>>>> +Either you are in a git tree and an easy way to identify this is to >>>> run:: >>>>> + >>>>> + git checkout $(git describe --abbrev=0) >>>>> + >>>>> +Or you use a tarball and you extract the sources in a director of >>>>> +your >>>>> choice. >>>>> + >>>>> +Next is building those sources, refer to the previous paragraph. >>>>> +You can set ``DPDK_BUILD_TEST_DIR=reference``, so that the builds >>>>> +occur in this directory. >>>>> + >>>>> +Finally, the ABI dump files are generated with the >>>>> +``devtools/gen-abi-reference.sh`` script. This script will look for >>>>> +builds in the current sub directory ``reference``. But you can set >>>>> +the environment variable ``DPDK_ABI_REF_BUILD_DIR`` to a different >>>> location. >>>>> + >>>>> +Once done, you can check your current binaries ABI with this >>>>> +reference with the ``devtools/check-abi-reference.sh`` script. >>>>> + >>>>> + >>>>> Sending Patches >>>>> --------------- >>>>> >>>>> -- >>>>> 2.23.0 >>>> >>>> I still very much dislike forcing the user to generate his own >>>> reference version to compare the ABI against. These should be archived >>>> and the user should just be able to pull them down via git or http or >>>> otherwise. Two reasons for this: >>>> >>>> 1. Less error prone, since there is no chance of the user having an >>>> incorrect build for whatever reason. > > It's more error prone I think. There are issues with archived versions > of ABI dumps, or bad content delivery networks. Working from the git > repository is *guaranteed* to generate a correct ABI dump. Anything > else allows your CDN / other to break. I can't speak for everyone else, but normally when i'm working on a DPDK codebase, there's a whole bunch of stuff that isn't built by default, and i normally never bother. So, while working from git repo is guaranteed to generate a correct ABI dump, it is *not* guaranteed to cover everything, unless the developer takes steps to do otherwise. As far as i understand, the plan is to make ABI checks part of the automation - so the effort of *having* these reference ABI dumps is already spent anyway, might as well make them accessible to whoever develops DPDK too. And if CDN/connectivity fails - well, so be it, either fall back to manual process, or let the automation handle it. > >>>> 2. Less effort for the user than asking them to do extra builds. The >>>> more steps the user has to follow, the less likely they are to attempt >>>> the process. > > It's important to remember that (as far as I'm aware) the vast majority > of DPDK users don't make many code changes or even compile it. And > those who do typically don't even run the unit tests. I think it's good > to document a process for people to follow, but such process shouldn't > assume that developers can't run basic git commands or execute scripts. > >>>> Regards, >>>> /Bruce >>>> >>> >>> +1 ... 100% agree with this. >>> >>> Many people won't know or understand what the reference is, >>> or why they to generate it. >> >> Many people won't run the test at all and will rely on the automatic CI tests. > > +1 to this. It's good for the robot's travis build to validate the ABI for > patches, since it will alert us anyway. > > -- Thanks, Anatoly
On Wed, Jan 15, 2020 at 01:38:17PM +0100, Thomas Monjalon wrote: > 15/01/2020 12:33, Neil Horman: > > On Wed, Jan 15, 2020 at 12:19:30AM +0100, Thomas Monjalon wrote: > > > 20/12/2019 17:20, Kinsella, Ray: > > > > From: Richardson, Bruce <bruce.richardson@intel.com> > > > > > From: David Marchand <david.marchand@redhat.com> > > > > > > +Checking ABI compatibility > > > > > > +-------------------------- > > > > > > + > > > > > > +The first thing is to build reference binaries for the latest > > > > > release > > > > > > +your patches are built on top of. > > > > > > + > > > > > > +Either you are in a git tree and an easy way to identify this is to > > > > > run:: > > > > > > + > > > > > > + git checkout $(git describe --abbrev=0) > > > > > > + > > > > > > +Or you use a tarball and you extract the sources in a director of > > > > > > +your > > > > > > choice. > > > > > > + > > > > > > +Next is building those sources, refer to the previous paragraph. > > > > > > +You can set ``DPDK_BUILD_TEST_DIR=reference``, so that the builds > > > > > > +occur in this directory. > > > > > > + > > > > > > +Finally, the ABI dump files are generated with the > > > > > > +``devtools/gen-abi-reference.sh`` script. This script will look for > > > > > > +builds in the current sub directory ``reference``. But you can set > > > > > > +the environment variable ``DPDK_ABI_REF_BUILD_DIR`` to a different > > > > > location. > > > > > > + > > > > > > +Once done, you can check your current binaries ABI with this > > > > > > +reference with the ``devtools/check-abi-reference.sh`` script. > > > > > > > > > > > > > > > > I still very much dislike forcing the user to generate his own > > > > > reference version to compare the ABI against. These should be archived > > > > > and the user should just be able to pull them down via git or http or > > > > > otherwise. Two reasons for this: > > > > > > > > > > 1. Less error prone, since there is no chance of the user having an > > > > > incorrect build for whatever reason. > > > > > > > > > > 2. Less effort for the user than asking them to do extra builds. The > > > > > more steps the user has to follow, the less likely they are to attempt > > > > > the process. > > > > > > > > +1 ... 100% agree with this. > > > > > > > > Many people won't know or understand what the reference is, > > > > or why they to generate it. > > > > > > I don't want to generate and save the reference in git for each arch. > > > > > Can I ask what your reluctance is? Is it related to not wanting to have to save > > all this information that is otherwise not used for building purposes? > > Yes I prefer keeping only the sources in the repository. > And these dumps are big. > And last but not the least, there is no ready-to-use environment to build > and dump all libs for all archs. > > > If so I might suggest saving the dumps in a separate git tree and pulling them > > in as a git submodule when the check is performed > > > > I really like the idea of caching the results so everyone is working from a > > known ABI baseline. > > You don't trust the result of the build made from tagged sources? > I trust the result from the tools, sure, its trusting that people will take the extra time to build a version from a prior tag that I'm less sure of. Consistent use in my mind is predicated on ease and timeliness of use. I get not wanting to store large dumps in the source tree, but storage is cheap, and I don't see the issue with storing the xml dump in a separate git tree to be referenced through a git submodule that gets pulled in when the check is run. Neil > > > We can make reference build more automatic with a command like this: > > > git clone --branch v19.11 . $DPDK_BUILD_TEST_DIR/abiref-19.11 > > > > > > Also I don't like mixing build and check steps. > > > I believe the compilation should be simple and right to the point. > > > > > > This approach, from David, does not prevent from saving the dumps later > > > if we really feel a strong need. > > > > > > That's why I suggest going with this patch. > > > >
16/01/2020 12:52, Neil Horman:
> On Wed, Jan 15, 2020 at 01:38:17PM +0100, Thomas Monjalon wrote:
> > 15/01/2020 12:33, Neil Horman:
> > > On Wed, Jan 15, 2020 at 12:19:30AM +0100, Thomas Monjalon wrote:
> > > > 20/12/2019 17:20, Kinsella, Ray:
> > > > > From: Richardson, Bruce <bruce.richardson@intel.com>
> > > > > > From: David Marchand <david.marchand@redhat.com>
> > > > > > > +Checking ABI compatibility
> > > > > > > +--------------------------
> > > > > > > +
> > > > > > > +The first thing is to build reference binaries for the latest
> > > > > > release
> > > > > > > +your patches are built on top of.
> > > > > > > +
> > > > > > > +Either you are in a git tree and an easy way to identify this is to
> > > > > > run::
> > > > > > > +
> > > > > > > + git checkout $(git describe --abbrev=0)
> > > > > > > +
> > > > > > > +Or you use a tarball and you extract the sources in a director of
> > > > > > > +your
> > > > > > > choice.
> > > > > > > +
> > > > > > > +Next is building those sources, refer to the previous paragraph.
> > > > > > > +You can set ``DPDK_BUILD_TEST_DIR=reference``, so that the builds
> > > > > > > +occur in this directory.
> > > > > > > +
> > > > > > > +Finally, the ABI dump files are generated with the
> > > > > > > +``devtools/gen-abi-reference.sh`` script. This script will look for
> > > > > > > +builds in the current sub directory ``reference``. But you can set
> > > > > > > +the environment variable ``DPDK_ABI_REF_BUILD_DIR`` to a different
> > > > > > location.
> > > > > > > +
> > > > > > > +Once done, you can check your current binaries ABI with this
> > > > > > > +reference with the ``devtools/check-abi-reference.sh`` script.
> > > > > > >
> > > > > >
> > > > > > I still very much dislike forcing the user to generate his own
> > > > > > reference version to compare the ABI against. These should be archived
> > > > > > and the user should just be able to pull them down via git or http or
> > > > > > otherwise. Two reasons for this:
> > > > > >
> > > > > > 1. Less error prone, since there is no chance of the user having an
> > > > > > incorrect build for whatever reason.
> > > > > >
> > > > > > 2. Less effort for the user than asking them to do extra builds. The
> > > > > > more steps the user has to follow, the less likely they are to attempt
> > > > > > the process.
> > > > >
> > > > > +1 ... 100% agree with this.
> > > > >
> > > > > Many people won't know or understand what the reference is,
> > > > > or why they to generate it.
> > > >
> > > > I don't want to generate and save the reference in git for each arch.
> > > >
> > > Can I ask what your reluctance is? Is it related to not wanting to have to save
> > > all this information that is otherwise not used for building purposes?
> >
> > Yes I prefer keeping only the sources in the repository.
> > And these dumps are big.
> > And last but not the least, there is no ready-to-use environment to build
> > and dump all libs for all archs.
> >
> > > If so I might suggest saving the dumps in a separate git tree and pulling them
> > > in as a git submodule when the check is performed
> > >
> > > I really like the idea of caching the results so everyone is working from a
> > > known ABI baseline.
> >
> > You don't trust the result of the build made from tagged sources?
> >
> I trust the result from the tools, sure, its trusting that people will take the
> extra time to build a version from a prior tag that I'm less sure of.
> Consistent use in my mind is predicated on ease and timeliness of use.
>
> I get not wanting to store large dumps in the source tree, but storage is cheap,
> and I don't see the issue with storing the xml dump in a separate git tree to be
> referenced through a git submodule that gets pulled in when the check is run.
Yes this is an option.
My fear is that this reference database will not be complete
if we don't build it for all libraries/drivers on all archs,
managing setups and dependencies.
On Thu, Jan 16, 2020 at 03:20:48PM +0100, Thomas Monjalon wrote: > 16/01/2020 12:52, Neil Horman: > > On Wed, Jan 15, 2020 at 01:38:17PM +0100, Thomas Monjalon wrote: > > > 15/01/2020 12:33, Neil Horman: > > > > On Wed, Jan 15, 2020 at 12:19:30AM +0100, Thomas Monjalon wrote: > > > > > 20/12/2019 17:20, Kinsella, Ray: > > > > > > From: Richardson, Bruce <bruce.richardson@intel.com> > > > > > > > From: David Marchand <david.marchand@redhat.com> > > > > > > > > +Checking ABI compatibility > > > > > > > > +-------------------------- > > > > > > > > + > > > > > > > > +The first thing is to build reference binaries for the latest > > > > > > > release > > > > > > > > +your patches are built on top of. > > > > > > > > + > > > > > > > > +Either you are in a git tree and an easy way to identify this is to > > > > > > > run:: > > > > > > > > + > > > > > > > > + git checkout $(git describe --abbrev=0) > > > > > > > > + > > > > > > > > +Or you use a tarball and you extract the sources in a director of > > > > > > > > +your > > > > > > > > choice. > > > > > > > > + > > > > > > > > +Next is building those sources, refer to the previous paragraph. > > > > > > > > +You can set ``DPDK_BUILD_TEST_DIR=reference``, so that the builds > > > > > > > > +occur in this directory. > > > > > > > > + > > > > > > > > +Finally, the ABI dump files are generated with the > > > > > > > > +``devtools/gen-abi-reference.sh`` script. This script will look for > > > > > > > > +builds in the current sub directory ``reference``. But you can set > > > > > > > > +the environment variable ``DPDK_ABI_REF_BUILD_DIR`` to a different > > > > > > > location. > > > > > > > > + > > > > > > > > +Once done, you can check your current binaries ABI with this > > > > > > > > +reference with the ``devtools/check-abi-reference.sh`` script. > > > > > > > > > > > > > > > > > > > > > > I still very much dislike forcing the user to generate his own > > > > > > > reference version to compare the ABI against. These should be archived > > > > > > > and the user should just be able to pull them down via git or http or > > > > > > > otherwise. Two reasons for this: > > > > > > > > > > > > > > 1. Less error prone, since there is no chance of the user having an > > > > > > > incorrect build for whatever reason. > > > > > > > > > > > > > > 2. Less effort for the user than asking them to do extra builds. The > > > > > > > more steps the user has to follow, the less likely they are to attempt > > > > > > > the process. > > > > > > > > > > > > +1 ... 100% agree with this. > > > > > > > > > > > > Many people won't know or understand what the reference is, > > > > > > or why they to generate it. > > > > > > > > > > I don't want to generate and save the reference in git for each arch. > > > > > > > > > Can I ask what your reluctance is? Is it related to not wanting to have to save > > > > all this information that is otherwise not used for building purposes? > > > > > > Yes I prefer keeping only the sources in the repository. > > > And these dumps are big. > > > And last but not the least, there is no ready-to-use environment to build > > > and dump all libs for all archs. > > > > > > > If so I might suggest saving the dumps in a separate git tree and pulling them > > > > in as a git submodule when the check is performed > > > > > > > > I really like the idea of caching the results so everyone is working from a > > > > known ABI baseline. > > > > > > You don't trust the result of the build made from tagged sources? > > > > > I trust the result from the tools, sure, its trusting that people will take the > > extra time to build a version from a prior tag that I'm less sure of. > > Consistent use in my mind is predicated on ease and timeliness of use. > > > > I get not wanting to store large dumps in the source tree, but storage is cheap, > > and I don't see the issue with storing the xml dump in a separate git tree to be > > referenced through a git submodule that gets pulled in when the check is run. > > Yes this is an option. > My fear is that this reference database will not be complete > if we don't build it for all libraries/drivers on all archs, > managing setups and dependencies. > I can understand that, but I would have assumed that we would have done all config build for all supported arches as part of the CI for a release, from which we could archive the results. Is that not the case? Neil > >
16/01/2020 19:49, Neil Horman:
> On Thu, Jan 16, 2020 at 03:20:48PM +0100, Thomas Monjalon wrote:
> > 16/01/2020 12:52, Neil Horman:
> > > On Wed, Jan 15, 2020 at 01:38:17PM +0100, Thomas Monjalon wrote:
> > > > 15/01/2020 12:33, Neil Horman:
> > > > > On Wed, Jan 15, 2020 at 12:19:30AM +0100, Thomas Monjalon wrote:
> > > > > > 20/12/2019 17:20, Kinsella, Ray:
> > > > > > > From: Richardson, Bruce <bruce.richardson@intel.com>
> > > > > > > > From: David Marchand <david.marchand@redhat.com>
> > > > > > > > > +Checking ABI compatibility
> > > > > > > > > +--------------------------
> > > > > > > > > +
> > > > > > > > > +The first thing is to build reference binaries for the latest
> > > > > > > > release
> > > > > > > > > +your patches are built on top of.
> > > > > > > > > +
> > > > > > > > > +Either you are in a git tree and an easy way to identify this is to
> > > > > > > > run::
> > > > > > > > > +
> > > > > > > > > + git checkout $(git describe --abbrev=0)
> > > > > > > > > +
> > > > > > > > > +Or you use a tarball and you extract the sources in a director of
> > > > > > > > > +your
> > > > > > > > > choice.
> > > > > > > > > +
> > > > > > > > > +Next is building those sources, refer to the previous paragraph.
> > > > > > > > > +You can set ``DPDK_BUILD_TEST_DIR=reference``, so that the builds
> > > > > > > > > +occur in this directory.
> > > > > > > > > +
> > > > > > > > > +Finally, the ABI dump files are generated with the
> > > > > > > > > +``devtools/gen-abi-reference.sh`` script. This script will look for
> > > > > > > > > +builds in the current sub directory ``reference``. But you can set
> > > > > > > > > +the environment variable ``DPDK_ABI_REF_BUILD_DIR`` to a different
> > > > > > > > location.
> > > > > > > > > +
> > > > > > > > > +Once done, you can check your current binaries ABI with this
> > > > > > > > > +reference with the ``devtools/check-abi-reference.sh`` script.
> > > > > > > > >
> > > > > > > >
> > > > > > > > I still very much dislike forcing the user to generate his own
> > > > > > > > reference version to compare the ABI against. These should be archived
> > > > > > > > and the user should just be able to pull them down via git or http or
> > > > > > > > otherwise. Two reasons for this:
> > > > > > > >
> > > > > > > > 1. Less error prone, since there is no chance of the user having an
> > > > > > > > incorrect build for whatever reason.
> > > > > > > >
> > > > > > > > 2. Less effort for the user than asking them to do extra builds. The
> > > > > > > > more steps the user has to follow, the less likely they are to attempt
> > > > > > > > the process.
> > > > > > >
> > > > > > > +1 ... 100% agree with this.
> > > > > > >
> > > > > > > Many people won't know or understand what the reference is,
> > > > > > > or why they to generate it.
> > > > > >
> > > > > > I don't want to generate and save the reference in git for each arch.
> > > > > >
> > > > > Can I ask what your reluctance is? Is it related to not wanting to have to save
> > > > > all this information that is otherwise not used for building purposes?
> > > >
> > > > Yes I prefer keeping only the sources in the repository.
> > > > And these dumps are big.
> > > > And last but not the least, there is no ready-to-use environment to build
> > > > and dump all libs for all archs.
> > > >
> > > > > If so I might suggest saving the dumps in a separate git tree and pulling them
> > > > > in as a git submodule when the check is performed
> > > > >
> > > > > I really like the idea of caching the results so everyone is working from a
> > > > > known ABI baseline.
> > > >
> > > > You don't trust the result of the build made from tagged sources?
> > > >
> > > I trust the result from the tools, sure, its trusting that people will take the
> > > extra time to build a version from a prior tag that I'm less sure of.
> > > Consistent use in my mind is predicated on ease and timeliness of use.
> > >
> > > I get not wanting to store large dumps in the source tree, but storage is cheap,
> > > and I don't see the issue with storing the xml dump in a separate git tree to be
> > > referenced through a git submodule that gets pulled in when the check is run.
> >
> > Yes this is an option.
> > My fear is that this reference database will not be complete
> > if we don't build it for all libraries/drivers on all archs,
> > managing setups and dependencies.
> >
> I can understand that, but I would have assumed that we would have done all
> config build for all supported arches as part of the CI for a release, from
> which we could archive the results. Is that not the case?
No, we don't have a fully complete setup covering all dependencies and archs.
On Thu, Jan 16, 2020 at 09:01:52PM +0100, Thomas Monjalon wrote: > 16/01/2020 19:49, Neil Horman: > > On Thu, Jan 16, 2020 at 03:20:48PM +0100, Thomas Monjalon wrote: > > > 16/01/2020 12:52, Neil Horman: > > > > On Wed, Jan 15, 2020 at 01:38:17PM +0100, Thomas Monjalon wrote: > > > > > 15/01/2020 12:33, Neil Horman: > > > > > > On Wed, Jan 15, 2020 at 12:19:30AM +0100, Thomas Monjalon wrote: > > > > > > > 20/12/2019 17:20, Kinsella, Ray: > > > > > > > > From: Richardson, Bruce <bruce.richardson@intel.com> > > > > > > > > > From: David Marchand <david.marchand@redhat.com> > > > > > > > > > > +Checking ABI compatibility > > > > > > > > > > +-------------------------- > > > > > > > > > > + > > > > > > > > > > +The first thing is to build reference binaries for the latest > > > > > > > > > release > > > > > > > > > > +your patches are built on top of. > > > > > > > > > > + > > > > > > > > > > +Either you are in a git tree and an easy way to identify this is to > > > > > > > > > run:: > > > > > > > > > > + > > > > > > > > > > + git checkout $(git describe --abbrev=0) > > > > > > > > > > + > > > > > > > > > > +Or you use a tarball and you extract the sources in a director of > > > > > > > > > > +your > > > > > > > > > > choice. > > > > > > > > > > + > > > > > > > > > > +Next is building those sources, refer to the previous paragraph. > > > > > > > > > > +You can set ``DPDK_BUILD_TEST_DIR=reference``, so that the builds > > > > > > > > > > +occur in this directory. > > > > > > > > > > + > > > > > > > > > > +Finally, the ABI dump files are generated with the > > > > > > > > > > +``devtools/gen-abi-reference.sh`` script. This script will look for > > > > > > > > > > +builds in the current sub directory ``reference``. But you can set > > > > > > > > > > +the environment variable ``DPDK_ABI_REF_BUILD_DIR`` to a different > > > > > > > > > location. > > > > > > > > > > + > > > > > > > > > > +Once done, you can check your current binaries ABI with this > > > > > > > > > > +reference with the ``devtools/check-abi-reference.sh`` script. > > > > > > > > > > > > > > > > > > > > > > > > > > > > I still very much dislike forcing the user to generate his own > > > > > > > > > reference version to compare the ABI against. These should be archived > > > > > > > > > and the user should just be able to pull them down via git or http or > > > > > > > > > otherwise. Two reasons for this: > > > > > > > > > > > > > > > > > > 1. Less error prone, since there is no chance of the user having an > > > > > > > > > incorrect build for whatever reason. > > > > > > > > > > > > > > > > > > 2. Less effort for the user than asking them to do extra builds. The > > > > > > > > > more steps the user has to follow, the less likely they are to attempt > > > > > > > > > the process. > > > > > > > > > > > > > > > > +1 ... 100% agree with this. > > > > > > > > > > > > > > > > Many people won't know or understand what the reference is, > > > > > > > > or why they to generate it. > > > > > > > > > > > > > > I don't want to generate and save the reference in git for each arch. > > > > > > > > > > > > > Can I ask what your reluctance is? Is it related to not wanting to have to save > > > > > > all this information that is otherwise not used for building purposes? > > > > > > > > > > Yes I prefer keeping only the sources in the repository. > > > > > And these dumps are big. > > > > > And last but not the least, there is no ready-to-use environment to build > > > > > and dump all libs for all archs. > > > > > > > > > > > If so I might suggest saving the dumps in a separate git tree and pulling them > > > > > > in as a git submodule when the check is performed > > > > > > > > > > > > I really like the idea of caching the results so everyone is working from a > > > > > > known ABI baseline. > > > > > > > > > > You don't trust the result of the build made from tagged sources? > > > > > > > > > I trust the result from the tools, sure, its trusting that people will take the > > > > extra time to build a version from a prior tag that I'm less sure of. > > > > Consistent use in my mind is predicated on ease and timeliness of use. > > > > > > > > I get not wanting to store large dumps in the source tree, but storage is cheap, > > > > and I don't see the issue with storing the xml dump in a separate git tree to be > > > > referenced through a git submodule that gets pulled in when the check is run. > > > > > > Yes this is an option. > > > My fear is that this reference database will not be complete > > > if we don't build it for all libraries/drivers on all archs, > > > managing setups and dependencies. > > > > > I can understand that, but I would have assumed that we would have done all > > config build for all supported arches as part of the CI for a release, from > > which we could archive the results. Is that not the case? > > No, we don't have a fully complete setup covering all dependencies and archs. > Hmmm....I wonder if its worth orchestrating the build system to use a git submodule storing whatever our CI system can produce and using it as a cache, and falling back to a local build if the appropriate arch isn't found? That might offer some incentive to alternate arch maintainers to contribute hardware or compute time to populating it in pursuit of better build times? Neil > >
On Fri, Jan 17, 2020 at 8:02 PM Neil Horman <nhorman@tuxdriver.com> wrote: > Hmmm....I wonder if its worth orchestrating the build system to use a git > submodule storing whatever our CI system can produce and using it as a cache, > and falling back to a local build if the appropriate arch isn't found? That > might offer some incentive to alternate arch maintainers to contribute hardware > or compute time to populating it in pursuit of better build times? Thomas, Neil, I would prefer we consider this in a second step. Just want to give a little update on this patch. Building dpdk with debuginfo seems necessary, if we want to catch internal structures changes. I suppose Bruce patch can be merged already: https://patchwork.dpdk.org/patch/63400/ libabigail in Ubuntu 16.04 (Xenial) is a bit old (version 1.0-rc3) and exhibits a false positive on the linkage name of the default symbol if we do function versioning: we caught this with Olivier when he asked for help on his patch for mempool. This issue disappears with version 1.2 that is in Ubuntu 18.04 (Bionic). After running the check in my environment (fc30 with libabigail 1.5), I caught issues with abidiff when comparing a .so and an abi dump. I reported this upstream, and Dodji fixed this right away. https://sourceware.org/bugzilla/show_bug.cgi?id=25409 The fix should be part of version 1.7. This could be ignored if we only do the checks with binaries generated with gcc. I just got a false positive on an ABI change for the "custom element size" ring series, but on a type that is not user visible (thanks Honnappa). So this needs more work: I hope the --headers-dirX options will help but it means we must store the public headers with the ABI dumps. I can prepare a v2 and have the CI only warns about changes without reporting a failure. -- David Marchand
Here is the current state of the ABI checks. libabigail has some issues when mixing dump and so files compiled with clang [1], so for now, all checks are done on dumps only. libabigail 1.0-rc3 in Xenial reported issues that disappear with the version 1.2 in Bionic. To avoid getting warnings on internal types like [2], the checks now make use of the public headers part of a dpdk installation (patch 2 and 3 to prepare for this). Some internal rte_hash headers were installed by meson, so patch 1 fixes this. The most important point, abidiff complains on the rc1 cryptodev changes: - Chacha20-Poly1305 AEAD support, - ECPM and ECDSA support A suppression rule has been put on the internal type rte_cryptodev_ops. But other changes are an ABI breakage afaiu. I put suppression rules on them so that we can run the checks, but some action must be taken for 20.02 if my analysis is confirmed. Special thanks to Dodji the libabigail maintainer for helping on this topic. 1: https://sourceware.org/bugzilla/show_bug.cgi?id=25409 2: http://inbox.dpdk.org/dev/CAJFAV8yFKoDZROX9Mkyp7pDMvXw3e7mHwxjfrcjD5ZoFB2tZ8w@mail.gmail.com/ -- David Marchand David Marchand (4): hash: fix meson headers packaging build: split build helper build: test meson installation add ABI checks .ci/linux-build.sh | 29 ++++++++- .travis.yml | 20 +++++- MAINTAINERS | 2 + devtools/check-abi.sh | 59 +++++++++++++++++ devtools/dpdk.abignore | 20 ++++++ devtools/gen-abi.sh | 26 ++++++++ devtools/test-build.sh | 45 ++++++++++++- devtools/test-meson-builds.sh | 98 ++++++++++++++++++++++------- devtools/test-null.sh | 1 + doc/guides/contributing/patches.rst | 13 ++++ lib/librte_hash/meson.build | 5 +- 11 files changed, 286 insertions(+), 32 deletions(-) create mode 100755 devtools/check-abi.sh create mode 100644 devtools/dpdk.abignore create mode 100755 devtools/gen-abi.sh -- 2.23.0
Those headers are internal and should not be distributed. Fixes: 5b9656b157d3 ("lib: build with meson") Cc: stable@dpdk.org Signed-off-by: David Marchand <david.marchand@redhat.com> --- lib/librte_hash/meson.build | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/librte_hash/meson.build b/lib/librte_hash/meson.build index 5d02b3084..bce11ad9e 100644 --- a/lib/librte_hash/meson.build +++ b/lib/librte_hash/meson.build @@ -1,10 +1,7 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2017 Intel Corporation -headers = files('rte_cmp_arm64.h', - 'rte_cmp_x86.h', - 'rte_crc_arm64.h', - 'rte_cuckoo_hash.h', +headers = files('rte_crc_arm64.h', 'rte_fbk_hash.h', 'rte_hash_crc.h', 'rte_hash.h', -- 2.23.0
No functional change intended, prepare for reusing this code. The config and compilation parts are separated in helpers. Unsetting CC is moved to the caller of the helper. Signed-off-by: David Marchand <david.marchand@redhat.com> --- devtools/test-meson-builds.sh | 46 ++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/devtools/test-meson-builds.sh b/devtools/test-meson-builds.sh index 688567714..aed175889 100755 --- a/devtools/test-meson-builds.sh +++ b/devtools/test-meson-builds.sh @@ -57,25 +57,27 @@ load_env () # <target compiler> . $srcdir/devtools/load-devel-config } -build () # <directory> <target compiler> <meson options> +config () # <dir> <builddir> <meson options> { - builddir=$builds_dir/$1 + dir=$1 shift - targetcc=$1 + builddir=$1 shift - # skip build if compiler not available - command -v ${CC##* } >/dev/null 2>&1 || return 0 - load_env $targetcc || return 0 + options="--werror -Dexamples=all" + for option in $DPDK_MESON_OPTIONS ; do + options="$options -D$option" + done + options="$options $*" if [ ! -f "$builddir/build.ninja" ] ; then - options="--werror -Dexamples=all" - for option in $DPDK_MESON_OPTIONS ; do - options="$options -D$option" - done - options="$options $*" - echo "$MESON $options $srcdir $builddir" - $MESON $options $srcdir $builddir - unset CC + echo "$MESON $options $dir $builddir" + $MESON $options $dir $builddir fi +} + +compile () # <builddir> +{ + builddir=$1 + shift if [ -n "$TEST_MESON_BUILD_VERY_VERBOSE" ] ; then # for full output from ninja use "-v" echo "$ninja_cmd -v -C $builddir" @@ -90,6 +92,19 @@ build () # <directory> <target compiler> <meson options> fi } +build () # <directory> <target compiler> <meson options> +{ + targetdir=$1 + shift + targetcc=$1 + shift + # skip build if compiler not available + command -v ${CC##* } >/dev/null 2>&1 || return 0 + load_env $targetcc || return 0 + config $srcdir $builds_dir/$targetdir $* + compile $builds_dir/$targetdir +} + if [ "$1" = "-vv" ] ; then TEST_MESON_BUILD_VERY_VERBOSE=1 elif [ "$1" = "-v" ] ; then @@ -107,6 +122,7 @@ for c in gcc clang ; do for s in static shared ; do export CC="$CCACHE $c" build build-$c-$s $c --default-library=$s + unset CC done done @@ -125,11 +141,13 @@ c=aarch64-linux-gnu-gcc export CC="clang" build build-arm64-host-clang $c $use_shared \ --cross-file $srcdir/config/arm/arm64_armv8_linux_gcc +unset CC # all gcc/arm configurations for f in $srcdir/config/arm/arm64_[bdo]*gcc ; do export CC="$CCACHE gcc" build build-$(basename $f | tr '_' '-' | cut -d'-' -f-2) $c \ $use_shared --cross-file $f + unset CC done # Test installation of the x86-default target, to be used for checking -- 2.23.0
Let's test installing with meson as part of Travis and the devtools/test-meson-builds.sh script. The resulting headers and binaries make more sense to run checks against, since they should be the same as what the final users get. In this patch, test-null.sh is now called on an installed testpmd. For this to work LD_LIBRARY_PATH must be set appropriately, but it can be hard to debug, so a call to ldd has been added. The (future) ABI compatibility checks will also need to filter its report against installed public headers. Signed-off-by: David Marchand <david.marchand@redhat.com> --- .ci/linux-build.sh | 6 +++++- devtools/test-meson-builds.sh | 27 ++++++++++++++++----------- devtools/test-null.sh | 1 + 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh index ccc3a7ccd..e61aa2b0a 100755 --- a/.ci/linux-build.sh +++ b/.ci/linux-build.sh @@ -29,11 +29,15 @@ if [ "$BUILD_32BIT" = "1" ]; then fi OPTS="$OPTS --default-library=$DEF_LIB" +OPTS="$OPTS --prefix=/usr -Dlibdir=lib" meson build --werror -Dexamples=all $OPTS ninja -C build +DESTDIR=$(pwd)/install ninja -C build install if [ "$AARCH64" != "1" ]; then - devtools/test-null.sh + export LD_LIBRARY_PATH=$(pwd)/install/usr/lib + devtools/test-null.sh install/usr/bin/dpdk-testpmd + unset LD_LIBRARY_PATH fi if [ "$RUN_TESTS" = "1" ]; then diff --git a/devtools/test-meson-builds.sh b/devtools/test-meson-builds.sh index aed175889..254588ae6 100755 --- a/devtools/test-meson-builds.sh +++ b/devtools/test-meson-builds.sh @@ -63,7 +63,7 @@ config () # <dir> <builddir> <meson options> shift builddir=$1 shift - options="--werror -Dexamples=all" + options="--werror -Dexamples=all --prefix=/usr -Dlibdir=lib" for option in $DPDK_MESON_OPTIONS ; do options="$options -D$option" done @@ -74,22 +74,29 @@ config () # <dir> <builddir> <meson options> fi } -compile () # <builddir> +compile () # <builddir> <installdir> { builddir=$1 shift + export DESTDIR=$1 + shift + rm -rf $DESTDIR if [ -n "$TEST_MESON_BUILD_VERY_VERBOSE" ] ; then # for full output from ninja use "-v" echo "$ninja_cmd -v -C $builddir" $ninja_cmd -v -C $builddir + $ninja_cmd -v -C $builddir install elif [ -n "$TEST_MESON_BUILD_VERBOSE" ] ; then # for keeping the history of short cmds, pipe through cat echo "$ninja_cmd -C $builddir | cat" $ninja_cmd -C $builddir | cat + $ninja_cmd -C $builddir install | cat else echo "$ninja_cmd -C $builddir" $ninja_cmd -C $builddir + $ninja_cmd -C $builddir install fi + unset DESTDIR } build () # <directory> <target compiler> <meson options> @@ -102,7 +109,8 @@ build () # <directory> <target compiler> <meson options> command -v ${CC##* } >/dev/null 2>&1 || return 0 load_env $targetcc || return 0 config $srcdir $builds_dir/$targetdir $* - compile $builds_dir/$targetdir + compile $builds_dir/$targetdir \ + $(readlink -f $builds_dir/$targetdir/install) } if [ "$1" = "-vv" ] ; then @@ -134,7 +142,7 @@ ok=$(cc -march=$default_machine -E - < /dev/null > /dev/null 2>&1 || echo false) if [ "$ok" = "false" ] ; then default_machine='corei7' fi -build build-x86-default cc -Dlibdir=lib -Dmachine=$default_machine $use_shared +build build-x86-default cc -Dmachine=$default_machine $use_shared c=aarch64-linux-gnu-gcc # generic armv8a with clang as host compiler @@ -150,12 +158,9 @@ for f in $srcdir/config/arm/arm64_[bdo]*gcc ; do unset CC done -# Test installation of the x86-default target, to be used for checking -# the sample apps build using the pkg-config file for cflags and libs -build_path=$(readlink -f $builds_dir/build-x86-default) -export DESTDIR=$build_path/install-root -$ninja_cmd -C $build_path install - +# Use the x86-default target, to check the sample apps build using the +# pkg-config file for cflags and libs +export DESTDIR=$(readlink -f $builds_dir/build-x86-default/install) load_env cc pc_file=$(find $DESTDIR -name libdpdk.pc) export PKG_CONFIG_PATH=$(dirname $pc_file):$PKG_CONFIG_PATH @@ -165,6 +170,6 @@ if pkg-config --define-prefix libdpdk >/dev/null 2>&1; then export PKGCONF="pkg-config --define-prefix" for example in cmdline helloworld l2fwd l3fwd skeleton timer; do echo "## Building $example" - $MAKE -C $DESTDIR/usr/local/share/dpdk/examples/$example clean all + $MAKE -C $DESTDIR/usr/share/dpdk/examples/$example clean all done fi diff --git a/devtools/test-null.sh b/devtools/test-null.sh index 548de8113..8121ec9e3 100755 --- a/devtools/test-null.sh +++ b/devtools/test-null.sh @@ -21,6 +21,7 @@ fi if ldd $testpmd | grep -q librte_ ; then export LD_LIBRARY_PATH=$build/drivers:$build/lib:$LD_LIBRARY_PATH + ldd $testpmd libs='-d librte_mempool_ring.so -d librte_pmd_null.so' else libs= -- 2.23.0
For normal developers, those checks are disabled. Enabling them requires a configuration that will trigger the ABI dumps generation as part of the existing devtools/test-build.sh and devtools/test-meson-builds.sh scripts. Those checks are enabled in the CI for the default meson options on x86 and aarch64 so that proposed patches are validated via our CI robot. A cache of the ABI is stored in travis jobs to avoid rebuilding too often. Checks can be only informational by setting ABI_CHECKS_WARN_ONLY when breaking the ABI in a future release. Explicit suppression rules have been added on internal structures exposed to crypto and security drivers as the current ABI policy does not apply to them. This could be improved in the future by carefully splitting the headers content with application and driver "users" in mind. We currently have issues reported for librte_crypto recent changes for which suppression rules have been added too. Mellanox glue libraries are explicitly skipped as they are not part of the application ABI. Signed-off-by: David Marchand <david.marchand@redhat.com> --- Changelog since v1: - reworked the scripts so that the build test scripts clone and build the reference automatically. A developer only needs to set one variable to enable the checks, - meson builds are done with debug so that abidiff can inspect the structures, - abidiff checks only public types by looking at installed headers, - abidiff has some issue when comparing a dump with a .so built with clang so all diff are now done with dump files only, - suppression rules have been added to waive warnings on exposed internal types, - an abi breakage has been reported on changes in cryptodev. For now, suppression rules have been put in place to let the CI run, --- .ci/linux-build.sh | 23 +++++++++++ .travis.yml | 20 +++++++++- MAINTAINERS | 2 + devtools/check-abi.sh | 59 +++++++++++++++++++++++++++++ devtools/dpdk.abignore | 20 ++++++++++ devtools/gen-abi.sh | 26 +++++++++++++ devtools/test-build.sh | 45 ++++++++++++++++++++-- devtools/test-meson-builds.sh | 35 ++++++++++++++++- doc/guides/contributing/patches.rst | 13 +++++++ 9 files changed, 236 insertions(+), 7 deletions(-) create mode 100755 devtools/check-abi.sh create mode 100644 devtools/dpdk.abignore create mode 100755 devtools/gen-abi.sh diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh index e61aa2b0a..95bd869c3 100755 --- a/.ci/linux-build.sh +++ b/.ci/linux-build.sh @@ -30,6 +30,7 @@ fi OPTS="$OPTS --default-library=$DEF_LIB" OPTS="$OPTS --prefix=/usr -Dlibdir=lib" +OPTS="$OPTS --buildtype=debugoptimized" meson build --werror -Dexamples=all $OPTS ninja -C build DESTDIR=$(pwd)/install ninja -C build install @@ -40,6 +41,28 @@ if [ "$AARCH64" != "1" ]; then unset LD_LIBRARY_PATH fi +if [ "$ABI_CHECKS" = "1" ]; then + REF_GIT_REPO=${REF_GIT_REPO:-https://dpdk.org/git/dpdk} + REF_GIT_TAG=${REF_GIT_TAG:-v19.11} + + if [ "$(cat reference/VERSION 2>/dev/null)" != "$REF_GIT_TAG" ]; then + rm -rf reference + fi + + if [ ! -d reference ]; then + refsrcdir=$(readlink -f $(pwd)/../dpdk-$REF_GIT_TAG) + git clone --single-branch -b $REF_GIT_TAG $REF_GIT_REPO $refsrcdir + meson --werror $OPTS $refsrcdir $refsrcdir/build + ninja -C $refsrcdir/build + DESTDIR=$(pwd)/reference ninja -C $refsrcdir/build install + devtools/gen-abi.sh reference + echo $REF_GIT_TAG > reference/VERSION + fi + + devtools/gen-abi.sh install + devtools/check-abi.sh reference install ${ABI_CHECKS_WARN_ONLY:-} +fi + if [ "$RUN_TESTS" = "1" ]; then sudo meson test -C build --suite fast-tests -t 3 fi diff --git a/.travis.yml b/.travis.yml index 8162f1c05..22539d823 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,8 @@ language: c -cache: ccache +cache: + ccache: true + directories: + - reference compiler: - gcc - clang @@ -21,7 +24,7 @@ aarch64_packages: &aarch64_packages extra_packages: &extra_packages - *required_packages - - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4] + - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4, abigail-tools] build_32b_packages: &build_32b_packages - *required_packages @@ -151,5 +154,18 @@ matrix: packages: - *required_packages - *doc_packages + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1 + compiler: gcc + addons: + apt: + packages: + - *extra_packages + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1 + arch: arm64 + compiler: gcc + addons: + apt: + packages: + - *extra_packages script: ./.ci/${TRAVIS_OS_NAME}-build.sh diff --git a/MAINTAINERS b/MAINTAINERS index 94bccae6d..6dae4ee63 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -144,8 +144,10 @@ M: Neil Horman <nhorman@tuxdriver.com> F: lib/librte_eal/common/include/rte_compat.h F: lib/librte_eal/common/include/rte_function_versioning.h F: doc/guides/rel_notes/deprecation.rst +F: devtools/check-abi.sh F: devtools/check-abi-version.sh F: devtools/check-symbol-change.sh +F: devtools/gen-abi.sh F: devtools/update-abi.sh F: devtools/update_version_map_abi.py F: devtools/validate-abi.sh diff --git a/devtools/check-abi.sh b/devtools/check-abi.sh new file mode 100755 index 000000000..5872499ec --- /dev/null +++ b/devtools/check-abi.sh @@ -0,0 +1,59 @@ +#!/bin/sh -e +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2019 Red Hat, Inc. + +if [ $# != 2 ] && [ $# != 3 ]; then + echo "Usage: $0 refdir newdir [warnonly]" + exit 1 +fi + +refdir=$1 +newdir=$2 +warnonly=${3:-} +ABIDIFF_OPTIONS="--suppr $(dirname $0)/dpdk.abignore --no-added-syms" + +if [ ! -d $refdir ]; then + echo "Error: reference directory '$refdir' does not exist." + exit 1 +fi +incdir=$(find $refdir -type d -a -name include) +if [ -z "$incdir" ] || [ ! -e "$incdir" ]; then + echo "WARNING: could not identify a include directory for $refdir, expect false positives..." +else + ABIDIFF_OPTIONS="$ABIDIFF_OPTIONS --headers-dir1 $incdir" +fi + +if [ ! -d $newdir ]; then + echo "Error: directory to check '$newdir' does not exist." + exit 1 +fi +incdir2=$(find $newdir -type d -a -name include) +if [ -z "$incdir2" ] || [ ! -e "$incdir2" ]; then + echo "WARNING: could not identify a include directory for $newdir, expect false positives..." +else + ABIDIFF_OPTIONS="$ABIDIFF_OPTIONS --headers-dir2 $incdir2" +fi + +error= +for dump in $(find $refdir -name "*.dump"); do + name=$(basename $dump) + # skip glue drivers, example librte_pmd_mlx5_glue.dump + # We can't rely on a suppression rule for now: + # https://sourceware.org/bugzilla/show_bug.cgi?id=25480 + if [ "$name" != "${name%%_glue.dump}" ]; then + echo "Skipping ${dump}..." + continue + fi + dump2=$(find $newdir -name $name) + if [ -z "$dump2" ] || [ ! -e "$dump2" ]; then + echo "Error: can't find $name in $newdir" + error=1 + continue + fi + if ! abidiff $ABIDIFF_OPTIONS $dump $dump2; then + echo "Error: ABI issue reported for 'abidiff $ABIDIFF_OPTIONS $dump $dump2'" + error=1 + fi +done + +[ -z "$error" ] || [ -n "$warnonly" ] diff --git a/devtools/dpdk.abignore b/devtools/dpdk.abignore new file mode 100644 index 000000000..0c01eebea --- /dev/null +++ b/devtools/dpdk.abignore @@ -0,0 +1,20 @@ +[suppress_function] + symbol_version = EXPERIMENTAL +[suppress_variable] + symbol_version = EXPERIMENTAL + +; Explicit ignore for driver-only ABI +[suppress_type] + name = rte_cryptodev_ops + +; FIXME +[suppress_type] + type_kind = enum + name = rte_crypto_aead_algorithm + changed_enumerators = RTE_CRYPTO_AEAD_LIST_END +[suppress_type] + type_kind = enum + name = rte_crypto_asym_xform_type + changed_enumerators = RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END +[suppress_variable] + name = rte_crypto_aead_algorithm_strings diff --git a/devtools/gen-abi.sh b/devtools/gen-abi.sh new file mode 100755 index 000000000..c44b0e228 --- /dev/null +++ b/devtools/gen-abi.sh @@ -0,0 +1,26 @@ +#!/bin/sh -e +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2019 Red Hat, Inc. + +if [ $# != 1 ]; then + echo "Usage: $0 installdir" + exit 1 +fi + +installdir=$1 +if [ ! -d $installdir ]; then + echo "Error: install directory '$installdir' does not exist." + exit 1 +fi + +dumpdir=$installdir/dump +rm -rf $dumpdir +mkdir -p $dumpdir +for f in $(find $installdir -name "*.so.*"); do + if test -L $f; then + continue + fi + + libname=$(basename $f) + abidw --out-file $dumpdir/${libname%.so*}.dump $f +done diff --git a/devtools/test-build.sh b/devtools/test-build.sh index 52305fbb8..fba30bac9 100755 --- a/devtools/test-build.sh +++ b/devtools/test-build.sh @@ -30,7 +30,8 @@ default_path=$PATH # - LIBSSO_SNOW3G_PATH # - LIBSSO_KASUMI_PATH # - LIBSSO_ZUC_PATH -. $(dirname $(readlink -f $0))/load-devel-config +devtools_dir=$(dirname $(readlink -f $0)) +. $devtools_dir/load-devel-config print_usage () { echo "usage: $(basename $0) [-h] [-jX] [-s] [config1 [config2] ...]]" @@ -64,6 +65,7 @@ print_help () { [ -z $MAKE ] && echo "Cannot find make or gmake" && exit 1 J=$DPDK_MAKE_JOBS +refsrcdir=$(mktemp -d -t dpdk-${DPDK_ABI_REF_VERSION:-}.XXX) builds_dir=${DPDK_BUILD_TEST_DIR:-.} short=false unset verbose @@ -91,13 +93,14 @@ on_exit () [ "$DPDK_NOTIFY" != notify-send ] || \ notify-send -u low --icon=dialog-error 'DPDK build' 'failed' fi + rm -rf $refsrcdir } # catch manual interrupt to ignore notification trap "signal=INT ; trap - INT ; kill -INT $$" INT # notify result on exit trap on_exit EXIT -cd $(dirname $(readlink -f $0))/.. +cd $devtools_dir/.. reset_env () { @@ -233,7 +236,7 @@ for conf in $configs ; do # reload config with DPDK_TARGET set DPDK_TARGET=$target reset_env - . $(dirname $(readlink -f $0))/load-devel-config + . $devtools_dir/load-devel-config options=$(echo $conf | sed 's,[^~+]*,,') dir=$builds_dir/$conf @@ -253,6 +256,42 @@ for conf in $configs ; do EXTRA_LDFLAGS="$DPDK_DEP_LDFLAGS" $verbose \ O=$(readlink -f $dir)/examples unset RTE_TARGET + if [ -n "$DPDK_ABI_REF_VERSION" ]; then + DPDK_ABI_REF_DIR=${DPDK_ABI_REF_DIR:-reference} + abirefdir=$DPDK_ABI_REF_DIR/$DPDK_ABI_REF_VERSION/$conf + if [ ! -d $abirefdir ]; then + # clone current sources + if [ ! -d $refsrcdir/.git ]; then + git clone --local --no-hardlinks \ + --single-branch \ + -b $DPDK_ABI_REF_VERSION \ + $(pwd) $refsrcdir + fi + + cd $refsrcdir + + rm -rf build + config build $target $options + + echo -n "================== Build $conf " + echo "($DPDK_ABI_REF_VERSION)" + ${MAKE} -j$J EXTRA_CFLAGS="$maxerr $DPDK_DEP_CFLAGS" \ + EXTRA_LDFLAGS="$DPDK_DEP_LDFLAGS" $verbose \ + O=build + ! $short || break + export RTE_TARGET=$target + ${MAKE} install O=build DESTDIR=$abirefdir \ + prefix= + $devtools_dir/gen-abi.sh $abirefdir + + # back to current workdir + cd $devtools_dir/.. + fi + + echo "================== Check ABI $conf" + $devtools_dir/gen-abi.sh $dir/install + $devtools_dir/check-abi.sh $abirefdir $dir/install + fi echo "################## $conf done." unset dir done diff --git a/devtools/test-meson-builds.sh b/devtools/test-meson-builds.sh index 254588ae6..1b410c784 100755 --- a/devtools/test-meson-builds.sh +++ b/devtools/test-meson-builds.sh @@ -16,8 +16,15 @@ srcdir=$(dirname $(readlink -f $0))/.. MESON=${MESON:-meson} use_shared="--default-library=shared" +refsrcdir=$(mktemp -d -t dpdk-${DPDK_ABI_REF_VERSION:-}.XXX) builds_dir=${DPDK_BUILD_TEST_DIR:-.} +on_exit () +{ + rm -rf $refsrcdir +} +trap on_exit EXIT + if command -v gmake >/dev/null 2>&1 ; then MAKE=gmake else @@ -63,7 +70,9 @@ config () # <dir> <builddir> <meson options> shift builddir=$1 shift - options="--werror -Dexamples=all --prefix=/usr -Dlibdir=lib" + options= + options="$options --werror --buildtype=debugoptimized -Dexamples=all" + options="$options --prefix=/usr -Dlibdir=lib" for option in $DPDK_MESON_OPTIONS ; do options="$options -D$option" done @@ -96,7 +105,6 @@ compile () # <builddir> <installdir> $ninja_cmd -C $builddir $ninja_cmd -C $builddir install fi - unset DESTDIR } build () # <directory> <target compiler> <meson options> @@ -111,6 +119,29 @@ build () # <directory> <target compiler> <meson options> config $srcdir $builds_dir/$targetdir $* compile $builds_dir/$targetdir \ $(readlink -f $builds_dir/$targetdir/install) + if [ -n "$DPDK_ABI_REF_VERSION" ]; then + DPDK_ABI_REF_DIR=${DPDK_ABI_REF_DIR:-reference} + abirefdir=$DPDK_ABI_REF_DIR/$DPDK_ABI_REF_VERSION/$targetdir + if [ ! -d $abirefdir ]; then + # clone current sources + if [ ! -d $refsrcdir/.git ]; then + git clone --local --no-hardlinks \ + --single-branch \ + -b $DPDK_ABI_REF_VERSION \ + $srcdir $refsrcdir + fi + + rm -rf $refsrcdir/build + config $refsrcdir $refsrcdir/build $* + compile $refsrcdir/build $abirefdir + $srcdir/devtools/gen-abi.sh $abirefdir + fi + + $srcdir/devtools/gen-abi.sh \ + $(readlink -f $builds_dir/$targetdir/install) + $srcdir/devtools/check-abi.sh $abirefdir \ + $(readlink -f $builds_dir/$targetdir/install) + fi } if [ "$1" = "-vv" ] ; then diff --git a/doc/guides/contributing/patches.rst b/doc/guides/contributing/patches.rst index 0686450e4..2e16741ca 100644 --- a/doc/guides/contributing/patches.rst +++ b/doc/guides/contributing/patches.rst @@ -513,6 +513,19 @@ in a single subfolder called "__builds" created in the current directory. Setting ``DPDK_BUILD_TEST_DIR`` to an absolute directory path e.g. ``/tmp`` is also supported. +Checking ABI compatibility +-------------------------- + +By default, ABI compatibility checks are disabled. + +To enable them, a reference version must be selected via the environment +variable ``DPDK_ABI_REF_VERSION``. + +The ``devtools/test-build.sh`` and ``devtools/test-meson-builds.sh`` scripts +then build this reference version in a temporary directory and store the +results in the ``DPDK_ABI_REF_DIR`` directory. + + Sending Patches --------------- -- 2.23.0
Anoob, Akhil, Please we need to revert or fix the ABI breakages in cryptodev very soon. The FIXME section below must be empty. Thanks 29/01/2020 18:26, David Marchand: > We currently have issues reported for librte_crypto recent changes for > which suppression rules have been added too. [..] > --- /dev/null > +++ b/devtools/dpdk.abignore > +; FIXME > +[suppress_type] > + type_kind = enum > + name = rte_crypto_aead_algorithm > + changed_enumerators = RTE_CRYPTO_AEAD_LIST_END > +[suppress_type] > + type_kind = enum > + name = rte_crypto_asym_xform_type > + changed_enumerators = RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END > +[suppress_variable] > + name = rte_crypto_aead_algorithm_strings
Hi Thomas,
The asymmetric crypto library is experimental. Changes to experimental code paths is allowed, right?
Also, I was wondering why changing the LIST_END would cause breakage. Before we introduced the ABI checks and ABI freeze policy, it was always allowed to add enums to the end. I'm just trying to understand the real impact of this case.
If we don't allow the LIST_END to be modified, then it means no feature can be implemented in between. And the best way to overcome that would be to just remove the LIST_END or set LIST_END to a very high value.
Thanks,
Anoob
> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Thomas Monjalon
> Sent: Wednesday, January 29, 2020 11:13 PM
> To: akhil.goyal@nxp.com; Anoob Joseph <anoobj@marvell.com>
> Cc: dev@dpdk.org; David Marchand <david.marchand@redhat.com>;
> bruce.richardson@intel.com; nhorman@tuxdriver.com; John McNamara
> <john.mcnamara@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v2 4/4] add ABI checks
>
> Anoob, Akhil,
>
> Please we need to revert or fix the ABI breakages in cryptodev very soon.
> The FIXME section below must be empty.
>
> Thanks
>
> 29/01/2020 18:26, David Marchand:
> > We currently have issues reported for librte_crypto recent changes for
> > which suppression rules have been added too.
> [..]
> > --- /dev/null
> > +++ b/devtools/dpdk.abignore
> > +; FIXME
> > +[suppress_type]
> > + type_kind = enum
> > + name = rte_crypto_aead_algorithm
> > + changed_enumerators = RTE_CRYPTO_AEAD_LIST_END
> > +[suppress_type]
> > + type_kind = enum
> > + name = rte_crypto_asym_xform_type
> > + changed_enumerators = RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
> > +[suppress_variable]
> > + name = rte_crypto_aead_algorithm_strings
>
>
>
On Wed, Jan 29, 2020 at 7:10 PM Anoob Joseph <anoobj@marvell.com> wrote:
> The asymmetric crypto library is experimental. Changes to experimental code paths is allowed, right?
The asymmetric crypto enum is referenced by a function part of the stable ABI.
It is possible to waive this enum, if we are sure no use out of the
experimental asym crypto APIs is possible.
The rest of the changes touch stable symbols.
Adding the abidiff report:
[C]'function void rte_cryptodev_info_get(uint8_t,
rte_cryptodev_info*)' at rte_cryptodev.c:1115:1 has some indirect
sub-type changes:
parameter 2 of type 'rte_cryptodev_info*' has sub-type changes:
in pointed to type 'struct rte_cryptodev_info' at rte_cryptodev.h:468:1:
type size hasn't changed
1 data member change:
type of 'const rte_cryptodev_capabilities*
rte_cryptodev_info::capabilities' changed:
in pointed to type 'const rte_cryptodev_capabilities':
in unqualified underlying type 'struct
rte_cryptodev_capabilities' at rte_cryptodev.h:176:1:
type size hasn't changed
1 data member change:
type of '__anonymous_union__ ' changed:
type size hasn't changed
1 data member change:
type of 'rte_cryptodev_asymmetric_capability
__anonymous_union__::asym' changed:
type size hasn't changed
1 data member change:
type of
'rte_cryptodev_asymmetric_xform_capability
rte_cryptodev_asymmetric_capability::xform_capa' changed:
type size hasn't changed
1 data member change:
type of 'rte_crypto_asym_xform_type
rte_cryptodev_asymmetric_xform_capability::xform_type' changed:
type size hasn't changed
2 enumerator insertions:
'rte_crypto_asym_xform_type::RTE_CRYPTO_ASYM_XFORM_ECDSA' value '7'
'rte_crypto_asym_xform_type::RTE_CRYPTO_ASYM_XFORM_ECPM' value '8'
1 enumerator change:
'rte_crypto_asym_xform_type::RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END' from
value '7' to '9' at rte_crypto_asym.h:60:1
[C]'function int
rte_cryptodev_get_aead_algo_enum(rte_crypto_aead_algorithm*, const
char*)' at rte_cryptodev.c:239:1 has some indirect sub-type changes:
parameter 1 of type 'rte_crypto_aead_algorithm*' has sub-type changes:
in pointed to type 'enum rte_crypto_aead_algorithm' at
rte_crypto_sym.h:346:1:
type size hasn't changed
1 enumerator insertion:
'rte_crypto_aead_algorithm::RTE_CRYPTO_AEAD_CHACHA20_POLY1305'
value '3'
1 enumerator change:
'rte_crypto_aead_algorithm::RTE_CRYPTO_AEAD_LIST_END' from
value '3' to '4' at rte_crypto_sym.h:346:1
[C]'const char* rte_crypto_aead_algorithm_strings[1]' was changed at
rte_crypto_sym.h:358:1:
size of symbol (in bytes) changed from 24 to 32
--
David Marchand
> > On Wed, Jan 29, 2020 at 7:10 PM Anoob Joseph <anoobj@marvell.com> wrote: > > The asymmetric crypto library is experimental. Changes to experimental code > paths is allowed, right? > > The asymmetric crypto enum is referenced by a function part of the stable ABI. > It is possible to waive this enum, if we are sure no use out of the > experimental asym crypto APIs is possible. > > The rest of the changes touch stable symbols. > > Adding the abidiff report: > > [C]'function void rte_cryptodev_info_get(uint8_t, > rte_cryptodev_info*)' at rte_cryptodev.c:1115:1 has some indirect > sub-type changes: > parameter 2 of type 'rte_cryptodev_info*' has sub-type changes: > in pointed to type 'struct rte_cryptodev_info' at rte_cryptodev.h:468:1: > type size hasn't changed > 1 data member change: > type of 'const rte_cryptodev_capabilities* > rte_cryptodev_info::capabilities' changed: > in pointed to type 'const rte_cryptodev_capabilities': > in unqualified underlying type 'struct > rte_cryptodev_capabilities' at rte_cryptodev.h:176:1: > type size hasn't changed > 1 data member change: > type of '__anonymous_union__ ' changed: > type size hasn't changed > 1 data member change: > type of 'rte_cryptodev_asymmetric_capability > __anonymous_union__::asym' changed: > type size hasn't changed > 1 data member change: > type of > 'rte_cryptodev_asymmetric_xform_capability > rte_cryptodev_asymmetric_capability::xform_capa' changed: > type size hasn't changed > 1 data member change: > type of 'rte_crypto_asym_xform_type > rte_cryptodev_asymmetric_xform_capability::xform_type' changed: > type size hasn't changed > 2 enumerator insertions: > > 'rte_crypto_asym_xform_type::RTE_CRYPTO_ASYM_XFORM_ECDSA' value '7' > > 'rte_crypto_asym_xform_type::RTE_CRYPTO_ASYM_XFORM_ECPM' value '8' > 1 enumerator change: > > 'rte_crypto_asym_xform_type::RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END' > from > value '7' to '9' at rte_crypto_asym.h:60:1 > I believe these enums will be used only in case of ASYM case which is experimental. > > [C]'function int > rte_cryptodev_get_aead_algo_enum(rte_crypto_aead_algorithm*, const > char*)' at rte_cryptodev.c:239:1 has some indirect sub-type changes: > parameter 1 of type 'rte_crypto_aead_algorithm*' has sub-type changes: > in pointed to type 'enum rte_crypto_aead_algorithm' at > rte_crypto_sym.h:346:1: > type size hasn't changed > 1 enumerator insertion: > 'rte_crypto_aead_algorithm::RTE_CRYPTO_AEAD_CHACHA20_POLY1305' > value '3' > 1 enumerator change: > 'rte_crypto_aead_algorithm::RTE_CRYPTO_AEAD_LIST_END' from > value '3' to '4' at rte_crypto_sym.h:346:1 > > > [C]'const char* rte_crypto_aead_algorithm_strings[1]' was changed at > rte_crypto_sym.h:358:1: > size of symbol (in bytes) changed from 24 to 32 > > +Fiona and Arek We may need to revert the chacha-poly patches. > -- > David Marchand
On Wed, 2020-01-29 at 18:26 +0100, David Marchand wrote:
> Those headers are internal and should not be distributed.
>
> Fixes: 5b9656b157d3 ("lib: build with meson")
> Cc:
> stable@dpdk.org
>
>
> Signed-off-by: David Marchand <
> david.marchand@redhat.com
> >
> ---
> lib/librte_hash/meson.build | 5 +----
> 1 file changed, 1 insertion(+), 4 deletions(-)
>
> diff --git a/lib/librte_hash/meson.build
> b/lib/librte_hash/meson.build
> index 5d02b3084..bce11ad9e 100644
> --- a/lib/librte_hash/meson.build
> +++ b/lib/librte_hash/meson.build
> @@ -1,10 +1,7 @@
> # SPDX-License-Identifier: BSD-3-Clause
> # Copyright(c) 2017 Intel Corporation
>
> -headers = files('rte_cmp_arm64.h',
> - 'rte_cmp_x86.h',
> - 'rte_crc_arm64.h',
> - 'rte_cuckoo_hash.h',
> +headers = files('rte_crc_arm64.h',
> 'rte_fbk_hash.h',
> 'rte_hash_crc.h',
> 'rte_hash.h',
Difficult question: how confident we are nobody is using those? :-)
--
Kind regards,
Luca Boccassi
On Thu, Jan 30, 2020 at 11:12 AM Luca Boccassi <bluca@debian.org> wrote:
>
> On Wed, 2020-01-29 at 18:26 +0100, David Marchand wrote:
> > Those headers are internal and should not be distributed.
> >
> > Fixes: 5b9656b157d3 ("lib: build with meson")
> > Cc:
> > stable@dpdk.org
> >
> >
> > Signed-off-by: David Marchand <
> > david.marchand@redhat.com
> > >
> > ---
> > lib/librte_hash/meson.build | 5 +----
> > 1 file changed, 1 insertion(+), 4 deletions(-)
> >
> > diff --git a/lib/librte_hash/meson.build
> > b/lib/librte_hash/meson.build
> > index 5d02b3084..bce11ad9e 100644
> > --- a/lib/librte_hash/meson.build
> > +++ b/lib/librte_hash/meson.build
> > @@ -1,10 +1,7 @@
> > # SPDX-License-Identifier: BSD-3-Clause
> > # Copyright(c) 2017 Intel Corporation
> >
> > -headers = files('rte_cmp_arm64.h',
> > - 'rte_cmp_x86.h',
> > - 'rte_crc_arm64.h',
> > - 'rte_cuckoo_hash.h',
> > +headers = files('rte_crc_arm64.h',
> > 'rte_fbk_hash.h',
> > 'rte_hash_crc.h',
> > 'rte_hash.h',
>
> Difficult question: how confident we are nobody is using those? :-)
Those headers are for internal structures.
When installing with make, those headers were skipped.
Grepping on the dpdk projects that I monitor (based on Stephen list):
$ for header in rte_cmp_arm64.h rte_cmp_x86.h rte_cuckoo_hash.h; do
echo "======= $header"; git grep-all -l $header; echo; done
======= rte_cmp_arm64.h
F-Stack origin/HEAD:dpdk/lib/librte_hash/meson.build
F-Stack origin/HEAD:dpdk/lib/librte_hash/rte_cuckoo_hash.h
Trex origin/HEAD:src/dpdk/lib/librte_hash/rte_cuckoo_hash.h
yastack origin/HEAD:dpdk/lib/librte_hash/meson.build
yastack origin/HEAD:dpdk/lib/librte_hash/rte_cuckoo_hash.h
======= rte_cmp_x86.h
F-Stack origin/HEAD:dpdk/lib/librte_hash/meson.build
F-Stack origin/HEAD:dpdk/lib/librte_hash/rte_cuckoo_hash.h
Trex origin/HEAD:src/dpdk/lib/librte_hash/rte_cuckoo_hash.h
yastack origin/HEAD:dpdk/lib/librte_hash/meson.build
yastack origin/HEAD:dpdk/lib/librte_hash/rte_cuckoo_hash.h
======= rte_cuckoo_hash.h
F-Stack origin/HEAD:dpdk/lib/librte_hash/meson.build
F-Stack origin/HEAD:dpdk/lib/librte_hash/rte_cuckoo_hash.c
F-Stack origin/HEAD:dpdk/lib/librte_hash/rte_cuckoo_hash.h
Trex origin/HEAD:src/dpdk/lib/librte_hash/rte_cuckoo_hash.c
Trex origin/HEAD:src/dpdk/lib/librte_hash/rte_cuckoo_hash.h
yastack origin/HEAD:dpdk/lib/librte_hash/meson.build
yastack origin/HEAD:dpdk/lib/librte_hash/rte_cuckoo_hash.c
yastack origin/HEAD:dpdk/lib/librte_hash/rte_cuckoo_hash.h
--
David Marchand
On Thu, 2020-01-30 at 11:54 +0100, David Marchand wrote:
> On Thu, Jan 30, 2020 at 11:12 AM Luca Boccassi <
> bluca@debian.org
> > wrote:
> > On Wed, 2020-01-29 at 18:26 +0100, David Marchand wrote:
> > > Those headers are internal and should not be distributed.
> > >
> > > Fixes: 5b9656b157d3 ("lib: build with meson")
> > > Cc:
> > > stable@dpdk.org
> > >
> > >
> > >
> > > Signed-off-by: David Marchand <
> > > david.marchand@redhat.com
> > >
> > >
> > > ---
> > > lib/librte_hash/meson.build | 5 +----
> > > 1 file changed, 1 insertion(+), 4 deletions(-)
> > >
> > > diff --git a/lib/librte_hash/meson.build
> > > b/lib/librte_hash/meson.build
> > > index 5d02b3084..bce11ad9e 100644
> > > --- a/lib/librte_hash/meson.build
> > > +++ b/lib/librte_hash/meson.build
> > > @@ -1,10 +1,7 @@
> > > # SPDX-License-Identifier: BSD-3-Clause
> > > # Copyright(c) 2017 Intel Corporation
> > >
> > > -headers = files('rte_cmp_arm64.h',
> > > - 'rte_cmp_x86.h',
> > > - 'rte_crc_arm64.h',
> > > - 'rte_cuckoo_hash.h',
> > > +headers = files('rte_crc_arm64.h',
> > > 'rte_fbk_hash.h',
> > > 'rte_hash_crc.h',
> > > 'rte_hash.h',
> >
> > Difficult question: how confident we are nobody is using those? :-)
>
> Those headers are for internal structures.
> When installing with make, those headers were skipped.
>
> Grepping on the dpdk projects that I monitor (based on Stephen list):
>
> $ for header in rte_cmp_arm64.h rte_cmp_x86.h rte_cuckoo_hash.h; do
> echo "======= $header"; git grep-all -l $header; echo; done
> ======= rte_cmp_arm64.h
> F-Stack origin/HEAD:dpdk/lib/librte_hash/meson.build
> F-Stack origin/HEAD:dpdk/lib/librte_hash/rte_cuckoo_hash.h
> Trex origin/HEAD:src/dpdk/lib/librte_hash/rte_cuckoo_hash.h
> yastack origin/HEAD:dpdk/lib/librte_hash/meson.build
> yastack origin/HEAD:dpdk/lib/librte_hash/rte_cuckoo_hash.h
>
> ======= rte_cmp_x86.h
> F-Stack origin/HEAD:dpdk/lib/librte_hash/meson.build
> F-Stack origin/HEAD:dpdk/lib/librte_hash/rte_cuckoo_hash.h
> Trex origin/HEAD:src/dpdk/lib/librte_hash/rte_cuckoo_hash.h
> yastack origin/HEAD:dpdk/lib/librte_hash/meson.build
> yastack origin/HEAD:dpdk/lib/librte_hash/rte_cuckoo_hash.h
>
> ======= rte_cuckoo_hash.h
> F-Stack origin/HEAD:dpdk/lib/librte_hash/meson.build
> F-Stack origin/HEAD:dpdk/lib/librte_hash/rte_cuckoo_hash.c
> F-Stack origin/HEAD:dpdk/lib/librte_hash/rte_cuckoo_hash.h
> Trex origin/HEAD:src/dpdk/lib/librte_hash/rte_cuckoo_hash.c
> Trex origin/HEAD:src/dpdk/lib/librte_hash/rte_cuckoo_hash.h
> yastack origin/HEAD:dpdk/lib/librte_hash/meson.build
> yastack origin/HEAD:dpdk/lib/librte_hash/rte_cuckoo_hash.c
> yastack origin/HEAD:dpdk/lib/librte_hash/rte_cuckoo_hash.h
Great, thanks for checking!
--
Kind regards,
Luca Boccassi
On Wed, 2020-01-29 at 18:26 +0100, David Marchand wrote:
> Here is the current state of the ABI checks.
>
> libabigail has some issues when mixing dump and so files compiled
> with
> clang [1], so for now, all checks are done on dumps only.
> libabigail 1.0-rc3 in Xenial reported issues that disappear with the
> version 1.2 in Bionic.
>
> To avoid getting warnings on internal types like [2], the checks now
> make
> use of the public headers part of a dpdk installation (patch 2 and 3
> to
> prepare for this).
>
> Some internal rte_hash headers were installed by meson, so patch 1
> fixes
> this.
>
> The most important point, abidiff complains on the rc1 cryptodev
> changes:
> - Chacha20-Poly1305 AEAD support,
> - ECPM and ECDSA support
>
> A suppression rule has been put on the internal type
> rte_cryptodev_ops.
> But other changes are an ABI breakage afaiu. I put suppression rules
> on
> them so that we can run the checks, but some action must be taken for
> 20.02 if my analysis is confirmed.
>
> Special thanks to Dodji the libabigail maintainer for helping on this
> topic.
>
> 1:
> https://sourceware.org/bugzilla/show_bug.cgi?id=25409
>
> 2:
> http://inbox.dpdk.org/dev/CAJFAV8yFKoDZROX9Mkyp7pDMvXw3e7mHwxjfrcjD5ZoFB2tZ8w@mail.gmail.com/
>
>
> --
> David Marchand
>
> David Marchand (4):
> hash: fix meson headers packaging
> build: split build helper
> build: test meson installation
> add ABI checks
>
> .ci/linux-build.sh | 29 ++++++++-
> .travis.yml | 20 +++++-
> MAINTAINERS | 2 +
> devtools/check-abi.sh | 59 +++++++++++++++++
> devtools/dpdk.abignore | 20 ++++++
> devtools/gen-abi.sh | 26 ++++++++
> devtools/test-build.sh | 45 ++++++++++++-
> devtools/test-meson-builds.sh | 98 ++++++++++++++++++++++-----
> --
> devtools/test-null.sh | 1 +
> doc/guides/contributing/patches.rst | 13 ++++
> lib/librte_hash/meson.build | 5 +-
> 11 files changed, 286 insertions(+), 32 deletions(-)
> create mode 100755 devtools/check-abi.sh
> create mode 100644 devtools/dpdk.abignore
> create mode 100755 devtools/gen-abi.sh
>
Series-acked-by: Luca Boccassi <bluca@debian.org>
--
Kind regards,
Luca Boccassi
We were unaware the LIST_END change could constitute an ABI breakage, but can see how it affects the array size when picked up.
We're exploring options.
I agree with Anoob's point that if we don't allow the LIST_END to be modified, then it means no feature can be implemented without ABI breakage.
Anyone object to removing those LIST_END elements - or have a better suggestion? Would have to be in 20.11 I suppose.
> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Anoob Joseph
> Sent: Wednesday, January 29, 2020 6:10 PM
> To: Thomas Monjalon <thomas@monjalon.net>; akhil.goyal@nxp.com
> Cc: dev@dpdk.org; David Marchand <david.marchand@redhat.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; nhorman@tuxdriver.com; Mcnamara, John
> <john.mcnamara@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v2 4/4] add ABI checks
>
> Hi Thomas,
>
> The asymmetric crypto library is experimental. Changes to experimental code paths is allowed, right?
>
> Also, I was wondering why changing the LIST_END would cause breakage. Before we introduced the ABI
> checks and ABI freeze policy, it was always allowed to add enums to the end. I'm just trying to
> understand the real impact of this case.
>
> If we don't allow the LIST_END to be modified, then it means no feature can be implemented in
> between. And the best way to overcome that would be to just remove the LIST_END or set LIST_END to
> a very high value.
>
> Thanks,
> Anoob
>
> > -----Original Message-----
> > From: dev <dev-bounces@dpdk.org> On Behalf Of Thomas Monjalon
> > Sent: Wednesday, January 29, 2020 11:13 PM
> > To: akhil.goyal@nxp.com; Anoob Joseph <anoobj@marvell.com>
> > Cc: dev@dpdk.org; David Marchand <david.marchand@redhat.com>;
> > bruce.richardson@intel.com; nhorman@tuxdriver.com; John McNamara
> > <john.mcnamara@intel.com>
> > Subject: Re: [dpdk-dev] [PATCH v2 4/4] add ABI checks
> >
> > Anoob, Akhil,
> >
> > Please we need to revert or fix the ABI breakages in cryptodev very soon.
> > The FIXME section below must be empty.
> >
> > Thanks
> >
> > 29/01/2020 18:26, David Marchand:
> > > We currently have issues reported for librte_crypto recent changes for
> > > which suppression rules have been added too.
> > [..]
> > > --- /dev/null
> > > +++ b/devtools/dpdk.abignore
> > > +; FIXME
> > > +[suppress_type]
> > > + type_kind = enum
> > > + name = rte_crypto_aead_algorithm
> > > + changed_enumerators = RTE_CRYPTO_AEAD_LIST_END
> > > +[suppress_type]
> > > + type_kind = enum
> > > + name = rte_crypto_asym_xform_type
> > > + changed_enumerators = RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END
> > > +[suppress_variable]
> > > + name = rte_crypto_aead_algorithm_strings
> >
> >
> >
30/01/2020 14:06, Trahe, Fiona:
> We were unaware the LIST_END change could constitute an ABI breakage, but can see how it affects the array size when picked up.
> We're exploring options.
>
> I agree with Anoob's point that if we don't allow the LIST_END to be modified, then it means no feature can be implemented without ABI breakage.
> Anyone object to removing those LIST_END elements - or have a better suggestion? Would have to be in 20.11 I suppose.
Yes, having max value right after the last value is ridiculous,
it prevents adding any value.
In 20.11, we should remove all these *_END and *_MAX from API enums
and replace them with a separate #define with reasonnable maximums.
Here is the current state of the ABI checks. libabigail has some issues when mixing dump and so files compiled with clang [1], so for now, all checks are done on dumps only. libabigail 1.0-rc3 in Xenial reported issues that disappear with the version 1.2 in Bionic. To avoid getting warnings on internal types like [2], the checks now make use of the public headers part of a dpdk installation (patch 2 and 3 to prepare for this). Some internal rte_hash headers were installed by meson, so patch 1 fixes this. The most important point, abidiff complains on the rc1 cryptodev changes: - Chacha20-Poly1305 AEAD support, - ECPM and ECDSA support A suppression rule has been put on the internal type rte_cryptodev_ops. But other changes are an ABI breakage afaiu. I put suppression rules on them so that we can run the checks, but some action must be taken for 20.02 if my analysis is confirmed. Special thanks to Dodji the libabigail maintainer for helping on this topic. 1: https://sourceware.org/bugzilla/show_bug.cgi?id=25409 2: http://inbox.dpdk.org/dev/CAJFAV8yFKoDZROX9Mkyp7pDMvXw3e7mHwxjfrcjD5ZoFB2tZ8w@mail.gmail.com/ -- David Marchand Changelog since v2: - incorporated offlist Thomas comments wrt to existing build envs (do not change --prefix, force builds with debug enabled) David Marchand (4): hash: fix meson headers packaging build: split build helper build: test meson installation add ABI checks .ci/linux-build.sh | 29 ++++++++- .travis.yml | 20 +++++- MAINTAINERS | 2 + devtools/check-abi.sh | 59 +++++++++++++++++ devtools/dpdk.abignore | 21 +++++++ devtools/gen-abi.sh | 26 ++++++++ devtools/test-build.sh | 51 +++++++++++++-- devtools/test-meson-builds.sh | 98 ++++++++++++++++++++++------- doc/guides/contributing/patches.rst | 15 +++++ lib/librte_hash/meson.build | 5 +- 10 files changed, 292 insertions(+), 34 deletions(-) create mode 100755 devtools/check-abi.sh create mode 100644 devtools/dpdk.abignore create mode 100755 devtools/gen-abi.sh -- 2.23.0
Those headers are internal and should not be distributed. Fixes: 5b9656b157d3 ("lib: build with meson") Cc: stable@dpdk.org Signed-off-by: David Marchand <david.marchand@redhat.com> Acked-by: Luca Boccassi <bluca@debian.org> --- lib/librte_hash/meson.build | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/librte_hash/meson.build b/lib/librte_hash/meson.build index 5d02b3084..bce11ad9e 100644 --- a/lib/librte_hash/meson.build +++ b/lib/librte_hash/meson.build @@ -1,10 +1,7 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2017 Intel Corporation -headers = files('rte_cmp_arm64.h', - 'rte_cmp_x86.h', - 'rte_crc_arm64.h', - 'rte_cuckoo_hash.h', +headers = files('rte_crc_arm64.h', 'rte_fbk_hash.h', 'rte_hash_crc.h', 'rte_hash.h', -- 2.23.0
No functional change intended, prepare for reusing this code. The config and compilation parts are separated in helpers. Unsetting CC is moved to the caller of the helper. Signed-off-by: David Marchand <david.marchand@redhat.com> Acked-by: Luca Boccassi <bluca@debian.org> --- Changelog since v2: - changed indent in config(), - removed useless shift in compile(), --- devtools/test-meson-builds.sh | 48 ++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/devtools/test-meson-builds.sh b/devtools/test-meson-builds.sh index 688567714..fb6c404e5 100755 --- a/devtools/test-meson-builds.sh +++ b/devtools/test-meson-builds.sh @@ -57,25 +57,27 @@ load_env () # <target compiler> . $srcdir/devtools/load-devel-config } -build () # <directory> <target compiler> <meson options> +config () # <dir> <builddir> <meson options> { - builddir=$builds_dir/$1 + dir=$1 shift - targetcc=$1 + builddir=$1 shift - # skip build if compiler not available - command -v ${CC##* } >/dev/null 2>&1 || return 0 - load_env $targetcc || return 0 - if [ ! -f "$builddir/build.ninja" ] ; then - options="--werror -Dexamples=all" - for option in $DPDK_MESON_OPTIONS ; do - options="$options -D$option" - done - options="$options $*" - echo "$MESON $options $srcdir $builddir" - $MESON $options $srcdir $builddir - unset CC + if [ -f "$builddir/build.ninja" ] ; then + return fi + options="--werror -Dexamples=all" + for option in $DPDK_MESON_OPTIONS ; do + options="$options -D$option" + done + options="$options $*" + echo "$MESON $options $dir $builddir" + $MESON $options $dir $builddir +} + +compile () # <builddir> +{ + builddir=$1 if [ -n "$TEST_MESON_BUILD_VERY_VERBOSE" ] ; then # for full output from ninja use "-v" echo "$ninja_cmd -v -C $builddir" @@ -90,6 +92,19 @@ build () # <directory> <target compiler> <meson options> fi } +build () # <directory> <target compiler> <meson options> +{ + targetdir=$1 + shift + targetcc=$1 + shift + # skip build if compiler not available + command -v ${CC##* } >/dev/null 2>&1 || return 0 + load_env $targetcc || return 0 + config $srcdir $builds_dir/$targetdir $* + compile $builds_dir/$targetdir +} + if [ "$1" = "-vv" ] ; then TEST_MESON_BUILD_VERY_VERBOSE=1 elif [ "$1" = "-v" ] ; then @@ -107,6 +122,7 @@ for c in gcc clang ; do for s in static shared ; do export CC="$CCACHE $c" build build-$c-$s $c --default-library=$s + unset CC done done @@ -125,11 +141,13 @@ c=aarch64-linux-gnu-gcc export CC="clang" build build-arm64-host-clang $c $use_shared \ --cross-file $srcdir/config/arm/arm64_armv8_linux_gcc +unset CC # all gcc/arm configurations for f in $srcdir/config/arm/arm64_[bdo]*gcc ; do export CC="$CCACHE gcc" build build-$(basename $f | tr '_' '-' | cut -d'-' -f-2) $c \ $use_shared --cross-file $f + unset CC done # Test installation of the x86-default target, to be used for checking -- 2.23.0
Let's test installing with meson as part of Travis and the devtools/test-meson-builds.sh script. The resulting headers and binaries make more sense to run checks against, since they should be the same as what the final users get. test-null.sh is now called on an installed testpmd. The (future) ABI compatibility checks will also need to filter its report against installed public headers. Signed-off-by: David Marchand <david.marchand@redhat.com> Acked-by: Luca Boccassi <bluca@debian.org> --- Changelog since v2: - removed forced --prefix= parameter in test-meson-builds.sh to avoid breakage of existing environments, - simplified install with no special verbose mode, - removed ldd call in test-null.sh since the main user of this script finds this change too much for his eyes, --- .ci/linux-build.sh | 6 +++++- devtools/test-meson-builds.sh | 21 +++++++++++---------- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh index ccc3a7ccd..e61aa2b0a 100755 --- a/.ci/linux-build.sh +++ b/.ci/linux-build.sh @@ -29,11 +29,15 @@ if [ "$BUILD_32BIT" = "1" ]; then fi OPTS="$OPTS --default-library=$DEF_LIB" +OPTS="$OPTS --prefix=/usr -Dlibdir=lib" meson build --werror -Dexamples=all $OPTS ninja -C build +DESTDIR=$(pwd)/install ninja -C build install if [ "$AARCH64" != "1" ]; then - devtools/test-null.sh + export LD_LIBRARY_PATH=$(pwd)/install/usr/lib + devtools/test-null.sh install/usr/bin/dpdk-testpmd + unset LD_LIBRARY_PATH fi if [ "$RUN_TESTS" = "1" ]; then diff --git a/devtools/test-meson-builds.sh b/devtools/test-meson-builds.sh index fb6c404e5..747fb4a1a 100755 --- a/devtools/test-meson-builds.sh +++ b/devtools/test-meson-builds.sh @@ -66,7 +66,7 @@ config () # <dir> <builddir> <meson options> if [ -f "$builddir/build.ninja" ] ; then return fi - options="--werror -Dexamples=all" + options="--werror -Dexamples=all -Dlibdir=lib" for option in $DPDK_MESON_OPTIONS ; do options="$options -D$option" done @@ -75,7 +75,7 @@ config () # <dir> <builddir> <meson options> $MESON $options $dir $builddir } -compile () # <builddir> +compile () # <builddir> <installdir> { builddir=$1 if [ -n "$TEST_MESON_BUILD_VERY_VERBOSE" ] ; then @@ -90,6 +90,9 @@ compile () # <builddir> echo "$ninja_cmd -C $builddir" $ninja_cmd -C $builddir fi + rm -rf $2 + echo "DESTDIR=$2 $ninja_cmd -C $builddir install" + DESTDIR=$2 $ninja_cmd -C $builddir install } build () # <directory> <target compiler> <meson options> @@ -102,7 +105,8 @@ build () # <directory> <target compiler> <meson options> command -v ${CC##* } >/dev/null 2>&1 || return 0 load_env $targetcc || return 0 config $srcdir $builds_dir/$targetdir $* - compile $builds_dir/$targetdir + compile $builds_dir/$targetdir \ + $(readlink -f $builds_dir/$targetdir/install) } if [ "$1" = "-vv" ] ; then @@ -134,7 +138,7 @@ ok=$(cc -march=$default_machine -E - < /dev/null > /dev/null 2>&1 || echo false) if [ "$ok" = "false" ] ; then default_machine='corei7' fi -build build-x86-default cc -Dlibdir=lib -Dmachine=$default_machine $use_shared +build build-x86-default cc -Dmachine=$default_machine $use_shared c=aarch64-linux-gnu-gcc # generic armv8a with clang as host compiler @@ -150,12 +154,9 @@ for f in $srcdir/config/arm/arm64_[bdo]*gcc ; do unset CC done -# Test installation of the x86-default target, to be used for checking -# the sample apps build using the pkg-config file for cflags and libs -build_path=$(readlink -f $builds_dir/build-x86-default) -export DESTDIR=$build_path/install-root -$ninja_cmd -C $build_path install - +# Use the x86-default target, to check the sample apps build using the +# pkg-config file for cflags and libs +export DESTDIR=$(readlink -f $builds_dir/build-x86-default/install) load_env cc pc_file=$(find $DESTDIR -name libdpdk.pc) export PKG_CONFIG_PATH=$(dirname $pc_file):$PKG_CONFIG_PATH -- 2.23.0
For normal developers, those checks are disabled. Enabling them requires a configuration that will trigger the ABI dumps generation as part of the existing devtools/test-build.sh and devtools/test-meson-builds.sh scripts. Those checks are enabled in the CI for the default meson options on x86 and aarch64 so that proposed patches are validated via our CI robot. A cache of the ABI is stored in travis jobs to avoid rebuilding too often. Checks can be only informational by setting ABI_CHECKS_WARN_ONLY when breaking the ABI in a future release. Explicit suppression rules have been added on internal structures exposed to crypto drivers as the current ABI policy does not apply to them. This could be improved in the future by carefully splitting the headers content with application and driver "users" in mind. We currently have issues reported for librte_crypto recent changes for which suppression rules have been added too. Mellanox glue libraries are explicitly skipped as they are not part of the application ABI. Signed-off-by: David Marchand <david.marchand@redhat.com> Acked-by: Luca Boccassi <bluca@debian.org> --- Changelog since v2: - forced -g / buildtype=debugoptimised in the test scripts so that we can check ABI in existing environments, - little update on the documentation, Changelog since v1: - reworked the scripts so that the build test scripts clone and build the reference automatically. A developer only needs to set one variable to enable the checks, - meson builds are done with debug so that abidiff can inspect the structures, - abidiff checks only public types by looking at installed headers, - abidiff has some issue when comparing a dump with a .so built with clang so all diff are now done with dump files only, - suppression rules have been added to waive warnings on exposed internal types, - an abi breakage has been reported on changes in cryptodev. For now, suppression rules have been put in place to let the CI run, --- .ci/linux-build.sh | 23 +++++++++++ .travis.yml | 20 +++++++++- MAINTAINERS | 2 + devtools/check-abi.sh | 59 +++++++++++++++++++++++++++++ devtools/dpdk.abignore | 21 ++++++++++ devtools/gen-abi.sh | 26 +++++++++++++ devtools/test-build.sh | 51 ++++++++++++++++++++++--- devtools/test-meson-builds.sh | 37 +++++++++++++++++- doc/guides/contributing/patches.rst | 15 ++++++++ 9 files changed, 246 insertions(+), 8 deletions(-) create mode 100755 devtools/check-abi.sh create mode 100644 devtools/dpdk.abignore create mode 100755 devtools/gen-abi.sh diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh index e61aa2b0a..95bd869c3 100755 --- a/.ci/linux-build.sh +++ b/.ci/linux-build.sh @@ -30,6 +30,7 @@ fi OPTS="$OPTS --default-library=$DEF_LIB" OPTS="$OPTS --prefix=/usr -Dlibdir=lib" +OPTS="$OPTS --buildtype=debugoptimized" meson build --werror -Dexamples=all $OPTS ninja -C build DESTDIR=$(pwd)/install ninja -C build install @@ -40,6 +41,28 @@ if [ "$AARCH64" != "1" ]; then unset LD_LIBRARY_PATH fi +if [ "$ABI_CHECKS" = "1" ]; then + REF_GIT_REPO=${REF_GIT_REPO:-https://dpdk.org/git/dpdk} + REF_GIT_TAG=${REF_GIT_TAG:-v19.11} + + if [ "$(cat reference/VERSION 2>/dev/null)" != "$REF_GIT_TAG" ]; then + rm -rf reference + fi + + if [ ! -d reference ]; then + refsrcdir=$(readlink -f $(pwd)/../dpdk-$REF_GIT_TAG) + git clone --single-branch -b $REF_GIT_TAG $REF_GIT_REPO $refsrcdir + meson --werror $OPTS $refsrcdir $refsrcdir/build + ninja -C $refsrcdir/build + DESTDIR=$(pwd)/reference ninja -C $refsrcdir/build install + devtools/gen-abi.sh reference + echo $REF_GIT_TAG > reference/VERSION + fi + + devtools/gen-abi.sh install + devtools/check-abi.sh reference install ${ABI_CHECKS_WARN_ONLY:-} +fi + if [ "$RUN_TESTS" = "1" ]; then sudo meson test -C build --suite fast-tests -t 3 fi diff --git a/.travis.yml b/.travis.yml index 8162f1c05..22539d823 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,8 @@ language: c -cache: ccache +cache: + ccache: true + directories: + - reference compiler: - gcc - clang @@ -21,7 +24,7 @@ aarch64_packages: &aarch64_packages extra_packages: &extra_packages - *required_packages - - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4] + - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4, abigail-tools] build_32b_packages: &build_32b_packages - *required_packages @@ -151,5 +154,18 @@ matrix: packages: - *required_packages - *doc_packages + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1 + compiler: gcc + addons: + apt: + packages: + - *extra_packages + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1 + arch: arm64 + compiler: gcc + addons: + apt: + packages: + - *extra_packages script: ./.ci/${TRAVIS_OS_NAME}-build.sh diff --git a/MAINTAINERS b/MAINTAINERS index 94bccae6d..6dae4ee63 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -144,8 +144,10 @@ M: Neil Horman <nhorman@tuxdriver.com> F: lib/librte_eal/common/include/rte_compat.h F: lib/librte_eal/common/include/rte_function_versioning.h F: doc/guides/rel_notes/deprecation.rst +F: devtools/check-abi.sh F: devtools/check-abi-version.sh F: devtools/check-symbol-change.sh +F: devtools/gen-abi.sh F: devtools/update-abi.sh F: devtools/update_version_map_abi.py F: devtools/validate-abi.sh diff --git a/devtools/check-abi.sh b/devtools/check-abi.sh new file mode 100755 index 000000000..5872499ec --- /dev/null +++ b/devtools/check-abi.sh @@ -0,0 +1,59 @@ +#!/bin/sh -e +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2019 Red Hat, Inc. + +if [ $# != 2 ] && [ $# != 3 ]; then + echo "Usage: $0 refdir newdir [warnonly]" + exit 1 +fi + +refdir=$1 +newdir=$2 +warnonly=${3:-} +ABIDIFF_OPTIONS="--suppr $(dirname $0)/dpdk.abignore --no-added-syms" + +if [ ! -d $refdir ]; then + echo "Error: reference directory '$refdir' does not exist." + exit 1 +fi +incdir=$(find $refdir -type d -a -name include) +if [ -z "$incdir" ] || [ ! -e "$incdir" ]; then + echo "WARNING: could not identify a include directory for $refdir, expect false positives..." +else + ABIDIFF_OPTIONS="$ABIDIFF_OPTIONS --headers-dir1 $incdir" +fi + +if [ ! -d $newdir ]; then + echo "Error: directory to check '$newdir' does not exist." + exit 1 +fi +incdir2=$(find $newdir -type d -a -name include) +if [ -z "$incdir2" ] || [ ! -e "$incdir2" ]; then + echo "WARNING: could not identify a include directory for $newdir, expect false positives..." +else + ABIDIFF_OPTIONS="$ABIDIFF_OPTIONS --headers-dir2 $incdir2" +fi + +error= +for dump in $(find $refdir -name "*.dump"); do + name=$(basename $dump) + # skip glue drivers, example librte_pmd_mlx5_glue.dump + # We can't rely on a suppression rule for now: + # https://sourceware.org/bugzilla/show_bug.cgi?id=25480 + if [ "$name" != "${name%%_glue.dump}" ]; then + echo "Skipping ${dump}..." + continue + fi + dump2=$(find $newdir -name $name) + if [ -z "$dump2" ] || [ ! -e "$dump2" ]; then + echo "Error: can't find $name in $newdir" + error=1 + continue + fi + if ! abidiff $ABIDIFF_OPTIONS $dump $dump2; then + echo "Error: ABI issue reported for 'abidiff $ABIDIFF_OPTIONS $dump $dump2'" + error=1 + fi +done + +[ -z "$error" ] || [ -n "$warnonly" ] diff --git a/devtools/dpdk.abignore b/devtools/dpdk.abignore new file mode 100644 index 000000000..f2903612c --- /dev/null +++ b/devtools/dpdk.abignore @@ -0,0 +1,21 @@ +[suppress_function] + symbol_version = EXPERIMENTAL +[suppress_variable] + symbol_version = EXPERIMENTAL + +; Explicit ignore for driver-only ABI +[suppress_type] + name = rte_cryptodev_ops +; Ignore this enum update as it is part of an experimental API +[suppress_type] + type_kind = enum + name = rte_crypto_asym_xform_type + changed_enumerators = RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END + +; FIXME +[suppress_type] + type_kind = enum + name = rte_crypto_aead_algorithm + changed_enumerators = RTE_CRYPTO_AEAD_LIST_END +[suppress_variable] + name = rte_crypto_aead_algorithm_strings diff --git a/devtools/gen-abi.sh b/devtools/gen-abi.sh new file mode 100755 index 000000000..c44b0e228 --- /dev/null +++ b/devtools/gen-abi.sh @@ -0,0 +1,26 @@ +#!/bin/sh -e +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2019 Red Hat, Inc. + +if [ $# != 1 ]; then + echo "Usage: $0 installdir" + exit 1 +fi + +installdir=$1 +if [ ! -d $installdir ]; then + echo "Error: install directory '$installdir' does not exist." + exit 1 +fi + +dumpdir=$installdir/dump +rm -rf $dumpdir +mkdir -p $dumpdir +for f in $(find $installdir -name "*.so.*"); do + if test -L $f; then + continue + fi + + libname=$(basename $f) + abidw --out-file $dumpdir/${libname%.so*}.dump $f +done diff --git a/devtools/test-build.sh b/devtools/test-build.sh index 52305fbb8..a97e1280e 100755 --- a/devtools/test-build.sh +++ b/devtools/test-build.sh @@ -30,7 +30,8 @@ default_path=$PATH # - LIBSSO_SNOW3G_PATH # - LIBSSO_KASUMI_PATH # - LIBSSO_ZUC_PATH -. $(dirname $(readlink -f $0))/load-devel-config +devtools_dir=$(dirname $(readlink -f $0)) +. $devtools_dir/load-devel-config print_usage () { echo "usage: $(basename $0) [-h] [-jX] [-s] [config1 [config2] ...]]" @@ -64,10 +65,12 @@ print_help () { [ -z $MAKE ] && echo "Cannot find make or gmake" && exit 1 J=$DPDK_MAKE_JOBS +refsrcdir=$(mktemp -d -t dpdk-${DPDK_ABI_REF_VERSION:-}.XXX) builds_dir=${DPDK_BUILD_TEST_DIR:-.} short=false unset verbose -maxerr=-Wfatal-errors +# for ABI checks, we need debuginfo +test_cflags="-Wfatal-errors -g" while getopts hj:sv ARG ; do case $ARG in j ) J=$OPTARG ;; @@ -91,13 +94,14 @@ on_exit () [ "$DPDK_NOTIFY" != notify-send ] || \ notify-send -u low --icon=dialog-error 'DPDK build' 'failed' fi + rm -rf $refsrcdir } # catch manual interrupt to ignore notification trap "signal=INT ; trap - INT ; kill -INT $$" INT # notify result on exit trap on_exit EXIT -cd $(dirname $(readlink -f $0))/.. +cd $devtools_dir/.. reset_env () { @@ -233,14 +237,14 @@ for conf in $configs ; do # reload config with DPDK_TARGET set DPDK_TARGET=$target reset_env - . $(dirname $(readlink -f $0))/load-devel-config + . $devtools_dir/load-devel-config options=$(echo $conf | sed 's,[^~+]*,,') dir=$builds_dir/$conf config $dir $target $options echo "================== Build $conf" - ${MAKE} -j$J EXTRA_CFLAGS="$maxerr $DPDK_DEP_CFLAGS" \ + ${MAKE} -j$J EXTRA_CFLAGS="$test_cflags $DPDK_DEP_CFLAGS" \ EXTRA_LDFLAGS="$DPDK_DEP_LDFLAGS" $verbose O=$dir ! $short || break export RTE_TARGET=$target @@ -253,6 +257,43 @@ for conf in $configs ; do EXTRA_LDFLAGS="$DPDK_DEP_LDFLAGS" $verbose \ O=$(readlink -f $dir)/examples unset RTE_TARGET + if [ -n "$DPDK_ABI_REF_VERSION" ]; then + DPDK_ABI_REF_DIR=${DPDK_ABI_REF_DIR:-reference} + abirefdir=$DPDK_ABI_REF_DIR/$DPDK_ABI_REF_VERSION/$conf + if [ ! -d $abirefdir ]; then + # clone current sources + if [ ! -d $refsrcdir/.git ]; then + git clone --local --no-hardlinks \ + --single-branch \ + -b $DPDK_ABI_REF_VERSION \ + $(pwd) $refsrcdir + fi + + cd $refsrcdir + + rm -rf build + config build $target $options + + echo -n "================== Build $conf " + echo "($DPDK_ABI_REF_VERSION)" + ${MAKE} -j$J \ + EXTRA_CFLAGS="$test_cflags $DPDK_DEP_CFLAGS" \ + EXTRA_LDFLAGS="$DPDK_DEP_LDFLAGS" $verbose \ + O=build + ! $short || break + export RTE_TARGET=$target + ${MAKE} install O=build DESTDIR=$abirefdir \ + prefix= + $devtools_dir/gen-abi.sh $abirefdir + + # back to current workdir + cd $devtools_dir/.. + fi + + echo "================== Check ABI $conf" + $devtools_dir/gen-abi.sh $dir/install + $devtools_dir/check-abi.sh $abirefdir $dir/install + fi echo "################## $conf done." unset dir done diff --git a/devtools/test-meson-builds.sh b/devtools/test-meson-builds.sh index 747fb4a1a..23e93770d 100755 --- a/devtools/test-meson-builds.sh +++ b/devtools/test-meson-builds.sh @@ -16,8 +16,15 @@ srcdir=$(dirname $(readlink -f $0))/.. MESON=${MESON:-meson} use_shared="--default-library=shared" +refsrcdir=$(mktemp -d -t dpdk-${DPDK_ABI_REF_VERSION:-}.XXX) builds_dir=${DPDK_BUILD_TEST_DIR:-.} +on_exit () +{ + rm -rf $refsrcdir +} +trap on_exit EXIT + if command -v gmake >/dev/null 2>&1 ; then MAKE=gmake else @@ -64,9 +71,14 @@ config () # <dir> <builddir> <meson options> builddir=$1 shift if [ -f "$builddir/build.ninja" ] ; then + # for existing environments, force debugoptimized so that ABI + # checks can run + $MESON configure --buildtype=debugoptimized $builddir return fi - options="--werror -Dexamples=all -Dlibdir=lib" + options= + options="$options --werror -Dexamples=all -Dlibdir=lib" + options="$options --buildtype=debugoptimized" for option in $DPDK_MESON_OPTIONS ; do options="$options -D$option" done @@ -107,6 +119,29 @@ build () # <directory> <target compiler> <meson options> config $srcdir $builds_dir/$targetdir $* compile $builds_dir/$targetdir \ $(readlink -f $builds_dir/$targetdir/install) + if [ -n "$DPDK_ABI_REF_VERSION" ]; then + DPDK_ABI_REF_DIR=${DPDK_ABI_REF_DIR:-reference} + abirefdir=$DPDK_ABI_REF_DIR/$DPDK_ABI_REF_VERSION/$targetdir + if [ ! -d $abirefdir ]; then + # clone current sources + if [ ! -d $refsrcdir/.git ]; then + git clone --local --no-hardlinks \ + --single-branch \ + -b $DPDK_ABI_REF_VERSION \ + $srcdir $refsrcdir + fi + + rm -rf $refsrcdir/build + config $refsrcdir $refsrcdir/build $* + compile $refsrcdir/build $abirefdir + $srcdir/devtools/gen-abi.sh $abirefdir + fi + + $srcdir/devtools/gen-abi.sh \ + $(readlink -f $builds_dir/$targetdir/install) + $srcdir/devtools/check-abi.sh $abirefdir \ + $(readlink -f $builds_dir/$targetdir/install) + fi } if [ "$1" = "-vv" ] ; then diff --git a/doc/guides/contributing/patches.rst b/doc/guides/contributing/patches.rst index 0686450e4..59442824a 100644 --- a/doc/guides/contributing/patches.rst +++ b/doc/guides/contributing/patches.rst @@ -513,6 +513,21 @@ in a single subfolder called "__builds" created in the current directory. Setting ``DPDK_BUILD_TEST_DIR`` to an absolute directory path e.g. ``/tmp`` is also supported. +Checking ABI compatibility +-------------------------- + +By default, ABI compatibility checks are disabled. + +To enable them, a reference version must be selected via the environment +variable ``DPDK_ABI_REF_VERSION``. + +The ``devtools/test-build.sh`` and ``devtools/test-meson-builds.sh`` scripts +then build this reference version in a temporary directory and store the +results in a subfolder of the current working directory. +The environment variable ``DPDK_ABI_REF_DIR`` can be set so that the results go +to a different location. + + Sending Patches --------------- -- 2.23.0
On 1/29/2020 8:13 PM, Akhil Goyal wrote: > > >> >> On Wed, Jan 29, 2020 at 7:10 PM Anoob Joseph <anoobj@marvell.com> wrote: >>> The asymmetric crypto library is experimental. Changes to experimental code >> paths is allowed, right? >> >> The asymmetric crypto enum is referenced by a function part of the stable ABI. >> It is possible to waive this enum, if we are sure no use out of the >> experimental asym crypto APIs is possible. >> >> The rest of the changes touch stable symbols. >> >> Adding the abidiff report: >> >> [C]'function void rte_cryptodev_info_get(uint8_t, >> rte_cryptodev_info*)' at rte_cryptodev.c:1115:1 has some indirect >> sub-type changes: >> parameter 2 of type 'rte_cryptodev_info*' has sub-type changes: >> in pointed to type 'struct rte_cryptodev_info' at rte_cryptodev.h:468:1: >> type size hasn't changed >> 1 data member change: >> type of 'const rte_cryptodev_capabilities* >> rte_cryptodev_info::capabilities' changed: >> in pointed to type 'const rte_cryptodev_capabilities': >> in unqualified underlying type 'struct >> rte_cryptodev_capabilities' at rte_cryptodev.h:176:1: >> type size hasn't changed >> 1 data member change: >> type of '__anonymous_union__ ' changed: >> type size hasn't changed >> 1 data member change: >> type of 'rte_cryptodev_asymmetric_capability >> __anonymous_union__::asym' changed: >> type size hasn't changed >> 1 data member change: >> type of >> 'rte_cryptodev_asymmetric_xform_capability >> rte_cryptodev_asymmetric_capability::xform_capa' changed: >> type size hasn't changed >> 1 data member change: >> type of 'rte_crypto_asym_xform_type >> rte_cryptodev_asymmetric_xform_capability::xform_type' changed: >> type size hasn't changed >> 2 enumerator insertions: >> >> 'rte_crypto_asym_xform_type::RTE_CRYPTO_ASYM_XFORM_ECDSA' value '7' >> >> 'rte_crypto_asym_xform_type::RTE_CRYPTO_ASYM_XFORM_ECPM' value '8' >> 1 enumerator change: >> >> 'rte_crypto_asym_xform_type::RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END' >> from >> value '7' to '9' at rte_crypto_asym.h:60:1 >> > > I believe these enums will be used only in case of ASYM case which is experimental. Independent from being experiment and not, this shouldn't be a problem, I think this is a false positive. The ABI break can happen when a struct has been shared between the application and the library (DPDK) and the layout of that memory know differently by application and the library. Here in all cases, there is no layout/size change. As to the value changes of the enums, since application compiled with old DPDK, it will know only up to '6', 7 and more means invalid to the application. So it won't send these values also it should ignore these values from library. Only consequence is old application won't able to use new features those new enums provide but that is expected/normal. > >> >> [C]'function int >> rte_cryptodev_get_aead_algo_enum(rte_crypto_aead_algorithm*, const >> char*)' at rte_cryptodev.c:239:1 has some indirect sub-type changes: >> parameter 1 of type 'rte_crypto_aead_algorithm*' has sub-type changes: >> in pointed to type 'enum rte_crypto_aead_algorithm' at >> rte_crypto_sym.h:346:1: >> type size hasn't changed >> 1 enumerator insertion: >> 'rte_crypto_aead_algorithm::RTE_CRYPTO_AEAD_CHACHA20_POLY1305' >> value '3' >> 1 enumerator change: >> 'rte_crypto_aead_algorithm::RTE_CRYPTO_AEAD_LIST_END' from >> value '3' to '4' at rte_crypto_sym.h:346:1 Same as above, no layout change. >> >> >> [C]'const char* rte_crypto_aead_algorithm_strings[1]' was changed at >> rte_crypto_sym.h:358:1: >> size of symbol (in bytes) changed from 24 to 32 >> The shared memory size changes, but this is global variable in the library, and the values application can request 'RTE_CRYPTO_AEAD_AES_CCM' & 'RTE_CRYPTO_AEAD_AES_GCM' is already there, so there is no backward compatibility issue here. >> > +Fiona and Arek > > We may need to revert the chacha-poly patches. > I don't see any ABI break in this case, can someone explain if I am missing anything here?
On 1/30/2020 3:59 PM, Thomas Monjalon wrote: > 30/01/2020 14:06, Trahe, Fiona: >> We were unaware the LIST_END change could constitute an ABI breakage, but can see how it affects the array size when picked up. >> We're exploring options. >> >> I agree with Anoob's point that if we don't allow the LIST_END to be modified, then it means no feature can be implemented without ABI breakage. >> Anyone object to removing those LIST_END elements - or have a better suggestion? Would have to be in 20.11 I suppose. > > Yes, having max value right after the last value is ridiculous, > it prevents adding any value. > In 20.11, we should remove all these *_END and *_MAX from API enums > and replace them with a separate #define with reasonnable maximums. > > I disagree, that kind of usage is common and lets loops iterate on the valid elements, and it is not a source of ABI break on its own. Indeed other way around, not having MAX, is problematic, if we don't have the MAX value to compare and decide if a provided value is valid or not, and when new version of the library introduces the new values, how old application can detect unsupported new values? As far as I can see the problem occurs when that *_END and *_MAX used to define the size of array in the public struct. This usage prevents adding new values and I already send a deprecation notice for it: https://patches.dpdk.org/patch/65359/
>-----Original Message-----
>From: David Marchand [mailto:david.marchand@redhat.com]
>Sent: Thursday, January 30, 2020 8:00 AM
>To: dev@dpdk.org
>Cc: thomas@monjalon.net; Richardson, Bruce <bruce.richardson@intel.com>; Laatz, Kevin <kevin.laatz@intel.com>;
>aconole@redhat.com; nhorman@tuxdriver.com; akhil.goyal@nxp.com; anoobj@marvell.com; bluca@debian.org; Trahe, Fiona
><fiona.trahe@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>; stable@dpdk.org; Wang, Yipeng1 <yipeng1.wang@intel.com>;
>Gobriel, Sameh <sameh.gobriel@intel.com>; Van Haaren, Harry <harry.van.haaren@intel.com>; Luca Boccassi
><luca.boccassi@gmail.com>; Wiles, Keith <keith.wiles@intel.com>
>Subject: [PATCH v3 1/4] hash: fix meson headers packaging
>
>Those headers are internal and should not be distributed.
>
>Fixes: 5b9656b157d3 ("lib: build with meson")
>Cc: stable@dpdk.org
>
>Signed-off-by: David Marchand <david.marchand@redhat.com>
>Acked-by: Luca Boccassi <bluca@debian.org>
[Wang, Yipeng]
Thanks for the patch! I believe they are for internal used only.
But include Honnappa from ARM here since in the makefile seems the rte_crc_arm64.h is installed?
<snip>
> >Subject: [PATCH v3 1/4] hash: fix meson headers packaging
> >
> >Those headers are internal and should not be distributed.
> >
> >Fixes: 5b9656b157d3 ("lib: build with meson")
> >Cc: stable@dpdk.org
> >
> >Signed-off-by: David Marchand <david.marchand@redhat.com>
> >Acked-by: Luca Boccassi <bluca@debian.org>
>
> [Wang, Yipeng]
> Thanks for the patch! I believe they are for internal used only.
> But include Honnappa from ARM here since in the makefile seems the
> rte_crc_arm64.h is installed?
I see that this patch installs rte_crc_arm64.h. I do no see any issue.
30/01/2020 17:09, Ferruh Yigit: > On 1/29/2020 8:13 PM, Akhil Goyal wrote: > > > > > >> > >> On Wed, Jan 29, 2020 at 7:10 PM Anoob Joseph <anoobj@marvell.com> wrote: > >>> The asymmetric crypto library is experimental. Changes to experimental code > >> paths is allowed, right? > >> > >> The asymmetric crypto enum is referenced by a function part of the stable ABI. > >> It is possible to waive this enum, if we are sure no use out of the > >> experimental asym crypto APIs is possible. > >> > >> The rest of the changes touch stable symbols. > >> > >> Adding the abidiff report: > >> > >> [C]'function void rte_cryptodev_info_get(uint8_t, > >> rte_cryptodev_info*)' at rte_cryptodev.c:1115:1 has some indirect > >> sub-type changes: > >> parameter 2 of type 'rte_cryptodev_info*' has sub-type changes: > >> in pointed to type 'struct rte_cryptodev_info' at rte_cryptodev.h:468:1: > >> type size hasn't changed > >> 1 data member change: > >> type of 'const rte_cryptodev_capabilities* > >> rte_cryptodev_info::capabilities' changed: > >> in pointed to type 'const rte_cryptodev_capabilities': > >> in unqualified underlying type 'struct > >> rte_cryptodev_capabilities' at rte_cryptodev.h:176:1: > >> type size hasn't changed > >> 1 data member change: > >> type of '__anonymous_union__ ' changed: > >> type size hasn't changed > >> 1 data member change: > >> type of 'rte_cryptodev_asymmetric_capability > >> __anonymous_union__::asym' changed: > >> type size hasn't changed > >> 1 data member change: > >> type of > >> 'rte_cryptodev_asymmetric_xform_capability > >> rte_cryptodev_asymmetric_capability::xform_capa' changed: > >> type size hasn't changed > >> 1 data member change: > >> type of 'rte_crypto_asym_xform_type > >> rte_cryptodev_asymmetric_xform_capability::xform_type' changed: > >> type size hasn't changed > >> 2 enumerator insertions: > >> > >> 'rte_crypto_asym_xform_type::RTE_CRYPTO_ASYM_XFORM_ECDSA' value '7' > >> > >> 'rte_crypto_asym_xform_type::RTE_CRYPTO_ASYM_XFORM_ECPM' value '8' > >> 1 enumerator change: > >> > >> 'rte_crypto_asym_xform_type::RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END' > >> from > >> value '7' to '9' at rte_crypto_asym.h:60:1 > >> > > > > I believe these enums will be used only in case of ASYM case which is experimental. > > Independent from being experiment and not, this shouldn't be a problem, I think > this is a false positive. > > The ABI break can happen when a struct has been shared between the application > and the library (DPDK) and the layout of that memory know differently by > application and the library. > > Here in all cases, there is no layout/size change. > > As to the value changes of the enums, since application compiled with old DPDK, > it will know only up to '6', 7 and more means invalid to the application. So it > won't send these values also it should ignore these values from library. Only > consequence is old application won't able to use new features those new enums > provide but that is expected/normal. If library give higher value than expected by the application, if the application uses this value as array index, there can be an access out of bounds. > >> [C]'function int > >> rte_cryptodev_get_aead_algo_enum(rte_crypto_aead_algorithm*, const > >> char*)' at rte_cryptodev.c:239:1 has some indirect sub-type changes: > >> parameter 1 of type 'rte_crypto_aead_algorithm*' has sub-type changes: > >> in pointed to type 'enum rte_crypto_aead_algorithm' at > >> rte_crypto_sym.h:346:1: > >> type size hasn't changed > >> 1 enumerator insertion: > >> 'rte_crypto_aead_algorithm::RTE_CRYPTO_AEAD_CHACHA20_POLY1305' > >> value '3' > >> 1 enumerator change: > >> 'rte_crypto_aead_algorithm::RTE_CRYPTO_AEAD_LIST_END' from > >> value '3' to '4' at rte_crypto_sym.h:346:1 > > Same as above, no layout change. > > >> > >> > >> [C]'const char* rte_crypto_aead_algorithm_strings[1]' was changed at > >> rte_crypto_sym.h:358:1: > >> size of symbol (in bytes) changed from 24 to 32 > >> > > The shared memory size changes, but this is global variable in the library, and > the values application can request 'RTE_CRYPTO_AEAD_AES_CCM' & > 'RTE_CRYPTO_AEAD_AES_GCM' is already there, so there is no backward > compatibility issue here. For this one, I don't know what is the breakage. > > +Fiona and Arek > > > > We may need to revert the chacha-poly patches. > > > > I don't see any ABI break in this case, can someone explain if I am missing > anything here?
30/01/2020 17:00, David Marchand: > Let's test installing with meson as part of Travis and the > devtools/test-meson-builds.sh script. For test-meson-builds.sh, I would prefer avoiding install if not needed. Can we install only if compiling examples or checking ABI? > -compile () # <builddir> > +compile () # <builddir> <installdir> > { > builddir=$1 > if [ -n "$TEST_MESON_BUILD_VERY_VERBOSE" ] ; then > @@ -90,6 +90,9 @@ compile () # <builddir> > echo "$ninja_cmd -C $builddir" > $ninja_cmd -C $builddir > fi > + rm -rf $2 > + echo "DESTDIR=$2 $ninja_cmd -C $builddir install" > + DESTDIR=$2 $ninja_cmd -C $builddir install > } > > build () # <directory> <target compiler> <meson options> > @@ -102,7 +105,8 @@ build () # <directory> <target compiler> <meson options> > command -v ${CC##* } >/dev/null 2>&1 || return 0 > load_env $targetcc || return 0 > config $srcdir $builds_dir/$targetdir $* > - compile $builds_dir/$targetdir > + compile $builds_dir/$targetdir \ > + $(readlink -f $builds_dir/$targetdir/install) > }
30/01/2020 17:00, David Marchand: > Enabling them requires a configuration that will trigger the ABI dumps > generation as part of the existing devtools/test-build.sh and > devtools/test-meson-builds.sh scripts. [...] > --- a/devtools/test-meson-builds.sh > +++ b/devtools/test-meson-builds.sh > if [ -f "$builddir/build.ninja" ] ; then > + # for existing environments, force debugoptimized so that ABI > + # checks can run > + $MESON configure --buildtype=debugoptimized $builddir This is forcing meson to re-run each time, even if the buildtype is already "debugoptimized". Please query meson configuration to avoid useless re-run: $MESON configure $builddir | awk '$1=="buildtype" {print $2}'
30/01/2020 17:00, David Marchand: > --- a/devtools/test-meson-builds.sh > +++ b/devtools/test-meson-builds.sh > +refsrcdir=$(mktemp -d -t dpdk-${DPDK_ABI_REF_VERSION:-}.XXX) Instead of a temporary source directory, could it be inside $DPDK_ABI_REF_DIR/$DPDK_ABI_REF_VERSION ? I feel it would more "hackable" for debugging of the process. [..] > + if [ -n "$DPDK_ABI_REF_VERSION" ]; then > + DPDK_ABI_REF_DIR=${DPDK_ABI_REF_DIR:-reference} > + abirefdir=$DPDK_ABI_REF_DIR/$DPDK_ABI_REF_VERSION/$targetdir > + if [ ! -d $abirefdir ]; then > + # clone current sources > + if [ ! -d $refsrcdir/.git ]; then > + git clone --local --no-hardlinks \ > + --single-branch \ > + -b $DPDK_ABI_REF_VERSION \ > + $srcdir $refsrcdir > + fi > + > + rm -rf $refsrcdir/build > + config $refsrcdir $refsrcdir/build $* > + compile $refsrcdir/build $abirefdir > + $srcdir/devtools/gen-abi.sh $abirefdir > + fi
> -----Original Message-----
> From: dev <dev-bounces@dpdk.org> On Behalf Of Thomas Monjalon
> Sent: Thursday, January 30, 2020 4:00 PM
> To: Anoob Joseph <anoobj@marvell.com>; akhil.goyal@nxp.com; Trahe, Fiona <fiona.trahe@intel.com>
> Cc: dev@dpdk.org; David Marchand <david.marchand@redhat.com>; Richardson, Bruce <bruce.richardson@intel.com>;
> nhorman@tuxdriver.com; Mcnamara, John <john.mcnamara@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>; Kusztal, ArkadiuszX
> <arkadiuszx.kusztal@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v2 4/4] add ABI checks
>
> 30/01/2020 14:06, Trahe, Fiona:
> > We were unaware the LIST_END change could constitute an ABI breakage, but can see how it affects the array size when picked up.
> > We're exploring options.
> >
> > I agree with Anoob's point that if we don't allow the LIST_END to be modified, then it means no feature can be implemented without ABI
> breakage.
> > Anyone object to removing those LIST_END elements - or have a better suggestion? Would have to be in 20.11 I suppose.
>
> Yes, having max value right after the last value is ridiculous,
> it prevents adding any value.
> In 20.11, we should remove all these *_END and *_MAX from API enums
> and replace them with a separate #define with reasonnable maximums.
>
I think we'd better avoid public structs that have array of _MAX elems in them.
On 1/30/2020 8:18 PM, Thomas Monjalon wrote: > 30/01/2020 17:09, Ferruh Yigit: >> On 1/29/2020 8:13 PM, Akhil Goyal wrote: >>> >>> >>>> >>>> On Wed, Jan 29, 2020 at 7:10 PM Anoob Joseph <anoobj@marvell.com> wrote: >>>>> The asymmetric crypto library is experimental. Changes to experimental code >>>> paths is allowed, right? >>>> >>>> The asymmetric crypto enum is referenced by a function part of the stable ABI. >>>> It is possible to waive this enum, if we are sure no use out of the >>>> experimental asym crypto APIs is possible. >>>> >>>> The rest of the changes touch stable symbols. >>>> >>>> Adding the abidiff report: >>>> >>>> [C]'function void rte_cryptodev_info_get(uint8_t, >>>> rte_cryptodev_info*)' at rte_cryptodev.c:1115:1 has some indirect >>>> sub-type changes: >>>> parameter 2 of type 'rte_cryptodev_info*' has sub-type changes: >>>> in pointed to type 'struct rte_cryptodev_info' at rte_cryptodev.h:468:1: >>>> type size hasn't changed >>>> 1 data member change: >>>> type of 'const rte_cryptodev_capabilities* >>>> rte_cryptodev_info::capabilities' changed: >>>> in pointed to type 'const rte_cryptodev_capabilities': >>>> in unqualified underlying type 'struct >>>> rte_cryptodev_capabilities' at rte_cryptodev.h:176:1: >>>> type size hasn't changed >>>> 1 data member change: >>>> type of '__anonymous_union__ ' changed: >>>> type size hasn't changed >>>> 1 data member change: >>>> type of 'rte_cryptodev_asymmetric_capability >>>> __anonymous_union__::asym' changed: >>>> type size hasn't changed >>>> 1 data member change: >>>> type of >>>> 'rte_cryptodev_asymmetric_xform_capability >>>> rte_cryptodev_asymmetric_capability::xform_capa' changed: >>>> type size hasn't changed >>>> 1 data member change: >>>> type of 'rte_crypto_asym_xform_type >>>> rte_cryptodev_asymmetric_xform_capability::xform_type' changed: >>>> type size hasn't changed >>>> 2 enumerator insertions: >>>> >>>> 'rte_crypto_asym_xform_type::RTE_CRYPTO_ASYM_XFORM_ECDSA' value '7' >>>> >>>> 'rte_crypto_asym_xform_type::RTE_CRYPTO_ASYM_XFORM_ECPM' value '8' >>>> 1 enumerator change: >>>> >>>> 'rte_crypto_asym_xform_type::RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END' >>>> from >>>> value '7' to '9' at rte_crypto_asym.h:60:1 >>>> >>> >>> I believe these enums will be used only in case of ASYM case which is experimental. >> >> Independent from being experiment and not, this shouldn't be a problem, I think >> this is a false positive. >> >> The ABI break can happen when a struct has been shared between the application >> and the library (DPDK) and the layout of that memory know differently by >> application and the library. >> >> Here in all cases, there is no layout/size change. >> >> As to the value changes of the enums, since application compiled with old DPDK, >> it will know only up to '6', 7 and more means invalid to the application. So it >> won't send these values also it should ignore these values from library. Only >> consequence is old application won't able to use new features those new enums >> provide but that is expected/normal. > > If library give higher value than expected by the application, > if the application uses this value as array index, > there can be an access out of bounds. First this concern is not an ABI break concern, but application should ignore any value bigger than the MAX value it knows. Otherwise this would mean we can't add any new enum or define to the project, which is wrong I believe. > > >>>> [C]'function int >>>> rte_cryptodev_get_aead_algo_enum(rte_crypto_aead_algorithm*, const >>>> char*)' at rte_cryptodev.c:239:1 has some indirect sub-type changes: >>>> parameter 1 of type 'rte_crypto_aead_algorithm*' has sub-type changes: >>>> in pointed to type 'enum rte_crypto_aead_algorithm' at >>>> rte_crypto_sym.h:346:1: >>>> type size hasn't changed >>>> 1 enumerator insertion: >>>> 'rte_crypto_aead_algorithm::RTE_CRYPTO_AEAD_CHACHA20_POLY1305' >>>> value '3' >>>> 1 enumerator change: >>>> 'rte_crypto_aead_algorithm::RTE_CRYPTO_AEAD_LIST_END' from >>>> value '3' to '4' at rte_crypto_sym.h:346:1 >> >> Same as above, no layout change. >> >>>> >>>> >>>> [C]'const char* rte_crypto_aead_algorithm_strings[1]' was changed at >>>> rte_crypto_sym.h:358:1: >>>> size of symbol (in bytes) changed from 24 to 32 >>>> >> >> The shared memory size changes, but this is global variable in the library, and >> the values application can request 'RTE_CRYPTO_AEAD_AES_CCM' & >> 'RTE_CRYPTO_AEAD_AES_GCM' is already there, so there is no backward >> compatibility issue here. > > For this one, I don't know what is the breakage. > > >>> +Fiona and Arek >>> >>> We may need to revert the chacha-poly patches. >>> >> >> I don't see any ABI break in this case, can someone explain if I am missing >> anything here? > > > > >
On 1/30/2020 11:49 PM, Ananyev, Konstantin wrote:
>
>
>> -----Original Message-----
>> From: dev <dev-bounces@dpdk.org> On Behalf Of Thomas Monjalon
>> Sent: Thursday, January 30, 2020 4:00 PM
>> To: Anoob Joseph <anoobj@marvell.com>; akhil.goyal@nxp.com; Trahe, Fiona <fiona.trahe@intel.com>
>> Cc: dev@dpdk.org; David Marchand <david.marchand@redhat.com>; Richardson, Bruce <bruce.richardson@intel.com>;
>> nhorman@tuxdriver.com; Mcnamara, John <john.mcnamara@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>; Kusztal, ArkadiuszX
>> <arkadiuszx.kusztal@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
>> Subject: Re: [dpdk-dev] [PATCH v2 4/4] add ABI checks
>>
>> 30/01/2020 14:06, Trahe, Fiona:
>>> We were unaware the LIST_END change could constitute an ABI breakage, but can see how it affects the array size when picked up.
>>> We're exploring options.
>>>
>>> I agree with Anoob's point that if we don't allow the LIST_END to be modified, then it means no feature can be implemented without ABI
>> breakage.
>>> Anyone object to removing those LIST_END elements - or have a better suggestion? Would have to be in 20.11 I suppose.
>>
>> Yes, having max value right after the last value is ridiculous,
>> it prevents adding any value.
>> In 20.11, we should remove all these *_END and *_MAX from API enums
>> and replace them with a separate #define with reasonnable maximums.
>>
>
> I think we'd better avoid public structs that have array of _MAX elems in them.
>
That should fix, but we need to wait for 20.11 for the change, and what should
be the new array size?
> -----Original Message-----
> From: Yigit, Ferruh <ferruh.yigit@intel.com>
> Sent: Friday, January 31, 2020 9:07 AM
> To: Ananyev, Konstantin <konstantin.ananyev@intel.com>; Thomas Monjalon <thomas@monjalon.net>; Anoob Joseph
> <anoobj@marvell.com>; akhil.goyal@nxp.com; Trahe, Fiona <fiona.trahe@intel.com>
> Cc: dev@dpdk.org; David Marchand <david.marchand@redhat.com>; Richardson, Bruce <bruce.richardson@intel.com>;
> nhorman@tuxdriver.com; Mcnamara, John <john.mcnamara@intel.com>; Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v2 4/4] add ABI checks
>
> On 1/30/2020 11:49 PM, Ananyev, Konstantin wrote:
> >
> >
> >> -----Original Message-----
> >> From: dev <dev-bounces@dpdk.org> On Behalf Of Thomas Monjalon
> >> Sent: Thursday, January 30, 2020 4:00 PM
> >> To: Anoob Joseph <anoobj@marvell.com>; akhil.goyal@nxp.com; Trahe, Fiona <fiona.trahe@intel.com>
> >> Cc: dev@dpdk.org; David Marchand <david.marchand@redhat.com>; Richardson, Bruce <bruce.richardson@intel.com>;
> >> nhorman@tuxdriver.com; Mcnamara, John <john.mcnamara@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>; Kusztal, ArkadiuszX
> >> <arkadiuszx.kusztal@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> >> Subject: Re: [dpdk-dev] [PATCH v2 4/4] add ABI checks
> >>
> >> 30/01/2020 14:06, Trahe, Fiona:
> >>> We were unaware the LIST_END change could constitute an ABI breakage, but can see how it affects the array size when picked up.
> >>> We're exploring options.
> >>>
> >>> I agree with Anoob's point that if we don't allow the LIST_END to be modified, then it means no feature can be implemented without
> ABI
> >> breakage.
> >>> Anyone object to removing those LIST_END elements - or have a better suggestion? Would have to be in 20.11 I suppose.
> >>
> >> Yes, having max value right after the last value is ridiculous,
> >> it prevents adding any value.
> >> In 20.11, we should remove all these *_END and *_MAX from API enums
> >> and replace them with a separate #define with reasonnable maximums.
> >>
> >
> > I think we'd better avoid public structs that have array of _MAX elems in them.
> >
>
> That should fix, but we need to wait for 20.11 for the change, and what should
> be the new array size?
Make it dynamic whenever possible?
Make Input/output args to provide both pointer and size,
or use some predefined value for terminating element (NULL, -1, etc.)?
> > On 1/30/2020 8:18 PM, Thomas Monjalon wrote: > > 30/01/2020 17:09, Ferruh Yigit: > >> On 1/29/2020 8:13 PM, Akhil Goyal wrote: > >>> > >>> > >>>> > >>>> On Wed, Jan 29, 2020 at 7:10 PM Anoob Joseph <anoobj@marvell.com> wrote: > >>>>> The asymmetric crypto library is experimental. Changes to experimental code > >>>> paths is allowed, right? > >>>> > >>>> The asymmetric crypto enum is referenced by a function part of the stable ABI. > >>>> It is possible to waive this enum, if we are sure no use out of the > >>>> experimental asym crypto APIs is possible. > >>>> > >>>> The rest of the changes touch stable symbols. > >>>> > >>>> Adding the abidiff report: > >>>> > >>>> [C]'function void rte_cryptodev_info_get(uint8_t, > >>>> rte_cryptodev_info*)' at rte_cryptodev.c:1115:1 has some indirect > >>>> sub-type changes: > >>>> parameter 2 of type 'rte_cryptodev_info*' has sub-type changes: > >>>> in pointed to type 'struct rte_cryptodev_info' at rte_cryptodev.h:468:1: > >>>> type size hasn't changed > >>>> 1 data member change: > >>>> type of 'const rte_cryptodev_capabilities* > >>>> rte_cryptodev_info::capabilities' changed: > >>>> in pointed to type 'const rte_cryptodev_capabilities': > >>>> in unqualified underlying type 'struct > >>>> rte_cryptodev_capabilities' at rte_cryptodev.h:176:1: > >>>> type size hasn't changed > >>>> 1 data member change: > >>>> type of '__anonymous_union__ ' changed: > >>>> type size hasn't changed > >>>> 1 data member change: > >>>> type of 'rte_cryptodev_asymmetric_capability > >>>> __anonymous_union__::asym' changed: > >>>> type size hasn't changed > >>>> 1 data member change: > >>>> type of > >>>> 'rte_cryptodev_asymmetric_xform_capability > >>>> rte_cryptodev_asymmetric_capability::xform_capa' changed: > >>>> type size hasn't changed > >>>> 1 data member change: > >>>> type of 'rte_crypto_asym_xform_type > >>>> rte_cryptodev_asymmetric_xform_capability::xform_type' changed: > >>>> type size hasn't changed > >>>> 2 enumerator insertions: > >>>> > >>>> 'rte_crypto_asym_xform_type::RTE_CRYPTO_ASYM_XFORM_ECDSA' value '7' > >>>> > >>>> 'rte_crypto_asym_xform_type::RTE_CRYPTO_ASYM_XFORM_ECPM' value '8' > >>>> 1 enumerator change: > >>>> > >>>> 'rte_crypto_asym_xform_type::RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END' > >>>> from > >>>> value '7' to '9' at rte_crypto_asym.h:60:1 > >>>> > >>> > >>> I believe these enums will be used only in case of ASYM case which is experimental. > >> > >> Independent from being experiment and not, this shouldn't be a problem, I think > >> this is a false positive. > >> > >> The ABI break can happen when a struct has been shared between the application > >> and the library (DPDK) and the layout of that memory know differently by > >> application and the library. > >> > >> Here in all cases, there is no layout/size change. > >> > >> As to the value changes of the enums, since application compiled with old DPDK, > >> it will know only up to '6', 7 and more means invalid to the application. So it > >> won't send these values also it should ignore these values from library. Only > >> consequence is old application won't able to use new features those new enums > >> provide but that is expected/normal. > > > > If library give higher value than expected by the application, > > if the application uses this value as array index, > > there can be an access out of bounds. > > First this concern is not an ABI break concern, but application should ignore > any value bigger than the MAX value it knows. > Otherwise this would mean we can't add any new enum or define to the project, > which is wrong I believe. > > > > > > >>>> [C]'function int > >>>> rte_cryptodev_get_aead_algo_enum(rte_crypto_aead_algorithm*, const > >>>> char*)' at rte_cryptodev.c:239:1 has some indirect sub-type changes: > >>>> parameter 1 of type 'rte_crypto_aead_algorithm*' has sub-type changes: > >>>> in pointed to type 'enum rte_crypto_aead_algorithm' at > >>>> rte_crypto_sym.h:346:1: > >>>> type size hasn't changed > >>>> 1 enumerator insertion: > >>>> 'rte_crypto_aead_algorithm::RTE_CRYPTO_AEAD_CHACHA20_POLY1305' > >>>> value '3' > >>>> 1 enumerator change: > >>>> 'rte_crypto_aead_algorithm::RTE_CRYPTO_AEAD_LIST_END' from > >>>> value '3' to '4' at rte_crypto_sym.h:346:1 > >> > >> Same as above, no layout change. > >> > >>>> > >>>> > >>>> [C]'const char* rte_crypto_aead_algorithm_strings[1]' was changed at > >>>> rte_crypto_sym.h:358:1: > >>>> size of symbol (in bytes) changed from 24 to 32 > >>>> > >> > >> The shared memory size changes, but this is global variable in the library, and > >> the values application can request 'RTE_CRYPTO_AEAD_AES_CCM' & > >> 'RTE_CRYPTO_AEAD_AES_GCM' is already there, so there is no backward > >> compatibility issue here. > > > > For this one, I don't know what is the breakage. Reading through this report, I am also don't see why it is considered as ABI breakage. Yes, size of rte_crypto_aead_algorithm_strings[] has changed, but this array is not public one. Also I don't see any place where we use RTE_CRYPTO_AEAD_LIST_END to define array size in our public API. At first glance it looks like false positive to me. Do I miss something obvious here? Konstantin > > > > > >>> +Fiona and Arek > >>> > >>> We may need to revert the chacha-poly patches. > >>> > >> > >> I don't see any ABI break in this case, can someone explain if I am missing > >> anything here? > > > > > > > > > >
> > > I believe these enums will be used only in case of ASYM case which is experimental. > > > > Independent from being experiment and not, this shouldn't be a problem, I think > > this is a false positive. > > > > The ABI break can happen when a struct has been shared between the application > > and the library (DPDK) and the layout of that memory know differently by > > application and the library. > > > > Here in all cases, there is no layout/size change. > > > > As to the value changes of the enums, since application compiled with old DPDK, > > it will know only up to '6', 7 and more means invalid to the application. So it > > won't send these values also it should ignore these values from library. Only > > consequence is old application won't able to use new features those new enums > > provide but that is expected/normal. > > If library give higher value than expected by the application, > if the application uses this value as array index, > there can be an access out of bounds. [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. But for the same issue with sym crypto below, I believe Ferruh's explanation makes sense and I don't see how there can be an API breakage. So if an application hasn't compiled against the new lib it will be still using the old value which will be within bounds. If it's picking up the higher new value from the lib it must have been compiled against the lib so shouldn't have problems. There are also no structs on the API which contain arrays using this for sizing, so I don't see an opportunity for an appl to have a mismatch in memory addresses. > > >> [C]'function int > > >> rte_cryptodev_get_aead_algo_enum(rte_crypto_aead_algorithm*, const > > >> char*)' at rte_cryptodev.c:239:1 has some indirect sub-type changes: > > >> parameter 1 of type 'rte_crypto_aead_algorithm*' has sub-type changes: > > >> in pointed to type 'enum rte_crypto_aead_algorithm' at > > >> rte_crypto_sym.h:346:1: > > >> type size hasn't changed > > >> 1 enumerator insertion: > > >> 'rte_crypto_aead_algorithm::RTE_CRYPTO_AEAD_CHACHA20_POLY1305' > > >> value '3' > > >> 1 enumerator change: > > >> 'rte_crypto_aead_algorithm::RTE_CRYPTO_AEAD_LIST_END' from > > >> value '3' to '4' at rte_crypto_sym.h:346:1 > > > > Same as above, no layout change. > > > > >> > > >> > > >> [C]'const char* rte_crypto_aead_algorithm_strings[1]' was changed at > > >> rte_crypto_sym.h:358:1: > > >> size of symbol (in bytes) changed from 24 to 32 > > >> > > > > The shared memory size changes, but this is global variable in the library, and > > the values application can request 'RTE_CRYPTO_AEAD_AES_CCM' & > > 'RTE_CRYPTO_AEAD_AES_GCM' is already there, so there is no backward > > compatibility issue here. > > For this one, I don't know what is the breakage. > > > > > +Fiona and Arek > > > > > > We may need to revert the chacha-poly patches. > > > > > > > I don't see any ABI break in this case, can someone explain if I am missing > > anything here? > > > >
On Thu, Jan 30, 2020 at 11:33 PM Thomas Monjalon <thomas@monjalon.net> wrote:
>
> 30/01/2020 17:00, David Marchand:
> > Enabling them requires a configuration that will trigger the ABI dumps
> > generation as part of the existing devtools/test-build.sh and
> > devtools/test-meson-builds.sh scripts.
> [...]
> > --- a/devtools/test-meson-builds.sh
> > +++ b/devtools/test-meson-builds.sh
> > if [ -f "$builddir/build.ninja" ] ; then
> > + # for existing environments, force debugoptimized so that ABI
> > + # checks can run
> > + $MESON configure --buildtype=debugoptimized $builddir
>
> This is forcing meson to re-run each time, even if the buildtype is
> already "debugoptimized".
> Please query meson configuration to avoid useless re-run:
>
> $MESON configure $builddir | awk '$1=="buildtype" {print $2}'
>
>
Good catch, will fix.
--
David Marchand
31/01/2020 15:16, Trahe, Fiona: > On 1/30/2020 8:18 PM, Thomas Monjalon wrote: > > 30/01/2020 17:09, Ferruh Yigit: > > > On 1/29/2020 8:13 PM, Akhil Goyal wrote: > > > > > > > > I believe these enums will be used only in case of ASYM case which is experimental. > > > > > > Independent from being experiment and not, this shouldn't be a problem, I think > > > this is a false positive. > > > > > > The ABI break can happen when a struct has been shared between the application > > > and the library (DPDK) and the layout of that memory know differently by > > > application and the library. > > > > > > Here in all cases, there is no layout/size change. > > > > > > As to the value changes of the enums, since application compiled with old DPDK, > > > it will know only up to '6', 7 and more means invalid to the application. So it > > > won't send these values also it should ignore these values from library. Only > > > consequence is old application won't able to use new features those new enums > > > provide but that is expected/normal. > > > > If library give higher value than expected by the application, > > if the application uses this value as array index, > > there can be an access out of bounds. > > [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. > But for the same issue with sym crypto below, I believe Ferruh's explanation makes > sense and I don't see how there can be an API breakage. > So if an application hasn't compiled against the new lib it will be still using the old value > which will be within bounds. If it's picking up the higher new value from the lib it must > have been compiled against the lib so shouldn't have problems. You say there is no ABI issue because the application will be re-compiled for the updated library. Indeed, compilation fixes compatibility issues. But this is not relevant for ABI compatibility. ABI compatibility means we can upgrade the library without recompiling the application and it must work. You think it is a false positive because you assume the application "picks" the new value. I think you miss the case where the new value is returned by a function in the upgraded library. > There are also no structs on the API which contain arrays using this > for sizing, so I don't see an opportunity for an appl to have a > mismatch in memory addresses. Let me demonstrate where the API may "use" the new value RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application. Once upon a time a DPDK application counting the number of devices supporting each AEAD algo (in order to find the best supported algo). It is done in an array indexed by algo id: int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; The application is compiled with DPDK 19.11, where RTE_CRYPTO_AEAD_LIST_END = 3. So the size of the application array aead_dev_count is 3. This binary is run with DPDK 20.02, where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. When calling rte_cryptodev_info_get() on a device QAT_GEN3, rte_cryptodev_info.capabilities.sym.aead.algo is set to RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). The application uses this value: ++ aead_dev_count[info.capabilities.sym.aead.algo]; The application is crashing because of out of bound access.
> 31/01/2020 15:16, Trahe, Fiona:
> > On 1/30/2020 8:18 PM, Thomas Monjalon wrote:
> > > 30/01/2020 17:09, Ferruh Yigit:
> > > > On 1/29/2020 8:13 PM, Akhil Goyal wrote:
> > > > >
> > > > > I believe these enums will be used only in case of ASYM case which is experimental.
> > > >
> > > > Independent from being experiment and not, this shouldn't be a problem, I think
> > > > this is a false positive.
> > > >
> > > > The ABI break can happen when a struct has been shared between the application
> > > > and the library (DPDK) and the layout of that memory know differently by
> > > > application and the library.
> > > >
> > > > Here in all cases, there is no layout/size change.
> > > >
> > > > As to the value changes of the enums, since application compiled with old DPDK,
> > > > it will know only up to '6', 7 and more means invalid to the application. So it
> > > > won't send these values also it should ignore these values from library. Only
> > > > consequence is old application won't able to use new features those new enums
> > > > provide but that is expected/normal.
> > >
> > > If library give higher value than expected by the application,
> > > if the application uses this value as array index,
> > > there can be an access out of bounds.
> >
> > [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem.
> > But for the same issue with sym crypto below, I believe Ferruh's explanation makes
> > sense and I don't see how there can be an API breakage.
> > So if an application hasn't compiled against the new lib it will be still using the old value
> > which will be within bounds. If it's picking up the higher new value from the lib it must
> > have been compiled against the lib so shouldn't have problems.
>
> You say there is no ABI issue because the application will be re-compiled
> for the updated library. Indeed, compilation fixes compatibility issues.
> But this is not relevant for ABI compatibility.
> ABI compatibility means we can upgrade the library without recompiling
> the application and it must work.
> You think it is a false positive because you assume the application
> "picks" the new value. I think you miss the case where the new value
> is returned by a function in the upgraded library.
>
> > There are also no structs on the API which contain arrays using this
> > for sizing, so I don't see an opportunity for an appl to have a
> > mismatch in memory addresses.
>
> Let me demonstrate where the API may "use" the new value
> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application.
>
> Once upon a time a DPDK application counting the number of devices
> supporting each AEAD algo (in order to find the best supported algo).
> It is done in an array indexed by algo id:
> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END];
> The application is compiled with DPDK 19.11,
> where RTE_CRYPTO_AEAD_LIST_END = 3.
> So the size of the application array aead_dev_count is 3.
> This binary is run with DPDK 20.02,
> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3.
> When calling rte_cryptodev_info_get() on a device QAT_GEN3,
> rte_cryptodev_info.capabilities.sym.aead.algo is set to
> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3).
> The application uses this value:
> ++ aead_dev_count[info.capabilities.sym.aead.algo];
> The application is crashing because of out of bound access.
I'd say this is an example of bad written app.
It probably should check that returned by library value doesn't
exceed its internal array size.
Konstantin
Here is the current state of the ABI checks. libabigail has some issues when mixing dump and so files compiled with clang [1], so for now, all checks are done on dumps only. libabigail 1.0-rc3 in Xenial reported issues that disappear with the version 1.2 in Bionic. To avoid getting warnings on internal types like [2], the checks now make use of the public headers part of a dpdk installation (patch 2 and 3 to prepare for this). Some internal rte_hash headers were installed by meson, so patch 1 fixes this. The most important point, abidiff complains on the rc1 cryptodev changes: - Chacha20-Poly1305 AEAD support, - ECPM and ECDSA support A suppression rule has been put on the internal type rte_cryptodev_ops. But other changes are an ABI breakage afaiu. I put suppression rules on them so that we can run the checks, but some action must be taken for 20.02 if my analysis is confirmed. Special thanks to Dodji the libabigail maintainer for helping on this topic. 1: https://sourceware.org/bugzilla/show_bug.cgi?id=25409 2: http://inbox.dpdk.org/dev/CAJFAV8yFKoDZROX9Mkyp7pDMvXw3e7mHwxjfrcjD5ZoFB2tZ8w@mail.gmail.com/ -- David Marchand Changelog since v3: - removed patch 3 based on Thomas feedback, - switched to fixed sources location for building ABI references, Changelog since v2: - incorporated offlist Thomas comments wrt to existing build envs (do not change --prefix, force builds with debug enabled) David Marchand (3): hash: fix meson headers packaging build: split build helper add ABI checks .ci/linux-build.sh | 24 ++++++++ .travis.yml | 20 +++++- MAINTAINERS | 3 + devtools/check-abi.sh | 59 ++++++++++++++++++ devtools/dpdk.abignore | 21 +++++++ devtools/gen-abi.sh | 26 ++++++++ devtools/test-build.sh | 52 ++++++++++++++-- devtools/test-meson-builds.sh | 96 ++++++++++++++++++++++++----- doc/guides/contributing/patches.rst | 15 +++++ lib/librte_hash/meson.build | 5 +- 10 files changed, 293 insertions(+), 28 deletions(-) create mode 100755 devtools/check-abi.sh create mode 100644 devtools/dpdk.abignore create mode 100755 devtools/gen-abi.sh -- 2.23.0
Those headers are internal and should not be distributed. Fixes: 5b9656b157d3 ("lib: build with meson") Cc: stable@dpdk.org Signed-off-by: David Marchand <david.marchand@redhat.com> Acked-by: Luca Boccassi <bluca@debian.org> --- lib/librte_hash/meson.build | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/lib/librte_hash/meson.build b/lib/librte_hash/meson.build index 5d02b3084..bce11ad9e 100644 --- a/lib/librte_hash/meson.build +++ b/lib/librte_hash/meson.build @@ -1,10 +1,7 @@ # SPDX-License-Identifier: BSD-3-Clause # Copyright(c) 2017 Intel Corporation -headers = files('rte_cmp_arm64.h', - 'rte_cmp_x86.h', - 'rte_crc_arm64.h', - 'rte_cuckoo_hash.h', +headers = files('rte_crc_arm64.h', 'rte_fbk_hash.h', 'rte_hash_crc.h', 'rte_hash.h', -- 2.23.0
No functional change intended, prepare for reusing this code. The config and compilation parts are separated in helpers. Unsetting CC is moved to the caller of the helper. Signed-off-by: David Marchand <david.marchand@redhat.com> Acked-by: Luca Boccassi <bluca@debian.org> --- Changelog since v2: - changed indent in config(), - removed useless shift in compile(), --- devtools/test-meson-builds.sh | 48 ++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/devtools/test-meson-builds.sh b/devtools/test-meson-builds.sh index 688567714..fb6c404e5 100755 --- a/devtools/test-meson-builds.sh +++ b/devtools/test-meson-builds.sh @@ -57,25 +57,27 @@ load_env () # <target compiler> . $srcdir/devtools/load-devel-config } -build () # <directory> <target compiler> <meson options> +config () # <dir> <builddir> <meson options> { - builddir=$builds_dir/$1 + dir=$1 shift - targetcc=$1 + builddir=$1 shift - # skip build if compiler not available - command -v ${CC##* } >/dev/null 2>&1 || return 0 - load_env $targetcc || return 0 - if [ ! -f "$builddir/build.ninja" ] ; then - options="--werror -Dexamples=all" - for option in $DPDK_MESON_OPTIONS ; do - options="$options -D$option" - done - options="$options $*" - echo "$MESON $options $srcdir $builddir" - $MESON $options $srcdir $builddir - unset CC + if [ -f "$builddir/build.ninja" ] ; then + return fi + options="--werror -Dexamples=all" + for option in $DPDK_MESON_OPTIONS ; do + options="$options -D$option" + done + options="$options $*" + echo "$MESON $options $dir $builddir" + $MESON $options $dir $builddir +} + +compile () # <builddir> +{ + builddir=$1 if [ -n "$TEST_MESON_BUILD_VERY_VERBOSE" ] ; then # for full output from ninja use "-v" echo "$ninja_cmd -v -C $builddir" @@ -90,6 +92,19 @@ build () # <directory> <target compiler> <meson options> fi } +build () # <directory> <target compiler> <meson options> +{ + targetdir=$1 + shift + targetcc=$1 + shift + # skip build if compiler not available + command -v ${CC##* } >/dev/null 2>&1 || return 0 + load_env $targetcc || return 0 + config $srcdir $builds_dir/$targetdir $* + compile $builds_dir/$targetdir +} + if [ "$1" = "-vv" ] ; then TEST_MESON_BUILD_VERY_VERBOSE=1 elif [ "$1" = "-v" ] ; then @@ -107,6 +122,7 @@ for c in gcc clang ; do for s in static shared ; do export CC="$CCACHE $c" build build-$c-$s $c --default-library=$s + unset CC done done @@ -125,11 +141,13 @@ c=aarch64-linux-gnu-gcc export CC="clang" build build-arm64-host-clang $c $use_shared \ --cross-file $srcdir/config/arm/arm64_armv8_linux_gcc +unset CC # all gcc/arm configurations for f in $srcdir/config/arm/arm64_[bdo]*gcc ; do export CC="$CCACHE gcc" build build-$(basename $f | tr '_' '-' | cut -d'-' -f-2) $c \ $use_shared --cross-file $f + unset CC done # Test installation of the x86-default target, to be used for checking -- 2.23.0
For normal developers, those checks are disabled. Enabling them requires a configuration that will trigger the ABI dumps generation as part of the existing devtools/test-build.sh and devtools/test-meson-builds.sh scripts. Those checks are enabled in the CI for the default meson options on x86 and aarch64 so that proposed patches are validated via our CI robot. A cache of the ABI is stored in travis jobs to avoid rebuilding too often. Checks can be informational only, by setting ABI_CHECKS_WARN_ONLY when breaking the ABI in a future release. Explicit suppression rules have been added on internal structures exposed to crypto drivers as the current ABI policy does not apply to them. This could be improved in the future by carefully splitting the headers content with application and driver "users" in mind. We currently have issues reported for librte_crypto recent changes for which suppression rules have been added too. Mellanox glue libraries are explicitly skipped as they are not part of the application ABI. Signed-off-by: David Marchand <david.marchand@redhat.com> Acked-by: Luca Boccassi <bluca@debian.org> --- Changelog since v3: - rebased following patch 3 removal, - added dpdk.abignore to MAINTAINERS, - avoided meson reconfiguration when unneeded, - switched to fixed sources location for building ABI references, Changelog since v2: - forced -g / buildtype=debugoptimised in the test scripts so that we can check ABI in existing environments, - little update on the documentation, Changelog since v1: - reworked the scripts so that the build test scripts clone and build the reference automatically. A developer only needs to set one variable to enable the checks, - meson builds are done with debug so that abidiff can inspect the structures, - abidiff checks only public types by looking at installed headers, - abidiff has some issue when comparing a dump with a .so built with clang so all diff are now done with dump files only, - suppression rules have been added to waive warnings on exposed internal types, - an abi breakage has been reported on changes in cryptodev. For now, suppression rules have been put in place to let the CI run, --- .ci/linux-build.sh | 24 ++++++++++++ .travis.yml | 20 +++++++++- MAINTAINERS | 3 ++ devtools/check-abi.sh | 59 +++++++++++++++++++++++++++++ devtools/dpdk.abignore | 21 ++++++++++ devtools/gen-abi.sh | 26 +++++++++++++ devtools/test-build.sh | 52 ++++++++++++++++++++++--- devtools/test-meson-builds.sh | 50 ++++++++++++++++++++++-- doc/guides/contributing/patches.rst | 15 ++++++++ 9 files changed, 260 insertions(+), 10 deletions(-) create mode 100755 devtools/check-abi.sh create mode 100644 devtools/dpdk.abignore create mode 100755 devtools/gen-abi.sh diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh index ccc3a7ccd..c7c3840fc 100755 --- a/.ci/linux-build.sh +++ b/.ci/linux-build.sh @@ -29,6 +29,7 @@ if [ "$BUILD_32BIT" = "1" ]; then fi OPTS="$OPTS --default-library=$DEF_LIB" +OPTS="$OPTS --buildtype=debugoptimized" meson build --werror -Dexamples=all $OPTS ninja -C build @@ -36,6 +37,29 @@ if [ "$AARCH64" != "1" ]; then devtools/test-null.sh fi +if [ "$ABI_CHECKS" = "1" ]; then + REF_GIT_REPO=${REF_GIT_REPO:-https://dpdk.org/git/dpdk} + REF_GIT_TAG=${REF_GIT_TAG:-v19.11} + + if [ "$(cat reference/VERSION 2>/dev/null)" != "$REF_GIT_TAG" ]; then + rm -rf reference + fi + + if [ ! -d reference ]; then + refsrcdir=$(readlink -f $(pwd)/../dpdk-$REF_GIT_TAG) + git clone --single-branch -b $REF_GIT_TAG $REF_GIT_REPO $refsrcdir + meson --werror $OPTS $refsrcdir $refsrcdir/build + ninja -C $refsrcdir/build + DESTDIR=$(pwd)/reference ninja -C $refsrcdir/build install + devtools/gen-abi.sh reference + echo $REF_GIT_TAG > reference/VERSION + fi + + DESTDIR=$(pwd)/install ninja -C build install + devtools/gen-abi.sh install + devtools/check-abi.sh reference install ${ABI_CHECKS_WARN_ONLY:-} +fi + if [ "$RUN_TESTS" = "1" ]; then sudo meson test -C build --suite fast-tests -t 3 fi diff --git a/.travis.yml b/.travis.yml index 8162f1c05..22539d823 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,8 @@ language: c -cache: ccache +cache: + ccache: true + directories: + - reference compiler: - gcc - clang @@ -21,7 +24,7 @@ aarch64_packages: &aarch64_packages extra_packages: &extra_packages - *required_packages - - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4] + - [libbsd-dev, libpcap-dev, libcrypto++-dev, libjansson4, abigail-tools] build_32b_packages: &build_32b_packages - *required_packages @@ -151,5 +154,18 @@ matrix: packages: - *required_packages - *doc_packages + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1 + compiler: gcc + addons: + apt: + packages: + - *extra_packages + - env: DEF_LIB="shared" EXTRA_PACKAGES=1 ABI_CHECKS=1 + arch: arm64 + compiler: gcc + addons: + apt: + packages: + - *extra_packages script: ./.ci/${TRAVIS_OS_NAME}-build.sh diff --git a/MAINTAINERS b/MAINTAINERS index 94bccae6d..db4b8c5b6 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -144,8 +144,11 @@ M: Neil Horman <nhorman@tuxdriver.com> F: lib/librte_eal/common/include/rte_compat.h F: lib/librte_eal/common/include/rte_function_versioning.h F: doc/guides/rel_notes/deprecation.rst +F: devtools/check-abi.sh F: devtools/check-abi-version.sh F: devtools/check-symbol-change.sh +F: devtools/dpdk.abignore +F: devtools/gen-abi.sh F: devtools/update-abi.sh F: devtools/update_version_map_abi.py F: devtools/validate-abi.sh diff --git a/devtools/check-abi.sh b/devtools/check-abi.sh new file mode 100755 index 000000000..5872499ec --- /dev/null +++ b/devtools/check-abi.sh @@ -0,0 +1,59 @@ +#!/bin/sh -e +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2019 Red Hat, Inc. + +if [ $# != 2 ] && [ $# != 3 ]; then + echo "Usage: $0 refdir newdir [warnonly]" + exit 1 +fi + +refdir=$1 +newdir=$2 +warnonly=${3:-} +ABIDIFF_OPTIONS="--suppr $(dirname $0)/dpdk.abignore --no-added-syms" + +if [ ! -d $refdir ]; then + echo "Error: reference directory '$refdir' does not exist." + exit 1 +fi +incdir=$(find $refdir -type d -a -name include) +if [ -z "$incdir" ] || [ ! -e "$incdir" ]; then + echo "WARNING: could not identify a include directory for $refdir, expect false positives..." +else + ABIDIFF_OPTIONS="$ABIDIFF_OPTIONS --headers-dir1 $incdir" +fi + +if [ ! -d $newdir ]; then + echo "Error: directory to check '$newdir' does not exist." + exit 1 +fi +incdir2=$(find $newdir -type d -a -name include) +if [ -z "$incdir2" ] || [ ! -e "$incdir2" ]; then + echo "WARNING: could not identify a include directory for $newdir, expect false positives..." +else + ABIDIFF_OPTIONS="$ABIDIFF_OPTIONS --headers-dir2 $incdir2" +fi + +error= +for dump in $(find $refdir -name "*.dump"); do + name=$(basename $dump) + # skip glue drivers, example librte_pmd_mlx5_glue.dump + # We can't rely on a suppression rule for now: + # https://sourceware.org/bugzilla/show_bug.cgi?id=25480 + if [ "$name" != "${name%%_glue.dump}" ]; then + echo "Skipping ${dump}..." + continue + fi + dump2=$(find $newdir -name $name) + if [ -z "$dump2" ] || [ ! -e "$dump2" ]; then + echo "Error: can't find $name in $newdir" + error=1 + continue + fi + if ! abidiff $ABIDIFF_OPTIONS $dump $dump2; then + echo "Error: ABI issue reported for 'abidiff $ABIDIFF_OPTIONS $dump $dump2'" + error=1 + fi +done + +[ -z "$error" ] || [ -n "$warnonly" ] diff --git a/devtools/dpdk.abignore b/devtools/dpdk.abignore new file mode 100644 index 000000000..f2903612c --- /dev/null +++ b/devtools/dpdk.abignore @@ -0,0 +1,21 @@ +[suppress_function] + symbol_version = EXPERIMENTAL +[suppress_variable] + symbol_version = EXPERIMENTAL + +; Explicit ignore for driver-only ABI +[suppress_type] + name = rte_cryptodev_ops +; Ignore this enum update as it is part of an experimental API +[suppress_type] + type_kind = enum + name = rte_crypto_asym_xform_type + changed_enumerators = RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END + +; FIXME +[suppress_type] + type_kind = enum + name = rte_crypto_aead_algorithm + changed_enumerators = RTE_CRYPTO_AEAD_LIST_END +[suppress_variable] + name = rte_crypto_aead_algorithm_strings diff --git a/devtools/gen-abi.sh b/devtools/gen-abi.sh new file mode 100755 index 000000000..c44b0e228 --- /dev/null +++ b/devtools/gen-abi.sh @@ -0,0 +1,26 @@ +#!/bin/sh -e +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (c) 2019 Red Hat, Inc. + +if [ $# != 1 ]; then + echo "Usage: $0 installdir" + exit 1 +fi + +installdir=$1 +if [ ! -d $installdir ]; then + echo "Error: install directory '$installdir' does not exist." + exit 1 +fi + +dumpdir=$installdir/dump +rm -rf $dumpdir +mkdir -p $dumpdir +for f in $(find $installdir -name "*.so.*"); do + if test -L $f; then + continue + fi + + libname=$(basename $f) + abidw --out-file $dumpdir/${libname%.so*}.dump $f +done diff --git a/devtools/test-build.sh b/devtools/test-build.sh index 52305fbb8..2f55e9147 100755 --- a/devtools/test-build.sh +++ b/devtools/test-build.sh @@ -6,6 +6,8 @@ default_path=$PATH # Load config options: # - ARMV8_CRYPTO_LIB_PATH +# - DPDK_ABI_REF_DIR +# - DPDK_ABI_REF_VERSION # - DPDK_BUILD_TEST_CONFIGS (defconfig1+option1+option2 defconfig2) # - DPDK_BUILD_TEST_DIR # - DPDK_DEP_ARCHIVE @@ -30,7 +32,8 @@ default_path=$PATH # - LIBSSO_SNOW3G_PATH # - LIBSSO_KASUMI_PATH # - LIBSSO_ZUC_PATH -. $(dirname $(readlink -f $0))/load-devel-config +devtools_dir=$(dirname $(readlink -f $0)) +. $devtools_dir/load-devel-config print_usage () { echo "usage: $(basename $0) [-h] [-jX] [-s] [config1 [config2] ...]]" @@ -67,7 +70,8 @@ J=$DPDK_MAKE_JOBS builds_dir=${DPDK_BUILD_TEST_DIR:-.} short=false unset verbose -maxerr=-Wfatal-errors +# for ABI checks, we need debuginfo +test_cflags="-Wfatal-errors -g" while getopts hj:sv ARG ; do case $ARG in j ) J=$OPTARG ;; @@ -97,7 +101,7 @@ trap "signal=INT ; trap - INT ; kill -INT $$" INT # notify result on exit trap on_exit EXIT -cd $(dirname $(readlink -f $0))/.. +cd $devtools_dir/.. reset_env () { @@ -233,14 +237,14 @@ for conf in $configs ; do # reload config with DPDK_TARGET set DPDK_TARGET=$target reset_env - . $(dirname $(readlink -f $0))/load-devel-config + . $devtools_dir/load-devel-config options=$(echo $conf | sed 's,[^~+]*,,') dir=$builds_dir/$conf config $dir $target $options echo "================== Build $conf" - ${MAKE} -j$J EXTRA_CFLAGS="$maxerr $DPDK_DEP_CFLAGS" \ + ${MAKE} -j$J EXTRA_CFLAGS="$test_cflags $DPDK_DEP_CFLAGS" \ EXTRA_LDFLAGS="$DPDK_DEP_LDFLAGS" $verbose O=$dir ! $short || break export RTE_TARGET=$target @@ -253,6 +257,44 @@ for conf in $configs ; do EXTRA_LDFLAGS="$DPDK_DEP_LDFLAGS" $verbose \ O=$(readlink -f $dir)/examples unset RTE_TARGET + if [ -n "$DPDK_ABI_REF_VERSION" ]; then + abirefdir=${DPDK_ABI_REF_DIR:-reference}/$DPDK_ABI_REF_VERSION + if [ ! -d $abirefdir/$conf ]; then + # clone current sources + if [ ! -d $abirefdir/src ]; then + git clone --local --no-hardlinks \ + --single-branch \ + -b $DPDK_ABI_REF_VERSION \ + $(pwd) $abirefdir/src + fi + + cd $abirefdir/src + + rm -rf $abirefdir/build + config $abirefdir/build $target $options + + echo -n "================== Build $conf " + echo "($DPDK_ABI_REF_VERSION)" + ${MAKE} -j$J \ + EXTRA_CFLAGS="$test_cflags $DPDK_DEP_CFLAGS" \ + EXTRA_LDFLAGS="$DPDK_DEP_LDFLAGS" $verbose \ + O=$abirefdir/build + ! $short || break + export RTE_TARGET=$target + ${MAKE} install O=$abirefdir/build \ + DESTDIR=$abirefdir/$conf \ + prefix= + unset RTE_TARGET + $devtools_dir/gen-abi.sh $abirefdir/$conf + + # back to current workdir + cd $devtools_dir/.. + fi + + echo "================== Check ABI $conf" + $devtools_dir/gen-abi.sh $dir/install + $devtools_dir/check-abi.sh $abirefdir/$conf $dir/install + fi echo "################## $conf done." unset dir done diff --git a/devtools/test-meson-builds.sh b/devtools/test-meson-builds.sh index fb6c404e5..c2d33b3b9 100755 --- a/devtools/test-meson-builds.sh +++ b/devtools/test-meson-builds.sh @@ -64,9 +64,18 @@ config () # <dir> <builddir> <meson options> builddir=$1 shift if [ -f "$builddir/build.ninja" ] ; then + # for existing environments, switch to debugoptimized if unset + # so that ABI checks can run + if ! $MESON configure $builddir | + awk '$1=="buildtype" {print $2}' | + grep -qw debugoptimized; then + $MESON configure --buildtype=debugoptimized $builddir + fi return fi - options="--werror -Dexamples=all" + options= + options="$options --werror -Dexamples=all" + options="$options --buildtype=debugoptimized" for option in $DPDK_MESON_OPTIONS ; do options="$options -D$option" done @@ -92,6 +101,13 @@ compile () # <builddir> fi } +install_target () # <builddir> <installdir> +{ + rm -rf $2 + echo "DESTDIR=$2 $ninja_cmd -C $1 install" + DESTDIR=$2 $ninja_cmd -C $1 install +} + build () # <directory> <target compiler> <meson options> { targetdir=$1 @@ -103,6 +119,31 @@ build () # <directory> <target compiler> <meson options> load_env $targetcc || return 0 config $srcdir $builds_dir/$targetdir $* compile $builds_dir/$targetdir + if [ -n "$DPDK_ABI_REF_VERSION" ]; then + abirefdir=${DPDK_ABI_REF_DIR:-reference}/$DPDK_ABI_REF_VERSION + if [ ! -d $abirefdir/$targetdir ]; then + # clone current sources + if [ ! -d $abirefdir/src ]; then + git clone --local --no-hardlinks \ + --single-branch \ + -b $DPDK_ABI_REF_VERSION \ + $srcdir $abirefdir/src + fi + + rm -rf $abirefdir/build + config $abirefdir/src $abirefdir/build $* + compile $abirefdir/build + install_target $abirefdir/build $abirefdir/$targetdir + $srcdir/devtools/gen-abi.sh $abirefdir/$targetdir + fi + + install_target $builds_dir/$targetdir \ + $(readlink -f $builds_dir/$targetdir/install) + $srcdir/devtools/gen-abi.sh \ + $(readlink -f $builds_dir/$targetdir/install) + $srcdir/devtools/check-abi.sh $abirefdir/$targetdir \ + $(readlink -f $builds_dir/$targetdir/install) + fi } if [ "$1" = "-vv" ] ; then @@ -153,8 +194,11 @@ done # Test installation of the x86-default target, to be used for checking # the sample apps build using the pkg-config file for cflags and libs build_path=$(readlink -f $builds_dir/build-x86-default) -export DESTDIR=$build_path/install-root -$ninja_cmd -C $build_path install +export DESTDIR=$build_path/install +# No need to reinstall if ABI checks are enabled +if [ -z "$DPDK_ABI_REF_VERSION" ]; then + install_target $build_path $DESTDIR +fi load_env cc pc_file=$(find $DESTDIR -name libdpdk.pc) diff --git a/doc/guides/contributing/patches.rst b/doc/guides/contributing/patches.rst index 0686450e4..59442824a 100644 --- a/doc/guides/contributing/patches.rst +++ b/doc/guides/contributing/patches.rst @@ -513,6 +513,21 @@ in a single subfolder called "__builds" created in the current directory. Setting ``DPDK_BUILD_TEST_DIR`` to an absolute directory path e.g. ``/tmp`` is also supported. +Checking ABI compatibility +-------------------------- + +By default, ABI compatibility checks are disabled. + +To enable them, a reference version must be selected via the environment +variable ``DPDK_ABI_REF_VERSION``. + +The ``devtools/test-build.sh`` and ``devtools/test-meson-builds.sh`` scripts +then build this reference version in a temporary directory and store the +results in a subfolder of the current working directory. +The environment variable ``DPDK_ABI_REF_DIR`` can be set so that the results go +to a different location. + + Sending Patches --------------- -- 2.23.0
On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote:
>
>> 31/01/2020 15:16, Trahe, Fiona:
>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote:
>>>> 30/01/2020 17:09, Ferruh Yigit:
>>>>> On 1/29/2020 8:13 PM, Akhil Goyal wrote:
>>>>>>
>>>>>> I believe these enums will be used only in case of ASYM case which is experimental.
>>>>>
>>>>> Independent from being experiment and not, this shouldn't be a problem, I think
>>>>> this is a false positive.
>>>>>
>>>>> The ABI break can happen when a struct has been shared between the application
>>>>> and the library (DPDK) and the layout of that memory know differently by
>>>>> application and the library.
>>>>>
>>>>> Here in all cases, there is no layout/size change.
>>>>>
>>>>> As to the value changes of the enums, since application compiled with old DPDK,
>>>>> it will know only up to '6', 7 and more means invalid to the application. So it
>>>>> won't send these values also it should ignore these values from library. Only
>>>>> consequence is old application won't able to use new features those new enums
>>>>> provide but that is expected/normal.
>>>>
>>>> If library give higher value than expected by the application,
>>>> if the application uses this value as array index,
>>>> there can be an access out of bounds.
>>>
>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem.
>>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes
>>> sense and I don't see how there can be an API breakage.
>>> So if an application hasn't compiled against the new lib it will be still using the old value
>>> which will be within bounds. If it's picking up the higher new value from the lib it must
>>> have been compiled against the lib so shouldn't have problems.
>>
>> You say there is no ABI issue because the application will be re-compiled
>> for the updated library. Indeed, compilation fixes compatibility issues.
>> But this is not relevant for ABI compatibility.
>> ABI compatibility means we can upgrade the library without recompiling
>> the application and it must work.
>> You think it is a false positive because you assume the application
>> "picks" the new value. I think you miss the case where the new value
>> is returned by a function in the upgraded library.
>>
>>> There are also no structs on the API which contain arrays using this
>>> for sizing, so I don't see an opportunity for an appl to have a
>>> mismatch in memory addresses.
>>
>> Let me demonstrate where the API may "use" the new value
>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application.
>>
>> Once upon a time a DPDK application counting the number of devices
>> supporting each AEAD algo (in order to find the best supported algo).
>> It is done in an array indexed by algo id:
>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END];
>> The application is compiled with DPDK 19.11,
>> where RTE_CRYPTO_AEAD_LIST_END = 3.
>> So the size of the application array aead_dev_count is 3.
>> This binary is run with DPDK 20.02,
>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3.
>> When calling rte_cryptodev_info_get() on a device QAT_GEN3,
>> rte_cryptodev_info.capabilities.sym.aead.algo is set to
>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3).
>> The application uses this value:
>> ++ aead_dev_count[info.capabilities.sym.aead.algo];
>> The application is crashing because of out of bound access.
>
> I'd say this is an example of bad written app.
> It probably should check that returned by library value doesn't
> exceed its internal array size.
+1
Application should ignore values >= MAX.
Do you suggest we don't extend any enum or define between ABI breakage releases
to be sure bad written applications not affected?
On Mon, Feb 03, 2020 at 09:30:06AM +0000, Ferruh Yigit wrote: > On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: > > > >> 31/01/2020 15:16, Trahe, Fiona: > >>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: > >>>> 30/01/2020 17:09, Ferruh Yigit: > >>>>> On 1/29/2020 8:13 PM, Akhil Goyal wrote: > >>>>>> > >>>>>> I believe these enums will be used only in case of ASYM case which is experimental. > >>>>> > >>>>> Independent from being experiment and not, this shouldn't be a problem, I think > >>>>> this is a false positive. > >>>>> > >>>>> The ABI break can happen when a struct has been shared between the application > >>>>> and the library (DPDK) and the layout of that memory know differently by > >>>>> application and the library. > >>>>> > >>>>> Here in all cases, there is no layout/size change. > >>>>> > >>>>> As to the value changes of the enums, since application compiled with old DPDK, > >>>>> it will know only up to '6', 7 and more means invalid to the application. So it > >>>>> won't send these values also it should ignore these values from library. Only > >>>>> consequence is old application won't able to use new features those new enums > >>>>> provide but that is expected/normal. > >>>> > >>>> If library give higher value than expected by the application, > >>>> if the application uses this value as array index, > >>>> there can be an access out of bounds. > >>> > >>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. > >>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes > >>> sense and I don't see how there can be an API breakage. > >>> So if an application hasn't compiled against the new lib it will be still using the old value > >>> which will be within bounds. If it's picking up the higher new value from the lib it must > >>> have been compiled against the lib so shouldn't have problems. > >> > >> You say there is no ABI issue because the application will be re-compiled > >> for the updated library. Indeed, compilation fixes compatibility issues. > >> But this is not relevant for ABI compatibility. > >> ABI compatibility means we can upgrade the library without recompiling > >> the application and it must work. > >> You think it is a false positive because you assume the application > >> "picks" the new value. I think you miss the case where the new value > >> is returned by a function in the upgraded library. > >> > >>> There are also no structs on the API which contain arrays using this > >>> for sizing, so I don't see an opportunity for an appl to have a > >>> mismatch in memory addresses. > >> > >> Let me demonstrate where the API may "use" the new value > >> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application. > >> > >> Once upon a time a DPDK application counting the number of devices > >> supporting each AEAD algo (in order to find the best supported algo). > >> It is done in an array indexed by algo id: > >> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; > >> The application is compiled with DPDK 19.11, > >> where RTE_CRYPTO_AEAD_LIST_END = 3. > >> So the size of the application array aead_dev_count is 3. > >> This binary is run with DPDK 20.02, > >> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. > >> When calling rte_cryptodev_info_get() on a device QAT_GEN3, > >> rte_cryptodev_info.capabilities.sym.aead.algo is set to > >> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). > >> The application uses this value: > >> ++ aead_dev_count[info.capabilities.sym.aead.algo]; > >> The application is crashing because of out of bound access. > > > > I'd say this is an example of bad written app. > > It probably should check that returned by library value doesn't > > exceed its internal array size. > > +1 > > Application should ignore values >= MAX. > The example is still somewhat valid in it general principle though. While extending an ennumeration may be flagged by libabigail as an ABI breakage, its not necessecarily a false positive. By extending the ennumeration, all the previous entries in an array defined by said ennumeration remain constant in their offsets, so you can 'get away with such a change' in terms of preserving backwards compatibility in the above example, but you cannot, for example, shuffle the values in the ennumeration, as doing so would cause a functional breakage (i.e. requesting an instance of RTE_CRYPTO_AEAD_CHACHA20_POLY1305 might instead give you an instance of RTE_CRYPTO_AEAD_AES_GCM. These sorts of changes are the type that we could collectively waive in terms of ABI checking, as they should be ok, but the errors from libabigail should be taken as an indicator that this API could be rewritten (for example by removing the abi entirely, and adding an API call that returns an array of instance name and ids), so that changes of the above sort arent required. > Do you suggest we don't extend any enum or define between ABI breakage releases > to be sure bad written applications not affected? > As noted above, we could waive such corner cases, and probably be fine, but the error from the ABI check still serves a valid purpose in that its an indicator that your library API is ABI sensitive to code changes that re-architecture may address Neil
On 2/3/2020 11:50 AM, Neil Horman wrote: > On Mon, Feb 03, 2020 at 09:30:06AM +0000, Ferruh Yigit wrote: >> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: >>> >>>> 31/01/2020 15:16, Trahe, Fiona: >>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: >>>>>> 30/01/2020 17:09, Ferruh Yigit: >>>>>>> On 1/29/2020 8:13 PM, Akhil Goyal wrote: >>>>>>>> >>>>>>>> I believe these enums will be used only in case of ASYM case which is experimental. >>>>>>> >>>>>>> Independent from being experiment and not, this shouldn't be a problem, I think >>>>>>> this is a false positive. >>>>>>> >>>>>>> The ABI break can happen when a struct has been shared between the application >>>>>>> and the library (DPDK) and the layout of that memory know differently by >>>>>>> application and the library. >>>>>>> >>>>>>> Here in all cases, there is no layout/size change. >>>>>>> >>>>>>> As to the value changes of the enums, since application compiled with old DPDK, >>>>>>> it will know only up to '6', 7 and more means invalid to the application. So it >>>>>>> won't send these values also it should ignore these values from library. Only >>>>>>> consequence is old application won't able to use new features those new enums >>>>>>> provide but that is expected/normal. >>>>>> >>>>>> If library give higher value than expected by the application, >>>>>> if the application uses this value as array index, >>>>>> there can be an access out of bounds. >>>>> >>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. >>>>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes >>>>> sense and I don't see how there can be an API breakage. >>>>> So if an application hasn't compiled against the new lib it will be still using the old value >>>>> which will be within bounds. If it's picking up the higher new value from the lib it must >>>>> have been compiled against the lib so shouldn't have problems. >>>> >>>> You say there is no ABI issue because the application will be re-compiled >>>> for the updated library. Indeed, compilation fixes compatibility issues. >>>> But this is not relevant for ABI compatibility. >>>> ABI compatibility means we can upgrade the library without recompiling >>>> the application and it must work. >>>> You think it is a false positive because you assume the application >>>> "picks" the new value. I think you miss the case where the new value >>>> is returned by a function in the upgraded library. >>>> >>>>> There are also no structs on the API which contain arrays using this >>>>> for sizing, so I don't see an opportunity for an appl to have a >>>>> mismatch in memory addresses. >>>> >>>> Let me demonstrate where the API may "use" the new value >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application. >>>> >>>> Once upon a time a DPDK application counting the number of devices >>>> supporting each AEAD algo (in order to find the best supported algo). >>>> It is done in an array indexed by algo id: >>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; >>>> The application is compiled with DPDK 19.11, >>>> where RTE_CRYPTO_AEAD_LIST_END = 3. >>>> So the size of the application array aead_dev_count is 3. >>>> This binary is run with DPDK 20.02, >>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. >>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3, >>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). >>>> The application uses this value: >>>> ++ aead_dev_count[info.capabilities.sym.aead.algo]; >>>> The application is crashing because of out of bound access. >>> >>> I'd say this is an example of bad written app. >>> It probably should check that returned by library value doesn't >>> exceed its internal array size. >> >> +1 >> >> Application should ignore values >= MAX. >> > The example is still somewhat valid in it general principle though. While > extending an ennumeration may be flagged by libabigail as an ABI breakage, its > not necessecarily a false positive. By extending the ennumeration, all the > previous entries in an array defined by said ennumeration remain constant in > their offsets, so you can 'get away with such a change' in terms of preserving > backwards compatibility in the above example, but you cannot, for example, > shuffle the values in the ennumeration, as doing so would cause a functional > breakage (i.e. requesting an instance of RTE_CRYPTO_AEAD_CHACHA20_POLY1305 might > instead give you an instance of RTE_CRYPTO_AEAD_AES_GCM. +1 the change/shuffle of the existing values are problematic, but we don't have it in this case. > > These sorts of changes are the type that we could collectively waive in terms of > ABI checking, as they should be ok, but the errors from libabigail should be > taken as an indicator that this API could be rewritten (for example by removing > the abi entirely, and adding an API call that returns an array of instance name > and ids), so that changes of the above sort arent required. We can spend more time on it, but I can't see for now how to escape returning enumaration as indication of type, and this looks legitimate sage as long as other side verifies the received value is valid in the type range. > > >> Do you suggest we don't extend any enum or define between ABI breakage releases >> to be sure bad written applications not affected? >> > As noted above, we could waive such corner cases, and probably be fine, but the > error from the ABI check still serves a valid purpose in that its an indicator > that your library API is ABI sensitive to code changes that re-architecture may > address > The concern is when there are cases we can waive, we can't directly rely on the tool and automate it. These indicators good for improving the code, but not good to use it as build time checker. Is there any way to reduce the failure only to definite ABI breakages?
Hello, Ferruh Yigit <ferruh.yigit@intel.com> a écrit: [...] > +1 the change/shuffle of the existing values are problematic, but we don't have > it in this case. Right. [...] > The concern is when there are cases we can waive, we can't directly rely on the > tool and automate it. These indicators good for improving the code, but not good > to use it as build time checker. Well, it depends. The tooling as it is today have the capability to automatically "waive" some classes of A{B,P}I change reports that you guys (the developers) deem harmless, in the context of your project. For instance, in the precise case of interest here, one could define a "suppression specification" to teach the ABI verifier that, for the enum rte_crypto_asym_xform_type, the only enumerator which numerical value is allowed to change is the one named RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END. The content of the suppression specification file would look like: [suppress_type] # So, in practise, this rule is to allow adding enumerators # only to the of the the rte_crypto_asym_xform_type enum, # right before the RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END # enumerator which is meant to always be the last enumerator. type_kind = enum name = rte_crypto_asym_xform_type changed_enumerators = RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END This way, you can hopefully reduce the surface of the changes you want to see reported, tailored in a way that is specific to your project. This should hopefully bring the system closer to a state that would allow you guys to having something that is automated enough to have it be triggered at build time. And if there is some sensibly needed tweaking that the libabigail tooling doesn't allow you guys to do right away, I'd be happy to hear about it and try to add the functionality to the framework for you guys. > Is there any way to reduce the failure only to definite ABI breakages? I hope my comment above somewhat answers this question of yours. If it does not, please tell me. Cheers, -- Dodji
On 2/3/2020 2:00 PM, Dodji Seketeli wrote: > Hello, > > Ferruh Yigit <ferruh.yigit@intel.com> a écrit: > > [...] > >> +1 the change/shuffle of the existing values are problematic, but we don't have >> it in this case. > > Right. > > [...] > >> The concern is when there are cases we can waive, we can't directly rely on the >> tool and automate it. These indicators good for improving the code, but not good >> to use it as build time checker. > > Well, it depends. The tooling as it is today have the capability to > automatically "waive" some classes of A{B,P}I change reports that you > guys (the developers) deem harmless, in the context of your project. > > For instance, in the precise case of interest here, one could define a > "suppression specification" to teach the ABI verifier that, for the enum > rte_crypto_asym_xform_type, the only enumerator which numerical value is > allowed to change is the one named RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END. > > The content of the suppression specification file would look like: > > [suppress_type] > # So, in practise, this rule is to allow adding enumerators > # only to the of the the rte_crypto_asym_xform_type enum, > # right before the RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END > # enumerator which is meant to always be the last enumerator. > type_kind = enum > name = rte_crypto_asym_xform_type > changed_enumerators = RTE_CRYPTO_ASYM_XFORM_TYPE_LIST_END > > This way, you can hopefully reduce the surface of the changes you want > to see reported, tailored in a way that is specific to your project. > This should hopefully bring the system closer to a state that would > allow you guys to having something that is automated enough to have it > be triggered at build time. Thanks, at least this provides a way to silence the warnings not an issue for us as we hit them. Is there a more global, don't warn on new enums kind of option? Although I assume this is not possible since _END or _MAX enum value will be changing and tool can't know its usage and will report the change. > > And if there is some sensibly needed tweaking that the libabigail > tooling doesn't allow you guys to do right away, I'd be happy to hear > about it and try to add the functionality to the framework for you guys. > >> Is there any way to reduce the failure only to definite ABI breakages? > > I hope my comment above somewhat answers this question of yours. If it > does not, please tell me. > > Cheers, >
> >
> > These sorts of changes are the type that we could collectively waive in terms of
> > ABI checking, as they should be ok, but the errors from libabigail should be
> > taken as an indicator that this API could be rewritten (for example by removing
> > the abi entirely, and adding an API call that returns an array of instance name
> > and ids), so that changes of the above sort arent required.
>
> We can spend more time on it, but I can't see for now how to escape returning
> enumaration as indication of type, and this looks legitimate sage as long as
> other side verifies the received value is valid in the type range.
[Fiona] Regarding re-work to make the original code more robust to ABI breakage
One option would be to remove LIST_END from the enum, but keep the enum and allow appending values to it.
Instead of LIST_END have a static var keeping track of the MAX_NUM_AEAD_ALGOS
and an API call rte_cryptodev_get_max_aead_algos() forcing an application to dynamically size any array to accommodate any new values.
The API is safer I think - but there are other pitfalls with this approach - the MAX can more easily get out-of-sync with the enum.
And the application still needs to safely handle values it doesn't recognise.
Anyone think this is a better way?
I still think the best solution is to suppress changes to the LIST_END element.
03/02/2020 10:30, Ferruh Yigit: > On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: > > 02/02/2020 14:05, Thomas Monjalon: > >> 31/01/2020 15:16, Trahe, Fiona: > >>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: > >>>> 30/01/2020 17:09, Ferruh Yigit: > >>>>> On 1/29/2020 8:13 PM, Akhil Goyal wrote: > >>>>>> > >>>>>> I believe these enums will be used only in case of ASYM case which is experimental. > >>>>> > >>>>> Independent from being experiment and not, this shouldn't be a problem, I think > >>>>> this is a false positive. > >>>>> > >>>>> The ABI break can happen when a struct has been shared between the application > >>>>> and the library (DPDK) and the layout of that memory know differently by > >>>>> application and the library. > >>>>> > >>>>> Here in all cases, there is no layout/size change. > >>>>> > >>>>> As to the value changes of the enums, since application compiled with old DPDK, > >>>>> it will know only up to '6', 7 and more means invalid to the application. So it > >>>>> won't send these values also it should ignore these values from library. Only > >>>>> consequence is old application won't able to use new features those new enums > >>>>> provide but that is expected/normal. > >>>> > >>>> If library give higher value than expected by the application, > >>>> if the application uses this value as array index, > >>>> there can be an access out of bounds. > >>> > >>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. > >>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes > >>> sense and I don't see how there can be an API breakage. > >>> So if an application hasn't compiled against the new lib it will be still using the old value > >>> which will be within bounds. If it's picking up the higher new value from the lib it must > >>> have been compiled against the lib so shouldn't have problems. > >> > >> You say there is no ABI issue because the application will be re-compiled > >> for the updated library. Indeed, compilation fixes compatibility issues. > >> But this is not relevant for ABI compatibility. > >> ABI compatibility means we can upgrade the library without recompiling > >> the application and it must work. > >> You think it is a false positive because you assume the application > >> "picks" the new value. I think you miss the case where the new value > >> is returned by a function in the upgraded library. > >> > >>> There are also no structs on the API which contain arrays using this > >>> for sizing, so I don't see an opportunity for an appl to have a > >>> mismatch in memory addresses. > >> > >> Let me demonstrate where the API may "use" the new value > >> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application. > >> > >> Once upon a time a DPDK application counting the number of devices > >> supporting each AEAD algo (in order to find the best supported algo). > >> It is done in an array indexed by algo id: > >> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; > >> The application is compiled with DPDK 19.11, > >> where RTE_CRYPTO_AEAD_LIST_END = 3. > >> So the size of the application array aead_dev_count is 3. > >> This binary is run with DPDK 20.02, > >> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. > >> When calling rte_cryptodev_info_get() on a device QAT_GEN3, > >> rte_cryptodev_info.capabilities.sym.aead.algo is set to > >> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). > >> The application uses this value: > >> ++ aead_dev_count[info.capabilities.sym.aead.algo]; > >> The application is crashing because of out of bound access. > > > > I'd say this is an example of bad written app. > > It probably should check that returned by library value doesn't > > exceed its internal array size. > > +1 > > Application should ignore values >= MAX. Of course, blaming the API user is a lot easier than looking at the API. Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood as the max value for the application. Value ranges are part of the ABI compatibility contract. It seems you expect the application developer to be aware that DPDK could return a higher value, so the application should check every enum values after calling an API. CRAZY. When we decide to announce an ABI compatibility and do some marketing, everyone is OK. But when we need to really make our ABI compatible, I see little or no effort. DISAPPOINTING. > Do you suggest we don't extend any enum or define between ABI breakage releases > to be sure bad written applications not affected? I suggest we must consider not breaking any assumption made on the API. Here we are breaking the enum range because nothing mentions _LIST_END is not really the absolute end of the enum. The solution is to make the change below in 20.02 + backport in 19.11.1: - _LIST_END + _LIST_END, /* an ABI-compatible version may increase this value */ + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */ }; Then *_LIST_END values could be ignored by libabigail with such a change. If such a patch is not done by tomorrow, I will have to revert Chacha-Poly commits before 20.02-rc2, because 1/ LIST_END, without any comment, means "size of range" 2/ we do not blame users for undocumented ABI changes 3/ we respect the ABI compatibility contract
03/02/2020 18:09, Thomas Monjalon: > 03/02/2020 10:30, Ferruh Yigit: > > On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: > > > 02/02/2020 14:05, Thomas Monjalon: > > >> 31/01/2020 15:16, Trahe, Fiona: > > >>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: > > >>>> If library give higher value than expected by the application, > > >>>> if the application uses this value as array index, > > >>>> there can be an access out of bounds. > > >>> > > >>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. > > >>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes > > >>> sense and I don't see how there can be an API breakage. > > >>> So if an application hasn't compiled against the new lib it will be still using the old value > > >>> which will be within bounds. If it's picking up the higher new value from the lib it must > > >>> have been compiled against the lib so shouldn't have problems. > > >> > > >> You say there is no ABI issue because the application will be re-compiled > > >> for the updated library. Indeed, compilation fixes compatibility issues. > > >> But this is not relevant for ABI compatibility. > > >> ABI compatibility means we can upgrade the library without recompiling > > >> the application and it must work. > > >> You think it is a false positive because you assume the application > > >> "picks" the new value. I think you miss the case where the new value > > >> is returned by a function in the upgraded library. > > >> > > >>> There are also no structs on the API which contain arrays using this > > >>> for sizing, so I don't see an opportunity for an appl to have a > > >>> mismatch in memory addresses. > > >> > > >> Let me demonstrate where the API may "use" the new value > > >> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application. > > >> > > >> Once upon a time a DPDK application counting the number of devices > > >> supporting each AEAD algo (in order to find the best supported algo). > > >> It is done in an array indexed by algo id: > > >> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; > > >> The application is compiled with DPDK 19.11, > > >> where RTE_CRYPTO_AEAD_LIST_END = 3. > > >> So the size of the application array aead_dev_count is 3. > > >> This binary is run with DPDK 20.02, > > >> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. > > >> When calling rte_cryptodev_info_get() on a device QAT_GEN3, > > >> rte_cryptodev_info.capabilities.sym.aead.algo is set to > > >> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). > > >> The application uses this value: > > >> ++ aead_dev_count[info.capabilities.sym.aead.algo]; > > >> The application is crashing because of out of bound access. > > > > > > I'd say this is an example of bad written app. > > > It probably should check that returned by library value doesn't > > > exceed its internal array size. > > > > +1 > > > > Application should ignore values >= MAX. > > Of course, blaming the API user is a lot easier than looking at the API. > Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood > as the max value for the application. > Value ranges are part of the ABI compatibility contract. > It seems you expect the application developer to be aware that > DPDK could return a higher value, so the application should > check every enum values after calling an API. CRAZY. > > When we decide to announce an ABI compatibility and do some marketing, > everyone is OK. But when we need to really make our ABI compatible, > I see little or no effort. DISAPPOINTING. > > > Do you suggest we don't extend any enum or define between ABI breakage releases > > to be sure bad written applications not affected? > > I suggest we must consider not breaking any assumption made on the API. > Here we are breaking the enum range because nothing mentions _LIST_END > is not really the absolute end of the enum. > The solution is to make the change below in 20.02 + backport in 19.11.1: Thinking twice, merging such change before 20.11 is breaking the ABI assumption based on the API 19.11.0. I ask the release maintainers (Luca, Kevin, David and me) and the ABI maintainers (Neil and Ray) to vote for a or b solution: a) add comment and LIST_MAX as below in 20.02 + 19.11.1 b) wait 20.11 and revert Chacha-Poly from 20.02 > - _LIST_END > + _LIST_END, /* an ABI-compatible version may increase this value */ > + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */ > }; > > Then *_LIST_END values could be ignored by libabigail with such a change. > > If such a patch is not done by tomorrow, I will have to revert > Chacha-Poly commits before 20.02-rc2, because > > 1/ LIST_END, without any comment, means "size of range" > 2/ we do not blame users for undocumented ABI changes > 3/ we respect the ABI compatibility contract
On 2/3/2020 5:09 PM, Thomas Monjalon wrote: > 03/02/2020 10:30, Ferruh Yigit: >> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: >>> 02/02/2020 14:05, Thomas Monjalon: >>>> 31/01/2020 15:16, Trahe, Fiona: >>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: >>>>>> 30/01/2020 17:09, Ferruh Yigit: >>>>>>> On 1/29/2020 8:13 PM, Akhil Goyal wrote: >>>>>>>> >>>>>>>> I believe these enums will be used only in case of ASYM case which is experimental. >>>>>>> >>>>>>> Independent from being experiment and not, this shouldn't be a problem, I think >>>>>>> this is a false positive. >>>>>>> >>>>>>> The ABI break can happen when a struct has been shared between the application >>>>>>> and the library (DPDK) and the layout of that memory know differently by >>>>>>> application and the library. >>>>>>> >>>>>>> Here in all cases, there is no layout/size change. >>>>>>> >>>>>>> As to the value changes of the enums, since application compiled with old DPDK, >>>>>>> it will know only up to '6', 7 and more means invalid to the application. So it >>>>>>> won't send these values also it should ignore these values from library. Only >>>>>>> consequence is old application won't able to use new features those new enums >>>>>>> provide but that is expected/normal. >>>>>> >>>>>> If library give higher value than expected by the application, >>>>>> if the application uses this value as array index, >>>>>> there can be an access out of bounds. >>>>> >>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. >>>>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes >>>>> sense and I don't see how there can be an API breakage. >>>>> So if an application hasn't compiled against the new lib it will be still using the old value >>>>> which will be within bounds. If it's picking up the higher new value from the lib it must >>>>> have been compiled against the lib so shouldn't have problems. >>>> >>>> You say there is no ABI issue because the application will be re-compiled >>>> for the updated library. Indeed, compilation fixes compatibility issues. >>>> But this is not relevant for ABI compatibility. >>>> ABI compatibility means we can upgrade the library without recompiling >>>> the application and it must work. >>>> You think it is a false positive because you assume the application >>>> "picks" the new value. I think you miss the case where the new value >>>> is returned by a function in the upgraded library. >>>> >>>>> There are also no structs on the API which contain arrays using this >>>>> for sizing, so I don't see an opportunity for an appl to have a >>>>> mismatch in memory addresses. >>>> >>>> Let me demonstrate where the API may "use" the new value >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application. >>>> >>>> Once upon a time a DPDK application counting the number of devices >>>> supporting each AEAD algo (in order to find the best supported algo). >>>> It is done in an array indexed by algo id: >>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; >>>> The application is compiled with DPDK 19.11, >>>> where RTE_CRYPTO_AEAD_LIST_END = 3. >>>> So the size of the application array aead_dev_count is 3. >>>> This binary is run with DPDK 20.02, >>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. >>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3, >>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). >>>> The application uses this value: >>>> ++ aead_dev_count[info.capabilities.sym.aead.algo]; >>>> The application is crashing because of out of bound access. >>> >>> I'd say this is an example of bad written app. >>> It probably should check that returned by library value doesn't >>> exceed its internal array size. >> >> +1 >> >> Application should ignore values >= MAX. > > Of course, blaming the API user is a lot easier than looking at the API. > Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood > as the max value for the application. > Value ranges are part of the ABI compatibility contract. > It seems you expect the application developer to be aware that > DPDK could return a higher value, so the application should > check every enum values after calling an API. CRAZY. > > When we decide to announce an ABI compatibility and do some marketing, > everyone is OK. But when we need to really make our ABI compatible, > I see little or no effort. DISAPPOINTING. This is not to blame the user or to do less work, this is more sane approach that library provides the _END/_MAX value and application uses it as valid range check. > >> Do you suggest we don't extend any enum or define between ABI breakage releases >> to be sure bad written applications not affected? > > I suggest we must consider not breaking any assumption made on the API. > Here we are breaking the enum range because nothing mentions _LIST_END > is not really the absolute end of the enum. > The solution is to make the change below in 20.02 + backport in 19.11.1: > > - _LIST_END > + _LIST_END, /* an ABI-compatible version may increase this value */ > + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */ > }; > What is the point of "_LIST_MAX" here? Application should know the "_LIST_END" of when it has been compiled for the valid range check. Next time it is compiled "_LIST_END" may be different value but same logic applies. When "_LIST_END" is missing, application can't protect itself, in that case library should send only the values application knows when it is compiled, this means either we can't extend our enum/defines until next ABI breakage, or we need to do ABI versioning to the functions that returns an enum each time enum value extended. I believe it is saner to provide _END/_MAX values to the application to use. And if required comment them to clarify the expected usage. But in above suggestion application can't use or rely on "_LIST_MAX", it doesn't mean anything to application. > Then *_LIST_END values could be ignored by libabigail with such a change. > > If such a patch is not done by tomorrow, I will have to revert > Chacha-Poly commits before 20.02-rc2, because > > 1/ LIST_END, without any comment, means "size of range" > 2/ we do not blame users for undocumented ABI changes > 3/ we respect the ABI compatibility contract > >
03/02/2020 18:40, Ferruh Yigit: > On 2/3/2020 5:09 PM, Thomas Monjalon wrote: > > 03/02/2020 10:30, Ferruh Yigit: > >> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: > >>> 02/02/2020 14:05, Thomas Monjalon: > >>>> 31/01/2020 15:16, Trahe, Fiona: > >>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: > >>>>>> 30/01/2020 17:09, Ferruh Yigit: > >>>>>>> On 1/29/2020 8:13 PM, Akhil Goyal wrote: > >>>>>>>> > >>>>>>>> I believe these enums will be used only in case of ASYM case which is experimental. > >>>>>>> > >>>>>>> Independent from being experiment and not, this shouldn't be a problem, I think > >>>>>>> this is a false positive. > >>>>>>> > >>>>>>> The ABI break can happen when a struct has been shared between the application > >>>>>>> and the library (DPDK) and the layout of that memory know differently by > >>>>>>> application and the library. > >>>>>>> > >>>>>>> Here in all cases, there is no layout/size change. > >>>>>>> > >>>>>>> As to the value changes of the enums, since application compiled with old DPDK, > >>>>>>> it will know only up to '6', 7 and more means invalid to the application. So it > >>>>>>> won't send these values also it should ignore these values from library. Only > >>>>>>> consequence is old application won't able to use new features those new enums > >>>>>>> provide but that is expected/normal. > >>>>>> > >>>>>> If library give higher value than expected by the application, > >>>>>> if the application uses this value as array index, > >>>>>> there can be an access out of bounds. > >>>>> > >>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. > >>>>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes > >>>>> sense and I don't see how there can be an API breakage. > >>>>> So if an application hasn't compiled against the new lib it will be still using the old value > >>>>> which will be within bounds. If it's picking up the higher new value from the lib it must > >>>>> have been compiled against the lib so shouldn't have problems. > >>>> > >>>> You say there is no ABI issue because the application will be re-compiled > >>>> for the updated library. Indeed, compilation fixes compatibility issues. > >>>> But this is not relevant for ABI compatibility. > >>>> ABI compatibility means we can upgrade the library without recompiling > >>>> the application and it must work. > >>>> You think it is a false positive because you assume the application > >>>> "picks" the new value. I think you miss the case where the new value > >>>> is returned by a function in the upgraded library. > >>>> > >>>>> There are also no structs on the API which contain arrays using this > >>>>> for sizing, so I don't see an opportunity for an appl to have a > >>>>> mismatch in memory addresses. > >>>> > >>>> Let me demonstrate where the API may "use" the new value > >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application. > >>>> > >>>> Once upon a time a DPDK application counting the number of devices > >>>> supporting each AEAD algo (in order to find the best supported algo). > >>>> It is done in an array indexed by algo id: > >>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; > >>>> The application is compiled with DPDK 19.11, > >>>> where RTE_CRYPTO_AEAD_LIST_END = 3. > >>>> So the size of the application array aead_dev_count is 3. > >>>> This binary is run with DPDK 20.02, > >>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. > >>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3, > >>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to > >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). > >>>> The application uses this value: > >>>> ++ aead_dev_count[info.capabilities.sym.aead.algo]; > >>>> The application is crashing because of out of bound access. > >>> > >>> I'd say this is an example of bad written app. > >>> It probably should check that returned by library value doesn't > >>> exceed its internal array size. > >> > >> +1 > >> > >> Application should ignore values >= MAX. > > > > Of course, blaming the API user is a lot easier than looking at the API. > > Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood > > as the max value for the application. > > Value ranges are part of the ABI compatibility contract. > > It seems you expect the application developer to be aware that > > DPDK could return a higher value, so the application should > > check every enum values after calling an API. CRAZY. > > > > When we decide to announce an ABI compatibility and do some marketing, > > everyone is OK. But when we need to really make our ABI compatible, > > I see little or no effort. DISAPPOINTING. > > This is not to blame the user or to do less work, this is more sane approach > that library provides the _END/_MAX value and application uses it as valid range > check. > > >> Do you suggest we don't extend any enum or define between ABI breakage releases > >> to be sure bad written applications not affected? > > > > I suggest we must consider not breaking any assumption made on the API. > > Here we are breaking the enum range because nothing mentions _LIST_END > > is not really the absolute end of the enum. > > The solution is to make the change below in 20.02 + backport in 19.11.1: > > > > - _LIST_END > > + _LIST_END, /* an ABI-compatible version may increase this value */ > > + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */ > > }; > > > > What is the point of "_LIST_MAX" here? _LIST_MAX is range of value that DPDK can return in the ABI contract. So the appplication can rely on the range 0.._LIST_MAX. > Application should know the "_LIST_END" of when it has been compiled for the > valid range check. Next time it is compiled "_LIST_END" may be different value > but same logic applies. No, ABI compatibility contract means you can compile your application with DPDK 19.11.0 and run it with DPDK 20.02. So _LIST_END comes from 19.11 and does not include ChachaPoly. > When "_LIST_END" is missing, application can't protect itself, in that case > library should send only the values application knows when it is compiled, this > means either we can't extend our enum/defines until next ABI breakage, or we > need to do ABI versioning to the functions that returns an enum each time enum > value extended. If we define _LIST_MAX as a bigger value than current _LIST_END, we have some room to add values in between. If (as of now) we don't have _LIST_MAX room, then yes we must version the functions returning the enum. In this case, the proper solution is to implement rte_cryptodev_info_get_v1911() so it filters out RTE_CRYPTO_AEAD_CHACHA20_POLY1305 capability. With this solution, an application compiled with DPDK 19.11 will keep seeing the same range as before, while a 20.02 application could see and use ChachaPoly. This is another proposal that I was expecting from the crypto team, instead of claiming there is no issue (and wasting precious time). > I believe it is saner to provide _END/_MAX values to the application to use. And > if required comment them to clarify the expected usage. > > But in above suggestion application can't use or rely on "_LIST_MAX", it doesn't > mean anything to application. I don't understand what you mean. I think you misunderstood what is ABI compat. > > Then *_LIST_END values could be ignored by libabigail with such a change. > > > > If such a patch is not done by tomorrow, I will have to revert > > Chacha-Poly commits before 20.02-rc2, because > > > > 1/ LIST_END, without any comment, means "size of range" > > 2/ we do not blame users for undocumented ABI changes > > 3/ we respect the ABI compatibility contract
On 03/02/2020 17:34, Thomas Monjalon wrote: > 03/02/2020 18:09, Thomas Monjalon: >> 03/02/2020 10:30, Ferruh Yigit: >>> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: >>>> 02/02/2020 14:05, Thomas Monjalon: >>>>> 31/01/2020 15:16, Trahe, Fiona: >>>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: >>>>>>> If library give higher value than expected by the application, >>>>>>> if the application uses this value as array index, >>>>>>> there can be an access out of bounds. >>>>>> >>>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. >>>>>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes >>>>>> sense and I don't see how there can be an API breakage. >>>>>> So if an application hasn't compiled against the new lib it will be still using the old value >>>>>> which will be within bounds. If it's picking up the higher new value from the lib it must >>>>>> have been compiled against the lib so shouldn't have problems. >>>>> >>>>> You say there is no ABI issue because the application will be re-compiled >>>>> for the updated library. Indeed, compilation fixes compatibility issues. >>>>> But this is not relevant for ABI compatibility. >>>>> ABI compatibility means we can upgrade the library without recompiling >>>>> the application and it must work. >>>>> You think it is a false positive because you assume the application >>>>> "picks" the new value. I think you miss the case where the new value >>>>> is returned by a function in the upgraded library. >>>>> >>>>>> There are also no structs on the API which contain arrays using this >>>>>> for sizing, so I don't see an opportunity for an appl to have a >>>>>> mismatch in memory addresses. >>>>> >>>>> Let me demonstrate where the API may "use" the new value >>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application. >>>>> >>>>> Once upon a time a DPDK application counting the number of devices >>>>> supporting each AEAD algo (in order to find the best supported algo). >>>>> It is done in an array indexed by algo id: >>>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; >>>>> The application is compiled with DPDK 19.11, >>>>> where RTE_CRYPTO_AEAD_LIST_END = 3. >>>>> So the size of the application array aead_dev_count is 3. >>>>> This binary is run with DPDK 20.02, >>>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. >>>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3, >>>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to >>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). >>>>> The application uses this value: >>>>> ++ aead_dev_count[info.capabilities.sym.aead.algo]; >>>>> The application is crashing because of out of bound access. >>>> >>>> I'd say this is an example of bad written app. >>>> It probably should check that returned by library value doesn't >>>> exceed its internal array size. >>> >>> +1 >>> >>> Application should ignore values >= MAX. >> >> Of course, blaming the API user is a lot easier than looking at the API. >> Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood >> as the max value for the application. >> Value ranges are part of the ABI compatibility contract. >> It seems you expect the application developer to be aware that >> DPDK could return a higher value, so the application should >> check every enum values after calling an API. CRAZY. >> >> When we decide to announce an ABI compatibility and do some marketing, >> everyone is OK. But when we need to really make our ABI compatible, >> I see little or no effort. DISAPPOINTING. >> >>> Do you suggest we don't extend any enum or define between ABI breakage releases >>> to be sure bad written applications not affected? >> >> I suggest we must consider not breaking any assumption made on the API. >> Here we are breaking the enum range because nothing mentions _LIST_END >> is not really the absolute end of the enum. >> The solution is to make the change below in 20.02 + backport in 19.11.1: > > Thinking twice, merging such change before 20.11 is breaking the > ABI assumption based on the API 19.11.0. > I ask the release maintainers (Luca, Kevin, David and me) and > the ABI maintainers (Neil and Ray) to vote for a or b solution: > a) add comment and LIST_MAX as below in 20.02 + 19.11.1 That would still be an ABI breakage though right. > b) wait 20.11 and revert Chacha-Poly from 20.02 Thanks for analysis above Fiona, Ferruh and all. That is a nasty one alright - there is no "good" answer here. I agree with Ferruh's sentiments overall, we should rethink this API for 20.11. Could do without an enumeration? There a c) though right. We could work around the issue by api versioning rte_cryptodev_info_get() and friends. So they only support/acknowledge the existence of Chacha-Poly for applications build against > 20.02. It would be painful I know. It would also mean that Chacha-Poly would only be available to those building against >= 20.02. > > >> - _LIST_END >> + _LIST_END, /* an ABI-compatible version may increase this value */ >> + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */ >> }; >> >> Then *_LIST_END values could be ignored by libabigail with such a change. >> >> If such a patch is not done by tomorrow, I will have to revert >> Chacha-Poly commits before 20.02-rc2, because >> >> 1/ LIST_END, without any comment, means "size of range" >> 2/ we do not blame users for undocumented ABI changes >> 3/ we respect the ABI compatibility contract
03/02/2020 19:55, Ray Kinsella: > On 03/02/2020 17:34, Thomas Monjalon wrote: > > 03/02/2020 18:09, Thomas Monjalon: > >> 03/02/2020 10:30, Ferruh Yigit: > >>> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: > >>>> 02/02/2020 14:05, Thomas Monjalon: > >>>>> 31/01/2020 15:16, Trahe, Fiona: > >>>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: > >>>>>>> If library give higher value than expected by the application, > >>>>>>> if the application uses this value as array index, > >>>>>>> there can be an access out of bounds. > >>>>>> > >>>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. > >>>>>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes > >>>>>> sense and I don't see how there can be an API breakage. > >>>>>> So if an application hasn't compiled against the new lib it will be still using the old value > >>>>>> which will be within bounds. If it's picking up the higher new value from the lib it must > >>>>>> have been compiled against the lib so shouldn't have problems. > >>>>> > >>>>> You say there is no ABI issue because the application will be re-compiled > >>>>> for the updated library. Indeed, compilation fixes compatibility issues. > >>>>> But this is not relevant for ABI compatibility. > >>>>> ABI compatibility means we can upgrade the library without recompiling > >>>>> the application and it must work. > >>>>> You think it is a false positive because you assume the application > >>>>> "picks" the new value. I think you miss the case where the new value > >>>>> is returned by a function in the upgraded library. > >>>>> > >>>>>> There are also no structs on the API which contain arrays using this > >>>>>> for sizing, so I don't see an opportunity for an appl to have a > >>>>>> mismatch in memory addresses. > >>>>> > >>>>> Let me demonstrate where the API may "use" the new value > >>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application. > >>>>> > >>>>> Once upon a time a DPDK application counting the number of devices > >>>>> supporting each AEAD algo (in order to find the best supported algo). > >>>>> It is done in an array indexed by algo id: > >>>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; > >>>>> The application is compiled with DPDK 19.11, > >>>>> where RTE_CRYPTO_AEAD_LIST_END = 3. > >>>>> So the size of the application array aead_dev_count is 3. > >>>>> This binary is run with DPDK 20.02, > >>>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. > >>>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3, > >>>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to > >>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). > >>>>> The application uses this value: > >>>>> ++ aead_dev_count[info.capabilities.sym.aead.algo]; > >>>>> The application is crashing because of out of bound access. > >>>> > >>>> I'd say this is an example of bad written app. > >>>> It probably should check that returned by library value doesn't > >>>> exceed its internal array size. > >>> > >>> +1 > >>> > >>> Application should ignore values >= MAX. > >> > >> Of course, blaming the API user is a lot easier than looking at the API. > >> Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood > >> as the max value for the application. > >> Value ranges are part of the ABI compatibility contract. > >> It seems you expect the application developer to be aware that > >> DPDK could return a higher value, so the application should > >> check every enum values after calling an API. CRAZY. > >> > >> When we decide to announce an ABI compatibility and do some marketing, > >> everyone is OK. But when we need to really make our ABI compatible, > >> I see little or no effort. DISAPPOINTING. > >> > >>> Do you suggest we don't extend any enum or define between ABI breakage releases > >>> to be sure bad written applications not affected? > >> > >> I suggest we must consider not breaking any assumption made on the API. > >> Here we are breaking the enum range because nothing mentions _LIST_END > >> is not really the absolute end of the enum. > >> The solution is to make the change below in 20.02 + backport in 19.11.1: > > > > Thinking twice, merging such change before 20.11 is breaking the > > ABI assumption based on the API 19.11.0. > > I ask the release maintainers (Luca, Kevin, David and me) and > > the ABI maintainers (Neil and Ray) to vote for a or b solution: > > a) add comment and LIST_MAX as below in 20.02 + 19.11.1 > > That would still be an ABI breakage though right. > > > b) wait 20.11 and revert Chacha-Poly from 20.02 > > Thanks for analysis above Fiona, Ferruh and all. > > That is a nasty one alright - there is no "good" answer here. > I agree with Ferruh's sentiments overall, we should rethink this API for 20.11. > Could do without an enumeration? > > There a c) though right. > We could work around the issue by api versioning rte_cryptodev_info_get() and friends. > So they only support/acknowledge the existence of Chacha-Poly for applications build against > 20.02. I agree there is a c) as I proposed in another email: http://mails.dpdk.org/archives/dev/2020-February/156919.html " In this case, the proper solution is to implement rte_cryptodev_info_get_v1911() so it filters out RTE_CRYPTO_AEAD_CHACHA20_POLY1305 capability. With this solution, an application compiled with DPDK 19.11 will keep seeing the same range as before, while a 20.02 application could see and use ChachaPoly. " > It would be painful I know. Not so painful in my opinion. Just need to call rte_cryptodev_info_get() from rte_cryptodev_info_get_v1911() and filter the value in the 19.11 range: [0..AES_GCM]. > It would also mean that Chacha-Poly would only be available to > those building against >= 20.02. Yes exactly. The addition of comments and LIST_MAX like below are still valid to avoid versioning after 20.11. > >> - _LIST_END > >> + _LIST_END, /* an ABI-compatible version may increase this value */ > >> + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */ > >> }; > >> > >> Then *_LIST_END values could be ignored by libabigail with such a change. In order to avoid ABI check complaining, the best is to completely remove LIST_END in DPDK 20.11. > >> If such a patch is not done by tomorrow, I will have to revert > >> Chacha-Poly commits before 20.02-rc2, because > >> > >> 1/ LIST_END, without any comment, means "size of range" > >> 2/ we do not blame users for undocumented ABI changes > >> 3/ we respect the ABI compatibility contract
On 2/3/2020 6:40 PM, Thomas Monjalon wrote: > 03/02/2020 18:40, Ferruh Yigit: >> On 2/3/2020 5:09 PM, Thomas Monjalon wrote: >>> 03/02/2020 10:30, Ferruh Yigit: >>>> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: >>>>> 02/02/2020 14:05, Thomas Monjalon: >>>>>> 31/01/2020 15:16, Trahe, Fiona: >>>>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: >>>>>>>> 30/01/2020 17:09, Ferruh Yigit: >>>>>>>>> On 1/29/2020 8:13 PM, Akhil Goyal wrote: >>>>>>>>>> >>>>>>>>>> I believe these enums will be used only in case of ASYM case which is experimental. >>>>>>>>> >>>>>>>>> Independent from being experiment and not, this shouldn't be a problem, I think >>>>>>>>> this is a false positive. >>>>>>>>> >>>>>>>>> The ABI break can happen when a struct has been shared between the application >>>>>>>>> and the library (DPDK) and the layout of that memory know differently by >>>>>>>>> application and the library. >>>>>>>>> >>>>>>>>> Here in all cases, there is no layout/size change. >>>>>>>>> >>>>>>>>> As to the value changes of the enums, since application compiled with old DPDK, >>>>>>>>> it will know only up to '6', 7 and more means invalid to the application. So it >>>>>>>>> won't send these values also it should ignore these values from library. Only >>>>>>>>> consequence is old application won't able to use new features those new enums >>>>>>>>> provide but that is expected/normal. >>>>>>>> >>>>>>>> If library give higher value than expected by the application, >>>>>>>> if the application uses this value as array index, >>>>>>>> there can be an access out of bounds. >>>>>>> >>>>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. >>>>>>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes >>>>>>> sense and I don't see how there can be an API breakage. >>>>>>> So if an application hasn't compiled against the new lib it will be still using the old value >>>>>>> which will be within bounds. If it's picking up the higher new value from the lib it must >>>>>>> have been compiled against the lib so shouldn't have problems. >>>>>> >>>>>> You say there is no ABI issue because the application will be re-compiled >>>>>> for the updated library. Indeed, compilation fixes compatibility issues. >>>>>> But this is not relevant for ABI compatibility. >>>>>> ABI compatibility means we can upgrade the library without recompiling >>>>>> the application and it must work. >>>>>> You think it is a false positive because you assume the application >>>>>> "picks" the new value. I think you miss the case where the new value >>>>>> is returned by a function in the upgraded library. >>>>>> >>>>>>> There are also no structs on the API which contain arrays using this >>>>>>> for sizing, so I don't see an opportunity for an appl to have a >>>>>>> mismatch in memory addresses. >>>>>> >>>>>> Let me demonstrate where the API may "use" the new value >>>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application. >>>>>> >>>>>> Once upon a time a DPDK application counting the number of devices >>>>>> supporting each AEAD algo (in order to find the best supported algo). >>>>>> It is done in an array indexed by algo id: >>>>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; >>>>>> The application is compiled with DPDK 19.11, >>>>>> where RTE_CRYPTO_AEAD_LIST_END = 3. >>>>>> So the size of the application array aead_dev_count is 3. >>>>>> This binary is run with DPDK 20.02, >>>>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. >>>>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3, >>>>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to >>>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). >>>>>> The application uses this value: >>>>>> ++ aead_dev_count[info.capabilities.sym.aead.algo]; >>>>>> The application is crashing because of out of bound access. >>>>> >>>>> I'd say this is an example of bad written app. >>>>> It probably should check that returned by library value doesn't >>>>> exceed its internal array size. >>>> >>>> +1 >>>> >>>> Application should ignore values >= MAX. >>> >>> Of course, blaming the API user is a lot easier than looking at the API. >>> Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood >>> as the max value for the application. >>> Value ranges are part of the ABI compatibility contract. >>> It seems you expect the application developer to be aware that >>> DPDK could return a higher value, so the application should >>> check every enum values after calling an API. CRAZY. >>> >>> When we decide to announce an ABI compatibility and do some marketing, >>> everyone is OK. But when we need to really make our ABI compatible, >>> I see little or no effort. DISAPPOINTING. >> >> This is not to blame the user or to do less work, this is more sane approach >> that library provides the _END/_MAX value and application uses it as valid range >> check. >> >>>> Do you suggest we don't extend any enum or define between ABI breakage releases >>>> to be sure bad written applications not affected? >>> >>> I suggest we must consider not breaking any assumption made on the API. >>> Here we are breaking the enum range because nothing mentions _LIST_END >>> is not really the absolute end of the enum. >>> The solution is to make the change below in 20.02 + backport in 19.11.1: >>> >>> - _LIST_END >>> + _LIST_END, /* an ABI-compatible version may increase this value */ >>> + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */ >>> }; >>> >> >> What is the point of "_LIST_MAX" here? > > _LIST_MAX is range of value that DPDK can return in the ABI contract. > So the appplication can rely on the range 0.._LIST_MAX. > >> Application should know the "_LIST_END" of when it has been compiled for the >> valid range check. Next time it is compiled "_LIST_END" may be different value >> but same logic applies. > > No, ABI compatibility contract means you can compile your application > with DPDK 19.11.0 and run it with DPDK 20.02. > So _LIST_END comes from 19.11 and does not include ChachaPoly. That is what I mean, let me try to give a sample. DPDK19.11 returns, A=1, B=2, END=3 Application compiled with DPDK19.11, it will process A, B and ignore anything ">= 3" DPDK20.02 returns A=1, B=2, C=3, D=4, END=5 Old application will still only will know/use A, B and can ignore when library sends C=3, D=4 etc... In above, if you add another limit as you suggested, like MAX=10 and ask application to use it, Application compiled with DPDK19.11 will be OK since library only sends A,B and application uses them. But with DPDK20.02 application may have problem, since library will be sending C=3, which is valid according to the check " <= MAX (10)", how application will know to ignore it. So application should use _END to know the valid ones according it, if so what is the point of having _MAX. > >> When "_LIST_END" is missing, application can't protect itself, in that case >> library should send only the values application knows when it is compiled, this >> means either we can't extend our enum/defines until next ABI breakage, or we >> need to do ABI versioning to the functions that returns an enum each time enum >> value extended. > > If we define _LIST_MAX as a bigger value than current _LIST_END, > we have some room to add values in between. > > If (as of now) we don't have _LIST_MAX room, then yes we must version > the functions returning the enum. > In this case, the proper solution is to implement > rte_cryptodev_info_get_v1911() so it filters out > RTE_CRYPTO_AEAD_CHACHA20_POLY1305 capability. > With this solution, an application compiled with DPDK 19.11 will keep > seeing the same range as before, while a 20.02 application could > see and use ChachaPoly. > This is another proposal that I was expecting from the crypto team, > instead of claiming there is no issue (and wasting precious time). > > >> I believe it is saner to provide _END/_MAX values to the application to use. And >> if required comment them to clarify the expected usage. >> >> But in above suggestion application can't use or rely on "_LIST_MAX", it doesn't >> mean anything to application. > > I don't understand what you mean. I think you misunderstood what is ABI compat. > > >>> Then *_LIST_END values could be ignored by libabigail with such a change. >>> >>> If such a patch is not done by tomorrow, I will have to revert >>> Chacha-Poly commits before 20.02-rc2, because >>> >>> 1/ LIST_END, without any comment, means "size of range" >>> 2/ we do not blame users for undocumented ABI changes >>> 3/ we respect the ABI compatibility contract > > >
04/02/2020 10:19, Ferruh Yigit: > On 2/3/2020 6:40 PM, Thomas Monjalon wrote: > > 03/02/2020 18:40, Ferruh Yigit: > >> On 2/3/2020 5:09 PM, Thomas Monjalon wrote: > >>> 03/02/2020 10:30, Ferruh Yigit: > >>>> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: > >>>>> 02/02/2020 14:05, Thomas Monjalon: > >>>>>> 31/01/2020 15:16, Trahe, Fiona: > >>>>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: > >>>>>>>> 30/01/2020 17:09, Ferruh Yigit: > >>>>>>>>> On 1/29/2020 8:13 PM, Akhil Goyal wrote: > >>>>>>>>>> > >>>>>>>>>> I believe these enums will be used only in case of ASYM case which is experimental. > >>>>>>>>> > >>>>>>>>> Independent from being experiment and not, this shouldn't be a problem, I think > >>>>>>>>> this is a false positive. > >>>>>>>>> > >>>>>>>>> The ABI break can happen when a struct has been shared between the application > >>>>>>>>> and the library (DPDK) and the layout of that memory know differently by > >>>>>>>>> application and the library. > >>>>>>>>> > >>>>>>>>> Here in all cases, there is no layout/size change. > >>>>>>>>> > >>>>>>>>> As to the value changes of the enums, since application compiled with old DPDK, > >>>>>>>>> it will know only up to '6', 7 and more means invalid to the application. So it > >>>>>>>>> won't send these values also it should ignore these values from library. Only > >>>>>>>>> consequence is old application won't able to use new features those new enums > >>>>>>>>> provide but that is expected/normal. > >>>>>>>> > >>>>>>>> If library give higher value than expected by the application, > >>>>>>>> if the application uses this value as array index, > >>>>>>>> there can be an access out of bounds. > >>>>>>> > >>>>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. > >>>>>>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes > >>>>>>> sense and I don't see how there can be an API breakage. > >>>>>>> So if an application hasn't compiled against the new lib it will be still using the old value > >>>>>>> which will be within bounds. If it's picking up the higher new value from the lib it must > >>>>>>> have been compiled against the lib so shouldn't have problems. > >>>>>> > >>>>>> You say there is no ABI issue because the application will be re-compiled > >>>>>> for the updated library. Indeed, compilation fixes compatibility issues. > >>>>>> But this is not relevant for ABI compatibility. > >>>>>> ABI compatibility means we can upgrade the library without recompiling > >>>>>> the application and it must work. > >>>>>> You think it is a false positive because you assume the application > >>>>>> "picks" the new value. I think you miss the case where the new value > >>>>>> is returned by a function in the upgraded library. > >>>>>> > >>>>>>> There are also no structs on the API which contain arrays using this > >>>>>>> for sizing, so I don't see an opportunity for an appl to have a > >>>>>>> mismatch in memory addresses. > >>>>>> > >>>>>> Let me demonstrate where the API may "use" the new value > >>>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application. > >>>>>> > >>>>>> Once upon a time a DPDK application counting the number of devices > >>>>>> supporting each AEAD algo (in order to find the best supported algo). > >>>>>> It is done in an array indexed by algo id: > >>>>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; > >>>>>> The application is compiled with DPDK 19.11, > >>>>>> where RTE_CRYPTO_AEAD_LIST_END = 3. > >>>>>> So the size of the application array aead_dev_count is 3. > >>>>>> This binary is run with DPDK 20.02, > >>>>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. > >>>>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3, > >>>>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to > >>>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). > >>>>>> The application uses this value: > >>>>>> ++ aead_dev_count[info.capabilities.sym.aead.algo]; > >>>>>> The application is crashing because of out of bound access. > >>>>> > >>>>> I'd say this is an example of bad written app. > >>>>> It probably should check that returned by library value doesn't > >>>>> exceed its internal array size. > >>>> > >>>> +1 > >>>> > >>>> Application should ignore values >= MAX. > >>> > >>> Of course, blaming the API user is a lot easier than looking at the API. > >>> Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood > >>> as the max value for the application. > >>> Value ranges are part of the ABI compatibility contract. > >>> It seems you expect the application developer to be aware that > >>> DPDK could return a higher value, so the application should > >>> check every enum values after calling an API. CRAZY. > >>> > >>> When we decide to announce an ABI compatibility and do some marketing, > >>> everyone is OK. But when we need to really make our ABI compatible, > >>> I see little or no effort. DISAPPOINTING. > >> > >> This is not to blame the user or to do less work, this is more sane approach > >> that library provides the _END/_MAX value and application uses it as valid range > >> check. > >> > >>>> Do you suggest we don't extend any enum or define between ABI breakage releases > >>>> to be sure bad written applications not affected? > >>> > >>> I suggest we must consider not breaking any assumption made on the API. > >>> Here we are breaking the enum range because nothing mentions _LIST_END > >>> is not really the absolute end of the enum. > >>> The solution is to make the change below in 20.02 + backport in 19.11.1: > >>> > >>> - _LIST_END > >>> + _LIST_END, /* an ABI-compatible version may increase this value */ > >>> + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */ > >>> }; > >>> > >> > >> What is the point of "_LIST_MAX" here? > > > > _LIST_MAX is range of value that DPDK can return in the ABI contract. > > So the appplication can rely on the range 0.._LIST_MAX. > > > >> Application should know the "_LIST_END" of when it has been compiled for the > >> valid range check. Next time it is compiled "_LIST_END" may be different value > >> but same logic applies. > > > > No, ABI compatibility contract means you can compile your application > > with DPDK 19.11.0 and run it with DPDK 20.02. > > So _LIST_END comes from 19.11 and does not include ChachaPoly. > > That is what I mean, let me try to give a sample. > > DPDK19.11 returns, A=1, B=2, END=3 > > Application compiled with DPDK19.11, it will process A, B and ignore anything ">= 3" No, the application will not ignore anything ">=3" as I explained above, and you blamed the application for it. Nothing in the API says the application must filter value higher than 3, because as of now, values higher than 3 are PMD bug. > DPDK20.02 returns A=1, B=2, C=3, D=4, END=5 > > Old application will still only will know/use A, B and can ignore when library > sends C=3, D=4 etc... > > > In above, if you add another limit as you suggested, like MAX=10 and ask > application to use it, > > Application compiled with DPDK19.11 will be OK since library only sends A,B and > application uses them. > > But with DPDK20.02 application may have problem, since library will be sending > C=3, which is valid according to the check " <= MAX (10)", how application will > know to ignore it. Why application should ignore value C=3 with DPDK 20.02? > So application should use _END to know the valid ones according it, if so what > is the point of having _MAX. > > > >> When "_LIST_END" is missing, application can't protect itself, in that case > >> library should send only the values application knows when it is compiled, this > >> means either we can't extend our enum/defines until next ABI breakage, or we > >> need to do ABI versioning to the functions that returns an enum each time enum > >> value extended. > > > > If we define _LIST_MAX as a bigger value than current _LIST_END, > > we have some room to add values in between. > > > > If (as of now) we don't have _LIST_MAX room, then yes we must version > > the functions returning the enum. > > In this case, the proper solution is to implement > > rte_cryptodev_info_get_v1911() so it filters out > > RTE_CRYPTO_AEAD_CHACHA20_POLY1305 capability. > > With this solution, an application compiled with DPDK 19.11 will keep > > seeing the same range as before, while a 20.02 application could > > see and use ChachaPoly. > > This is another proposal that I was expecting from the crypto team, > > instead of claiming there is no issue (and wasting precious time). > > > > > >> I believe it is saner to provide _END/_MAX values to the application to use. And > >> if required comment them to clarify the expected usage. > >> > >> But in above suggestion application can't use or rely on "_LIST_MAX", it doesn't > >> mean anything to application. > > > > I don't understand what you mean. I think you misunderstood what is ABI compat. > > > > > >>> Then *_LIST_END values could be ignored by libabigail with such a change. > >>> > >>> If such a patch is not done by tomorrow, I will have to revert > >>> Chacha-Poly commits before 20.02-rc2, because > >>> > >>> 1/ LIST_END, without any comment, means "size of range" > >>> 2/ we do not blame users for undocumented ABI changes > >>> 3/ we respect the ABI compatibility contract
On 2/3/2020 9:07 PM, Thomas Monjalon wrote: > 03/02/2020 19:55, Ray Kinsella: >> On 03/02/2020 17:34, Thomas Monjalon wrote: >>> 03/02/2020 18:09, Thomas Monjalon: >>>> 03/02/2020 10:30, Ferruh Yigit: >>>>> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: >>>>>> 02/02/2020 14:05, Thomas Monjalon: >>>>>>> 31/01/2020 15:16, Trahe, Fiona: >>>>>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: >>>>>>>>> If library give higher value than expected by the application, >>>>>>>>> if the application uses this value as array index, >>>>>>>>> there can be an access out of bounds. >>>>>>>> >>>>>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. >>>>>>>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes >>>>>>>> sense and I don't see how there can be an API breakage. >>>>>>>> So if an application hasn't compiled against the new lib it will be still using the old value >>>>>>>> which will be within bounds. If it's picking up the higher new value from the lib it must >>>>>>>> have been compiled against the lib so shouldn't have problems. >>>>>>> >>>>>>> You say there is no ABI issue because the application will be re-compiled >>>>>>> for the updated library. Indeed, compilation fixes compatibility issues. >>>>>>> But this is not relevant for ABI compatibility. >>>>>>> ABI compatibility means we can upgrade the library without recompiling >>>>>>> the application and it must work. >>>>>>> You think it is a false positive because you assume the application >>>>>>> "picks" the new value. I think you miss the case where the new value >>>>>>> is returned by a function in the upgraded library. >>>>>>> >>>>>>>> There are also no structs on the API which contain arrays using this >>>>>>>> for sizing, so I don't see an opportunity for an appl to have a >>>>>>>> mismatch in memory addresses. >>>>>>> >>>>>>> Let me demonstrate where the API may "use" the new value >>>>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application. >>>>>>> >>>>>>> Once upon a time a DPDK application counting the number of devices >>>>>>> supporting each AEAD algo (in order to find the best supported algo). >>>>>>> It is done in an array indexed by algo id: >>>>>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; >>>>>>> The application is compiled with DPDK 19.11, >>>>>>> where RTE_CRYPTO_AEAD_LIST_END = 3. >>>>>>> So the size of the application array aead_dev_count is 3. >>>>>>> This binary is run with DPDK 20.02, >>>>>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. >>>>>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3, >>>>>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to >>>>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). >>>>>>> The application uses this value: >>>>>>> ++ aead_dev_count[info.capabilities.sym.aead.algo]; >>>>>>> The application is crashing because of out of bound access. >>>>>> >>>>>> I'd say this is an example of bad written app. >>>>>> It probably should check that returned by library value doesn't >>>>>> exceed its internal array size. >>>>> >>>>> +1 >>>>> >>>>> Application should ignore values >= MAX. >>>> >>>> Of course, blaming the API user is a lot easier than looking at the API. >>>> Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood >>>> as the max value for the application. >>>> Value ranges are part of the ABI compatibility contract. >>>> It seems you expect the application developer to be aware that >>>> DPDK could return a higher value, so the application should >>>> check every enum values after calling an API. CRAZY. >>>> >>>> When we decide to announce an ABI compatibility and do some marketing, >>>> everyone is OK. But when we need to really make our ABI compatible, >>>> I see little or no effort. DISAPPOINTING. >>>> >>>>> Do you suggest we don't extend any enum or define between ABI breakage releases >>>>> to be sure bad written applications not affected? >>>> >>>> I suggest we must consider not breaking any assumption made on the API. >>>> Here we are breaking the enum range because nothing mentions _LIST_END >>>> is not really the absolute end of the enum. >>>> The solution is to make the change below in 20.02 + backport in 19.11.1: >>> >>> Thinking twice, merging such change before 20.11 is breaking the >>> ABI assumption based on the API 19.11.0. >>> I ask the release maintainers (Luca, Kevin, David and me) and >>> the ABI maintainers (Neil and Ray) to vote for a or b solution: >>> a) add comment and LIST_MAX as below in 20.02 + 19.11.1 >> >> That would still be an ABI breakage though right. >> >>> b) wait 20.11 and revert Chacha-Poly from 20.02 >> >> Thanks for analysis above Fiona, Ferruh and all. >> >> That is a nasty one alright - there is no "good" answer here. >> I agree with Ferruh's sentiments overall, we should rethink this API for 20.11. >> Could do without an enumeration? >> >> There a c) though right. >> We could work around the issue by api versioning rte_cryptodev_info_get() and friends. >> So they only support/acknowledge the existence of Chacha-Poly for applications build against > 20.02. > > I agree there is a c) as I proposed in another email: > http://mails.dpdk.org/archives/dev/2020-February/156919.html > " > In this case, the proper solution is to implement > rte_cryptodev_info_get_v1911() so it filters out > RTE_CRYPTO_AEAD_CHACHA20_POLY1305 capability. > With this solution, an application compiled with DPDK 19.11 will keep > seeing the same range as before, while a 20.02 application could > see and use ChachaPoly. > " > >> It would be painful I know. > > Not so painful in my opinion. > Just need to call rte_cryptodev_info_get() from > rte_cryptodev_info_get_v1911() and filter the value > in the 19.11 range: [0..AES_GCM]. > >> It would also mean that Chacha-Poly would only be available to >> those building against >= 20.02. > > Yes exactly. > > The addition of comments and LIST_MAX like below are still valid > to avoid versioning after 20.11. > >>>> - _LIST_END >>>> + _LIST_END, /* an ABI-compatible version may increase this value */ >>>> + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */ >>>> }; >>>> >>>> Then *_LIST_END values could be ignored by libabigail with such a change. > > In order to avoid ABI check complaining, the best is to completely > remove LIST_END in DPDK 20.11. We can remove LIST_END only if we go with option (c). Two different approach, - Provide the LIST_END and expect application protect itself against new values can be coming in newer version of the library - Do ABI versioning to prevent application receive new values at all, (c). We can select one, but I believe the selection shouldn't be based on just silencing the ABI check tool. > > >>>> If such a patch is not done by tomorrow, I will have to revert >>>> Chacha-Poly commits before 20.02-rc2, because >>>> >>>> 1/ LIST_END, without any comment, means "size of range" >>>> 2/ we do not blame users for undocumented ABI changes >>>> 3/ we respect the ABI compatibility contract > > >
On Mon, Feb 3, 2020 at 7:56 PM Ray Kinsella <mdr@ashroe.eu> wrote: > On 03/02/2020 17:34, Thomas Monjalon wrote: > > 03/02/2020 18:09, Thomas Monjalon: > >> 03/02/2020 10:30, Ferruh Yigit: > >>> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: > >>>> 02/02/2020 14:05, Thomas Monjalon: > >>>>> 31/01/2020 15:16, Trahe, Fiona: > >>>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: > >>>>>>> If library give higher value than expected by the application, > >>>>>>> if the application uses this value as array index, > >>>>>>> there can be an access out of bounds. > >>>>>> > >>>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. > >>>>>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes > >>>>>> sense and I don't see how there can be an API breakage. > >>>>>> So if an application hasn't compiled against the new lib it will be still using the old value > >>>>>> which will be within bounds. If it's picking up the higher new value from the lib it must > >>>>>> have been compiled against the lib so shouldn't have problems. > >>>>> > >>>>> You say there is no ABI issue because the application will be re-compiled > >>>>> for the updated library. Indeed, compilation fixes compatibility issues. > >>>>> But this is not relevant for ABI compatibility. > >>>>> ABI compatibility means we can upgrade the library without recompiling > >>>>> the application and it must work. > >>>>> You think it is a false positive because you assume the application > >>>>> "picks" the new value. I think you miss the case where the new value > >>>>> is returned by a function in the upgraded library. > >>>>> > >>>>>> There are also no structs on the API which contain arrays using this > >>>>>> for sizing, so I don't see an opportunity for an appl to have a > >>>>>> mismatch in memory addresses. > >>>>> > >>>>> Let me demonstrate where the API may "use" the new value > >>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application. > >>>>> > >>>>> Once upon a time a DPDK application counting the number of devices > >>>>> supporting each AEAD algo (in order to find the best supported algo). > >>>>> It is done in an array indexed by algo id: > >>>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; > >>>>> The application is compiled with DPDK 19.11, > >>>>> where RTE_CRYPTO_AEAD_LIST_END = 3. > >>>>> So the size of the application array aead_dev_count is 3. > >>>>> This binary is run with DPDK 20.02, > >>>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. > >>>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3, > >>>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to > >>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). > >>>>> The application uses this value: > >>>>> ++ aead_dev_count[info.capabilities.sym.aead.algo]; > >>>>> The application is crashing because of out of bound access. > >>>> > >>>> I'd say this is an example of bad written app. > >>>> It probably should check that returned by library value doesn't > >>>> exceed its internal array size. > >>> > >>> +1 > >>> > >>> Application should ignore values >= MAX. > >> > >> Of course, blaming the API user is a lot easier than looking at the API. > >> Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood > >> as the max value for the application. > >> Value ranges are part of the ABI compatibility contract. > >> It seems you expect the application developer to be aware that > >> DPDK could return a higher value, so the application should > >> check every enum values after calling an API. CRAZY. > >> > >> When we decide to announce an ABI compatibility and do some marketing, > >> everyone is OK. But when we need to really make our ABI compatible, > >> I see little or no effort. DISAPPOINTING. > >> > >>> Do you suggest we don't extend any enum or define between ABI breakage releases > >>> to be sure bad written applications not affected? > >> > >> I suggest we must consider not breaking any assumption made on the API. > >> Here we are breaking the enum range because nothing mentions _LIST_END > >> is not really the absolute end of the enum. > >> The solution is to make the change below in 20.02 + backport in 19.11.1: > > > > Thinking twice, merging such change before 20.11 is breaking the > > ABI assumption based on the API 19.11.0. > > I ask the release maintainers (Luca, Kevin, David and me) and > > the ABI maintainers (Neil and Ray) to vote for a or b solution: > > a) add comment and LIST_MAX as below in 20.02 + 19.11.1 > > That would still be an ABI breakage though right. Yes. > > > b) wait 20.11 and revert Chacha-Poly from 20.02 > > Thanks for analysis above Fiona, Ferruh and all. > > That is a nasty one alright - there is no "good" answer here. > I agree with Ferruh's sentiments overall, we should rethink this API for 20.11. > Could do without an enumeration? > > There a c) though right. > We could work around the issue by api versioning rte_cryptodev_info_get() and friends. It has a lot of friends, but it sounds like the right approach. Is someone looking into this? > So they only support/acknowledge the existence of Chacha-Poly for applications build against > 20.02. > > It would be painful I know. > It would also mean that Chacha-Poly would only be available to those building against >= 20.02. Yes. -- David Marchand
On 2/4/2020 9:45 AM, Thomas Monjalon wrote: > 04/02/2020 10:19, Ferruh Yigit: >> On 2/3/2020 6:40 PM, Thomas Monjalon wrote: >>> 03/02/2020 18:40, Ferruh Yigit: >>>> On 2/3/2020 5:09 PM, Thomas Monjalon wrote: >>>>> 03/02/2020 10:30, Ferruh Yigit: >>>>>> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: >>>>>>> 02/02/2020 14:05, Thomas Monjalon: >>>>>>>> 31/01/2020 15:16, Trahe, Fiona: >>>>>>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: >>>>>>>>>> 30/01/2020 17:09, Ferruh Yigit: >>>>>>>>>>> On 1/29/2020 8:13 PM, Akhil Goyal wrote: >>>>>>>>>>>> >>>>>>>>>>>> I believe these enums will be used only in case of ASYM case which is experimental. >>>>>>>>>>> >>>>>>>>>>> Independent from being experiment and not, this shouldn't be a problem, I think >>>>>>>>>>> this is a false positive. >>>>>>>>>>> >>>>>>>>>>> The ABI break can happen when a struct has been shared between the application >>>>>>>>>>> and the library (DPDK) and the layout of that memory know differently by >>>>>>>>>>> application and the library. >>>>>>>>>>> >>>>>>>>>>> Here in all cases, there is no layout/size change. >>>>>>>>>>> >>>>>>>>>>> As to the value changes of the enums, since application compiled with old DPDK, >>>>>>>>>>> it will know only up to '6', 7 and more means invalid to the application. So it >>>>>>>>>>> won't send these values also it should ignore these values from library. Only >>>>>>>>>>> consequence is old application won't able to use new features those new enums >>>>>>>>>>> provide but that is expected/normal. >>>>>>>>>> >>>>>>>>>> If library give higher value than expected by the application, >>>>>>>>>> if the application uses this value as array index, >>>>>>>>>> there can be an access out of bounds. >>>>>>>>> >>>>>>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. >>>>>>>>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes >>>>>>>>> sense and I don't see how there can be an API breakage. >>>>>>>>> So if an application hasn't compiled against the new lib it will be still using the old value >>>>>>>>> which will be within bounds. If it's picking up the higher new value from the lib it must >>>>>>>>> have been compiled against the lib so shouldn't have problems. >>>>>>>> >>>>>>>> You say there is no ABI issue because the application will be re-compiled >>>>>>>> for the updated library. Indeed, compilation fixes compatibility issues. >>>>>>>> But this is not relevant for ABI compatibility. >>>>>>>> ABI compatibility means we can upgrade the library without recompiling >>>>>>>> the application and it must work. >>>>>>>> You think it is a false positive because you assume the application >>>>>>>> "picks" the new value. I think you miss the case where the new value >>>>>>>> is returned by a function in the upgraded library. >>>>>>>> >>>>>>>>> There are also no structs on the API which contain arrays using this >>>>>>>>> for sizing, so I don't see an opportunity for an appl to have a >>>>>>>>> mismatch in memory addresses. >>>>>>>> >>>>>>>> Let me demonstrate where the API may "use" the new value >>>>>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application. >>>>>>>> >>>>>>>> Once upon a time a DPDK application counting the number of devices >>>>>>>> supporting each AEAD algo (in order to find the best supported algo). >>>>>>>> It is done in an array indexed by algo id: >>>>>>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; >>>>>>>> The application is compiled with DPDK 19.11, >>>>>>>> where RTE_CRYPTO_AEAD_LIST_END = 3. >>>>>>>> So the size of the application array aead_dev_count is 3. >>>>>>>> This binary is run with DPDK 20.02, >>>>>>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. >>>>>>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3, >>>>>>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to >>>>>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). >>>>>>>> The application uses this value: >>>>>>>> ++ aead_dev_count[info.capabilities.sym.aead.algo]; >>>>>>>> The application is crashing because of out of bound access. >>>>>>> >>>>>>> I'd say this is an example of bad written app. >>>>>>> It probably should check that returned by library value doesn't >>>>>>> exceed its internal array size. >>>>>> >>>>>> +1 >>>>>> >>>>>> Application should ignore values >= MAX. >>>>> >>>>> Of course, blaming the API user is a lot easier than looking at the API. >>>>> Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood >>>>> as the max value for the application. >>>>> Value ranges are part of the ABI compatibility contract. >>>>> It seems you expect the application developer to be aware that >>>>> DPDK could return a higher value, so the application should >>>>> check every enum values after calling an API. CRAZY. >>>>> >>>>> When we decide to announce an ABI compatibility and do some marketing, >>>>> everyone is OK. But when we need to really make our ABI compatible, >>>>> I see little or no effort. DISAPPOINTING. >>>> >>>> This is not to blame the user or to do less work, this is more sane approach >>>> that library provides the _END/_MAX value and application uses it as valid range >>>> check. >>>> >>>>>> Do you suggest we don't extend any enum or define between ABI breakage releases >>>>>> to be sure bad written applications not affected? >>>>> >>>>> I suggest we must consider not breaking any assumption made on the API. >>>>> Here we are breaking the enum range because nothing mentions _LIST_END >>>>> is not really the absolute end of the enum. >>>>> The solution is to make the change below in 20.02 + backport in 19.11.1: >>>>> >>>>> - _LIST_END >>>>> + _LIST_END, /* an ABI-compatible version may increase this value */ >>>>> + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */ >>>>> }; >>>>> >>>> >>>> What is the point of "_LIST_MAX" here? >>> >>> _LIST_MAX is range of value that DPDK can return in the ABI contract. >>> So the appplication can rely on the range 0.._LIST_MAX. >>> >>>> Application should know the "_LIST_END" of when it has been compiled for the >>>> valid range check. Next time it is compiled "_LIST_END" may be different value >>>> but same logic applies. >>> >>> No, ABI compatibility contract means you can compile your application >>> with DPDK 19.11.0 and run it with DPDK 20.02. >>> So _LIST_END comes from 19.11 and does not include ChachaPoly. >> >> That is what I mean, let me try to give a sample. >> >> DPDK19.11 returns, A=1, B=2, END=3 >> >> Application compiled with DPDK19.11, it will process A, B and ignore anything ">= 3" > > No, the application will not ignore anything ">=3" as I explained above, > and you blamed the application for it. > Nothing in the API says the application must filter value higher than 3, > because as of now, values higher than 3 are PMD bug. When application compiled, that is the END value, anything bigger than this value is not valid, if any application use the return value directly I think it is doing something wrong. But yes there may be applications relying on library will always send in the range. We never communicated this. But we can add comments to clarify this. > > >> DPDK20.02 returns A=1, B=2, C=3, D=4, END=5 >> >> Old application will still only will know/use A, B and can ignore when library >> sends C=3, D=4 etc... >> >> >> In above, if you add another limit as you suggested, like MAX=10 and ask >> application to use it, >> >> Application compiled with DPDK19.11 will be OK since library only sends A,B and >> application uses them. >> >> But with DPDK20.02 application may have problem, since library will be sending >> C=3, which is valid according to the check " <= MAX (10)", how application will >> know to ignore it. > > Why application should ignore value C=3 with DPDK 20.02? This is the application compiled with DPDK19.11, and running with DPDK20.02. So for the application this is the value >= MAX and something it doesn't know what to do. > > >> So application should use _END to know the valid ones according it, if so what >> is the point of having _MAX. >> >> >>>> When "_LIST_END" is missing, application can't protect itself, in that case >>>> library should send only the values application knows when it is compiled, this >>>> means either we can't extend our enum/defines until next ABI breakage, or we >>>> need to do ABI versioning to the functions that returns an enum each time enum >>>> value extended. >>> >>> If we define _LIST_MAX as a bigger value than current _LIST_END, >>> we have some room to add values in between. >>> >>> If (as of now) we don't have _LIST_MAX room, then yes we must version >>> the functions returning the enum. >>> In this case, the proper solution is to implement >>> rte_cryptodev_info_get_v1911() so it filters out >>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 capability. >>> With this solution, an application compiled with DPDK 19.11 will keep >>> seeing the same range as before, while a 20.02 application could >>> see and use ChachaPoly. >>> This is another proposal that I was expecting from the crypto team, >>> instead of claiming there is no issue (and wasting precious time). >>> >>> >>>> I believe it is saner to provide _END/_MAX values to the application to use. And >>>> if required comment them to clarify the expected usage. >>>> >>>> But in above suggestion application can't use or rely on "_LIST_MAX", it doesn't >>>> mean anything to application. >>> >>> I don't understand what you mean. I think you misunderstood what is ABI compat. >>> >>> >>>>> Then *_LIST_END values could be ignored by libabigail with such a change. >>>>> >>>>> If such a patch is not done by tomorrow, I will have to revert >>>>> Chacha-Poly commits before 20.02-rc2, because >>>>> >>>>> 1/ LIST_END, without any comment, means "size of range" >>>>> 2/ we do not blame users for undocumented ABI changes >>>>> 3/ we respect the ABI compatibility contract > > >
On Tue, Feb 04, 2020 at 09:56:31AM +0000, Ferruh Yigit wrote:
> On 2/4/2020 9:45 AM, Thomas Monjalon wrote:
> > 04/02/2020 10:19, Ferruh Yigit:
> >> On 2/3/2020 6:40 PM, Thomas Monjalon wrote:
> >>> 03/02/2020 18:40, Ferruh Yigit:
> >>>> On 2/3/2020 5:09 PM, Thomas Monjalon wrote:
> >>>>> 03/02/2020 10:30, Ferruh Yigit:
> >>>>>> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote:
> >>>>>>> 02/02/2020 14:05, Thomas Monjalon:
> >>>>>>>> 31/01/2020 15:16, Trahe, Fiona:
> >>>>>>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote:
> >>>>>>>>>> 30/01/2020 17:09, Ferruh Yigit:
> >>>>>>>>>>> On 1/29/2020 8:13 PM, Akhil Goyal wrote:
> >>>>>>>>>>>>
> >>>>>>>>>>>> I believe these enums will be used only in case of ASYM case which is experimental.
> >>>>>>>>>>>
> >>>>>>>>>>> Independent from being experiment and not, this shouldn't be a problem, I think
> >>>>>>>>>>> this is a false positive.
> >>>>>>>>>>>
> >>>>>>>>>>> The ABI break can happen when a struct has been shared between the application
> >>>>>>>>>>> and the library (DPDK) and the layout of that memory know differently by
> >>>>>>>>>>> application and the library.
> >>>>>>>>>>>
> >>>>>>>>>>> Here in all cases, there is no layout/size change.
> >>>>>>>>>>>
> >>>>>>>>>>> As to the value changes of the enums, since application compiled with old DPDK,
> >>>>>>>>>>> it will know only up to '6', 7 and more means invalid to the application. So it
> >>>>>>>>>>> won't send these values also it should ignore these values from library. Only
> >>>>>>>>>>> consequence is old application won't able to use new features those new enums
> >>>>>>>>>>> provide but that is expected/normal.
> >>>>>>>>>>
> >>>>>>>>>> If library give higher value than expected by the application,
> >>>>>>>>>> if the application uses this value as array index,
> >>>>>>>>>> there can be an access out of bounds.
> >>>>>>>>>
> >>>>>>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem.
> >>>>>>>>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes
> >>>>>>>>> sense and I don't see how there can be an API breakage.
> >>>>>>>>> So if an application hasn't compiled against the new lib it will be still using the old value
> >>>>>>>>> which will be within bounds. If it's picking up the higher new value from the lib it must
> >>>>>>>>> have been compiled against the lib so shouldn't have problems.
> >>>>>>>>
> >>>>>>>> You say there is no ABI issue because the application will be re-compiled
> >>>>>>>> for the updated library. Indeed, compilation fixes compatibility issues.
> >>>>>>>> But this is not relevant for ABI compatibility.
> >>>>>>>> ABI compatibility means we can upgrade the library without recompiling
> >>>>>>>> the application and it must work.
> >>>>>>>> You think it is a false positive because you assume the application
> >>>>>>>> "picks" the new value. I think you miss the case where the new value
> >>>>>>>> is returned by a function in the upgraded library.
> >>>>>>>>
> >>>>>>>>> There are also no structs on the API which contain arrays using this
> >>>>>>>>> for sizing, so I don't see an opportunity for an appl to have a
> >>>>>>>>> mismatch in memory addresses.
> >>>>>>>>
> >>>>>>>> Let me demonstrate where the API may "use" the new value
> >>>>>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application.
> >>>>>>>>
> >>>>>>>> Once upon a time a DPDK application counting the number of devices
> >>>>>>>> supporting each AEAD algo (in order to find the best supported algo).
> >>>>>>>> It is done in an array indexed by algo id:
> >>>>>>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END];
> >>>>>>>> The application is compiled with DPDK 19.11,
> >>>>>>>> where RTE_CRYPTO_AEAD_LIST_END = 3.
> >>>>>>>> So the size of the application array aead_dev_count is 3.
> >>>>>>>> This binary is run with DPDK 20.02,
> >>>>>>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3.
> >>>>>>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3,
> >>>>>>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to
> >>>>>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3).
> >>>>>>>> The application uses this value:
> >>>>>>>> ++ aead_dev_count[info.capabilities.sym.aead.algo];
> >>>>>>>> The application is crashing because of out of bound access.
> >>>>>>>
> >>>>>>> I'd say this is an example of bad written app.
> >>>>>>> It probably should check that returned by library value doesn't
> >>>>>>> exceed its internal array size.
> >>>>>>
> >>>>>> +1
> >>>>>>
> >>>>>> Application should ignore values >= MAX.
> >>>>>
> >>>>> Of course, blaming the API user is a lot easier than looking at the API.
> >>>>> Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood
> >>>>> as the max value for the application.
> >>>>> Value ranges are part of the ABI compatibility contract.
> >>>>> It seems you expect the application developer to be aware that
> >>>>> DPDK could return a higher value, so the application should
> >>>>> check every enum values after calling an API. CRAZY.
> >>>>>
> >>>>> When we decide to announce an ABI compatibility and do some marketing,
> >>>>> everyone is OK. But when we need to really make our ABI compatible,
> >>>>> I see little or no effort. DISAPPOINTING.
> >>>>
> >>>> This is not to blame the user or to do less work, this is more sane approach
> >>>> that library provides the _END/_MAX value and application uses it as valid range
> >>>> check.
> >>>>
> >>>>>> Do you suggest we don't extend any enum or define between ABI breakage releases
> >>>>>> to be sure bad written applications not affected?
> >>>>>
> >>>>> I suggest we must consider not breaking any assumption made on the API.
> >>>>> Here we are breaking the enum range because nothing mentions _LIST_END
> >>>>> is not really the absolute end of the enum.
> >>>>> The solution is to make the change below in 20.02 + backport in 19.11.1:
> >>>>>
> >>>>> - _LIST_END
> >>>>> + _LIST_END, /* an ABI-compatible version may increase this value */
> >>>>> + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */
> >>>>> };
> >>>>>
> >>>>
> >>>> What is the point of "_LIST_MAX" here?
> >>>
> >>> _LIST_MAX is range of value that DPDK can return in the ABI contract.
> >>> So the appplication can rely on the range 0.._LIST_MAX.
> >>>
> >>>> Application should know the "_LIST_END" of when it has been compiled for the
> >>>> valid range check. Next time it is compiled "_LIST_END" may be different value
> >>>> but same logic applies.
> >>>
> >>> No, ABI compatibility contract means you can compile your application
> >>> with DPDK 19.11.0 and run it with DPDK 20.02.
> >>> So _LIST_END comes from 19.11 and does not include ChachaPoly.
> >>
> >> That is what I mean, let me try to give a sample.
> >>
> >> DPDK19.11 returns, A=1, B=2, END=3
> >>
> >> Application compiled with DPDK19.11, it will process A, B and ignore anything ">= 3"
> >
> > No, the application will not ignore anything ">=3" as I explained above,
> > and you blamed the application for it.
> > Nothing in the API says the application must filter value higher than 3,
> > because as of now, values higher than 3 are PMD bug.
>
> When application compiled, that is the END value, anything bigger than this
> value is not valid, if any application use the return value directly I think it
> is doing something wrong.
> But yes there may be applications relying on library will always send in the
> range. We never communicated this. But we can add comments to clarify this.
>
I don't think we should do so, as for any function returning an enum by
definition it should never return an out-of-range value. I strongly agree
with the suggestion of versioning the functions so that the ranges seen by
apps are clamped to the expected 19.11 compatible values.
And not used for sizing > >
> > There a c) though right.
> > We could work around the issue by api versioning rte_cryptodev_info_get() and friends.
>
> It has a lot of friends, but it sounds like the right approach.
> Is someone looking into this?
[Fiona] Yes. But not clear yet if can be done by tomorrow.
But even if feasible, that only works around the current issue.
There is a bigger issue to be decided here -
Should we be removing LIST_END/MAX values from all enums in 20.11?
Or defining through API comment that they should only be used as a range boundary and
NOT to size an array. And so having a fixed value is not part of the API contract.
Hi, > On 2/3/2020 5:09 PM, Thomas Monjalon wrote: > > 03/02/2020 10:30, Ferruh Yigit: > >> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: > >>> 02/02/2020 14:05, Thomas Monjalon: > >>>> 31/01/2020 15:16, Trahe, Fiona: > >>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: > >>>>>> 30/01/2020 17:09, Ferruh Yigit: > >>>>>>> On 1/29/2020 8:13 PM, Akhil Goyal wrote: > >>>>>>>> > >>>>>>>> I believe these enums will be used only in case of ASYM case which is > experimental. > >>>>>>> > >>>>>>> Independent from being experiment and not, this shouldn't be a > problem, I think > >>>>>>> this is a false positive. > >>>>>>> > >>>>>>> The ABI break can happen when a struct has been shared between the > application > >>>>>>> and the library (DPDK) and the layout of that memory know differently > by > >>>>>>> application and the library. > >>>>>>> > >>>>>>> Here in all cases, there is no layout/size change. > >>>>>>> > >>>>>>> As to the value changes of the enums, since application compiled with > old DPDK, > >>>>>>> it will know only up to '6', 7 and more means invalid to the application. > So it > >>>>>>> won't send these values also it should ignore these values from library. > Only > >>>>>>> consequence is old application won't able to use new features those > new enums > >>>>>>> provide but that is expected/normal. > >>>>>> > >>>>>> If library give higher value than expected by the application, > >>>>>> if the application uses this value as array index, > >>>>>> there can be an access out of bounds. > >>>>> > >>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a > problem. > >>>>> But for the same issue with sym crypto below, I believe Ferruh's > explanation makes > >>>>> sense and I don't see how there can be an API breakage. > >>>>> So if an application hasn't compiled against the new lib it will be still using > the old value > >>>>> which will be within bounds. If it's picking up the higher new value from > the lib it must > >>>>> have been compiled against the lib so shouldn't have problems. > >>>> > >>>> You say there is no ABI issue because the application will be re-compiled > >>>> for the updated library. Indeed, compilation fixes compatibility issues. > >>>> But this is not relevant for ABI compatibility. > >>>> ABI compatibility means we can upgrade the library without recompiling > >>>> the application and it must work. > >>>> You think it is a false positive because you assume the application > >>>> "picks" the new value. I think you miss the case where the new value > >>>> is returned by a function in the upgraded library. > >>>> > >>>>> There are also no structs on the API which contain arrays using this > >>>>> for sizing, so I don't see an opportunity for an appl to have a > >>>>> mismatch in memory addresses. > >>>> > >>>> Let me demonstrate where the API may "use" the new value > >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the > application. > >>>> > >>>> Once upon a time a DPDK application counting the number of devices > >>>> supporting each AEAD algo (in order to find the best supported algo). > >>>> It is done in an array indexed by algo id: > >>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; > >>>> The application is compiled with DPDK 19.11, > >>>> where RTE_CRYPTO_AEAD_LIST_END = 3. > >>>> So the size of the application array aead_dev_count is 3. > >>>> This binary is run with DPDK 20.02, > >>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. > >>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3, > >>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to > >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). > >>>> The application uses this value: > >>>> ++ aead_dev_count[info.capabilities.sym.aead.algo]; > >>>> The application is crashing because of out of bound access. > >>> > >>> I'd say this is an example of bad written app. > >>> It probably should check that returned by library value doesn't > >>> exceed its internal array size. > >> > >> +1 > >> > >> Application should ignore values >= MAX. > > > > Of course, blaming the API user is a lot easier than looking at the API. > > Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood > > as the max value for the application. > > Value ranges are part of the ABI compatibility contract. > > It seems you expect the application developer to be aware that > > DPDK could return a higher value, so the application should > > check every enum values after calling an API. CRAZY. > > > > When we decide to announce an ABI compatibility and do some marketing, > > everyone is OK. But when we need to really make our ABI compatible, > > I see little or no effort. DISAPPOINTING. > > This is not to blame the user or to do less work, this is more sane approach > that library provides the _END/_MAX value and application uses it as valid range > check. > > > > >> Do you suggest we don't extend any enum or define between ABI breakage > releases > >> to be sure bad written applications not affected? > > > > I suggest we must consider not breaking any assumption made on the API. > > Here we are breaking the enum range because nothing mentions _LIST_END > > is not really the absolute end of the enum. > > The solution is to make the change below in 20.02 + backport in 19.11.1: > > > > - _LIST_END > > + _LIST_END, /* an ABI-compatible version may increase this value */ > > + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */ > > }; > > > > What is the point of "_LIST_MAX" here? > > Application should know the "_LIST_END" of when it has been compiled for the > valid range check. Next time it is compiled "_LIST_END" may be different value > but same logic applies. > > When "_LIST_END" is missing, application can't protect itself, in that case > library should send only the values application knows when it is compiled, this > means either we can't extend our enum/defines until next ABI breakage, or we > need to do ABI versioning to the functions that returns an enum each time enum > value extended. > > I believe it is saner to provide _END/_MAX values to the application to use. And > if required comment them to clarify the expected usage. > > But in above suggestion application can't use or rely on "_LIST_MAX", it doesn't > mean anything to application. > Can we have something like enum rte_crypto_aead_algorithm { RTE_CRYPTO_AEAD_AES_CCM = 1, /**< AES algorithm in CCM mode. */ RTE_CRYPTO_AEAD_AES_GCM, /**< AES algorithm in GCM mode. */ RTE_CRYPTO_AEAD_LIST_END, /**< List end for 19.11 ABI compatibility */ RTE_CRYPTO_AEAD_CHACHA20_POLY1305, /**< Chacha20 cipher with poly1305 authenticator */ RTE_CRYPTO_AEAD_LIST_END_2011 /**< List end for 20.11 ABI compatibility */ }; And in 20.11 release we alter the RTE_CRYPTO_AEAD_LIST_END to the end and remove RTE_CRYPTO_AEAD_LIST_END_2011 I believe it will be ok for any application which need to use the chacha poly assume that this algo is Experimental and will move to formal list in 20.11. This can be documented in the documentation. I believe there is no way to add a new enum as experimental so far. This way we can formalize this requirement as well. I believe this way effect of ABI breakage will be nullified. -Akhil > > Then *_LIST_END values could be ignored by libabigail with such a change. > > > > If such a patch is not done by tomorrow, I will have to revert > > Chacha-Poly commits before 20.02-rc2, because > > > > 1/ LIST_END, without any comment, means "size of range" > > 2/ we do not blame users for undocumented ABI changes > > 3/ we respect the ABI compatibility contract > > > >
On 04/02/2020 09:56, Ferruh Yigit wrote: > On 2/4/2020 9:45 AM, Thomas Monjalon wrote: >> 04/02/2020 10:19, Ferruh Yigit: >>> On 2/3/2020 6:40 PM, Thomas Monjalon wrote: >>>> 03/02/2020 18:40, Ferruh Yigit: >>>>> On 2/3/2020 5:09 PM, Thomas Monjalon wrote: >>>>>> 03/02/2020 10:30, Ferruh Yigit: >>>>>>> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: >>>>>>>> 02/02/2020 14:05, Thomas Monjalon: >>>>>>>>> 31/01/2020 15:16, Trahe, Fiona: >>>>>>>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: >>>>>>>>>>> 30/01/2020 17:09, Ferruh Yigit: >>>>>>>>>>>> On 1/29/2020 8:13 PM, Akhil Goyal wrote: >>>>>>>>>>>>> >>>>>>>>>>>>> I believe these enums will be used only in case of ASYM case which is experimental. >>>>>>>>>>>> >>>>>>>>>>>> Independent from being experiment and not, this shouldn't be a problem, I think >>>>>>>>>>>> this is a false positive. >>>>>>>>>>>> >>>>>>>>>>>> The ABI break can happen when a struct has been shared between the application >>>>>>>>>>>> and the library (DPDK) and the layout of that memory know differently by >>>>>>>>>>>> application and the library. >>>>>>>>>>>> >>>>>>>>>>>> Here in all cases, there is no layout/size change. >>>>>>>>>>>> >>>>>>>>>>>> As to the value changes of the enums, since application compiled with old DPDK, >>>>>>>>>>>> it will know only up to '6', 7 and more means invalid to the application. So it >>>>>>>>>>>> won't send these values also it should ignore these values from library. Only >>>>>>>>>>>> consequence is old application won't able to use new features those new enums >>>>>>>>>>>> provide but that is expected/normal. >>>>>>>>>>> >>>>>>>>>>> If library give higher value than expected by the application, >>>>>>>>>>> if the application uses this value as array index, >>>>>>>>>>> there can be an access out of bounds. >>>>>>>>>> >>>>>>>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. >>>>>>>>>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes >>>>>>>>>> sense and I don't see how there can be an API breakage. >>>>>>>>>> So if an application hasn't compiled against the new lib it will be still using the old value >>>>>>>>>> which will be within bounds. If it's picking up the higher new value from the lib it must >>>>>>>>>> have been compiled against the lib so shouldn't have problems. >>>>>>>>> >>>>>>>>> You say there is no ABI issue because the application will be re-compiled >>>>>>>>> for the updated library. Indeed, compilation fixes compatibility issues. >>>>>>>>> But this is not relevant for ABI compatibility. >>>>>>>>> ABI compatibility means we can upgrade the library without recompiling >>>>>>>>> the application and it must work. >>>>>>>>> You think it is a false positive because you assume the application >>>>>>>>> "picks" the new value. I think you miss the case where the new value >>>>>>>>> is returned by a function in the upgraded library. >>>>>>>>> >>>>>>>>>> There are also no structs on the API which contain arrays using this >>>>>>>>>> for sizing, so I don't see an opportunity for an appl to have a >>>>>>>>>> mismatch in memory addresses. >>>>>>>>> >>>>>>>>> Let me demonstrate where the API may "use" the new value >>>>>>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application. >>>>>>>>> >>>>>>>>> Once upon a time a DPDK application counting the number of devices >>>>>>>>> supporting each AEAD algo (in order to find the best supported algo). >>>>>>>>> It is done in an array indexed by algo id: >>>>>>>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; >>>>>>>>> The application is compiled with DPDK 19.11, >>>>>>>>> where RTE_CRYPTO_AEAD_LIST_END = 3. >>>>>>>>> So the size of the application array aead_dev_count is 3. >>>>>>>>> This binary is run with DPDK 20.02, >>>>>>>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. >>>>>>>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3, >>>>>>>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to >>>>>>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). >>>>>>>>> The application uses this value: >>>>>>>>> ++ aead_dev_count[info.capabilities.sym.aead.algo]; >>>>>>>>> The application is crashing because of out of bound access. >>>>>>>> >>>>>>>> I'd say this is an example of bad written app. >>>>>>>> It probably should check that returned by library value doesn't >>>>>>>> exceed its internal array size. >>>>>>> >>>>>>> +1 >>>>>>> >>>>>>> Application should ignore values >= MAX. >>>>>> >>>>>> Of course, blaming the API user is a lot easier than looking at the API. >>>>>> Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood >>>>>> as the max value for the application. >>>>>> Value ranges are part of the ABI compatibility contract. >>>>>> It seems you expect the application developer to be aware that >>>>>> DPDK could return a higher value, so the application should >>>>>> check every enum values after calling an API. CRAZY. >>>>>> >>>>>> When we decide to announce an ABI compatibility and do some marketing, >>>>>> everyone is OK. But when we need to really make our ABI compatible, >>>>>> I see little or no effort. DISAPPOINTING. >>>>> >>>>> This is not to blame the user or to do less work, this is more sane approach >>>>> that library provides the _END/_MAX value and application uses it as valid range >>>>> check. >>>>> >>>>>>> Do you suggest we don't extend any enum or define between ABI breakage releases >>>>>>> to be sure bad written applications not affected? >>>>>> >>>>>> I suggest we must consider not breaking any assumption made on the API. >>>>>> Here we are breaking the enum range because nothing mentions _LIST_END >>>>>> is not really the absolute end of the enum. >>>>>> The solution is to make the change below in 20.02 + backport in 19.11.1: >>>>>> >>>>>> - _LIST_END >>>>>> + _LIST_END, /* an ABI-compatible version may increase this value */ >>>>>> + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */ >>>>>> }; >>>>>> >>>>> >>>>> What is the point of "_LIST_MAX" here? >>>> >>>> _LIST_MAX is range of value that DPDK can return in the ABI contract. >>>> So the appplication can rely on the range 0.._LIST_MAX. >>>> >>>>> Application should know the "_LIST_END" of when it has been compiled for the >>>>> valid range check. Next time it is compiled "_LIST_END" may be different value >>>>> but same logic applies. >>>> >>>> No, ABI compatibility contract means you can compile your application >>>> with DPDK 19.11.0 and run it with DPDK 20.02. >>>> So _LIST_END comes from 19.11 and does not include ChachaPoly. >>> >>> That is what I mean, let me try to give a sample. >>> >>> DPDK19.11 returns, A=1, B=2, END=3 >>> >>> Application compiled with DPDK19.11, it will process A, B and ignore anything ">= 3" >> >> No, the application will not ignore anything ">=3" as I explained above, >> and you blamed the application for it. >> Nothing in the API says the application must filter value higher than 3, >> because as of now, values higher than 3 are PMD bug. > > When application compiled, that is the END value, anything bigger than this > value is not valid, if any application use the return value directly I think it > is doing something wrong. I don't think we can make an assumption that the application will/should range check *and* silently ignore what it considers out of bounds values. An application may not range check, but if it does, it may ignore these new values (we got lucky), or it could print errors or even decide to abort because it considers that DPDK is now returning values higher than the (compiled) max so something must be corrupt. Versioning sounds the best solution to me too, but I'm not sure how difficult the mechanics are in this case. > But yes there may be applications relying on library will always send in the > range. We never communicated this. But we can add comments to clarify this. > >> >> >>> DPDK20.02 returns A=1, B=2, C=3, D=4, END=5 >>> >>> Old application will still only will know/use A, B and can ignore when library >>> sends C=3, D=4 etc... >>> >>> >>> In above, if you add another limit as you suggested, like MAX=10 and ask >>> application to use it, >>> >>> Application compiled with DPDK19.11 will be OK since library only sends A,B and >>> application uses them. >>> >>> But with DPDK20.02 application may have problem, since library will be sending >>> C=3, which is valid according to the check " <= MAX (10)", how application will >>> know to ignore it. >> >> Why application should ignore value C=3 with DPDK 20.02? > > This is the application compiled with DPDK19.11, and running with DPDK20.02. > > So for the application this is the value >= MAX and something it doesn't know > what to do. > >> >> >>> So application should use _END to know the valid ones according it, if so what >>> is the point of having _MAX. >>> >>> >>>>> When "_LIST_END" is missing, application can't protect itself, in that case >>>>> library should send only the values application knows when it is compiled, this >>>>> means either we can't extend our enum/defines until next ABI breakage, or we >>>>> need to do ABI versioning to the functions that returns an enum each time enum >>>>> value extended. >>>> >>>> If we define _LIST_MAX as a bigger value than current _LIST_END, >>>> we have some room to add values in between. >>>> >>>> If (as of now) we don't have _LIST_MAX room, then yes we must version >>>> the functions returning the enum. >>>> In this case, the proper solution is to implement >>>> rte_cryptodev_info_get_v1911() so it filters out >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 capability. >>>> With this solution, an application compiled with DPDK 19.11 will keep >>>> seeing the same range as before, while a 20.02 application could >>>> see and use ChachaPoly. >>>> This is another proposal that I was expecting from the crypto team, >>>> instead of claiming there is no issue (and wasting precious time). >>>> >>>> >>>>> I believe it is saner to provide _END/_MAX values to the application to use. And >>>>> if required comment them to clarify the expected usage. >>>>> >>>>> But in above suggestion application can't use or rely on "_LIST_MAX", it doesn't >>>>> mean anything to application. >>>> >>>> I don't understand what you mean. I think you misunderstood what is ABI compat. >>>> >>>> >>>>>> Then *_LIST_END values could be ignored by libabigail with such a change. >>>>>> >>>>>> If such a patch is not done by tomorrow, I will have to revert >>>>>> Chacha-Poly commits before 20.02-rc2, because >>>>>> >>>>>> 1/ LIST_END, without any comment, means "size of range" >>>>>> 2/ we do not blame users for undocumented ABI changes >>>>>> 3/ we respect the ABI compatibility contract >> >> >> >
RED FLAG
I don't see a lot of reactions, so I summarize the issue.
We need action TODAY!
API makes think that rte_cryptodev_info_get() cannot return
a value >= 3 (RTE_CRYPTO_AEAD_LIST_END in 19.11).
Current 20.02 returns 3 (RTE_CRYPTO_AEAD_CHACHA20_POLY1305).
The ABI compatibility contract is broken currently.
There are 3 possible outcomes:
a) Change the API comments and backport to 19.11.1
The details are discussed between Ferruh and me.
Either put responsibility on API user (with explicit comment),
or expose ABI extension allowance with a new API max value.
In both cases, this is breaking the implicit contract of 19.11.0.
This option can be chosen only if release and ABI maintainers
vote for it.
b) Revert Chacha-Poly from 20.02-rc2.
c) Add versioned function rte_cryptodev_info_get_v1911()
which calls rte_cryptodev_info_get() and filters out
RTE_CRYPTO_AEAD_CHACHA20_POLY1305 capability.
So Chacha-Poly capability would be seen and usable only
if compiling with DPDK 20.02.
I hope it is clear what are the actions for everybody:
- ABI and release maintainers must say yes or no to the proposal (a)
- In the meantime, crypto team must send a patch for the proposal (c)
- If (a) and (c) are not possible at the end of today, I will take (b)
Note: do not say it is too short for (c), as it was possible to work
on such solution since the issue was exposed on last Wednesday.
03/02/2020 22:07, Thomas Monjalon:
> 03/02/2020 19:55, Ray Kinsella:
> > On 03/02/2020 17:34, Thomas Monjalon wrote:
> > > 03/02/2020 18:09, Thomas Monjalon:
> > >> 03/02/2020 10:30, Ferruh Yigit:
> > >>> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote:
> > >>>> 02/02/2020 14:05, Thomas Monjalon:
> > >>>>> 31/01/2020 15:16, Trahe, Fiona:
> > >>>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote:
> > >>>>>>> If library give higher value than expected by the application,
> > >>>>>>> if the application uses this value as array index,
> > >>>>>>> there can be an access out of bounds.
> > >>>>>>
> > >>>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem.
> > >>>>>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes
> > >>>>>> sense and I don't see how there can be an API breakage.
> > >>>>>> So if an application hasn't compiled against the new lib it will be still using the old value
> > >>>>>> which will be within bounds. If it's picking up the higher new value from the lib it must
> > >>>>>> have been compiled against the lib so shouldn't have problems.
> > >>>>>
> > >>>>> You say there is no ABI issue because the application will be re-compiled
> > >>>>> for the updated library. Indeed, compilation fixes compatibility issues.
> > >>>>> But this is not relevant for ABI compatibility.
> > >>>>> ABI compatibility means we can upgrade the library without recompiling
> > >>>>> the application and it must work.
> > >>>>> You think it is a false positive because you assume the application
> > >>>>> "picks" the new value. I think you miss the case where the new value
> > >>>>> is returned by a function in the upgraded library.
> > >>>>>
> > >>>>>> There are also no structs on the API which contain arrays using this
> > >>>>>> for sizing, so I don't see an opportunity for an appl to have a
> > >>>>>> mismatch in memory addresses.
> > >>>>>
> > >>>>> Let me demonstrate where the API may "use" the new value
> > >>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application.
> > >>>>>
> > >>>>> Once upon a time a DPDK application counting the number of devices
> > >>>>> supporting each AEAD algo (in order to find the best supported algo).
> > >>>>> It is done in an array indexed by algo id:
> > >>>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END];
> > >>>>> The application is compiled with DPDK 19.11,
> > >>>>> where RTE_CRYPTO_AEAD_LIST_END = 3.
> > >>>>> So the size of the application array aead_dev_count is 3.
> > >>>>> This binary is run with DPDK 20.02,
> > >>>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3.
> > >>>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3,
> > >>>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to
> > >>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3).
> > >>>>> The application uses this value:
> > >>>>> ++ aead_dev_count[info.capabilities.sym.aead.algo];
> > >>>>> The application is crashing because of out of bound access.
> > >>>>
> > >>>> I'd say this is an example of bad written app.
> > >>>> It probably should check that returned by library value doesn't
> > >>>> exceed its internal array size.
> > >>>
> > >>> +1
> > >>>
> > >>> Application should ignore values >= MAX.
> > >>
> > >> Of course, blaming the API user is a lot easier than looking at the API.
> > >> Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood
> > >> as the max value for the application.
> > >> Value ranges are part of the ABI compatibility contract.
> > >> It seems you expect the application developer to be aware that
> > >> DPDK could return a higher value, so the application should
> > >> check every enum values after calling an API. CRAZY.
> > >>
> > >> When we decide to announce an ABI compatibility and do some marketing,
> > >> everyone is OK. But when we need to really make our ABI compatible,
> > >> I see little or no effort. DISAPPOINTING.
> > >>
> > >>> Do you suggest we don't extend any enum or define between ABI breakage releases
> > >>> to be sure bad written applications not affected?
> > >>
> > >> I suggest we must consider not breaking any assumption made on the API.
> > >> Here we are breaking the enum range because nothing mentions _LIST_END
> > >> is not really the absolute end of the enum.
> > >> The solution is to make the change below in 20.02 + backport in 19.11.1:
> > >
> > > Thinking twice, merging such change before 20.11 is breaking the
> > > ABI assumption based on the API 19.11.0.
> > > I ask the release maintainers (Luca, Kevin, David and me) and
> > > the ABI maintainers (Neil and Ray) to vote for a or b solution:
> > > a) add comment and LIST_MAX as below in 20.02 + 19.11.1
> >
> > That would still be an ABI breakage though right.
> >
> > > b) wait 20.11 and revert Chacha-Poly from 20.02
> >
> > Thanks for analysis above Fiona, Ferruh and all.
> >
> > That is a nasty one alright - there is no "good" answer here.
> > I agree with Ferruh's sentiments overall, we should rethink this API for 20.11.
> > Could do without an enumeration?
> >
> > There a c) though right.
> > We could work around the issue by api versioning rte_cryptodev_info_get() and friends.
> > So they only support/acknowledge the existence of Chacha-Poly for applications build against > 20.02.
>
> I agree there is a c) as I proposed in another email:
> http://mails.dpdk.org/archives/dev/2020-February/156919.html
> "
> In this case, the proper solution is to implement
> rte_cryptodev_info_get_v1911() so it filters out
> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 capability.
> With this solution, an application compiled with DPDK 19.11 will keep
> seeing the same range as before, while a 20.02 application could
> see and use ChachaPoly.
> "
>
> > It would be painful I know.
>
> Not so painful in my opinion.
> Just need to call rte_cryptodev_info_get() from
> rte_cryptodev_info_get_v1911() and filter the value
> in the 19.11 range: [0..AES_GCM].
>
> > It would also mean that Chacha-Poly would only be available to
> > those building against >= 20.02.
>
> Yes exactly.
>
> The addition of comments and LIST_MAX like below are still valid
> to avoid versioning after 20.11.
>
> > >> - _LIST_END
> > >> + _LIST_END, /* an ABI-compatible version may increase this value */
> > >> + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */
> > >> };
> > >>
> > >> Then *_LIST_END values could be ignored by libabigail with such a change.
>
> In order to avoid ABI check complaining, the best is to completely
> remove LIST_END in DPDK 20.11.
>
>
> > >> If such a patch is not done by tomorrow, I will have to revert
> > >> Chacha-Poly commits before 20.02-rc2, because
> > >>
> > >> 1/ LIST_END, without any comment, means "size of range"
> > >> 2/ we do not blame users for undocumented ABI changes
> > >> 3/ we respect the ABI compatibility contract
04/02/2020 11:16, Akhil Goyal: > Hi, > > On 2/3/2020 5:09 PM, Thomas Monjalon wrote: > > > 03/02/2020 10:30, Ferruh Yigit: > > >> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: > > >>> 02/02/2020 14:05, Thomas Monjalon: > > >>>> 31/01/2020 15:16, Trahe, Fiona: > > >>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: > > >>>>>> 30/01/2020 17:09, Ferruh Yigit: > > >>>>>>> On 1/29/2020 8:13 PM, Akhil Goyal wrote: > > >>>>>>>> > > >>>>>>>> I believe these enums will be used only in case of ASYM case which is > > experimental. > > >>>>>>> > > >>>>>>> Independent from being experiment and not, this shouldn't be a > > problem, I think > > >>>>>>> this is a false positive. > > >>>>>>> > > >>>>>>> The ABI break can happen when a struct has been shared between the > > application > > >>>>>>> and the library (DPDK) and the layout of that memory know differently > > by > > >>>>>>> application and the library. > > >>>>>>> > > >>>>>>> Here in all cases, there is no layout/size change. > > >>>>>>> > > >>>>>>> As to the value changes of the enums, since application compiled with > > old DPDK, > > >>>>>>> it will know only up to '6', 7 and more means invalid to the application. > > So it > > >>>>>>> won't send these values also it should ignore these values from library. > > Only > > >>>>>>> consequence is old application won't able to use new features those > > new enums > > >>>>>>> provide but that is expected/normal. > > >>>>>> > > >>>>>> If library give higher value than expected by the application, > > >>>>>> if the application uses this value as array index, > > >>>>>> there can be an access out of bounds. > > >>>>> > > >>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a > > problem. > > >>>>> But for the same issue with sym crypto below, I believe Ferruh's > > explanation makes > > >>>>> sense and I don't see how there can be an API breakage. > > >>>>> So if an application hasn't compiled against the new lib it will be still using > > the old value > > >>>>> which will be within bounds. If it's picking up the higher new value from > > the lib it must > > >>>>> have been compiled against the lib so shouldn't have problems. > > >>>> > > >>>> You say there is no ABI issue because the application will be re-compiled > > >>>> for the updated library. Indeed, compilation fixes compatibility issues. > > >>>> But this is not relevant for ABI compatibility. > > >>>> ABI compatibility means we can upgrade the library without recompiling > > >>>> the application and it must work. > > >>>> You think it is a false positive because you assume the application > > >>>> "picks" the new value. I think you miss the case where the new value > > >>>> is returned by a function in the upgraded library. > > >>>> > > >>>>> There are also no structs on the API which contain arrays using this > > >>>>> for sizing, so I don't see an opportunity for an appl to have a > > >>>>> mismatch in memory addresses. > > >>>> > > >>>> Let me demonstrate where the API may "use" the new value > > >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the > > application. > > >>>> > > >>>> Once upon a time a DPDK application counting the number of devices > > >>>> supporting each AEAD algo (in order to find the best supported algo). > > >>>> It is done in an array indexed by algo id: > > >>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; > > >>>> The application is compiled with DPDK 19.11, > > >>>> where RTE_CRYPTO_AEAD_LIST_END = 3. > > >>>> So the size of the application array aead_dev_count is 3. > > >>>> This binary is run with DPDK 20.02, > > >>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. > > >>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3, > > >>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to > > >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). > > >>>> The application uses this value: > > >>>> ++ aead_dev_count[info.capabilities.sym.aead.algo]; > > >>>> The application is crashing because of out of bound access. > > >>> > > >>> I'd say this is an example of bad written app. > > >>> It probably should check that returned by library value doesn't > > >>> exceed its internal array size. > > >> > > >> +1 > > >> > > >> Application should ignore values >= MAX. > > > > > > Of course, blaming the API user is a lot easier than looking at the API. > > > Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood > > > as the max value for the application. > > > Value ranges are part of the ABI compatibility contract. > > > It seems you expect the application developer to be aware that > > > DPDK could return a higher value, so the application should > > > check every enum values after calling an API. CRAZY. > > > > > > When we decide to announce an ABI compatibility and do some marketing, > > > everyone is OK. But when we need to really make our ABI compatible, > > > I see little or no effort. DISAPPOINTING. > > > > This is not to blame the user or to do less work, this is more sane approach > > that library provides the _END/_MAX value and application uses it as valid range > > check. > > > > > > > >> Do you suggest we don't extend any enum or define between ABI breakage > > releases > > >> to be sure bad written applications not affected? > > > > > > I suggest we must consider not breaking any assumption made on the API. > > > Here we are breaking the enum range because nothing mentions _LIST_END > > > is not really the absolute end of the enum. > > > The solution is to make the change below in 20.02 + backport in 19.11.1: > > > > > > - _LIST_END > > > + _LIST_END, /* an ABI-compatible version may increase this value */ > > > + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */ > > > }; > > > > > > > What is the point of "_LIST_MAX" here? > > > > Application should know the "_LIST_END" of when it has been compiled for the > > valid range check. Next time it is compiled "_LIST_END" may be different value > > but same logic applies. > > > > When "_LIST_END" is missing, application can't protect itself, in that case > > library should send only the values application knows when it is compiled, this > > means either we can't extend our enum/defines until next ABI breakage, or we > > need to do ABI versioning to the functions that returns an enum each time enum > > value extended. > > > > I believe it is saner to provide _END/_MAX values to the application to use. And > > if required comment them to clarify the expected usage. > > > > But in above suggestion application can't use or rely on "_LIST_MAX", it doesn't > > mean anything to application. > > > > Can we have something like > enum rte_crypto_aead_algorithm { > RTE_CRYPTO_AEAD_AES_CCM = 1, > /**< AES algorithm in CCM mode. */ > RTE_CRYPTO_AEAD_AES_GCM, > /**< AES algorithm in GCM mode. */ > RTE_CRYPTO_AEAD_LIST_END, > /**< List end for 19.11 ABI compatibility */ > RTE_CRYPTO_AEAD_CHACHA20_POLY1305, > /**< Chacha20 cipher with poly1305 authenticator */ > RTE_CRYPTO_AEAD_LIST_END_2011 > /**< List end for 20.11 ABI compatibility */ > }; > > And in 20.11 release we alter the RTE_CRYPTO_AEAD_LIST_END to the end and remove RTE_CRYPTO_AEAD_LIST_END_2011 > > I believe it will be ok for any application which need to use the chacha poly assume that this algo is > Experimental and will move to formal list in 20.11. This can be documented in the documentation. > I believe there is no way to add a new enum as experimental so far. This way we can formalize this > requirement as well. > > I believe this way effect of ABI breakage will be nullified. This is a possibility in the (a) proposal. But it breaks API (and ABI) because a high value is returned while not expected by the application. I guess ABI and release maintainers will vote no to such breakage. Note: I vote no. > > > Then *_LIST_END values could be ignored by libabigail with such a change. > > > > > > If such a patch is not done by tomorrow, I will have to revert > > > Chacha-Poly commits before 20.02-rc2, because > > > > > > 1/ LIST_END, without any comment, means "size of range" > > > 2/ we do not blame users for undocumented ABI changes > > > 3/ we respect the ABI compatibility contract
> > 04/02/2020 11:16, Akhil Goyal: > > Hi, > > > On 2/3/2020 5:09 PM, Thomas Monjalon wrote: > > > > 03/02/2020 10:30, Ferruh Yigit: > > > >> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: > > > >>> 02/02/2020 14:05, Thomas Monjalon: > > > >>>> 31/01/2020 15:16, Trahe, Fiona: > > > >>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: > > > >>>>>> 30/01/2020 17:09, Ferruh Yigit: > > > >>>>>>> On 1/29/2020 8:13 PM, Akhil Goyal wrote: > > > >>>>>>>> > > > >>>>>>>> I believe these enums will be used only in case of ASYM case which > is > > > experimental. > > > >>>>>>> > > > >>>>>>> Independent from being experiment and not, this shouldn't be a > > > problem, I think > > > >>>>>>> this is a false positive. > > > >>>>>>> > > > >>>>>>> The ABI break can happen when a struct has been shared between > the > > > application > > > >>>>>>> and the library (DPDK) and the layout of that memory know > differently > > > by > > > >>>>>>> application and the library. > > > >>>>>>> > > > >>>>>>> Here in all cases, there is no layout/size change. > > > >>>>>>> > > > >>>>>>> As to the value changes of the enums, since application compiled > with > > > old DPDK, > > > >>>>>>> it will know only up to '6', 7 and more means invalid to the > application. > > > So it > > > >>>>>>> won't send these values also it should ignore these values from > library. > > > Only > > > >>>>>>> consequence is old application won't able to use new features > those > > > new enums > > > >>>>>>> provide but that is expected/normal. > > > >>>>>> > > > >>>>>> If library give higher value than expected by the application, > > > >>>>>> if the application uses this value as array index, > > > >>>>>> there can be an access out of bounds. > > > >>>>> > > > >>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a > > > problem. > > > >>>>> But for the same issue with sym crypto below, I believe Ferruh's > > > explanation makes > > > >>>>> sense and I don't see how there can be an API breakage. > > > >>>>> So if an application hasn't compiled against the new lib it will be still > using > > > the old value > > > >>>>> which will be within bounds. If it's picking up the higher new value > from > > > the lib it must > > > >>>>> have been compiled against the lib so shouldn't have problems. > > > >>>> > > > >>>> You say there is no ABI issue because the application will be re- > compiled > > > >>>> for the updated library. Indeed, compilation fixes compatibility issues. > > > >>>> But this is not relevant for ABI compatibility. > > > >>>> ABI compatibility means we can upgrade the library without > recompiling > > > >>>> the application and it must work. > > > >>>> You think it is a false positive because you assume the application > > > >>>> "picks" the new value. I think you miss the case where the new value > > > >>>> is returned by a function in the upgraded library. > > > >>>> > > > >>>>> There are also no structs on the API which contain arrays using this > > > >>>>> for sizing, so I don't see an opportunity for an appl to have a > > > >>>>> mismatch in memory addresses. > > > >>>> > > > >>>> Let me demonstrate where the API may "use" the new value > > > >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the > > > application. > > > >>>> > > > >>>> Once upon a time a DPDK application counting the number of devices > > > >>>> supporting each AEAD algo (in order to find the best supported algo). > > > >>>> It is done in an array indexed by algo id: > > > >>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; > > > >>>> The application is compiled with DPDK 19.11, > > > >>>> where RTE_CRYPTO_AEAD_LIST_END = 3. > > > >>>> So the size of the application array aead_dev_count is 3. > > > >>>> This binary is run with DPDK 20.02, > > > >>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. > > > >>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3, > > > >>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to > > > >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). > > > >>>> The application uses this value: > > > >>>> ++ aead_dev_count[info.capabilities.sym.aead.algo]; > > > >>>> The application is crashing because of out of bound access. > > > >>> > > > >>> I'd say this is an example of bad written app. > > > >>> It probably should check that returned by library value doesn't > > > >>> exceed its internal array size. > > > >> > > > >> +1 > > > >> > > > >> Application should ignore values >= MAX. > > > > > > > > Of course, blaming the API user is a lot easier than looking at the API. > > > > Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood > > > > as the max value for the application. > > > > Value ranges are part of the ABI compatibility contract. > > > > It seems you expect the application developer to be aware that > > > > DPDK could return a higher value, so the application should > > > > check every enum values after calling an API. CRAZY. > > > > > > > > When we decide to announce an ABI compatibility and do some marketing, > > > > everyone is OK. But when we need to really make our ABI compatible, > > > > I see little or no effort. DISAPPOINTING. > > > > > > This is not to blame the user or to do less work, this is more sane approach > > > that library provides the _END/_MAX value and application uses it as valid > range > > > check. > > > > > > > > > > >> Do you suggest we don't extend any enum or define between ABI > breakage > > > releases > > > >> to be sure bad written applications not affected? > > > > > > > > I suggest we must consider not breaking any assumption made on the API. > > > > Here we are breaking the enum range because nothing mentions > _LIST_END > > > > is not really the absolute end of the enum. > > > > The solution is to make the change below in 20.02 + backport in 19.11.1: > > > > > > > > - _LIST_END > > > > + _LIST_END, /* an ABI-compatible version may increase this value */ > > > > + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */ > > > > }; > > > > > > > > > > What is the point of "_LIST_MAX" here? > > > > > > Application should know the "_LIST_END" of when it has been compiled for > the > > > valid range check. Next time it is compiled "_LIST_END" may be different > value > > > but same logic applies. > > > > > > When "_LIST_END" is missing, application can't protect itself, in that case > > > library should send only the values application knows when it is compiled, > this > > > means either we can't extend our enum/defines until next ABI breakage, or > we > > > need to do ABI versioning to the functions that returns an enum each time > enum > > > value extended. > > > > > > I believe it is saner to provide _END/_MAX values to the application to use. > And > > > if required comment them to clarify the expected usage. > > > > > > But in above suggestion application can't use or rely on "_LIST_MAX", it > doesn't > > > mean anything to application. > > > > > > > Can we have something like > > enum rte_crypto_aead_algorithm { > > RTE_CRYPTO_AEAD_AES_CCM = 1, > > /**< AES algorithm in CCM mode. */ > > RTE_CRYPTO_AEAD_AES_GCM, > > /**< AES algorithm in GCM mode. */ > > RTE_CRYPTO_AEAD_LIST_END, > > /**< List end for 19.11 ABI compatibility */ > > RTE_CRYPTO_AEAD_CHACHA20_POLY1305, > > /**< Chacha20 cipher with poly1305 authenticator */ > > RTE_CRYPTO_AEAD_LIST_END_2011 > > /**< List end for 20.11 ABI compatibility */ > > }; > > > > And in 20.11 release we alter the RTE_CRYPTO_AEAD_LIST_END to the end > and remove RTE_CRYPTO_AEAD_LIST_END_2011 > > > > I believe it will be ok for any application which need to use the chacha poly > assume that this algo is > > Experimental and will move to formal list in 20.11. This can be documented in > the documentation. > > I believe there is no way to add a new enum as experimental so far. This way > we can formalize this > > requirement as well. > > > > I believe this way effect of ABI breakage will be nullified. > > This is a possibility in the (a) proposal. > But it breaks API (and ABI) because a high value is returned > while not expected by the application. > > I guess ABI and release maintainers will vote no to such breakage. > Note: I vote no. > If that is the case, I would say we should go with b). Versioned APIs does not look good and adds more confusion. > > > > > Then *_LIST_END values could be ignored by libabigail with such a change. > > > > > > > > If such a patch is not done by tomorrow, I will have to revert > > > > Chacha-Poly commits before 20.02-rc2, because > > > > > > > > 1/ LIST_END, without any comment, means "size of range" > > > > 2/ we do not blame users for undocumented ABI changes > > > > 3/ we respect the ABI compatibility contract > > > >
04/02/2020 11:10, Trahe, Fiona: > And not used for sizing > > > > > There a c) though right. > > > We could work around the issue by api versioning rte_cryptodev_info_get() and friends. > > > > It has a lot of friends, but it sounds like the right approach. > > Is someone looking into this? > [Fiona] Yes. But not clear yet if can be done by tomorrow. Should be done by today now. > But even if feasible, that only works around the current issue. > There is a bigger issue to be decided here - > Should we be removing LIST_END/MAX values from all enums in 20.11? > Or defining through API comment that they should only be used as a range boundary and > NOT to size an array. And so having a fixed value is not part of the API contract. Please let's discuss 20.11 API later. It is not so urgent.
On Tue, Feb 04, 2020 at 10:32:01AM +0000, Akhil Goyal wrote:
>
> >
> > 04/02/2020 11:16, Akhil Goyal:
> > > Hi,
> > > > On 2/3/2020 5:09 PM, Thomas Monjalon wrote:
> > > > > 03/02/2020 10:30, Ferruh Yigit:
> > > > >> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote:
> > > > >>> 02/02/2020 14:05, Thomas Monjalon:
> > > > >>>> 31/01/2020 15:16, Trahe, Fiona:
> > > > >>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote:
> > > > >>>>>> 30/01/2020 17:09, Ferruh Yigit:
> > > > >>>>>>> On 1/29/2020 8:13 PM, Akhil Goyal wrote:
> > > > >>>>>>>>
> > > > >>>>>>>> I believe these enums will be used only in case of ASYM case which
> > is
> > > > experimental.
> > > > >>>>>>>
> > > > >>>>>>> Independent from being experiment and not, this shouldn't be a
> > > > problem, I think
> > > > >>>>>>> this is a false positive.
> > > > >>>>>>>
> > > > >>>>>>> The ABI break can happen when a struct has been shared between
> > the
> > > > application
> > > > >>>>>>> and the library (DPDK) and the layout of that memory know
> > differently
> > > > by
> > > > >>>>>>> application and the library.
> > > > >>>>>>>
> > > > >>>>>>> Here in all cases, there is no layout/size change.
> > > > >>>>>>>
> > > > >>>>>>> As to the value changes of the enums, since application compiled
> > with
> > > > old DPDK,
> > > > >>>>>>> it will know only up to '6', 7 and more means invalid to the
> > application.
> > > > So it
> > > > >>>>>>> won't send these values also it should ignore these values from
> > library.
> > > > Only
> > > > >>>>>>> consequence is old application won't able to use new features
> > those
> > > > new enums
> > > > >>>>>>> provide but that is expected/normal.
> > > > >>>>>>
> > > > >>>>>> If library give higher value than expected by the application,
> > > > >>>>>> if the application uses this value as array index,
> > > > >>>>>> there can be an access out of bounds.
> > > > >>>>>
> > > > >>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a
> > > > problem.
> > > > >>>>> But for the same issue with sym crypto below, I believe Ferruh's
> > > > explanation makes
> > > > >>>>> sense and I don't see how there can be an API breakage.
> > > > >>>>> So if an application hasn't compiled against the new lib it will be still
> > using
> > > > the old value
> > > > >>>>> which will be within bounds. If it's picking up the higher new value
> > from
> > > > the lib it must
> > > > >>>>> have been compiled against the lib so shouldn't have problems.
> > > > >>>>
> > > > >>>> You say there is no ABI issue because the application will be re-
> > compiled
> > > > >>>> for the updated library. Indeed, compilation fixes compatibility issues.
> > > > >>>> But this is not relevant for ABI compatibility.
> > > > >>>> ABI compatibility means we can upgrade the library without
> > recompiling
> > > > >>>> the application and it must work.
> > > > >>>> You think it is a false positive because you assume the application
> > > > >>>> "picks" the new value. I think you miss the case where the new value
> > > > >>>> is returned by a function in the upgraded library.
> > > > >>>>
> > > > >>>>> There are also no structs on the API which contain arrays using this
> > > > >>>>> for sizing, so I don't see an opportunity for an appl to have a
> > > > >>>>> mismatch in memory addresses.
> > > > >>>>
> > > > >>>> Let me demonstrate where the API may "use" the new value
> > > > >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the
> > > > application.
> > > > >>>>
> > > > >>>> Once upon a time a DPDK application counting the number of devices
> > > > >>>> supporting each AEAD algo (in order to find the best supported algo).
> > > > >>>> It is done in an array indexed by algo id:
> > > > >>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END];
> > > > >>>> The application is compiled with DPDK 19.11,
> > > > >>>> where RTE_CRYPTO_AEAD_LIST_END = 3.
> > > > >>>> So the size of the application array aead_dev_count is 3.
> > > > >>>> This binary is run with DPDK 20.02,
> > > > >>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3.
> > > > >>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3,
> > > > >>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to
> > > > >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3).
> > > > >>>> The application uses this value:
> > > > >>>> ++ aead_dev_count[info.capabilities.sym.aead.algo];
> > > > >>>> The application is crashing because of out of bound access.
> > > > >>>
> > > > >>> I'd say this is an example of bad written app.
> > > > >>> It probably should check that returned by library value doesn't
> > > > >>> exceed its internal array size.
> > > > >>
> > > > >> +1
> > > > >>
> > > > >> Application should ignore values >= MAX.
> > > > >
> > > > > Of course, blaming the API user is a lot easier than looking at the API.
> > > > > Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood
> > > > > as the max value for the application.
> > > > > Value ranges are part of the ABI compatibility contract.
> > > > > It seems you expect the application developer to be aware that
> > > > > DPDK could return a higher value, so the application should
> > > > > check every enum values after calling an API. CRAZY.
> > > > >
> > > > > When we decide to announce an ABI compatibility and do some marketing,
> > > > > everyone is OK. But when we need to really make our ABI compatible,
> > > > > I see little or no effort. DISAPPOINTING.
> > > >
> > > > This is not to blame the user or to do less work, this is more sane approach
> > > > that library provides the _END/_MAX value and application uses it as valid
> > range
> > > > check.
> > > >
> > > > >
> > > > >> Do you suggest we don't extend any enum or define between ABI
> > breakage
> > > > releases
> > > > >> to be sure bad written applications not affected?
> > > > >
> > > > > I suggest we must consider not breaking any assumption made on the API.
> > > > > Here we are breaking the enum range because nothing mentions
> > _LIST_END
> > > > > is not really the absolute end of the enum.
> > > > > The solution is to make the change below in 20.02 + backport in 19.11.1:
> > > > >
> > > > > - _LIST_END
> > > > > + _LIST_END, /* an ABI-compatible version may increase this value */
> > > > > + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */
> > > > > };
> > > > >
> > > >
> > > > What is the point of "_LIST_MAX" here?
> > > >
> > > > Application should know the "_LIST_END" of when it has been compiled for
> > the
> > > > valid range check. Next time it is compiled "_LIST_END" may be different
> > value
> > > > but same logic applies.
> > > >
> > > > When "_LIST_END" is missing, application can't protect itself, in that case
> > > > library should send only the values application knows when it is compiled,
> > this
> > > > means either we can't extend our enum/defines until next ABI breakage, or
> > we
> > > > need to do ABI versioning to the functions that returns an enum each time
> > enum
> > > > value extended.
> > > >
> > > > I believe it is saner to provide _END/_MAX values to the application to use.
> > And
> > > > if required comment them to clarify the expected usage.
> > > >
> > > > But in above suggestion application can't use or rely on "_LIST_MAX", it
> > doesn't
> > > > mean anything to application.
> > > >
> > >
> > > Can we have something like
> > > enum rte_crypto_aead_algorithm {
> > > RTE_CRYPTO_AEAD_AES_CCM = 1,
> > > /**< AES algorithm in CCM mode. */
> > > RTE_CRYPTO_AEAD_AES_GCM,
> > > /**< AES algorithm in GCM mode. */
> > > RTE_CRYPTO_AEAD_LIST_END,
> > > /**< List end for 19.11 ABI compatibility */
> > > RTE_CRYPTO_AEAD_CHACHA20_POLY1305,
> > > /**< Chacha20 cipher with poly1305 authenticator */
> > > RTE_CRYPTO_AEAD_LIST_END_2011
> > > /**< List end for 20.11 ABI compatibility */
> > > };
> > >
> > > And in 20.11 release we alter the RTE_CRYPTO_AEAD_LIST_END to the end
> > and remove RTE_CRYPTO_AEAD_LIST_END_2011
> > >
> > > I believe it will be ok for any application which need to use the chacha poly
> > assume that this algo is
> > > Experimental and will move to formal list in 20.11. This can be documented in
> > the documentation.
> > > I believe there is no way to add a new enum as experimental so far. This way
> > we can formalize this
> > > requirement as well.
> > >
> > > I believe this way effect of ABI breakage will be nullified.
> >
> > This is a possibility in the (a) proposal.
> > But it breaks API (and ABI) because a high value is returned
> > while not expected by the application.
> >
> > I guess ABI and release maintainers will vote no to such breakage.
> > Note: I vote no.
> >
>
> If that is the case, I would say we should go with b).
>
> Versioned APIs does not look good and adds more confusion.
>
How does it add confusion, it's the standard and recommended way to fix
things like this? To maintain stable ABIs in the medium and long term we
need to get used to using versioning and not be afraid of it. Developers
will soon get used to the added bit of complexity it involves.
Regards,
/Bruce
> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Tuesday, February 4, 2020 10:24 AM
> To: David Marchand <david.marchand@redhat.com>; nhorman@tuxdriver.com; bluca@debian.org;
> ktraynor@redhat.com; Ray Kinsella <mdr@ashroe.eu>; dev@dpdk.org; Akhil Goyal
> <akhil.goyal@nxp.com>; Trahe, Fiona <fiona.trahe@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>
> Cc: Ananyev, Konstantin <konstantin.ananyev@intel.com>; dev@dpdk.org; Anoob Joseph
> <anoobj@marvell.com>; Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>; Richardson, Bruce
> <bruce.richardson@intel.com>; Mcnamara, John <john.mcnamara@intel.com>; dodji@seketeli.net;
> Andrew Rybchenko <arybchenko@solarflare.com>; aconole@redhat.com
> Subject: Re: [dpdk-dev] [PATCH v2 4/4] add ABI checks
>
> RED FLAG
>
> I don't see a lot of reactions, so I summarize the issue.
> We need action TODAY!
>
> API makes think that rte_cryptodev_info_get() cannot return
> a value >= 3 (RTE_CRYPTO_AEAD_LIST_END in 19.11).
> Current 20.02 returns 3 (RTE_CRYPTO_AEAD_CHACHA20_POLY1305).
> The ABI compatibility contract is broken currently.
>
> There are 3 possible outcomes:
>
> a) Change the API comments and backport to 19.11.1
> The details are discussed between Ferruh and me.
> Either put responsibility on API user (with explicit comment),
> or expose ABI extension allowance with a new API max value.
> In both cases, this is breaking the implicit contract of 19.11.0.
> This option can be chosen only if release and ABI maintainers
> vote for it.
>
> b) Revert Chacha-Poly from 20.02-rc2.
>
> c) Add versioned function rte_cryptodev_info_get_v1911()
> which calls rte_cryptodev_info_get() and filters out
> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 capability.
> So Chacha-Poly capability would be seen and usable only
> if compiling with DPDK 20.02.
>
> I hope it is clear what are the actions for everybody:
> - ABI and release maintainers must say yes or no to the proposal (a)
> - In the meantime, crypto team must send a patch for the proposal (c)
> - If (a) and (c) are not possible at the end of today, I will take (b)
>
> Note: do not say it is too short for (c), as it was possible to work
> on such solution since the issue was exposed on last Wednesday.
>
[Fiona] Thanks for your understanding and help with our scheduling Thomas.
We are working on a patch, when it is ready we will send it.
If it's not ready by end of your today, of course, go ahead with (b) and
we will work towards 20.05.
On 04/02/2020 10:24, Thomas Monjalon wrote: > RED FLAG > > I don't see a lot of reactions, so I summarize the issue. > We need action TODAY! > > API makes think that rte_cryptodev_info_get() cannot return > a value >= 3 (RTE_CRYPTO_AEAD_LIST_END in 19.11). > Current 20.02 returns 3 (RTE_CRYPTO_AEAD_CHACHA20_POLY1305). > The ABI compatibility contract is broken currently. > > There are 3 possible outcomes: > > a) Change the API comments and backport to 19.11.1 > The details are discussed between Ferruh and me. > Either put responsibility on API user (with explicit comment), > or expose ABI extension allowance with a new API max value. > In both cases, this is breaking the implicit contract of 19.11.0. > This option can be chosen only if release and ABI maintainers > vote for it. > > b) Revert Chacha-Poly from 20.02-rc2. > > c) Add versioned function rte_cryptodev_info_get_v1911() > which calls rte_cryptodev_info_get() and filters out > RTE_CRYPTO_AEAD_CHACHA20_POLY1305 capability. > So Chacha-Poly capability would be seen and usable only > if compiling with DPDK 20.02. > Maybe a separate version of rte_cryptodev_get_aead_algo_enum() also needed to handle chacha string differently. > I hope it is clear what are the actions for everybody: > - ABI and release maintainers must say yes or no to the proposal (a) My 2c for a) is No. > - In the meantime, crypto team must send a patch for the proposal (c) > - If (a) and (c) are not possible at the end of today, I will take (b) > > Note: do not say it is too short for (c), as it was possible to work > on such solution since the issue was exposed on last Wednesday. > Could it be reverted today if necessary and re-added later in the release cycle? It seems like something modular that should not invalidate earlier testing. > > 03/02/2020 22:07, Thomas Monjalon: >> 03/02/2020 19:55, Ray Kinsella: >>> On 03/02/2020 17:34, Thomas Monjalon wrote: >>>> 03/02/2020 18:09, Thomas Monjalon: >>>>> 03/02/2020 10:30, Ferruh Yigit: >>>>>> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: >>>>>>> 02/02/2020 14:05, Thomas Monjalon: >>>>>>>> 31/01/2020 15:16, Trahe, Fiona: >>>>>>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: >>>>>>>>>> If library give higher value than expected by the application, >>>>>>>>>> if the application uses this value as array index, >>>>>>>>>> there can be an access out of bounds. >>>>>>>>> >>>>>>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. >>>>>>>>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes >>>>>>>>> sense and I don't see how there can be an API breakage. >>>>>>>>> So if an application hasn't compiled against the new lib it will be still using the old value >>>>>>>>> which will be within bounds. If it's picking up the higher new value from the lib it must >>>>>>>>> have been compiled against the lib so shouldn't have problems. >>>>>>>> >>>>>>>> You say there is no ABI issue because the application will be re-compiled >>>>>>>> for the updated library. Indeed, compilation fixes compatibility issues. >>>>>>>> But this is not relevant for ABI compatibility. >>>>>>>> ABI compatibility means we can upgrade the library without recompiling >>>>>>>> the application and it must work. >>>>>>>> You think it is a false positive because you assume the application >>>>>>>> "picks" the new value. I think you miss the case where the new value >>>>>>>> is returned by a function in the upgraded library. >>>>>>>> >>>>>>>>> There are also no structs on the API which contain arrays using this >>>>>>>>> for sizing, so I don't see an opportunity for an appl to have a >>>>>>>>> mismatch in memory addresses. >>>>>>>> >>>>>>>> Let me demonstrate where the API may "use" the new value >>>>>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application. >>>>>>>> >>>>>>>> Once upon a time a DPDK application counting the number of devices >>>>>>>> supporting each AEAD algo (in order to find the best supported algo). >>>>>>>> It is done in an array indexed by algo id: >>>>>>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; >>>>>>>> The application is compiled with DPDK 19.11, >>>>>>>> where RTE_CRYPTO_AEAD_LIST_END = 3. >>>>>>>> So the size of the application array aead_dev_count is 3. >>>>>>>> This binary is run with DPDK 20.02, >>>>>>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. >>>>>>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3, >>>>>>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to >>>>>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). >>>>>>>> The application uses this value: >>>>>>>> ++ aead_dev_count[info.capabilities.sym.aead.algo]; >>>>>>>> The application is crashing because of out of bound access. >>>>>>> >>>>>>> I'd say this is an example of bad written app. >>>>>>> It probably should check that returned by library value doesn't >>>>>>> exceed its internal array size. >>>>>> >>>>>> +1 >>>>>> >>>>>> Application should ignore values >= MAX. >>>>> >>>>> Of course, blaming the API user is a lot easier than looking at the API. >>>>> Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood >>>>> as the max value for the application. >>>>> Value ranges are part of the ABI compatibility contract. >>>>> It seems you expect the application developer to be aware that >>>>> DPDK could return a higher value, so the application should >>>>> check every enum values after calling an API. CRAZY. >>>>> >>>>> When we decide to announce an ABI compatibility and do some marketing, >>>>> everyone is OK. But when we need to really make our ABI compatible, >>>>> I see little or no effort. DISAPPOINTING. >>>>> >>>>>> Do you suggest we don't extend any enum or define between ABI breakage releases >>>>>> to be sure bad written applications not affected? >>>>> >>>>> I suggest we must consider not breaking any assumption made on the API. >>>>> Here we are breaking the enum range because nothing mentions _LIST_END >>>>> is not really the absolute end of the enum. >>>>> The solution is to make the change below in 20.02 + backport in 19.11.1: >>>> >>>> Thinking twice, merging such change before 20.11 is breaking the >>>> ABI assumption based on the API 19.11.0. >>>> I ask the release maintainers (Luca, Kevin, David and me) and >>>> the ABI maintainers (Neil and Ray) to vote for a or b solution: >>>> a) add comment and LIST_MAX as below in 20.02 + 19.11.1 >>> >>> That would still be an ABI breakage though right. >>> >>>> b) wait 20.11 and revert Chacha-Poly from 20.02 >>> >>> Thanks for analysis above Fiona, Ferruh and all. >>> >>> That is a nasty one alright - there is no "good" answer here. >>> I agree with Ferruh's sentiments overall, we should rethink this API for 20.11. >>> Could do without an enumeration? >>> >>> There a c) though right. >>> We could work around the issue by api versioning rte_cryptodev_info_get() and friends. >>> So they only support/acknowledge the existence of Chacha-Poly for applications build against > 20.02. >> >> I agree there is a c) as I proposed in another email: >> http://mails.dpdk.org/archives/dev/2020-February/156919.html >> " >> In this case, the proper solution is to implement >> rte_cryptodev_info_get_v1911() so it filters out >> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 capability. >> With this solution, an application compiled with DPDK 19.11 will keep >> seeing the same range as before, while a 20.02 application could >> see and use ChachaPoly. >> " >> >>> It would be painful I know. >> >> Not so painful in my opinion. >> Just need to call rte_cryptodev_info_get() from >> rte_cryptodev_info_get_v1911() and filter the value >> in the 19.11 range: [0..AES_GCM]. >> >>> It would also mean that Chacha-Poly would only be available to >>> those building against >= 20.02. >> >> Yes exactly. >> >> The addition of comments and LIST_MAX like below are still valid >> to avoid versioning after 20.11. >> >>>>> - _LIST_END >>>>> + _LIST_END, /* an ABI-compatible version may increase this value */ >>>>> + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */ >>>>> }; >>>>> >>>>> Then *_LIST_END values could be ignored by libabigail with such a change. >> >> In order to avoid ABI check complaining, the best is to completely >> remove LIST_END in DPDK 20.11. >> >> >>>>> If such a patch is not done by tomorrow, I will have to revert >>>>> Chacha-Poly commits before 20.02-rc2, because >>>>> >>>>> 1/ LIST_END, without any comment, means "size of range" >>>>> 2/ we do not blame users for undocumented ABI changes >>>>> 3/ we respect the ABI compatibility contract > > >
Thomas Monjalon <thomas@monjalon.net> writes: > RED FLAG > > I don't see a lot of reactions, so I summarize the issue. > We need action TODAY! > > API makes think that rte_cryptodev_info_get() cannot return > a value >= 3 (RTE_CRYPTO_AEAD_LIST_END in 19.11). > Current 20.02 returns 3 (RTE_CRYPTO_AEAD_CHACHA20_POLY1305). > The ABI compatibility contract is broken currently. > > There are 3 possible outcomes: > > a) Change the API comments and backport to 19.11.1 > The details are discussed between Ferruh and me. > Either put responsibility on API user (with explicit comment), > or expose ABI extension allowance with a new API max value. > In both cases, this is breaking the implicit contract of 19.11.0. > This option can be chosen only if release and ABI maintainers > vote for it. > > b) Revert Chacha-Poly from 20.02-rc2. > > c) Add versioned function rte_cryptodev_info_get_v1911() > which calls rte_cryptodev_info_get() and filters out > RTE_CRYPTO_AEAD_CHACHA20_POLY1305 capability. > So Chacha-Poly capability would be seen and usable only > if compiling with DPDK 20.02. > > I hope it is clear what are the actions for everybody: > - ABI and release maintainers must say yes or no to the proposal (a) > - In the meantime, crypto team must send a patch for the proposal (c) > - If (a) and (c) are not possible at the end of today, I will take (b) > > Note: do not say it is too short for (c), as it was possible to work > on such solution since the issue was exposed on last Wednesday. While I'm not a maintainer, if I my opinion counts for anything, I'd choose option c or b. Absolutely NACK to a. > > 03/02/2020 22:07, Thomas Monjalon: >> 03/02/2020 19:55, Ray Kinsella: >> > On 03/02/2020 17:34, Thomas Monjalon wrote: >> > > 03/02/2020 18:09, Thomas Monjalon: >> > >> 03/02/2020 10:30, Ferruh Yigit: >> > >>> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: >> > >>>> 02/02/2020 14:05, Thomas Monjalon: >> > >>>>> 31/01/2020 15:16, Trahe, Fiona: >> > >>>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: >> > >>>>>>> If library give higher value than expected by the application, >> > >>>>>>> if the application uses this value as array index, >> > >>>>>>> there can be an access out of bounds. >> > >>>>>> >> > >>>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. >> > >>>>>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes >> > >>>>>> sense and I don't see how there can be an API breakage. >> > >>>>>> So if an application hasn't compiled against the new lib it >> > >>>>>> will be still using the old value >> > >>>>>> which will be within bounds. If it's picking up the higher >> > >>>>>> new value from the lib it must >> > >>>>>> have been compiled against the lib so shouldn't have problems. >> > >>>>> >> > >>>>> You say there is no ABI issue because the application will be re-compiled >> > >>>>> for the updated library. Indeed, compilation fixes compatibility issues. >> > >>>>> But this is not relevant for ABI compatibility. >> > >>>>> ABI compatibility means we can upgrade the library without recompiling >> > >>>>> the application and it must work. >> > >>>>> You think it is a false positive because you assume the application >> > >>>>> "picks" the new value. I think you miss the case where the new value >> > >>>>> is returned by a function in the upgraded library. >> > >>>>> >> > >>>>>> There are also no structs on the API which contain arrays using this >> > >>>>>> for sizing, so I don't see an opportunity for an appl to have a >> > >>>>>> mismatch in memory addresses. >> > >>>>> >> > >>>>> Let me demonstrate where the API may "use" the new value >> > >>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application. >> > >>>>> >> > >>>>> Once upon a time a DPDK application counting the number of devices >> > >>>>> supporting each AEAD algo (in order to find the best supported algo). >> > >>>>> It is done in an array indexed by algo id: >> > >>>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; >> > >>>>> The application is compiled with DPDK 19.11, >> > >>>>> where RTE_CRYPTO_AEAD_LIST_END = 3. >> > >>>>> So the size of the application array aead_dev_count is 3. >> > >>>>> This binary is run with DPDK 20.02, >> > >>>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. >> > >>>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3, >> > >>>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to >> > >>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). >> > >>>>> The application uses this value: >> > >>>>> ++ aead_dev_count[info.capabilities.sym.aead.algo]; >> > >>>>> The application is crashing because of out of bound access. >> > >>>> >> > >>>> I'd say this is an example of bad written app. >> > >>>> It probably should check that returned by library value doesn't >> > >>>> exceed its internal array size. >> > >>> >> > >>> +1 >> > >>> >> > >>> Application should ignore values >= MAX. >> > >> >> > >> Of course, blaming the API user is a lot easier than looking at the API. >> > >> Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood >> > >> as the max value for the application. >> > >> Value ranges are part of the ABI compatibility contract. >> > >> It seems you expect the application developer to be aware that >> > >> DPDK could return a higher value, so the application should >> > >> check every enum values after calling an API. CRAZY. >> > >> >> > >> When we decide to announce an ABI compatibility and do some marketing, >> > >> everyone is OK. But when we need to really make our ABI compatible, >> > >> I see little or no effort. DISAPPOINTING. >> > >> >> > >>> Do you suggest we don't extend any enum or define between ABI breakage releases >> > >>> to be sure bad written applications not affected? >> > >> >> > >> I suggest we must consider not breaking any assumption made on the API. >> > >> Here we are breaking the enum range because nothing mentions _LIST_END >> > >> is not really the absolute end of the enum. >> > >> The solution is to make the change below in 20.02 + backport in 19.11.1: >> > > >> > > Thinking twice, merging such change before 20.11 is breaking the >> > > ABI assumption based on the API 19.11.0. >> > > I ask the release maintainers (Luca, Kevin, David and me) and >> > > the ABI maintainers (Neil and Ray) to vote for a or b solution: >> > > a) add comment and LIST_MAX as below in 20.02 + 19.11.1 >> > >> > That would still be an ABI breakage though right. >> > >> > > b) wait 20.11 and revert Chacha-Poly from 20.02 >> > >> > Thanks for analysis above Fiona, Ferruh and all. >> > >> > That is a nasty one alright - there is no "good" answer here. >> > I agree with Ferruh's sentiments overall, we should rethink this API for 20.11. >> > Could do without an enumeration? >> > >> > There a c) though right. >> > We could work around the issue by api versioning rte_cryptodev_info_get() and friends. >> > So they only support/acknowledge the existence of Chacha-Poly for >> > applications build against > 20.02. >> >> I agree there is a c) as I proposed in another email: >> http://mails.dpdk.org/archives/dev/2020-February/156919.html >> " >> In this case, the proper solution is to implement >> rte_cryptodev_info_get_v1911() so it filters out >> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 capability. >> With this solution, an application compiled with DPDK 19.11 will keep >> seeing the same range as before, while a 20.02 application could >> see and use ChachaPoly. >> " >> >> > It would be painful I know. >> >> Not so painful in my opinion. >> Just need to call rte_cryptodev_info_get() from >> rte_cryptodev_info_get_v1911() and filter the value >> in the 19.11 range: [0..AES_GCM]. >> >> > It would also mean that Chacha-Poly would only be available to >> > those building against >= 20.02. >> >> Yes exactly. >> >> The addition of comments and LIST_MAX like below are still valid >> to avoid versioning after 20.11. >> >> > >> - _LIST_END >> > >> + _LIST_END, /* an ABI-compatible version may increase this value */ >> > >> + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */ >> > >> }; >> > >> >> > >> Then *_LIST_END values could be ignored by libabigail with such a change. >> >> In order to avoid ABI check complaining, the best is to completely >> remove LIST_END in DPDK 20.11. >> >> >> > >> If such a patch is not done by tomorrow, I will have to revert >> > >> Chacha-Poly commits before 20.02-rc2, because >> > >> >> > >> 1/ LIST_END, without any comment, means "size of range" >> > >> 2/ we do not blame users for undocumented ABI changes >> > >> 3/ we respect the ABI compatibility contract
> We are working on a patch, when it is ready we will send it.
> If it's not ready by end of your today, of course, go ahead with (b) and
> we will work towards 20.05.
We will not be sending a patch today.
The patch we're working on will provide two versions of rte_cryptodev_info_get(),
both call the same PMD function from the dev_ops info_get fn ptr.
The default version operates s as normal, the 19.11 version searches
through the list returned by the PMD, looking for sym.aead.algo = ChaChaPoly, it needs to strip it from the list.
As PMDs just pass a ptr to their capabilities list ( it isn't a linked list, but an array
with an end marker = RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST) if the API
layer detects Chacha it must allocate some space and store a local copy of the
trimmed list. This must be stored only once per device.
This versioning will apply to any PMD which wants to take advantage of the new API between now and 20.11.
Note, I expect the ABI checker tools will still complain of ABI breakage as the LIST_END value will still change.
We are also reviewing all other cryptodev APIs in case there is any other API which needs versioning.
Anyone see any problem with this approach?
04/02/2020 16:52, Trahe, Fiona: > > > We are working on a patch, when it is ready we will send it. > > If it's not ready by end of your today, of course, go ahead with (b) and > > we will work towards 20.05. > > We will not be sending a patch today. > The patch we're working on will provide two versions of rte_cryptodev_info_get(), > both call the same PMD function from the dev_ops info_get fn ptr. > The default version operates s as normal, the 19.11 version searches > through the list returned by the PMD, looking for sym.aead.algo = ChaChaPoly, it needs to strip it from the list. > As PMDs just pass a ptr to their capabilities list ( it isn't a linked list, but an array > with an end marker = RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST) if the API > layer detects Chacha it must allocate some space and store a local copy of the > trimmed list. This must be stored only once per device. I don't understand what you have to store. Can't you just set the algo to 0 if it is ChaCha? > This versioning will apply to any PMD which wants to take advantage of the new API between now and 20.11. > > Note, I expect the ABI checker tools will still complain of ABI breakage as the LIST_END value will still change. Right, you need to update the ignore list for the tool. > We are also reviewing all other cryptodev APIs in case there is any other API which needs versioning. > > Anyone see any problem with this approach? The other issue is with all other functions accepting this enum as input. We should continue returning an error if getting Chacha as input with 19.11 version of these functions. But I would tend to consider this small ABI breakage can be ignored as it is in the error path.
> -----Original Message----- > From: Thomas Monjalon <thomas@monjalon.net> > Sent: Tuesday, February 4, 2020 4:00 PM > To: Trahe, Fiona <fiona.trahe@intel.com> > Cc: David Marchand <david.marchand@redhat.com>; nhorman@tuxdriver.com; bluca@debian.org; > ktraynor@redhat.com; Ray Kinsella <mdr@ashroe.eu>; dev@dpdk.org; Akhil Goyal > <akhil.goyal@nxp.com>; Yigit, Ferruh <ferruh.yigit@intel.com>; Ananyev, Konstantin > <konstantin.ananyev@intel.com>; dev@dpdk.org; Anoob Joseph <anoobj@marvell.com>; Kusztal, > ArkadiuszX <arkadiuszx.kusztal@intel.com>; Richardson, Bruce <bruce.richardson@intel.com>; > Mcnamara, John <john.mcnamara@intel.com>; dodji@seketeli.net; Andrew Rybchenko > <arybchenko@solarflare.com>; aconole@redhat.com > Subject: Re: [dpdk-dev] [PATCH v2 4/4] add ABI checks > > 04/02/2020 16:52, Trahe, Fiona: > > > > > We are working on a patch, when it is ready we will send it. > > > If it's not ready by end of your today, of course, go ahead with (b) and > > > we will work towards 20.05. > > > > We will not be sending a patch today. > > The patch we're working on will provide two versions of rte_cryptodev_info_get(), > > both call the same PMD function from the dev_ops info_get fn ptr. > > The default version operates s as normal, the 19.11 version searches > > through the list returned by the PMD, looking for sym.aead.algo = ChaChaPoly, it needs to strip it from > the list. > > As PMDs just pass a ptr to their capabilities list ( it isn't a linked list, but an array > > with an end marker = RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST) if the API > > layer detects Chacha it must allocate some space and store a local copy of the > > trimmed list. This must be stored only once per device. > > I don't understand what you have to store. > Can't you just set the algo to 0 if it is ChaCha? [Fiona] it returns a pointer to data in the PMD domain, which the API couldn't and shouldn't overwrite, e.g. static const struct rte_cryptodev_capabilities qat_gen3_sym_capabilities[] > > > This versioning will apply to any PMD which wants to take advantage of the new API between now and > 20.11. > > > > Note, I expect the ABI checker tools will still complain of ABI breakage as the LIST_END value will still > change. > > Right, you need to update the ignore list for the tool. > > > We are also reviewing all other cryptodev APIs in case there is any other API which needs versioning. > > > > Anyone see any problem with this approach? > > The other issue is with all other functions accepting this enum as input. > We should continue returning an error if getting Chacha as input with > 19.11 version of these functions. > But I would tend to consider this small ABI breakage can be ignored > as it is in the error path. [Fiona] The QAT PMD tests for and handles this error. I expect other PMDs do too.
On Tue, Feb 04, 2020 at 09:44:53AM -0500, Aaron Conole wrote: > Thomas Monjalon <thomas@monjalon.net> writes: > > > RED FLAG > > > > I don't see a lot of reactions, so I summarize the issue. > > We need action TODAY! > > > > API makes think that rte_cryptodev_info_get() cannot return > > a value >= 3 (RTE_CRYPTO_AEAD_LIST_END in 19.11). > > Current 20.02 returns 3 (RTE_CRYPTO_AEAD_CHACHA20_POLY1305). > > The ABI compatibility contract is broken currently. > > > > There are 3 possible outcomes: > > > > a) Change the API comments and backport to 19.11.1 > > The details are discussed between Ferruh and me. > > Either put responsibility on API user (with explicit comment), > > or expose ABI extension allowance with a new API max value. > > In both cases, this is breaking the implicit contract of 19.11.0. > > This option can be chosen only if release and ABI maintainers > > vote for it. > > > > b) Revert Chacha-Poly from 20.02-rc2. > > > > c) Add versioned function rte_cryptodev_info_get_v1911() > > which calls rte_cryptodev_info_get() and filters out > > RTE_CRYPTO_AEAD_CHACHA20_POLY1305 capability. > > So Chacha-Poly capability would be seen and usable only > > if compiling with DPDK 20.02. > > > > I hope it is clear what are the actions for everybody: > > - ABI and release maintainers must say yes or no to the proposal (a) > > - In the meantime, crypto team must send a patch for the proposal (c) > > - If (a) and (c) are not possible at the end of today, I will take (b) > > > > Note: do not say it is too short for (c), as it was possible to work > > on such solution since the issue was exposed on last Wednesday. > > While I'm not a maintainer, if I my opinion counts for anything, I'd > choose option c or b. Absolutely NACK to a. > Agreed, options c and b are reasonable, a isn't. ABI commitments are ours, not users. Neil > > > > 03/02/2020 22:07, Thomas Monjalon: > >> 03/02/2020 19:55, Ray Kinsella: > >> > On 03/02/2020 17:34, Thomas Monjalon wrote: > >> > > 03/02/2020 18:09, Thomas Monjalon: > >> > >> 03/02/2020 10:30, Ferruh Yigit: > >> > >>> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: > >> > >>>> 02/02/2020 14:05, Thomas Monjalon: > >> > >>>>> 31/01/2020 15:16, Trahe, Fiona: > >> > >>>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: > >> > >>>>>>> If library give higher value than expected by the application, > >> > >>>>>>> if the application uses this value as array index, > >> > >>>>>>> there can be an access out of bounds. > >> > >>>>>> > >> > >>>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. > >> > >>>>>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes > >> > >>>>>> sense and I don't see how there can be an API breakage. > >> > >>>>>> So if an application hasn't compiled against the new lib it > >> > >>>>>> will be still using the old value > >> > >>>>>> which will be within bounds. If it's picking up the higher > >> > >>>>>> new value from the lib it must > >> > >>>>>> have been compiled against the lib so shouldn't have problems. > >> > >>>>> > >> > >>>>> You say there is no ABI issue because the application will be re-compiled > >> > >>>>> for the updated library. Indeed, compilation fixes compatibility issues. > >> > >>>>> But this is not relevant for ABI compatibility. > >> > >>>>> ABI compatibility means we can upgrade the library without recompiling > >> > >>>>> the application and it must work. > >> > >>>>> You think it is a false positive because you assume the application > >> > >>>>> "picks" the new value. I think you miss the case where the new value > >> > >>>>> is returned by a function in the upgraded library. > >> > >>>>> > >> > >>>>>> There are also no structs on the API which contain arrays using this > >> > >>>>>> for sizing, so I don't see an opportunity for an appl to have a > >> > >>>>>> mismatch in memory addresses. > >> > >>>>> > >> > >>>>> Let me demonstrate where the API may "use" the new value > >> > >>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application. > >> > >>>>> > >> > >>>>> Once upon a time a DPDK application counting the number of devices > >> > >>>>> supporting each AEAD algo (in order to find the best supported algo). > >> > >>>>> It is done in an array indexed by algo id: > >> > >>>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; > >> > >>>>> The application is compiled with DPDK 19.11, > >> > >>>>> where RTE_CRYPTO_AEAD_LIST_END = 3. > >> > >>>>> So the size of the application array aead_dev_count is 3. > >> > >>>>> This binary is run with DPDK 20.02, > >> > >>>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. > >> > >>>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3, > >> > >>>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to > >> > >>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). > >> > >>>>> The application uses this value: > >> > >>>>> ++ aead_dev_count[info.capabilities.sym.aead.algo]; > >> > >>>>> The application is crashing because of out of bound access. > >> > >>>> > >> > >>>> I'd say this is an example of bad written app. > >> > >>>> It probably should check that returned by library value doesn't > >> > >>>> exceed its internal array size. > >> > >>> > >> > >>> +1 > >> > >>> > >> > >>> Application should ignore values >= MAX. > >> > >> > >> > >> Of course, blaming the API user is a lot easier than looking at the API. > >> > >> Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood > >> > >> as the max value for the application. > >> > >> Value ranges are part of the ABI compatibility contract. > >> > >> It seems you expect the application developer to be aware that > >> > >> DPDK could return a higher value, so the application should > >> > >> check every enum values after calling an API. CRAZY. > >> > >> > >> > >> When we decide to announce an ABI compatibility and do some marketing, > >> > >> everyone is OK. But when we need to really make our ABI compatible, > >> > >> I see little or no effort. DISAPPOINTING. > >> > >> > >> > >>> Do you suggest we don't extend any enum or define between ABI breakage releases > >> > >>> to be sure bad written applications not affected? > >> > >> > >> > >> I suggest we must consider not breaking any assumption made on the API. > >> > >> Here we are breaking the enum range because nothing mentions _LIST_END > >> > >> is not really the absolute end of the enum. > >> > >> The solution is to make the change below in 20.02 + backport in 19.11.1: > >> > > > >> > > Thinking twice, merging such change before 20.11 is breaking the > >> > > ABI assumption based on the API 19.11.0. > >> > > I ask the release maintainers (Luca, Kevin, David and me) and > >> > > the ABI maintainers (Neil and Ray) to vote for a or b solution: > >> > > a) add comment and LIST_MAX as below in 20.02 + 19.11.1 > >> > > >> > That would still be an ABI breakage though right. > >> > > >> > > b) wait 20.11 and revert Chacha-Poly from 20.02 > >> > > >> > Thanks for analysis above Fiona, Ferruh and all. > >> > > >> > That is a nasty one alright - there is no "good" answer here. > >> > I agree with Ferruh's sentiments overall, we should rethink this API for 20.11. > >> > Could do without an enumeration? > >> > > >> > There a c) though right. > >> > We could work around the issue by api versioning rte_cryptodev_info_get() and friends. > >> > So they only support/acknowledge the existence of Chacha-Poly for > >> > applications build against > 20.02. > >> > >> I agree there is a c) as I proposed in another email: > >> http://mails.dpdk.org/archives/dev/2020-February/156919.html > >> " > >> In this case, the proper solution is to implement > >> rte_cryptodev_info_get_v1911() so it filters out > >> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 capability. > >> With this solution, an application compiled with DPDK 19.11 will keep > >> seeing the same range as before, while a 20.02 application could > >> see and use ChachaPoly. > >> " > >> > >> > It would be painful I know. > >> > >> Not so painful in my opinion. > >> Just need to call rte_cryptodev_info_get() from > >> rte_cryptodev_info_get_v1911() and filter the value > >> in the 19.11 range: [0..AES_GCM]. > >> > >> > It would also mean that Chacha-Poly would only be available to > >> > those building against >= 20.02. > >> > >> Yes exactly. > >> > >> The addition of comments and LIST_MAX like below are still valid > >> to avoid versioning after 20.11. > >> > >> > >> - _LIST_END > >> > >> + _LIST_END, /* an ABI-compatible version may increase this value */ > >> > >> + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */ > >> > >> }; > >> > >> > >> > >> Then *_LIST_END values could be ignored by libabigail with such a change. > >> > >> In order to avoid ABI check complaining, the best is to completely > >> remove LIST_END in DPDK 20.11. > >> > >> > >> > >> If such a patch is not done by tomorrow, I will have to revert > >> > >> Chacha-Poly commits before 20.02-rc2, because > >> > >> > >> > >> 1/ LIST_END, without any comment, means "size of range" > >> > >> 2/ we do not blame users for undocumented ABI changes > >> > >> 3/ we respect the ABI compatibility contract > >
On Tue, Feb 04, 2020 at 10:16:56AM +0000, Akhil Goyal wrote: > Hi, > > On 2/3/2020 5:09 PM, Thomas Monjalon wrote: > > > 03/02/2020 10:30, Ferruh Yigit: > > >> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: > > >>> 02/02/2020 14:05, Thomas Monjalon: > > >>>> 31/01/2020 15:16, Trahe, Fiona: > > >>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: > > >>>>>> 30/01/2020 17:09, Ferruh Yigit: > > >>>>>>> On 1/29/2020 8:13 PM, Akhil Goyal wrote: > > >>>>>>>> > > >>>>>>>> I believe these enums will be used only in case of ASYM case which is > > experimental. > > >>>>>>> > > >>>>>>> Independent from being experiment and not, this shouldn't be a > > problem, I think > > >>>>>>> this is a false positive. > > >>>>>>> > > >>>>>>> The ABI break can happen when a struct has been shared between the > > application > > >>>>>>> and the library (DPDK) and the layout of that memory know differently > > by > > >>>>>>> application and the library. > > >>>>>>> > > >>>>>>> Here in all cases, there is no layout/size change. > > >>>>>>> > > >>>>>>> As to the value changes of the enums, since application compiled with > > old DPDK, > > >>>>>>> it will know only up to '6', 7 and more means invalid to the application. > > So it > > >>>>>>> won't send these values also it should ignore these values from library. > > Only > > >>>>>>> consequence is old application won't able to use new features those > > new enums > > >>>>>>> provide but that is expected/normal. > > >>>>>> > > >>>>>> If library give higher value than expected by the application, > > >>>>>> if the application uses this value as array index, > > >>>>>> there can be an access out of bounds. > > >>>>> > > >>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a > > problem. > > >>>>> But for the same issue with sym crypto below, I believe Ferruh's > > explanation makes > > >>>>> sense and I don't see how there can be an API breakage. > > >>>>> So if an application hasn't compiled against the new lib it will be still using > > the old value > > >>>>> which will be within bounds. If it's picking up the higher new value from > > the lib it must > > >>>>> have been compiled against the lib so shouldn't have problems. > > >>>> > > >>>> You say there is no ABI issue because the application will be re-compiled > > >>>> for the updated library. Indeed, compilation fixes compatibility issues. > > >>>> But this is not relevant for ABI compatibility. > > >>>> ABI compatibility means we can upgrade the library without recompiling > > >>>> the application and it must work. > > >>>> You think it is a false positive because you assume the application > > >>>> "picks" the new value. I think you miss the case where the new value > > >>>> is returned by a function in the upgraded library. > > >>>> > > >>>>> There are also no structs on the API which contain arrays using this > > >>>>> for sizing, so I don't see an opportunity for an appl to have a > > >>>>> mismatch in memory addresses. > > >>>> > > >>>> Let me demonstrate where the API may "use" the new value > > >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the > > application. > > >>>> > > >>>> Once upon a time a DPDK application counting the number of devices > > >>>> supporting each AEAD algo (in order to find the best supported algo). > > >>>> It is done in an array indexed by algo id: > > >>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; > > >>>> The application is compiled with DPDK 19.11, > > >>>> where RTE_CRYPTO_AEAD_LIST_END = 3. > > >>>> So the size of the application array aead_dev_count is 3. > > >>>> This binary is run with DPDK 20.02, > > >>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. > > >>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3, > > >>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to > > >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). > > >>>> The application uses this value: > > >>>> ++ aead_dev_count[info.capabilities.sym.aead.algo]; > > >>>> The application is crashing because of out of bound access. > > >>> > > >>> I'd say this is an example of bad written app. > > >>> It probably should check that returned by library value doesn't > > >>> exceed its internal array size. > > >> > > >> +1 > > >> > > >> Application should ignore values >= MAX. > > > > > > Of course, blaming the API user is a lot easier than looking at the API. > > > Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood > > > as the max value for the application. > > > Value ranges are part of the ABI compatibility contract. > > > It seems you expect the application developer to be aware that > > > DPDK could return a higher value, so the application should > > > check every enum values after calling an API. CRAZY. > > > > > > When we decide to announce an ABI compatibility and do some marketing, > > > everyone is OK. But when we need to really make our ABI compatible, > > > I see little or no effort. DISAPPOINTING. > > > > This is not to blame the user or to do less work, this is more sane approach > > that library provides the _END/_MAX value and application uses it as valid range > > check. > > > > > > > >> Do you suggest we don't extend any enum or define between ABI breakage > > releases > > >> to be sure bad written applications not affected? > > > > > > I suggest we must consider not breaking any assumption made on the API. > > > Here we are breaking the enum range because nothing mentions _LIST_END > > > is not really the absolute end of the enum. > > > The solution is to make the change below in 20.02 + backport in 19.11.1: > > > > > > - _LIST_END > > > + _LIST_END, /* an ABI-compatible version may increase this value */ > > > + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */ > > > }; > > > > > > > What is the point of "_LIST_MAX" here? > > > > Application should know the "_LIST_END" of when it has been compiled for the > > valid range check. Next time it is compiled "_LIST_END" may be different value > > but same logic applies. > > > > When "_LIST_END" is missing, application can't protect itself, in that case > > library should send only the values application knows when it is compiled, this > > means either we can't extend our enum/defines until next ABI breakage, or we > > need to do ABI versioning to the functions that returns an enum each time enum > > value extended. > > > > I believe it is saner to provide _END/_MAX values to the application to use. And > > if required comment them to clarify the expected usage. > > > > But in above suggestion application can't use or rely on "_LIST_MAX", it doesn't > > mean anything to application. > > > > Can we have something like > enum rte_crypto_aead_algorithm { > RTE_CRYPTO_AEAD_AES_CCM = 1, > /**< AES algorithm in CCM mode. */ > RTE_CRYPTO_AEAD_AES_GCM, > /**< AES algorithm in GCM mode. */ > RTE_CRYPTO_AEAD_LIST_END, > /**< List end for 19.11 ABI compatibility */ > RTE_CRYPTO_AEAD_CHACHA20_POLY1305, > /**< Chacha20 cipher with poly1305 authenticator */ > RTE_CRYPTO_AEAD_LIST_END_2011 > /**< List end for 20.11 ABI compatibility */ > }; > > And in 20.11 release we alter the RTE_CRYPTO_AEAD_LIST_END to the end and remove RTE_CRYPTO_AEAD_LIST_END_2011 > > I believe it will be ok for any application which need to use the chacha poly assume that this algo is > Experimental and will move to formal list in 20.11. This can be documented in the documentation. > I believe there is no way to add a new enum as experimental so far. This way we can formalize this > requirement as well. > > I believe this way effect of ABI breakage will be nullified. > Thats not really helpful though, in that libabigail will then complain that you've aliased an old ennumeration name in the ABI to a new name. A better solution would be do one of the following: a) add an API call - something like rte_crypto_get_max_alg(), which returns at run time the maximum number of algorithms available, so that the application is forced to learn that number at run time, rather than at compile time b) Modify the API such that you pass in an algorithm name rather than an index value defined by an ennumeration. You may also add an API call that dumps all the available strings back to the user. a) would be nice, but it would still require an ABI change, which is less than optimal b) is nice because it gives you flexibility in how you search for algs - if you want to add a new alg, you just update your internal tables with a new name string, and applications get get its information by querying based on that string, rather than an index. b is also nice because it can just superscede the existing implementation (i.e. the current implementation remains unchanged, but only supports the current, existing algs), if you want to get the new algs, you use the new API calls (which can also find the already existing algs), and at some point in the future we can just deprecate the old API. Neil > > -Akhil > > > > Then *_LIST_END values could be ignored by libabigail with such a change. > > > > > > If such a patch is not done by tomorrow, I will have to revert > > > Chacha-Poly commits before 20.02-rc2, because > > > > > > 1/ LIST_END, without any comment, means "size of range" > > > 2/ we do not blame users for undocumented ABI changes > > > 3/ we respect the ABI compatibility contract > > > > > > >
On Tue, Feb 04, 2020 at 10:32:01AM +0000, Akhil Goyal wrote:
>
> >
> > 04/02/2020 11:16, Akhil Goyal:
> > > Hi,
> > > > On 2/3/2020 5:09 PM, Thomas Monjalon wrote:
> > > > > 03/02/2020 10:30, Ferruh Yigit:
> > > > >> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote:
> > > > >>> 02/02/2020 14:05, Thomas Monjalon:
> > > > >>>> 31/01/2020 15:16, Trahe, Fiona:
> > > > >>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote:
> > > > >>>>>> 30/01/2020 17:09, Ferruh Yigit:
> > > > >>>>>>> On 1/29/2020 8:13 PM, Akhil Goyal wrote:
> > > > >>>>>>>>
> > > > >>>>>>>> I believe these enums will be used only in case of ASYM case which
> > is
> > > > experimental.
> > > > >>>>>>>
> > > > >>>>>>> Independent from being experiment and not, this shouldn't be a
> > > > problem, I think
> > > > >>>>>>> this is a false positive.
> > > > >>>>>>>
> > > > >>>>>>> The ABI break can happen when a struct has been shared between
> > the
> > > > application
> > > > >>>>>>> and the library (DPDK) and the layout of that memory know
> > differently
> > > > by
> > > > >>>>>>> application and the library.
> > > > >>>>>>>
> > > > >>>>>>> Here in all cases, there is no layout/size change.
> > > > >>>>>>>
> > > > >>>>>>> As to the value changes of the enums, since application compiled
> > with
> > > > old DPDK,
> > > > >>>>>>> it will know only up to '6', 7 and more means invalid to the
> > application.
> > > > So it
> > > > >>>>>>> won't send these values also it should ignore these values from
> > library.
> > > > Only
> > > > >>>>>>> consequence is old application won't able to use new features
> > those
> > > > new enums
> > > > >>>>>>> provide but that is expected/normal.
> > > > >>>>>>
> > > > >>>>>> If library give higher value than expected by the application,
> > > > >>>>>> if the application uses this value as array index,
> > > > >>>>>> there can be an access out of bounds.
> > > > >>>>>
> > > > >>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a
> > > > problem.
> > > > >>>>> But for the same issue with sym crypto below, I believe Ferruh's
> > > > explanation makes
> > > > >>>>> sense and I don't see how there can be an API breakage.
> > > > >>>>> So if an application hasn't compiled against the new lib it will be still
> > using
> > > > the old value
> > > > >>>>> which will be within bounds. If it's picking up the higher new value
> > from
> > > > the lib it must
> > > > >>>>> have been compiled against the lib so shouldn't have problems.
> > > > >>>>
> > > > >>>> You say there is no ABI issue because the application will be re-
> > compiled
> > > > >>>> for the updated library. Indeed, compilation fixes compatibility issues.
> > > > >>>> But this is not relevant for ABI compatibility.
> > > > >>>> ABI compatibility means we can upgrade the library without
> > recompiling
> > > > >>>> the application and it must work.
> > > > >>>> You think it is a false positive because you assume the application
> > > > >>>> "picks" the new value. I think you miss the case where the new value
> > > > >>>> is returned by a function in the upgraded library.
> > > > >>>>
> > > > >>>>> There are also no structs on the API which contain arrays using this
> > > > >>>>> for sizing, so I don't see an opportunity for an appl to have a
> > > > >>>>> mismatch in memory addresses.
> > > > >>>>
> > > > >>>> Let me demonstrate where the API may "use" the new value
> > > > >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the
> > > > application.
> > > > >>>>
> > > > >>>> Once upon a time a DPDK application counting the number of devices
> > > > >>>> supporting each AEAD algo (in order to find the best supported algo).
> > > > >>>> It is done in an array indexed by algo id:
> > > > >>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END];
> > > > >>>> The application is compiled with DPDK 19.11,
> > > > >>>> where RTE_CRYPTO_AEAD_LIST_END = 3.
> > > > >>>> So the size of the application array aead_dev_count is 3.
> > > > >>>> This binary is run with DPDK 20.02,
> > > > >>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3.
> > > > >>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3,
> > > > >>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to
> > > > >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3).
> > > > >>>> The application uses this value:
> > > > >>>> ++ aead_dev_count[info.capabilities.sym.aead.algo];
> > > > >>>> The application is crashing because of out of bound access.
> > > > >>>
> > > > >>> I'd say this is an example of bad written app.
> > > > >>> It probably should check that returned by library value doesn't
> > > > >>> exceed its internal array size.
> > > > >>
> > > > >> +1
> > > > >>
> > > > >> Application should ignore values >= MAX.
> > > > >
> > > > > Of course, blaming the API user is a lot easier than looking at the API.
> > > > > Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood
> > > > > as the max value for the application.
> > > > > Value ranges are part of the ABI compatibility contract.
> > > > > It seems you expect the application developer to be aware that
> > > > > DPDK could return a higher value, so the application should
> > > > > check every enum values after calling an API. CRAZY.
> > > > >
> > > > > When we decide to announce an ABI compatibility and do some marketing,
> > > > > everyone is OK. But when we need to really make our ABI compatible,
> > > > > I see little or no effort. DISAPPOINTING.
> > > >
> > > > This is not to blame the user or to do less work, this is more sane approach
> > > > that library provides the _END/_MAX value and application uses it as valid
> > range
> > > > check.
> > > >
> > > > >
> > > > >> Do you suggest we don't extend any enum or define between ABI
> > breakage
> > > > releases
> > > > >> to be sure bad written applications not affected?
> > > > >
> > > > > I suggest we must consider not breaking any assumption made on the API.
> > > > > Here we are breaking the enum range because nothing mentions
> > _LIST_END
> > > > > is not really the absolute end of the enum.
> > > > > The solution is to make the change below in 20.02 + backport in 19.11.1:
> > > > >
> > > > > - _LIST_END
> > > > > + _LIST_END, /* an ABI-compatible version may increase this value */
> > > > > + _LIST_MAX = _LIST_END + 42 /* room for ABI-compatible additions */
> > > > > };
> > > > >
> > > >
> > > > What is the point of "_LIST_MAX" here?
> > > >
> > > > Application should know the "_LIST_END" of when it has been compiled for
> > the
> > > > valid range check. Next time it is compiled "_LIST_END" may be different
> > value
> > > > but same logic applies.
> > > >
> > > > When "_LIST_END" is missing, application can't protect itself, in that case
> > > > library should send only the values application knows when it is compiled,
> > this
> > > > means either we can't extend our enum/defines until next ABI breakage, or
> > we
> > > > need to do ABI versioning to the functions that returns an enum each time
> > enum
> > > > value extended.
> > > >
> > > > I believe it is saner to provide _END/_MAX values to the application to use.
> > And
> > > > if required comment them to clarify the expected usage.
> > > >
> > > > But in above suggestion application can't use or rely on "_LIST_MAX", it
> > doesn't
> > > > mean anything to application.
> > > >
> > >
> > > Can we have something like
> > > enum rte_crypto_aead_algorithm {
> > > RTE_CRYPTO_AEAD_AES_CCM = 1,
> > > /**< AES algorithm in CCM mode. */
> > > RTE_CRYPTO_AEAD_AES_GCM,
> > > /**< AES algorithm in GCM mode. */
> > > RTE_CRYPTO_AEAD_LIST_END,
> > > /**< List end for 19.11 ABI compatibility */
> > > RTE_CRYPTO_AEAD_CHACHA20_POLY1305,
> > > /**< Chacha20 cipher with poly1305 authenticator */
> > > RTE_CRYPTO_AEAD_LIST_END_2011
> > > /**< List end for 20.11 ABI compatibility */
> > > };
> > >
> > > And in 20.11 release we alter the RTE_CRYPTO_AEAD_LIST_END to the end
> > and remove RTE_CRYPTO_AEAD_LIST_END_2011
> > >
> > > I believe it will be ok for any application which need to use the chacha poly
> > assume that this algo is
> > > Experimental and will move to formal list in 20.11. This can be documented in
> > the documentation.
> > > I believe there is no way to add a new enum as experimental so far. This way
> > we can formalize this
> > > requirement as well.
> > >
> > > I believe this way effect of ABI breakage will be nullified.
> >
> > This is a possibility in the (a) proposal.
> > But it breaks API (and ABI) because a high value is returned
> > while not expected by the application.
> >
> > I guess ABI and release maintainers will vote no to such breakage.
> > Note: I vote no.
> >
>
> If that is the case, I would say we should go with b).
>
> Versioned APIs does not look good and adds more confusion.
>
What makes you say that?
Versioned APIs are the way you maintain backward compatibility.
If a library doesn't use versioned API's, then they either:
1) break frequently, causing application headaches
2) have APIS that are so mature, strictly defined, and small, they never change anyway
3) go to the trouble of creating compat libs for as far back as they need to
support
DPDK doesn't yet have a mature, stable API, so we have to do (1) or (2). (1)
has already been declared a bad idea, because application developers and distros
have declared a desire for backwards compatibility. We could go with (3)
instead of ABI versioning, but between compat libs and versioning, the latter is
the much less difficult way to handle that.
Neil
Hi Akhil, Neil, Fiona
Sorry for the late response. I want to propose a new change in line with what you folks had proposed.
May be we can treat the new features EXPERIMENTAL until a new stable release.
enum rte_crypto_aead_algorithm {
RTE_CRYPTO_AEAD_AES_CCM = 1,
/**< AES algorithm in CCM mode. */
RTE_CRYPTO_AEAD_AES_GCM,
/**< AES algorithm in GCM mode. */
RTE_CRYPTO_AEAD_LIST_END,
/**< List end for stable */
/** EXPERIMENTAL */
RTE_CRYPTO_AEAD_CHACHA20_POLY1305,
/**< Chacha20 cipher with poly1305 authenticator */
RTE_CRYPTO_AEAD_LIST_END_EXPERIMENTAL
/**< List end */
};
And then introduce an experimental API,
const struct rte_cryptodev_capabilities *
rte_cryptodev_get_exp_capabilites(uint8_t dev_id);
The PMD owner is expected to add new capabilities (only new ones) to this one until the new feature is deemed stable (ie, in one of the next stable releases). We don't expect users to change their API/ABI. For applications using EXPERIMENTAL is allowed to use the above capabilities to get the EXPERIMENTAL features.
This does involve moving around code in PMD when one feature is added, but that's the risk PMD owner is taking by upstreaming as EXPERIMENTAL and not in stable release.
Thanks,
Anoob
> -----Original Message-----
> From: Neil Horman <nhorman@tuxdriver.com>
> Sent: Wednesday, February 5, 2020 3:40 AM
> To: Akhil Goyal <akhil.goyal@nxp.com>
> Cc: Thomas Monjalon <thomas@monjalon.net>; Ferruh Yigit
> <ferruh.yigit@intel.com>; Ananyev, Konstantin
> <konstantin.ananyev@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>;
> dev@dpdk.org; David Marchand <david.marchand@redhat.com>; Anoob Joseph
> <anoobj@marvell.com>; Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>;
> Richardson, Bruce <bruce.richardson@intel.com>; Mcnamara, John
> <john.mcnamara@intel.com>; dodji@seketeli.net; Andrew Rybchenko
> <arybchenko@solarflare.com>; aconole@redhat.com; bluca@debian.org;
> ktraynor@redhat.com
> Subject: [EXT] Re: [dpdk-dev] [PATCH v2 4/4] add ABI checks
>
> External Email
>
> ----------------------------------------------------------------------
> On Tue, Feb 04, 2020 at 10:32:01AM +0000, Akhil Goyal wrote:
> >
> > >
> > > 04/02/2020 11:16, Akhil Goyal:
> > > > Hi,
> > > > > On 2/3/2020 5:09 PM, Thomas Monjalon wrote:
> > > > > > 03/02/2020 10:30, Ferruh Yigit:
> > > > > >> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote:
> > > > > >>> 02/02/2020 14:05, Thomas Monjalon:
> > > > > >>>> 31/01/2020 15:16, Trahe, Fiona:
> > > > > >>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote:
> > > > > >>>>>> 30/01/2020 17:09, Ferruh Yigit:
> > > > > >>>>>>> On 1/29/2020 8:13 PM, Akhil Goyal wrote:
> > > > > >>>>>>>>
> > > > > >>>>>>>> I believe these enums will be used only in case of ASYM
> > > > > >>>>>>>> case which
> > > is
> > > > > experimental.
> > > > > >>>>>>>
> > > > > >>>>>>> Independent from being experiment and not, this
> > > > > >>>>>>> shouldn't be a
> > > > > problem, I think
> > > > > >>>>>>> this is a false positive.
> > > > > >>>>>>>
> > > > > >>>>>>> The ABI break can happen when a struct has been shared
> > > > > >>>>>>> between
> > > the
> > > > > application
> > > > > >>>>>>> and the library (DPDK) and the layout of that memory
> > > > > >>>>>>> know
> > > differently
> > > > > by
> > > > > >>>>>>> application and the library.
> > > > > >>>>>>>
> > > > > >>>>>>> Here in all cases, there is no layout/size change.
> > > > > >>>>>>>
> > > > > >>>>>>> As to the value changes of the enums, since application
> > > > > >>>>>>> compiled
> > > with
> > > > > old DPDK,
> > > > > >>>>>>> it will know only up to '6', 7 and more means invalid to
> > > > > >>>>>>> the
> > > application.
> > > > > So it
> > > > > >>>>>>> won't send these values also it should ignore these
> > > > > >>>>>>> values from
> > > library.
> > > > > Only
> > > > > >>>>>>> consequence is old application won't able to use new
> > > > > >>>>>>> features
> > > those
> > > > > new enums
> > > > > >>>>>>> provide but that is expected/normal.
> > > > > >>>>>>
> > > > > >>>>>> If library give higher value than expected by the
> > > > > >>>>>> application, if the application uses this value as array
> > > > > >>>>>> index, there can be an access out of bounds.
> > > > > >>>>>
> > > > > >>>>> [Fiona] All asymmetric APIs are experimental so above
> > > > > >>>>> shouldn't be a
> > > > > problem.
> > > > > >>>>> But for the same issue with sym crypto below, I believe
> > > > > >>>>> Ferruh's
> > > > > explanation makes
> > > > > >>>>> sense and I don't see how there can be an API breakage.
> > > > > >>>>> So if an application hasn't compiled against the new lib
> > > > > >>>>> it will be still
> > > using
> > > > > the old value
> > > > > >>>>> which will be within bounds. If it's picking up the higher
> > > > > >>>>> new value
> > > from
> > > > > the lib it must
> > > > > >>>>> have been compiled against the lib so shouldn't have problems.
> > > > > >>>>
> > > > > >>>> You say there is no ABI issue because the application will
> > > > > >>>> be re-
> > > compiled
> > > > > >>>> for the updated library. Indeed, compilation fixes compatibility
> issues.
> > > > > >>>> But this is not relevant for ABI compatibility.
> > > > > >>>> ABI compatibility means we can upgrade the library without
> > > recompiling
> > > > > >>>> the application and it must work.
> > > > > >>>> You think it is a false positive because you assume the
> > > > > >>>> application "picks" the new value. I think you miss the
> > > > > >>>> case where the new value is returned by a function in the upgraded
> library.
> > > > > >>>>
> > > > > >>>>> There are also no structs on the API which contain arrays
> > > > > >>>>> using this for sizing, so I don't see an opportunity for
> > > > > >>>>> an appl to have a mismatch in memory addresses.
> > > > > >>>>
> > > > > >>>> Let me demonstrate where the API may "use" the new value
> > > > > >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the
> > > > > application.
> > > > > >>>>
> > > > > >>>> Once upon a time a DPDK application counting the number of
> > > > > >>>> devices supporting each AEAD algo (in order to find the best
> supported algo).
> > > > > >>>> It is done in an array indexed by algo id:
> > > > > >>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END];
> > > > > >>>> The application is compiled with DPDK 19.11, where
> > > > > >>>> RTE_CRYPTO_AEAD_LIST_END = 3.
> > > > > >>>> So the size of the application array aead_dev_count is 3.
> > > > > >>>> This binary is run with DPDK 20.02, where
> > > > > >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3.
> > > > > >>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3,
> > > > > >>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to
> > > > > >>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3).
> > > > > >>>> The application uses this value:
> > > > > >>>> ++ aead_dev_count[info.capabilities.sym.aead.algo];
> > > > > >>>> The application is crashing because of out of bound access.
> > > > > >>>
> > > > > >>> I'd say this is an example of bad written app.
> > > > > >>> It probably should check that returned by library value
> > > > > >>> doesn't exceed its internal array size.
> > > > > >>
> > > > > >> +1
> > > > > >>
> > > > > >> Application should ignore values >= MAX.
> > > > > >
> > > > > > Of course, blaming the API user is a lot easier than looking at the API.
> > > > > > Here the API has RTE_CRYPTO_AEAD_LIST_END which can be
> > > > > > understood as the max value for the application.
> > > > > > Value ranges are part of the ABI compatibility contract.
> > > > > > It seems you expect the application developer to be aware that
> > > > > > DPDK could return a higher value, so the application should
> > > > > > check every enum values after calling an API. CRAZY.
> > > > > >
> > > > > > When we decide to announce an ABI compatibility and do some
> > > > > > marketing, everyone is OK. But when we need to really make our
> > > > > > ABI compatible, I see little or no effort. DISAPPOINTING.
> > > > >
> > > > > This is not to blame the user or to do less work, this is more
> > > > > sane approach that library provides the _END/_MAX value and
> > > > > application uses it as valid
> > > range
> > > > > check.
> > > > >
> > > > > >
> > > > > >> Do you suggest we don't extend any enum or define between ABI
> > > breakage
> > > > > releases
> > > > > >> to be sure bad written applications not affected?
> > > > > >
> > > > > > I suggest we must consider not breaking any assumption made on the
> API.
> > > > > > Here we are breaking the enum range because nothing mentions
> > > _LIST_END
> > > > > > is not really the absolute end of the enum.
> > > > > > The solution is to make the change below in 20.02 + backport in
> 19.11.1:
> > > > > >
> > > > > > - _LIST_END
> > > > > > + _LIST_END, /* an ABI-compatible version may increase this
> > > > > > + value */ _LIST_MAX = _LIST_END + 42 /* room for
> > > > > > + ABI-compatible additions */
> > > > > > };
> > > > > >
> > > > >
> > > > > What is the point of "_LIST_MAX" here?
> > > > >
> > > > > Application should know the "_LIST_END" of when it has been
> > > > > compiled for
> > > the
> > > > > valid range check. Next time it is compiled "_LIST_END" may be
> > > > > different
> > > value
> > > > > but same logic applies.
> > > > >
> > > > > When "_LIST_END" is missing, application can't protect itself,
> > > > > in that case library should send only the values application
> > > > > knows when it is compiled,
> > > this
> > > > > means either we can't extend our enum/defines until next ABI
> > > > > breakage, or
> > > we
> > > > > need to do ABI versioning to the functions that returns an enum
> > > > > each time
> > > enum
> > > > > value extended.
> > > > >
> > > > > I believe it is saner to provide _END/_MAX values to the application to
> use.
> > > And
> > > > > if required comment them to clarify the expected usage.
> > > > >
> > > > > But in above suggestion application can't use or rely on
> > > > > "_LIST_MAX", it
> > > doesn't
> > > > > mean anything to application.
> > > > >
> > > >
> > > > Can we have something like
> > > > enum rte_crypto_aead_algorithm {
> > > > RTE_CRYPTO_AEAD_AES_CCM = 1,
> > > > /**< AES algorithm in CCM mode. */
> > > > RTE_CRYPTO_AEAD_AES_GCM,
> > > > /**< AES algorithm in GCM mode. */
> > > > RTE_CRYPTO_AEAD_LIST_END,
> > > > /**< List end for 19.11 ABI compatibility */
> > > > RTE_CRYPTO_AEAD_CHACHA20_POLY1305,
> > > > /**< Chacha20 cipher with poly1305 authenticator */
> > > > RTE_CRYPTO_AEAD_LIST_END_2011
> > > > /**< List end for 20.11 ABI compatibility */ };
> > > >
> > > > And in 20.11 release we alter the RTE_CRYPTO_AEAD_LIST_END to the
> > > > end
> > > and remove RTE_CRYPTO_AEAD_LIST_END_2011
> > > >
> > > > I believe it will be ok for any application which need to use the
> > > > chacha poly
> > > assume that this algo is
> > > > Experimental and will move to formal list in 20.11. This can be
> > > > documented in
> > > the documentation.
> > > > I believe there is no way to add a new enum as experimental so
> > > > far. This way
> > > we can formalize this
> > > > requirement as well.
> > > >
> > > > I believe this way effect of ABI breakage will be nullified.
> > >
> > > This is a possibility in the (a) proposal.
> > > But it breaks API (and ABI) because a high value is returned while
> > > not expected by the application.
> > >
> > > I guess ABI and release maintainers will vote no to such breakage.
> > > Note: I vote no.
> > >
> >
> > If that is the case, I would say we should go with b).
> >
> > Versioned APIs does not look good and adds more confusion.
> >
> What makes you say that?
>
> Versioned APIs are the way you maintain backward compatibility.
>
> If a library doesn't use versioned API's, then they either:
>
> 1) break frequently, causing application headaches
> 2) have APIS that are so mature, strictly defined, and small, they never change
> anyway
> 3) go to the trouble of creating compat libs for as far back as they need to
> support
>
> DPDK doesn't yet have a mature, stable API, so we have to do (1) or (2). (1) has
> already been declared a bad idea, because application developers and distros
> have declared a desire for backwards compatibility. We could go with (3)
> instead of ABI versioning, but between compat libs and versioning, the latter is
> the much less difficult way to handle that.
>
> Neil
On 04/02/2020 09:51, David Marchand wrote: > On Mon, Feb 3, 2020 at 7:56 PM Ray Kinsella <mdr@ashroe.eu> wrote: >> On 03/02/2020 17:34, Thomas Monjalon wrote: >>> 03/02/2020 18:09, Thomas Monjalon: >>>> 03/02/2020 10:30, Ferruh Yigit: >>>>> On 2/2/2020 2:41 PM, Ananyev, Konstantin wrote: >>>>>> 02/02/2020 14:05, Thomas Monjalon: >>>>>>> 31/01/2020 15:16, Trahe, Fiona: >>>>>>>> On 1/30/2020 8:18 PM, Thomas Monjalon wrote: >>>>>>>>> If library give higher value than expected by the application, >>>>>>>>> if the application uses this value as array index, >>>>>>>>> there can be an access out of bounds. >>>>>>>> >>>>>>>> [Fiona] All asymmetric APIs are experimental so above shouldn't be a problem. >>>>>>>> But for the same issue with sym crypto below, I believe Ferruh's explanation makes >>>>>>>> sense and I don't see how there can be an API breakage. >>>>>>>> So if an application hasn't compiled against the new lib it will be still using the old value >>>>>>>> which will be within bounds. If it's picking up the higher new value from the lib it must >>>>>>>> have been compiled against the lib so shouldn't have problems. >>>>>>> >>>>>>> You say there is no ABI issue because the application will be re-compiled >>>>>>> for the updated library. Indeed, compilation fixes compatibility issues. >>>>>>> But this is not relevant for ABI compatibility. >>>>>>> ABI compatibility means we can upgrade the library without recompiling >>>>>>> the application and it must work. >>>>>>> You think it is a false positive because you assume the application >>>>>>> "picks" the new value. I think you miss the case where the new value >>>>>>> is returned by a function in the upgraded library. >>>>>>> >>>>>>>> There are also no structs on the API which contain arrays using this >>>>>>>> for sizing, so I don't see an opportunity for an appl to have a >>>>>>>> mismatch in memory addresses. >>>>>>> >>>>>>> Let me demonstrate where the API may "use" the new value >>>>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 and how it impacts the application. >>>>>>> >>>>>>> Once upon a time a DPDK application counting the number of devices >>>>>>> supporting each AEAD algo (in order to find the best supported algo). >>>>>>> It is done in an array indexed by algo id: >>>>>>> int aead_dev_count[RTE_CRYPTO_AEAD_LIST_END]; >>>>>>> The application is compiled with DPDK 19.11, >>>>>>> where RTE_CRYPTO_AEAD_LIST_END = 3. >>>>>>> So the size of the application array aead_dev_count is 3. >>>>>>> This binary is run with DPDK 20.02, >>>>>>> where RTE_CRYPTO_AEAD_CHACHA20_POLY1305 = 3. >>>>>>> When calling rte_cryptodev_info_get() on a device QAT_GEN3, >>>>>>> rte_cryptodev_info.capabilities.sym.aead.algo is set to >>>>>>> RTE_CRYPTO_AEAD_CHACHA20_POLY1305 (= 3). >>>>>>> The application uses this value: >>>>>>> ++ aead_dev_count[info.capabilities.sym.aead.algo]; >>>>>>> The application is crashing because of out of bound access. >>>>>> >>>>>> I'd say this is an example of bad written app. >>>>>> It probably should check that returned by library value doesn't >>>>>> exceed its internal array size. >>>>> >>>>> +1 >>>>> >>>>> Application should ignore values >= MAX. >>>> >>>> Of course, blaming the API user is a lot easier than looking at the API. >>>> Here the API has RTE_CRYPTO_AEAD_LIST_END which can be understood >>>> as the max value for the application. >>>> Value ranges are part of the ABI compatibility contract. >>>> It seems you expect the application developer to be aware that >>>> DPDK could return a higher value, so the application should >>>> check every enum values after calling an API. CRAZY. >>>> >>>> When we decide to announce an ABI compatibility and do some marketing, >>>> everyone is OK. But when we need to really make our ABI compatible, >>>> I see little or no effort. DISAPPOINTING. >>>> >>>>> Do you suggest we don't extend any enum or define between ABI breakage releases >>>>> to be sure bad written applications not affected? >>>> >>>> I suggest we must consider not breaking any assumption made on the API. >>>> Here we are breaking the enum range because nothing mentions _LIST_END >>>> is not really the absolute end of the enum. >>>> The solution is to make the change below in 20.02 + backport in 19.11.1: >>> >>> Thinking twice, merging such change before 20.11 is breaking the >>> ABI assumption based on the API 19.11.0. >>> I ask the release maintainers (Luca, Kevin, David and me) and >>> the ABI maintainers (Neil and Ray) to vote for a or b solution: >>> a) add comment and LIST_MAX as below in 20.02 + 19.11.1 >> >> That would still be an ABI breakage though right. > > Yes. > > >> >>> b) wait 20.11 and revert Chacha-Poly from 20.02 >> >> Thanks for analysis above Fiona, Ferruh and all. >> >> That is a nasty one alright - there is no "good" answer here. >> I agree with Ferruh's sentiments overall, we should rethink this API for 20.11. >> Could do without an enumeration? >> >> There a c) though right. >> We could work around the issue by api versioning rte_cryptodev_info_get() and friends. > > It has a lot of friends, but it sounds like the right approach. +1 > Is someone looking into this? Looks to be in hand now. > > >> So they only support/acknowledge the existence of Chacha-Poly for applications build against > 20.02. >> >> It would be painful I know. >> It would also mean that Chacha-Poly would only be available to those building against >= 20.02. > > Yes. > > > -- > David Marchand >
02/02/2020 22:08, David Marchand: > Here is the current state of the ABI checks. > > libabigail has some issues when mixing dump and so files compiled with > clang [1], so for now, all checks are done on dumps only. > libabigail 1.0-rc3 in Xenial reported issues that disappear with the > version 1.2 in Bionic. > > To avoid getting warnings on internal types like [2], the checks now make > use of the public headers part of a dpdk installation (patch 2 and 3 to > prepare for this). > > Some internal rte_hash headers were installed by meson, so patch 1 fixes > this. > > The most important point, abidiff complains on the rc1 cryptodev changes: > - Chacha20-Poly1305 AEAD support, > - ECPM and ECDSA support > > A suppression rule has been put on the internal type rte_cryptodev_ops. > But other changes are an ABI breakage afaiu. I put suppression rules on > them so that we can run the checks, but some action must be taken for > 20.02 if my analysis is confirmed. The suppression rules for Chacha-Poly are removed, and Chacha-Poly commits are reverted while merging this series. > Special thanks to Dodji the libabigail maintainer for helping on this > topic. > > 1: https://sourceware.org/bugzilla/show_bug.cgi?id=25409 > 2: http://inbox.dpdk.org/dev/CAJFAV8yFKoDZROX9Mkyp7pDMvXw3e7mHwxjfrcjD5ZoFB2tZ8w@mail.gmail.com/ Applied, thanks
Hi Anoob,
> -----Original Message-----
> From: Anoob Joseph <anoobj@marvell.com>
> Sent: Wednesday, February 5, 2020 6:16 AM
> To: Neil Horman <nhorman@tuxdriver.com>; Akhil Goyal <akhil.goyal@nxp.com>; Trahe, Fiona
> <fiona.trahe@intel.com>
> Cc: Thomas Monjalon <thomas@monjalon.net>; Yigit, Ferruh <ferruh.yigit@intel.com>; Ananyev,
> Konstantin <konstantin.ananyev@intel.com>; Trahe, Fiona <fiona.trahe@intel.com>; dev@dpdk.org;
> David Marchand <david.marchand@redhat.com>; Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>;
> Richardson, Bruce <bruce.richardson@intel.com>; Mcnamara, John <john.mcnamara@intel.com>;
> dodji@seketeli.net; Andrew Rybchenko <arybchenko@solarflare.com>; aconole@redhat.com;
> bluca@debian.org; ktraynor@redhat.com
> Subject: RE: [EXT] Re: [dpdk-dev] [PATCH v2 4/4] add ABI checks
>
> Hi Akhil, Neil, Fiona
>
> Sorry for the late response. I want to propose a new change in line with what you folks had proposed.
>
> May be we can treat the new features EXPERIMENTAL until a new stable release.
>
> enum rte_crypto_aead_algorithm {
> RTE_CRYPTO_AEAD_AES_CCM = 1,
> /**< AES algorithm in CCM mode. */
> RTE_CRYPTO_AEAD_AES_GCM,
> /**< AES algorithm in GCM mode. */
> RTE_CRYPTO_AEAD_LIST_END,
> /**< List end for stable */
> /** EXPERIMENTAL */
> RTE_CRYPTO_AEAD_CHACHA20_POLY1305,
> /**< Chacha20 cipher with poly1305 authenticator */
> RTE_CRYPTO_AEAD_LIST_END_EXPERIMENTAL
> /**< List end */
> };
>
> And then introduce an experimental API,
>
> const struct rte_cryptodev_capabilities *
> rte_cryptodev_get_exp_capabilites(uint8_t dev_id);
>
> The PMD owner is expected to add new capabilities (only new ones) to this one until the new feature is
> deemed stable (ie, in one of the next stable releases). We don't expect users to change their API/ABI.
> For applications using EXPERIMENTAL is allowed to use the above capabilities to get the EXPERIMENTAL
> features.
>
> This does involve moving around code in PMD when one feature is added, but that's the risk PMD
> owner is taking by upstreaming as EXPERIMENTAL and not in stable release.
>
> Thanks,
> Anoob
[Fiona] Thanks for the suggestion Anoob.
I like the enum part of the idea - but not the new temporary API as the applications need to be aware of it and would have to change again when it's removed.
I explored an alternative way of using the current experimental infrastructure, i.e.:
enum rte_crypto_aead_algorithm {
RTE_CRYPTO_AEAD_AES_CCM = 1,
/**< AES algorithm in CCM mode. */
RTE_CRYPTO_AEAD_AES_GCM,
/**< AES algorithm in GCM mode. */
#ifdef ALLOW_EXPERIMENTAL_API
RTE_CRYPTO_AEAD_CHACHA20_POLY1305,
/**< Chacha20 cipher with poly1305 authenticator */
#endif
RTE_CRYPTO_AEAD_LIST_END,
/**< List end */
};
No new rte_cryptodev_get_exp_capabilities() needed.
Any PMD that implements the experimental API must do the same:
#ifdef ALLOW_EXPERIMENTAL_API
<PMD code processing new enum>
#endif
Same with test code.
Any 19.11 production code that wants to run against shared objects from
20.02 can be expected to build DPDK with ALLOW_EXPERIMENTAL_API disabled,
so will not pick up the new feature.
However, it appears the flag is not globally consistent, i.e. most PMDs have it set, even if the application doesn't set it. So this probably wouldn't work.
We're testing the approach outlined yesterday and believe it satisfactorily resolves the issue, so will stick with that.
>-----Original Message-----
>From: Honnappa Nagarahalli [mailto:Honnappa.Nagarahalli@arm.com]
>Sent: Thursday, January 30, 2020 10:40 AM
>To: Wang, Yipeng1 <yipeng1.wang@intel.com>; David Marchand <david.marchand@redhat.com>; dev@dpdk.org
>Cc: thomas@monjalon.net; Richardson, Bruce <bruce.richardson@intel.com>; Laatz, Kevin <kevin.laatz@intel.com>;
>aconole@redhat.com; nhorman@tuxdriver.com; Akhil.goyal@nxp.com; anoobj@marvell.com; bluca@debian.org; Trahe, Fiona
><fiona.trahe@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>; stable@dpdk.org; Gobriel, Sameh <sameh.gobriel@intel.com>; Van
>Haaren, Harry <harry.van.haaren@intel.com>; Luca Boccassi <luca.boccassi@gmail.com>; Wiles, Keith <keith.wiles@intel.com>; nd
><nd@arm.com>; Honnappa Nagarahalli <Honnappa.Nagarahalli@arm.com>; nd <nd@arm.com>
>Subject: RE: [PATCH v3 1/4] hash: fix meson headers packaging
>
><snip>
>
>> >Subject: [PATCH v3 1/4] hash: fix meson headers packaging
>> >
>> >Those headers are internal and should not be distributed.
>> >
>> >Fixes: 5b9656b157d3 ("lib: build with meson")
>> >Cc: stable@dpdk.org
>> >
>> >Signed-off-by: David Marchand <david.marchand@redhat.com>
>> >Acked-by: Luca Boccassi <bluca@debian.org>
>>
>> [Wang, Yipeng]
>> Thanks for the patch! I believe they are for internal used only.
>> But include Honnappa from ARM here since in the makefile seems the
>> rte_crc_arm64.h is installed?
>I see that this patch installs rte_crc_arm64.h. I do no see any issue.
[Wang, Yipeng]
Right sorry, I mis-read the code line.
>-----Original Message-----
>From: David Marchand [mailto:david.marchand@redhat.com]
>Sent: Sunday, February 2, 2020 1:09 PM
>To: dev@dpdk.org
>Cc: thomas@monjalon.net; Richardson, Bruce <bruce.richardson@intel.com>; Laatz, Kevin <kevin.laatz@intel.com>;
>aconole@redhat.com; nhorman@tuxdriver.com; akhil.goyal@nxp.com; anoobj@marvell.com; bluca@debian.org; Trahe, Fiona
><fiona.trahe@intel.com>; Yigit, Ferruh <ferruh.yigit@intel.com>; stable@dpdk.org; Wang, Yipeng1 <yipeng1.wang@intel.com>;
>Gobriel, Sameh <sameh.gobriel@intel.com>; Van Haaren, Harry <harry.van.haaren@intel.com>; Luca Boccassi
><luca.boccassi@gmail.com>; Wiles, Keith <keith.wiles@intel.com>
>Subject: [PATCH v4 1/3] hash: fix meson headers packaging
>
>Those headers are internal and should not be distributed.
>
>Fixes: 5b9656b157d3 ("lib: build with meson")
>Cc: stable@dpdk.org
>
>Signed-off-by: David Marchand <david.marchand@redhat.com>
>Acked-by: Luca Boccassi <bluca@debian.org>
>---
> lib/librte_hash/meson.build | 5 +----
> 1 file changed, 1 insertion(+), 4 deletions(-)
>
>diff --git a/lib/librte_hash/meson.build b/lib/librte_hash/meson.build
>index 5d02b3084..bce11ad9e 100644
>--- a/lib/librte_hash/meson.build
>+++ b/lib/librte_hash/meson.build
>@@ -1,10 +1,7 @@
> # SPDX-License-Identifier: BSD-3-Clause
> # Copyright(c) 2017 Intel Corporation
>
>-headers = files('rte_cmp_arm64.h',
>- 'rte_cmp_x86.h',
>- 'rte_crc_arm64.h',
>- 'rte_cuckoo_hash.h',
>+headers = files('rte_crc_arm64.h',
> 'rte_fbk_hash.h',
> 'rte_hash_crc.h',
> 'rte_hash.h',
>--
>2.23.0
[Wang, Yipeng]
Acked-by: Yipeng Wang <yipeng1.wang@intel.com>
Hi, Two comments from me, > > > The patch we're working on will provide two versions of > > > rte_cryptodev_info_get(), both call the same PMD function from the > dev_ops info_get fn ptr. > > > The default version operates s as normal, the 19.11 version searches > > > through the list returned by the PMD, looking for sym.aead.algo = > > > ChaChaPoly, it needs to strip it from > > the list. > > > As PMDs just pass a ptr to their capabilities list ( it isn't a > > > linked list, but an array with an end marker = > > > RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST) if the API layer detects > > > Chacha it must allocate some space and store a local copy of the trimmed > list. This must be stored only once per device. [Arek] The problem with this solution is that we need to allocate memory. So the question is how to handle unlikely case of malloc error when we operate inside void function rte_cryptodev_info_get? And even if we would pass somehow error condition to the caller then what to do is another question. > > > > I don't understand what you have to store. > > Can't you just set the algo to 0 if it is ChaCha? > [Fiona] it returns a pointer to data in the PMD domain, which the API couldn't > and shouldn't overwrite, e.g. > static const struct rte_cryptodev_capabilities qat_gen3_sym_capabilities[] Should we print user some information > > > > > > This versioning will apply to any PMD which wants to take advantage > > > of the new API between now and > > 20.11. > > > > > > Note, I expect the ABI checker tools will still complain of ABI > > > breakage as the LIST_END value will still > > change. > > > > Right, you need to update the ignore list for the tool. > > > > > We are also reviewing all other cryptodev APIs in case there is any other > API which needs versioning. > > > > > > Anyone see any problem with this approach? > > > > The other issue is with all other functions accepting this enum as input. > > We should continue returning an error if getting Chacha as input with > > 19.11 version of these functions. > > But I would tend to consider this small ABI breakage can be ignored as > > it is in the error path. > [Fiona] The QAT PMD tests for and handles this error. I expect other PMDs > do too. [Arek] - Yes, it is error path but on the other hand we explicitly specify what value we will return when calling rte_cryptodev_sym_session_init so caller may expect EINVAL when wrong algorithm value selected (usually it probably will be ENOTSUP). In this case when setting 3 (LIST_END) on 19.11 app and linking against 20.02 (assuming with Chacha) shared build, caller would get success on return and fully set chacha session, which will probably result in undefined behavior. So shouldn't this function be versioned as well then? Regards, Arek
Hi, > -----Original Message----- > From: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com> > Sent: Thursday, February 13, 2020 2:51 PM > To: Trahe, Fiona <fiona.trahe@intel.com>; Thomas Monjalon <thomas@monjalon.net> > Cc: David Marchand <david.marchand@redhat.com>; nhorman@tuxdriver.com; bluca@debian.org; > ktraynor@redhat.com; Ray Kinsella <mdr@ashroe.eu>; dev@dpdk.org; Akhil Goyal > <akhil.goyal@nxp.com>; Yigit, Ferruh <ferruh.yigit@intel.com>; Ananyev, Konstantin > <konstantin.ananyev@intel.com>; dev@dpdk.org; Anoob Joseph <anoobj@marvell.com>; > Richardson, Bruce <bruce.richardson@intel.com>; Mcnamara, John <john.mcnamara@intel.com>; > dodji@seketeli.net; Andrew Rybchenko <arybchenko@solarflare.com>; aconole@redhat.com > Subject: RE: [dpdk-dev] [PATCH v2 4/4] add ABI checks > > Hi, > > Two comments from me, > > > > > The patch we're working on will provide two versions of > > > > rte_cryptodev_info_get(), both call the same PMD function from the > > dev_ops info_get fn ptr. > > > > The default version operates s as normal, the 19.11 version searches > > > > through the list returned by the PMD, looking for sym.aead.algo = > > > > ChaChaPoly, it needs to strip it from > > > the list. > > > > As PMDs just pass a ptr to their capabilities list ( it isn't a > > > > linked list, but an array with an end marker = > > > > RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST) if the API layer detects > > > > Chacha it must allocate some space and store a local copy of the trimmed > > list. This must be stored only once per device. > [Arek] The problem with this solution is that we need to allocate memory. > So the question is how to handle unlikely case of malloc error when we operate inside void function > rte_cryptodev_info_get? > And even if we would pass somehow error condition to the caller then what to do is another question. [Fiona] Quick recap: To avoid breaking ABI, we must return a set of capabilities with/without ChaChaPoly depending on the appl version. To resolve this, within the rte_cryptodev layer, we propose to inspect the capabilities returned by PMD and strip ChaCha if it exists. In that case memory for the new trimmed capabilities array has to be malloced by the lib. All good, except how to handle a malloc fail is yet another API breakage as rte_cryptodev_get_info() returns void. We propose to return an empty capability list, i.e. a list with only the END element (which can be done without malloc) in this corner case of a corner case. Anyone see any issue with this? > > > > > > > I don't understand what you have to store. > > > Can't you just set the algo to 0 if it is ChaCha? > > [Fiona] it returns a pointer to data in the PMD domain, which the API couldn't > > and shouldn't overwrite, e.g. > > static const struct rte_cryptodev_capabilities qat_gen3_sym_capabilities[] > Should we print user some information > > > > > > > > > This versioning will apply to any PMD which wants to take advantage > > > > of the new API between now and > > > 20.11. > > > > > > > > Note, I expect the ABI checker tools will still complain of ABI > > > > breakage as the LIST_END value will still > > > change. > > > > > > Right, you need to update the ignore list for the tool. > > > > > > > We are also reviewing all other cryptodev APIs in case there is any other > > API which needs versioning. > > > > > > > > Anyone see any problem with this approach? > > > > > > The other issue is with all other functions accepting this enum as input. > > > We should continue returning an error if getting Chacha as input with > > > 19.11 version of these functions. > > > But I would tend to consider this small ABI breakage can be ignored as > > > it is in the error path. > > [Fiona] The QAT PMD tests for and handles this error. I expect other PMDs > > do too. > [Arek] - Yes, it is error path but on the other hand we explicitly specify what value we will return when > calling > rte_cryptodev_sym_session_init so caller may expect EINVAL when wrong algorithm value selected > (usually it probably will be ENOTSUP). > In this case when setting 3 (LIST_END) on 19.11 app and linking against 20.02 (assuming with Chacha) > shared build, caller would get success on return and fully set chacha session, > which will probably result in undefined behavior. > So shouldn't this function be versioned as well then? [Fiona] I would agree with Tomas to ignore this small ABI break, as it is already an error case if a appl is passing in a bad value for the algorithm. Even if it does return SUCCESS, instead of ENOTSUP, what behaviour could the application be expecting with a session using LIST_END as an algo? > > Regards, > Arek > >
16/03/2020 13:57, Trahe, Fiona: > From: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com> > > > > > The patch we're working on will provide two versions of > > > > > rte_cryptodev_info_get(), both call the same PMD function from the > > > dev_ops info_get fn ptr. > > > > > The default version operates s as normal, the 19.11 version searches > > > > > through the list returned by the PMD, looking for sym.aead.algo = > > > > > ChaChaPoly, it needs to strip it from > > > > the list. > > > > > As PMDs just pass a ptr to their capabilities list ( it isn't a > > > > > linked list, but an array with an end marker = > > > > > RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST) if the API layer detects > > > > > Chacha it must allocate some space and store a local copy of the trimmed > > > list. This must be stored only once per device. > > > > [Arek] The problem with this solution is that we need to allocate memory. > > So the question is how to handle unlikely case of malloc error when we operate inside void function > > rte_cryptodev_info_get? > > And even if we would pass somehow error condition to the caller then what to do is another question. > > [Fiona] Quick recap: To avoid breaking ABI, we must return a set of capabilities with/without ChaChaPoly > depending on the appl version. To resolve this, within the rte_cryptodev layer, we propose to > inspect the capabilities returned by PMD and strip ChaCha if it exists. > In that case memory for the new trimmed capabilities array has to be malloced by the lib. What happens if the capability is removed from the original capabilities input? > All good, except how to handle a malloc fail is yet another API breakage as rte_cryptodev_get_info() returns void. > We propose to return an empty capability list, i.e. a list with only the END element (which can be done without malloc) > in this corner case of a corner case. > Anyone see any issue with this? How can we use the feature if it is not advertised in capabilities?
Hi Thomas, > -----Original Message----- > From: Thomas Monjalon <thomas@monjalon.net> > Sent: Monday, March 16, 2020 2:09 PM > To: Trahe, Fiona <fiona.trahe@intel.com> > Cc: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>; David Marchand > <david.marchand@redhat.com>; nhorman@tuxdriver.com; > bluca@debian.org; ktraynor@redhat.com; Ray Kinsella <mdr@ashroe.eu>; > dev@dpdk.org; Akhil Goyal <akhil.goyal@nxp.com>; Yigit, Ferruh > <ferruh.yigit@intel.com>; Ananyev, Konstantin > <konstantin.ananyev@intel.com>; dev@dpdk.org; Anoob Joseph > <anoobj@marvell.com>; Richardson, Bruce <bruce.richardson@intel.com>; > Mcnamara, John <john.mcnamara@intel.com>; dodji@seketeli.net; Andrew > Rybchenko <arybchenko@solarflare.com>; aconole@redhat.com; Trahe, > Fiona <fiona.trahe@intel.com> > Subject: Re: [dpdk-dev] [PATCH v2 4/4] add ABI checks > > 16/03/2020 13:57, Trahe, Fiona: > > From: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com> > > > > > > The patch we're working on will provide two versions of > > > > > > rte_cryptodev_info_get(), both call the same PMD function from > > > > > > the > > > > dev_ops info_get fn ptr. > > > > > > The default version operates s as normal, the 19.11 version > > > > > > searches through the list returned by the PMD, looking for > > > > > > sym.aead.algo = ChaChaPoly, it needs to strip it from > > > > > the list. > > > > > > As PMDs just pass a ptr to their capabilities list ( it isn't > > > > > > a linked list, but an array with an end marker = > > > > > > RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST) if the API layer > > > > > > detects Chacha it must allocate some space and store a local > > > > > > copy of the trimmed > > > > list. This must be stored only once per device. > > > > > > [Arek] The problem with this solution is that we need to allocate memory. > > > So the question is how to handle unlikely case of malloc error when > > > we operate inside void function rte_cryptodev_info_get? > > > And even if we would pass somehow error condition to the caller then > what to do is another question. > > > > [Fiona] Quick recap: To avoid breaking ABI, we must return a set of > > capabilities with/without ChaChaPoly depending on the appl version. To > > resolve this, within the rte_cryptodev layer, we propose to inspect the > capabilities returned by PMD and strip ChaCha if it exists. > > In that case memory for the new trimmed capabilities array has to be > malloced by the lib. > > What happens if the capability is removed from the original capabilities > input? > > > All good, except how to handle a malloc fail is yet another API breakage as > rte_cryptodev_get_info() returns void. > > We propose to return an empty capability list, i.e. a list with only > > the END element (which can be done without malloc) in this corner case of > a corner case. > > Anyone see any issue with this? > > How can we use the feature if it is not advertised in capabilities? What Fiona meant is that empty capability would indicate error condition in this case. That's why she asked if you ok with this API breakage. > >
17/03/2020 14:27, Kusztal, ArkadiuszX:
> Hi Thomas,
>
> > -----Original Message-----
> > From: Thomas Monjalon <thomas@monjalon.net>
> > Sent: Monday, March 16, 2020 2:09 PM
> > To: Trahe, Fiona <fiona.trahe@intel.com>
> > Cc: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>; David Marchand
> > <david.marchand@redhat.com>; nhorman@tuxdriver.com;
> > bluca@debian.org; ktraynor@redhat.com; Ray Kinsella <mdr@ashroe.eu>;
> > dev@dpdk.org; Akhil Goyal <akhil.goyal@nxp.com>; Yigit, Ferruh
> > <ferruh.yigit@intel.com>; Ananyev, Konstantin
> > <konstantin.ananyev@intel.com>; dev@dpdk.org; Anoob Joseph
> > <anoobj@marvell.com>; Richardson, Bruce <bruce.richardson@intel.com>;
> > Mcnamara, John <john.mcnamara@intel.com>; dodji@seketeli.net; Andrew
> > Rybchenko <arybchenko@solarflare.com>; aconole@redhat.com; Trahe,
> > Fiona <fiona.trahe@intel.com>
> > Subject: Re: [dpdk-dev] [PATCH v2 4/4] add ABI checks
> >
> > 16/03/2020 13:57, Trahe, Fiona:
> > > From: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>
> > > > > > > The patch we're working on will provide two versions of
> > > > > > > rte_cryptodev_info_get(), both call the same PMD function from
> > > > > > > the
> > > > > dev_ops info_get fn ptr.
> > > > > > > The default version operates s as normal, the 19.11 version
> > > > > > > searches through the list returned by the PMD, looking for
> > > > > > > sym.aead.algo = ChaChaPoly, it needs to strip it from
> > > > > > the list.
> > > > > > > As PMDs just pass a ptr to their capabilities list ( it isn't
> > > > > > > a linked list, but an array with an end marker =
> > > > > > > RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST) if the API layer
> > > > > > > detects Chacha it must allocate some space and store a local
> > > > > > > copy of the trimmed
> > > > > list. This must be stored only once per device.
> > > >
> > > > [Arek] The problem with this solution is that we need to allocate memory.
> > > > So the question is how to handle unlikely case of malloc error when
> > > > we operate inside void function rte_cryptodev_info_get?
> > > > And even if we would pass somehow error condition to the caller then
> > what to do is another question.
> > >
> > > [Fiona] Quick recap: To avoid breaking ABI, we must return a set of
> > > capabilities with/without ChaChaPoly depending on the appl version. To
> > > resolve this, within the rte_cryptodev layer, we propose to inspect the
> > capabilities returned by PMD and strip ChaCha if it exists.
> > > In that case memory for the new trimmed capabilities array has to be
> > malloced by the lib.
> >
> > What happens if the capability is removed from the original capabilities
> > input?
> >
> > > All good, except how to handle a malloc fail is yet another API breakage as
> > rte_cryptodev_get_info() returns void.
> > > We propose to return an empty capability list, i.e. a list with only
> > > the END element (which can be done without malloc) in this corner case of
> > a corner case.
> > > Anyone see any issue with this?
> >
> > How can we use the feature if it is not advertised in capabilities?
> What Fiona meant is that empty capability would indicate error condition in this case. That's why she asked if you ok with this API breakage.
Sorry I'm lost.
Please could you show what would be the usage?
> -----Original Message-----
> From: Thomas Monjalon <thomas@monjalon.net>
> Sent: Tuesday, March 17, 2020 4:10 PM
> To: Trahe, Fiona <fiona.trahe@intel.com>; Kusztal, ArkadiuszX
> <arkadiuszx.kusztal@intel.com>
> Cc: David Marchand <david.marchand@redhat.com>;
> nhorman@tuxdriver.com; bluca@debian.org; ktraynor@redhat.com; Ray
> Kinsella <mdr@ashroe.eu>; dev@dpdk.org; Akhil Goyal
> <akhil.goyal@nxp.com>; Yigit, Ferruh <ferruh.yigit@intel.com>; Ananyev,
> Konstantin <konstantin.ananyev@intel.com>; dev@dpdk.org; Anoob Joseph
> <anoobj@marvell.com>; Richardson, Bruce <bruce.richardson@intel.com>;
> Mcnamara, John <john.mcnamara@intel.com>; dodji@seketeli.net; Andrew
> Rybchenko <arybchenko@solarflare.com>; aconole@redhat.com; Trahe,
> Fiona <fiona.trahe@intel.com>
> Subject: Re: [dpdk-dev] [PATCH v2 4/4] add ABI checks
>
> 17/03/2020 14:27, Kusztal, ArkadiuszX:
> > Hi Thomas,
> >
> > > -----Original Message-----
> > > From: Thomas Monjalon <thomas@monjalon.net>
> > > Sent: Monday, March 16, 2020 2:09 PM
> > > To: Trahe, Fiona <fiona.trahe@intel.com>
> > > Cc: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>; David
> > > Marchand <david.marchand@redhat.com>; nhorman@tuxdriver.com;
> > > bluca@debian.org; ktraynor@redhat.com; Ray Kinsella
> <mdr@ashroe.eu>;
> > > dev@dpdk.org; Akhil Goyal <akhil.goyal@nxp.com>; Yigit, Ferruh
> > > <ferruh.yigit@intel.com>; Ananyev, Konstantin
> > > <konstantin.ananyev@intel.com>; dev@dpdk.org; Anoob Joseph
> > > <anoobj@marvell.com>; Richardson, Bruce
> > > <bruce.richardson@intel.com>; Mcnamara, John
> > > <john.mcnamara@intel.com>; dodji@seketeli.net; Andrew Rybchenko
> > > <arybchenko@solarflare.com>; aconole@redhat.com; Trahe, Fiona
> > > <fiona.trahe@intel.com>
> > > Subject: Re: [dpdk-dev] [PATCH v2 4/4] add ABI checks
> > >
> > > 16/03/2020 13:57, Trahe, Fiona:
> > > > From: Kusztal, ArkadiuszX <arkadiuszx.kusztal@intel.com>
> > > > > > > > The patch we're working on will provide two versions of
> > > > > > > > rte_cryptodev_info_get(), both call the same PMD function
> > > > > > > > from the
> > > > > > dev_ops info_get fn ptr.
> > > > > > > > The default version operates s as normal, the 19.11
> > > > > > > > version searches through the list returned by the PMD,
> > > > > > > > looking for sym.aead.algo = ChaChaPoly, it needs to strip
> > > > > > > > it from
> > > > > > > the list.
> > > > > > > > As PMDs just pass a ptr to their capabilities list ( it
> > > > > > > > isn't a linked list, but an array with an end marker =
> > > > > > > > RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST) if the API layer
> > > > > > > > detects Chacha it must allocate some space and store a
> > > > > > > > local copy of the trimmed
> > > > > > list. This must be stored only once per device.
> > > > >
> > > > > [Arek] The problem with this solution is that we need to allocate
> memory.
> > > > > So the question is how to handle unlikely case of malloc error
> > > > > when we operate inside void function rte_cryptodev_info_get?
> > > > > And even if we would pass somehow error condition to the caller
> > > > > then
> > > what to do is another question.
> > > >
> > > > [Fiona] Quick recap: To avoid breaking ABI, we must return a set
> > > > of capabilities with/without ChaChaPoly depending on the appl
> > > > version. To resolve this, within the rte_cryptodev layer, we
> > > > propose to inspect the
> > > capabilities returned by PMD and strip ChaCha if it exists.
> > > > In that case memory for the new trimmed capabilities array has to
> > > > be
> > > malloced by the lib.
> > >
> > > What happens if the capability is removed from the original
> > > capabilities input?
> > >
> > > > All good, except how to handle a malloc fail is yet another API
> > > > breakage as
> > > rte_cryptodev_get_info() returns void.
> > > > We propose to return an empty capability list, i.e. a list with
> > > > only the END element (which can be done without malloc) in this
> > > > corner case of
> > > a corner case.
> > > > Anyone see any issue with this?
> > >
> > > How can we use the feature if it is not advertised in capabilities?
> > What Fiona meant is that empty capability would indicate error condition in
> this case. That's why she asked if you ok with this API breakage.
>
> Sorry I'm lost.
> Please could you show what would be the usage?
>
So this case looks more or less like that:
There are two versions of `rte_cryptodev_info_get`
rte_cryptodev_info_get_v20 (versioned)
rte_cryptodev_info_get_v2005 (new default symbol)
Default version works normally as it will be called only by app build with 20.05 version.
When prior to 20.05 app calls `rte_cryptodev_info_get` version v20 is called. This function will remove Chacha Poly from capabilities, but to achieve this we need to get some memory to store `new` set of capabilities per device (without Chacha). So:
new_capability[dev_id] = malloc( (num_of_capabilies - 1 (chacha)) * sizeof(struct rte_cryptodev_capabilities))
The small problem is how to handle malloc error:
If (new_capability[dev_id] == NULL) {
/* What to do now as rte_cryptodev_info_get is void function, and API does not say anything about error condition */
/*So Fiona suggestion above is to inform user of an error by doing this: */
dev_info->capabilities = cryptodev_undefined_capabilities;
/* Where
static const struct rte_cryptodev_capabilities cryptodev_undefined_capabilities[] = {
RTE_CRYPTODEV_END_OF_CAPABILITIES_LIST()
}; */
}
Sizeof rte_cryptodev_capabilities is 38 bytes, padded to 40. So properly constructed capabilities can take at most 1920 bytes. No system should ever fail doing that though iam not an expert. Other option could probably be to preallocate this memory. This is how I understand that.
Another question is can something like that be done if API comments of `rte_cryptodev_info_get` function does not say anything about any potential error?
Regards,
Arek