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
Cc: Maxime Coquelin <maxime.coquelin@redhat.com>
Subject: [RFC v3 1/3] uapi: introduce kernel uAPI headers import
Date: Wed, 11 Sep 2024 21:32:22 +0200	[thread overview]
Message-ID: <20240911193224.1966122-2-maxime.coquelin@redhat.com> (raw)
In-Reply-To: <20240911193224.1966122-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 are have to be explicitly imported.

Guidelines are provided in the documentation, and helper
scripts are also provided to ensure proper importation of the
header (unmodified content from a released Kernel version):
 - import-linux-uapi.sh: used to add and update headers and
 their dependencies to linux-headers/uapi/
 - check-linux-uapi.sh: used to check all headers are valid

Signed-off-by: Maxime Coquelin <maxime.coquelin@redhat.com>
---
 devtools/check-linux-uapi.sh           |  85 ++++++++++++++++++
 devtools/import-linux-uapi.sh          | 119 +++++++++++++++++++++++++
 doc/guides/contributing/index.rst      |   1 +
 doc/guides/contributing/linux_uapi.rst |  71 +++++++++++++++
 linux-headers/uapi/.gitignore          |   4 +
 linux-headers/uapi/version             |   1 +
 meson.build                            |   8 +-
 7 files changed, 287 insertions(+), 2 deletions(-)
 create mode 100755 devtools/check-linux-uapi.sh
 create mode 100755 devtools/import-linux-uapi.sh
 create mode 100644 doc/guides/contributing/linux_uapi.rst
 create mode 100644 linux-headers/uapi/.gitignore
 create mode 100644 linux-headers/uapi/version

diff --git a/devtools/check-linux-uapi.sh b/devtools/check-linux-uapi.sh
new file mode 100755
index 0000000000..fc42c03169
--- /dev/null
+++ b/devtools/check-linux-uapi.sh
@@ -0,0 +1,85 @@
+#!/bin/sh
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright (c) 2024 Red Hat, Inc.
+
+#
+# Check Linux Kernel uAPI header files
+#
+
+base_url="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/include/uapi/"
+base_path="linux-headers/uapi/"
+errors=0
+version=""
+
+print_usage()
+{
+	echo "Usage: $(basename $0) [-h]"
+}
+
+check_uapi_header() {
+	path=$1
+	file=${1#$base_path}
+
+	cp -f $path $tmpinput1
+
+	# Restore includes fixups done by import-linux-uapi.sh
+	sed -i "s|//#include <linux/compiler.h>|#include <linux/compiler.h>|g" $tmpinput1
+	sed -i "s|#include <uapi/|#include <|g" $tmpinput1
+
+	url="${base_url}${file}?h=${version}"
+	echo -n "Checking $file... "
+	curl -s -f -o $tmpinput2 $url
+	if [ $? -ne 0 ]; then
+		echo "Failed to download $url"
+		exit 1
+	fi
+
+	diff -q $tmpinput1 $tmpinput2 >/dev/null
+	if [ $? -ne 0 ]; then
+		echo "KO"
+		diff -u $tmpinput1 $tmpinput2
+		errors=$((errors+1))
+	else
+		echo "OK"
+	fi
+}
+
+while getopts hv ARG ; do
+	case $ARG in
+		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)/..
+
+tmpinput1=$(mktemp -t dpdk.checkuapi.XXXXXX)
+tmpinput2=$(mktemp -t dpdk.checkuapi.XXXXXX)
+trap "rm -f '$tmpinput1 $tmpinput2'" INT
+
+version=$(< ${base_path}/version)
+
+echo "Checking imported headers for version ${version}"
+
+for filename in $(find $base_path -name "*.h" -type f); do
+	check_uapi_header "${filename}" </dev/null
+done
+
+echo "$errors error(s) found"
+
+rm -f $tmpinput1 $tmpinput2
+trap - INT
+
+exit $errors
diff --git a/devtools/import-linux-uapi.sh b/devtools/import-linux-uapi.sh
new file mode 100755
index 0000000000..ff15e23821
--- /dev/null
+++ b/devtools/import-linux-uapi.sh
@@ -0,0 +1,119 @@
+#!/bin/sh
+# SPDX-License-Identifier: BSD-3-Clause
+# Copyright (c) 2024 Red Hat, Inc.
+
+#
+# Import Linux Kernel uAPI header file
+#
+
+base_url="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/plain/include/uapi/"
+base_path="linux-headers/uapi/"
+version=""
+file=""
+
+print_usage()
+{
+	echo "Usage: $(basename $0) [-h] [-a FILE] [-u VERSION]"
+	echo "-a 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"
+}
+
+version_valid() {
+    printf '%s\n%s' "$1" "$2" | sort -C -V
+}
+
+update_headers()
+{
+	local header=${filename//"$base_path"}
+	local url
+	local path
+
+	echo "Updating to $version"
+	while IFS= read -d '' -r filename; do
+		header=${filename//"$base_path"/}
+		url="${base_url}${header}?h=${version}"
+		path="${base_path}${header}"
+		curl -s -f -o $path $url
+	done < <(find $base_path -name "*.h" -type f -print0)
+}
+
+import_header()
+{
+	local include
+	local import
+	local header=$1
+
+	local url="${base_url}${header}?h=${version}"
+	local path="${base_path}${header}"
+
+	curl -s -f --create-dirs -o $path $url
+
+	for include in $(sed -ne 's/^#include <\(.*\)>$/\1/p' $path); do
+		if [ ! -f "${base_path}${include}" ]; then
+			read -p "Import $include (y/n): " import < /dev/tty && [ "$import" = 'y' ] || continue
+			echo "Importing $include for $path"
+			import_header "$include"
+		fi
+	done
+}
+
+fixup_includes()
+{
+	local path=$1
+
+	# Do not include linux/compiler.h as done by make headers
+	sed -i "s|^#include <linux/compiler.h>|//#include <linux/compiler.h>|g" $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
+}
+
+while getopts a:u:hv opt ; do
+	case ${opt} in
+		a )
+			file=$OPTARG
+			;;
+		u )
+			version=$OPTARG
+			;;
+		h )
+			print_usage
+			exit 0
+			;;
+		? )
+			print_usage
+			exit 1
+			;;
+	esac
+done
+
+cd $(dirname $0)/..
+
+current_version=$(< ${base_path}/version)
+
+if [ -n "${version}" ]; then
+	version_valid "$version" "$current_version"
+	if [ $? -eq 0 ]; then
+		echo "Headers already up to date ($current_version >= $version)"
+		version=$current_version
+	else
+		update_headers
+	fi
+else
+	echo "Version not specified, using current version ($current_version)"
+	version=$current_version
+fi
+
+if [ -n "${file}" ]; then
+	import_header $file
+fi
+
+for filename in $(find $base_path -name "*.h" -type f); do
+	fixup_includes "${filename}" </dev/null
+done
+
+echo $version > ${base_path}/version
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..d4255eb22e
--- /dev/null
+++ b/doc/guides/contributing/linux_uapi.rst
@@ -0,0 +1,71 @@
+.. 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/import-linux-uapi.sh -a 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/import-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 Linux uAPI
+checker tool:
+
+.. code-block:: console
+
+   ./devtools/check-linux-uapi.sh
+
+Header inclusion into library or driver
+---------------------------------------
+
+The library or driver willing to make use of imported uAPI headers needs to
+explicitly add uAPI headers path to the ``includes`` var in its ``meson.build``
+file:
+
+.. code-block:: python
+
+   includes += linux_uapi_inc
+
+Then, it can be included with ``uapi/`` prefix in C files.
+For example to include VDUSE uAPI:
+
+.. code-block:: c
+
+   #include <uapi/linux/vduse.h>
+
diff --git a/linux-headers/uapi/.gitignore b/linux-headers/uapi/.gitignore
new file mode 100644
index 0000000000..558ba597d6
--- /dev/null
+++ b/linux-headers/uapi/.gitignore
@@ -0,0 +1,4 @@
+**
+!**/
+!**/*.h
+!version
diff --git a/linux-headers/uapi/version b/linux-headers/uapi/version
new file mode 100644
index 0000000000..2b256fd48f
--- /dev/null
+++ b/linux-headers/uapi/version
@@ -0,0 +1 @@
+v0.0
diff --git a/meson.build b/meson.build
index 8b248d4505..aca47334ab 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('linux-headers')
+endif
+
 # build libs and drivers
 subdir('lib')
 subdir('drivers')
-- 
2.46.0


  reply	other threads:[~2024-09-11 19:32 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-11 19:32 [RFC v3 0/3] Import Kernel uAPI header files Maxime Coquelin
2024-09-11 19:32 ` Maxime Coquelin [this message]
2024-09-17 11:36   ` [RFC v3 1/3] uapi: introduce kernel uAPI headers import David Marchand
2024-09-17 14:32     ` Maxime Coquelin
2024-09-19  8:39   ` Thomas Monjalon
2024-09-11 19:32 ` [RFC v3 2/3] uapi: import VDUSE header Maxime Coquelin
2024-09-11 19:32 ` [RFC v3 3/3] vduse: use imported VDUSE uAPI header Maxime Coquelin
2024-09-12  8:30 ` [RFC v3 0/3] Import Kernel uAPI header files Ferruh Yigit
2024-09-12 12:08   ` Maxime Coquelin
2024-09-12 13:16     ` Ferruh Yigit
2024-09-12 13:47       ` Maxime Coquelin

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=20240911193224.1966122-2-maxime.coquelin@redhat.com \
    --to=maxime.coquelin@redhat.com \
    --cc=david.marchand@redhat.com \
    --cc=dev@dpdk.org \
    --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).