Commit 44290e13 authored by Tomasz Zawadzki's avatar Tomasz Zawadzki
Browse files

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: default avatarTomasz Zawadzki <tomasz.zawadzki@intel.com>
Change-Id: Ief028c13564441560425761e7802c6cf07460876
Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/15857


Tested-by: default avatarSPDK CI Jenkins <sys_sgci@intel.com>
Reviewed-by: default avatarJim Harris <james.r.harris@intel.com>
Reviewed-by: default avatarKonrad Sztyber <konrad.sztyber@intel.com>
parent fcbbd17a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -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
+12 −0
Original line number Diff line number Diff line
@@ -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 */
+44 −0
Original line number Diff line number Diff line
# 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/<ver>` 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/<ver>`
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.
+79 −0
Original line number Diff line number Diff line
#!/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