DPDK patches and discussions
 help / color / mirror / Atom feed
From: Maxime Coquelin <maxime.coquelin@redhat.com>
To: dev@dpdk.org, techboard@dpdk.org, david.marchand@redhat.com,
	thomas@monjalon.net, mb@smartsharesystems.com,
	stephen@networkplumber.org, ferruh.yigit@amd.com
Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
Subject: [PATCH v1 1/3] uapi: introduce kernel uAPI headers import
Date: Wed,  9 Oct 2024 10:58:03 +0200	[thread overview]
Message-ID: <20241009085805.2638314-2-maxime.coquelin@redhat.com> (raw)
In-Reply-To: <20241009085805.2638314-1-maxime.coquelin@redhat.com>

This patch introduces uAPI headers import into the DPDK
repository. This import is possible thanks to Linux Kernel
licence exception for syscalls:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/LICENSES/exceptions/Linux-syscall-note

Header files have to be explicitly imported.

Guidelines are provided in the documentation, and helper
script is also provided to ensure proper import of the
headers (unmodified content from a released Kernel
version).

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 devtools/linux-uapi.sh                 | 177 +++++++++++++++++++++++++
 doc/guides/contributing/index.rst      |   1 +
 doc/guides/contributing/linux_uapi.rst |  70 ++++++++++
 kernel/linux/uapi/.gitignore           |   4 +
 kernel/linux/uapi/version              |   1 +
 meson.build                            |   8 +-
 6 files changed, 259 insertions(+), 2 deletions(-)
 create mode 100755 devtools/linux-uapi.sh
 create mode 100644 doc/guides/contributing/linux_uapi.rst
 create mode 100644 kernel/linux/uapi/.gitignore
 create mode 100644 kernel/linux/uapi/version

diff --git a/devtools/linux-uapi.sh b/devtools/linux-uapi.sh
new file mode 100755
index 0000000000..175d6a345d
--- /dev/null
+++ b/devtools/linux-uapi.sh
@@ -0,0 +1,177 @@
+#!/bin/sh -e
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright (c) 2024 Red Hat, Inc.
+
+#
+# Import and check Linux Kernel uAPI headers
+#
+
+base_url="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/include/uapi/"
+base_path="kernel/linux/uapi/"
+version=""
+file=""
+check_headers=0
+errors=0
+
+print_usage()
+{
+	echo "Usage: $(basename $0) [-h] [-i FILE] [-u VERSION] [-c]"
+	echo "-i FILE      import Linux header file. E.g. linux/vfio.h"
+	echo "-u VERSION   update imported list of Linux headers to a given version. E.g. v6.10"
+	echo "-c           check headers are valid"
+}
+
+version_older_than() {
+    printf '%s\n%s' "$1" "$2" | sort -C -V
+}
+
+download_header()
+{
+	local header=$1
+	local path=$2
+
+	local url="${base_url}${header}?h=${version}"
+
+	if ! curl -s -f --create-dirs -o $path $url; then
+		echo "Failed to download $url"
+		return 1
+	fi
+
+	return 0
+}
+
+update_headers()
+{
+	local header
+	local url
+	local path
+
+	echo "Updating to $version"
+	for filename in $(find $base_path -name "*.h" -type f); do
+		header=${filename#$base_path}
+		download_header $header $filename || return 1
+	done
+
+	return 0
+}
+
+import_header()
+{
+	local include
+	local import
+	local header=$1
+
+	local path="${base_path}${header}"
+
+	download_header $header $path || return 1
+
+	for include in $(sed -ne 's/^#include <\(.*\)>$/\1/p' $path); do
+		if [ ! -f "${base_path}${include}" ]; then
+			read -p "Import $include (y/n): " import && [ "$import" = 'y' ] || continue
+			echo "Importing $include for $path"
+			import_header "$include" || return 1
+		fi
+	done
+
+	return 0
+}
+
+fixup_includes()
+{
+	local path=$1
+
+	sed -i -E -e '
+	s/([[:space:](])(__user|__force|__iomem)[[:space:]]/\1/g
+	s/__attribute_const__([[:space:]]|$)/\1/g
+	s@^#include <linux/compiler(|_types).h>@@
+	s/(^|[^a-zA-Z0-9])__packed([^a-zA-Z0-9_]|$)/\1__attribute__((packed))\2/g
+	s/(^|[[:space:](])(inline|asm|volatile)([[:space:](]|$)/\1__\2__\3/g
+	s@#(ifndef|define|endif[[:space:]]*/[*])[[:space:]]*_UAPI@#\1 @
+	' $path
+
+	# Prepend include path with "uapi/" if the header is imported
+	for include in $(sed -ne 's/^#include <\(.*\)>$/\1/p' $path); do
+		if [ -f "${base_path}${include}" ]; then
+			sed -i "s|${include}|uapi/${include}|g" $path
+		fi
+	done
+}
+
+check_header() {
+	echo -n "Checking $1... "
+
+	if ! diff -q $1 $2 >/dev/null; then
+		echo "KO"
+		diff -u $1 $2
+		return 1
+	else
+		echo "OK"
+	fi
+
+	return 0
+}
+
+while getopts i:u:ch opt ; do
+	case ${opt} in
+		i ) file=$OPTARG ;;
+		u ) version=$OPTARG ;;
+		c ) check_headers=1 ;;
+		h ) print_usage ; exit 0 ;;
+		? ) print_usage ; exit 1 ;;
+	esac
+done
+
+shift $(($OPTIND - 1))
+if [ $# -ne 0 ]; then
+	print_usage
+	exit 1
+fi
+
+cd $(dirname $0)/..
+
+current_version=$(< ${base_path}/version)
+
+if [ -n "${version}" ]; then
+	if version_older_than "$version" "$current_version"; then
+		echo "Headers already up to date ($current_version >= $version)"
+		version=$current_version
+	else
+		update_headers || exit 1
+	fi
+else
+	echo "Version not specified, using current version ($current_version)"
+	version=$current_version
+fi
+
+if [ -n "${file}" ]; then
+	import_header $file || exit 1
+fi
+
+for filename in $(find $base_path -name "*.h" -type f); do
+	fixup_includes $filename || exit 1
+done
+
+echo $version > ${base_path}/version
+
+if [ $check_headers -eq 0 ]; then
+	exit 0
+fi
+
+tmpheader="$(mktemp -t dpdk.checkuapi.XXXXXX)"
+trap "rm -f '$tmpheader" INT
+
+echo "Checking imported headers for version ${version}"
+
+for filename in $(find $base_path -name "*.h" -type f); do
+	header=${filename#$base_path}
+	download_header $header $tmpheader || exit 1
+	fixup_includes $tmpheader || exit 1
+	check_header $filename $tmpheader || errors=$((errors+1))
+done
+
+echo "$errors error(s) found"
+
+rm -f $tmpheader
+trap - INT
+
+exit $errors
diff --git a/doc/guides/contributing/index.rst b/doc/guides/contributing/index.rst
index dcb9b1fbf0..603dc72654 100644
--- a/doc/guides/contributing/index.rst
+++ b/doc/guides/contributing/index.rst
@@ -19,3 +19,4 @@ Contributor's Guidelines
     vulnerability
     stable
     cheatsheet
+    linux_uapi
diff --git a/doc/guides/contributing/linux_uapi.rst b/doc/guides/contributing/linux_uapi.rst
new file mode 100644
index 0000000000..00bc092311
--- /dev/null
+++ b/doc/guides/contributing/linux_uapi.rst
@@ -0,0 +1,70 @@
+.. SPDX-License-Identifier: BSD-3-Clause
+   Copyright(c) 2024 Red Hat, Inc.
+
+Linux uAPI header files
+=======================
+
+Rationale
+---------
+
+The system a DPDK library or driver is built on is not necessarily running the
+same Kernel version than the system that will run it.
+Importing Linux Kernel uAPI headers enable to build features that are not
+supported yet by the build system.
+
+For example, the build system runs upstream Kernel v5.19 and we would like to
+build a VDUSE application that will use VDUSE_IOTLB_GET_INFO ioctl() introduced
+in Linux Kernel v6.0.
+
+`Linux Kernel licence exception regarding syscalls
+<https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/LICENSES/exceptions/Linux-syscall-note>`_
+enable importing unmodified Linux Kernel uAPI header files.
+
+Importing or updating an uAPI header file
+-----------------------------------------
+
+In order to ensure the imported uAPI headers are both unmodified and from a
+released version of the linux Kernel, a helper script is made available and
+MUST be used.
+Below is an example to import ``linux/vduse.h`` file from Linux ``v6.10``:
+
+.. code-block:: console
+
+   ./devtools/linux-uapi.sh -i linux/vduse.h -u v6.10
+
+Once imported, the header files should be committed without any other change.
+Note that all the imported headers will be updated to the requested version.
+
+Updating imported headers to a newer released version should only be done on
+a need basis, it can be achieved using the same script:
+
+.. code-block:: console
+
+   ./devtools/linux-uapi.sh -u v6.10
+
+The commit message should reflect why updating the headers is necessary.
+
+Once committed, user can check headers are valid by using the same Linux
+uAPI script using the check option:
+
+.. code-block:: console
+
+   ./devtools/linux-uapi.sh -c
+
+Note that all the linux-uapi.sh script options can be combined. For example:
+
+.. code-block:: console
+
+   ./devtools/linux-uapi.sh -i linux/virtio_net.h -u v6.10 -c
+
+Header inclusion into library or driver
+---------------------------------------
+
+The library or driver willing to make use of imported uAPI headers needs to
+explicitly include the header file with ``uapi/`` prefix in C files.
+For example to include VDUSE uAPI:
+
+.. code-block:: c
+
+   #include <uapi/linux/vduse.h>
+
diff --git a/kernel/linux/uapi/.gitignore b/kernel/linux/uapi/.gitignore
new file mode 100644
index 0000000000..558ba597d6
--- /dev/null
+++ b/kernel/linux/uapi/.gitignore
@@ -0,0 +1,4 @@
+**
+!**/
+!**/*.h
+!version
diff --git a/kernel/linux/uapi/version b/kernel/linux/uapi/version
new file mode 100644
index 0000000000..2b256fd48f
--- /dev/null
+++ b/kernel/linux/uapi/version
@@ -0,0 +1 @@
+v0.0
diff --git a/meson.build b/meson.build
index 8b248d4505..85b53cafbb 100644
--- a/meson.build
+++ b/meson.build
@@ -67,16 +67,20 @@ endif
 # configure the build, and make sure configs here and in config folder are
 # able to be included in any file. We also store a global array of include dirs
 # for passing to pmdinfogen scripts
-global_inc = include_directories('.', 'config',
+global_inc = [include_directories('.', 'config',
     'lib/eal/include',
     'lib/eal/@0@/include'.format(host_machine.system()),
     'lib/eal/@0@/include'.format(arch_subdir),
-)
+)]
 
 # do configuration and get tool paths
 subdir('buildtools')
 subdir('config')
 
+if is_linux
+    global_inc += include_directories('kernel/linux')
+endif
+
 # build libs and drivers
 subdir('lib')
 subdir('drivers')
-- 
2.46.2


  reply	other threads:[~2024-10-09  8:58 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-10-09  8:58 [PATCH v1 0/3] Import Kernel uAPI header files Maxime Coquelin
2024-10-09  8:58 ` Maxime Coquelin [this message]
2024-10-09 14:50   ` [PATCH v1 1/3] uapi: introduce kernel uAPI headers import Stephen Hemminger
2024-10-14 12:14     ` Maxime Coquelin
2024-10-09  8:58 ` [PATCH v1 2/3] uapi: import VDUSE header Maxime Coquelin
2024-10-09  8:58 ` [PATCH v1 3/3] vduse: use imported VDUSE uAPI header Maxime Coquelin
2024-10-15 17:10   ` Stephen Hemminger
2024-10-09 10:29 ` [PATCH v1 0/3] Import Kernel uAPI header files Morten Brørup

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20241009085805.2638314-2-maxime.coquelin@redhat.com \
    --to=maxime.coquelin@redhat.com \
    --cc=david.marchand@redhat.com \
    --cc=dev@dpdk.org \
    --cc=ferruh.yigit@amd.com \
    --cc=mb@smartsharesystems.com \
    --cc=stephen@networkplumber.org \
    --cc=techboard@dpdk.org \
    --cc=thomas@monjalon.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).