From 44290e13b4b59b1552e54a263dce8cc9534f7f45 Mon Sep 17 00:00:00 2001 From: Tomasz Zawadzki Date: Thu, 8 Dec 2022 18:21:22 +0100 Subject: [PATCH] env_dpdk: add script for comparing DPDK PCI API Starting with DPDK 22.11, PCI API are no longer public. In order to implement out-of-tree driver like SPDK NVMe driver that is compatible with DPDK, a copy of PCI API headers are required in SPDK. check_dpdk_pci_api.sh script is intended simplify the maintanance of the compatibility between SPDK copies of the headers and multiple DPDK versions. Please see the included README Signed-off-by: Tomasz Zawadzki Change-Id: Ief028c13564441560425761e7802c6cf07460876 Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15857 Tested-by: SPDK CI Jenkins Reviewed-by: Jim Harris Reviewed-by: Konrad Sztyber --- autobuild.sh | 1 + scripts/env_dpdk/22.07/rte_bus_pci.h.patch | 12 ++++ scripts/env_dpdk/README.md | 44 ++++++++++++ scripts/env_dpdk/check_dpdk_pci_api.sh | 79 ++++++++++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 scripts/env_dpdk/22.07/rte_bus_pci.h.patch create mode 100644 scripts/env_dpdk/README.md create mode 100755 scripts/env_dpdk/check_dpdk_pci_api.sh diff --git a/autobuild.sh b/autobuild.sh index 6bc9f973f..04da30aaa 100755 --- a/autobuild.sh +++ b/autobuild.sh @@ -342,6 +342,7 @@ function build_doc() { function autobuild_test_suite() { run_test "autobuild_check_format" ./scripts/check_format.sh run_test "autobuild_check_so_deps" $rootdir/test/make/check_so_deps.sh $1 + run_test "autobuild_check_dpdk_pci_api" $rootdir/scripts/env_dpdk/check_dpdk_pci_api.sh if [[ $SPDK_TEST_AUTOBUILD == 'full' ]]; then run_test "autobuild_external_code" $rootdir/test/external_code/test_make.sh $rootdir ./configure $config_params --without-shared diff --git a/scripts/env_dpdk/22.07/rte_bus_pci.h.patch b/scripts/env_dpdk/22.07/rte_bus_pci.h.patch new file mode 100644 index 000000000..8f2f15614 --- /dev/null +++ b/scripts/env_dpdk/22.07/rte_bus_pci.h.patch @@ -0,0 +1,12 @@ +@@ -69,7 +69,11 @@ + struct rte_pci_id id; /**< PCI ID. */ + struct rte_mem_resource mem_resource[PCI_MAX_RESOURCE]; + /**< PCI Memory Resource */ ++#if RTE_VERSION < RTE_VERSION_NUM(21, 11, 0, 0) ++ struct rte_intr_handle intr_handle; /**< Interrupt handle */ ++#else + struct rte_intr_handle *intr_handle; /**< Interrupt handle */ ++#endif + struct rte_pci_driver *driver; /**< PCI driver used in probing */ + uint16_t max_vfs; /**< sriov enable if not zero */ + enum rte_pci_kernel_driver kdrv; /**< Kernel driver passthrough */ diff --git a/scripts/env_dpdk/README.md b/scripts/env_dpdk/README.md new file mode 100644 index 000000000..52603a096 --- /dev/null +++ b/scripts/env_dpdk/README.md @@ -0,0 +1,44 @@ +# Introduction + +Starting with DPDK 22.11, PCI API are no longer public. In order to implement +out-of-tree driver like SPDK NVMe driver that is compatible with DPDK, +a copy of PCI API headers are required in SPDK. + +`check_dpdk_pci_api.sh` script is intended simplify the maintenance of the +compatibility between SPDK copies of the headers and multiple DPDK versions. + +## Arguments + +The script has two optional positional arguments: +$1 - `check` or `fix` mode (default: check) +$2 - path to DPDK sources (default: DPDK submodule) + +## Check mode + +When calling the script, default is to check the diff of the in-tree headers with +DPDK and report any differences found. This is used for testing of current and +future DPDK versions. + +## Fix mode + +Similar to check mode, but additionally patches the differences to the +currently tested DPDK version. This should be done only for cosmetic changes, +not for changes that break compatibility. + +## Workarounds for specific DPDK version + +Any changes that should be applied to all copied headers have to be part of the +`check_dpdk_pci_api.sh`. For example referring to in-tree copied PCI headers +rather than system installed ones. + +In rare cases there might be a need to apply a specific workaround for +particular DPDK PCI API version. Then a patch should be added in +`spdk_root/scripts/env_dpdk/` where ver is the matching DPDK version. + +## Flow for adding support for new DPDK PCI API version + +If API was changed, a new directory should be created `spdk_root/lib/env_dpdk/` +where ver is the appropriate DPDK version name. There the relevant headers should be copied. + +Please note that the directories should match only the first DPDK version that modified the API. +Not every DPDK version requires new directory. diff --git a/scripts/env_dpdk/check_dpdk_pci_api.sh b/scripts/env_dpdk/check_dpdk_pci_api.sh new file mode 100755 index 000000000..a5773719b --- /dev/null +++ b/scripts/env_dpdk/check_dpdk_pci_api.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: BSD-3-Clause +# Copyright (C) 2022 Intel Corporation +# All rights reserved. +# + +scriptdir=$(readlink -f "$(dirname "$0")") +rootdir=$(readlink -f "$scriptdir/../..") +source "$rootdir/scripts/common.sh" + +set -e +shopt -s extglob + +mode=${1:-check} # check or fix + +# By default verify headers matching the DPDK submodule +dpdk_dir=${2:-"$rootdir/dpdk"} +dpdk_ver=$(< "$dpdk_dir/VERSION") + +env_path="$rootdir/lib/env_dpdk" +tracked_versions=("$env_path/"+([0-9]).+([0-9])/*.h) +tracked_versions=("${tracked_versions[@]#"$env_path/"}") +tracked_versions=("${tracked_versions[@]%/*}") + +# The DPDK PCI API tracking started with DPDK 22.11, all prior versions will use DPDK 22.07 headers +target_ver="22.07" +while read -r ver; do + ge "$dpdk_ver" "$ver" && target_ver=$ver && break +done < <(printf "%s\n" "${tracked_versions[@]}" | sort -Vru) + +echo "Checking DPDK PCI API from $dpdk_ver against $target_ver ..." + +target_headers=("$env_path/$target_ver/"*.h) +target_headers=("${target_headers[@]##*/}") + +# The includes should point to headers in SPDK tree rather than system ones. +use_local_includes="-e " +for header in "${target_headers[@]}"; do + use_local_includes+="s/#include <$header>/#include \"$header\"/g;" +done + +for header in "${target_headers[@]}"; do + dpdk_file="$dpdk_dir/$(git -C "$dpdk_dir" ls-files "*/$header")" + + # Patch DPDK header with any workarounds necessary + patch_file="$scriptdir/$target_ver/$header.patch" + if [[ -s $patch_file ]]; then + dpdk_header=$(patch -s "$dpdk_file" "$patch_file" -o - | sed "$use_local_includes") + else + dpdk_header=$(sed "$use_local_includes" "$dpdk_file") + fi + + spdk_file="$env_path/$target_ver/$header" + if ! single_diff=$(diff -u "$spdk_file" <(echo "$dpdk_header")); then + header_diff+="$single_diff\n" + fi +done + +if [[ -z "$header_diff" ]]; then + echo "No differences in headers found." + exit 0 +fi + +if [[ "$mode" == "check" ]]; then + cat <<- CHECK + $(echo -e "$header_diff") + + Differences in DPDK and internal SPDK headers found. + For changes that do not affect the API, please use 'fix' as \$1 to this script. + If API was changed, please create "$env_path/$dpdk_ver/" with appropriate headers. + + CHECK +elif [[ "$mode" == "fix" ]]; then + echo -e "$header_diff" | patch -d "$env_path/$target_ver/" + echo "Fixed differences between DPDK and internal SPDK headers." +else + echo "Incorrect \$1 passed, please use 'check' or 'fix'." + exit 1 +fi