Re: [PATCH v3 2/9] kernel/api: enable kerneldoc-based API specifications

Nicolas Schier <[email protected]>
Newsgroups org.kernel.linux.tools,org.kernel.vger.linux-api,org.kernel.vger.linux-doc,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kbuild,org.kernel.vger.linux-kernel,org.kernel.vger.linux-kselftest,org.kernel.vger.workflows
Message-ID <afNrbm8URHlClZ-8@levanger>
On Fri, Apr 24, 2026 at 12:51:22PM -0400, Sasha Levin wrote:
> This patch adds support for extracting API specifications from
> kernel-doc comments and generating C macro invocations for the
> kernel API specification framework.
> 
> Changes include:
> - New kdoc_apispec.py module for generating API spec macros
> - Updates to kernel-doc.py to support -apispec output format
> - Build system integration in Makefile.build
> - Generator script for collecting all API specifications
> - Support for API-specific sections in kernel-doc comments
> 
> Signed-off-by: Sasha Levin <[email protected]>
> ---
>  Documentation/dev-tools/kernel-api-spec.rst |   11 +
>  scripts/Makefile.build                      |   31 +
>  scripts/Makefile.clean                      |    3 +
>  tools/docs/kernel-doc                       |    5 +
>  tools/lib/python/kdoc/kdoc_apispec.py       | 1249 +++++++++++++++++++
>  tools/lib/python/kdoc/kdoc_output.py        |    9 +-
>  tools/lib/python/kdoc/kdoc_parser.py        |   86 +-
>  7 files changed, 1389 insertions(+), 5 deletions(-)
>  create mode 100644 tools/lib/python/kdoc/kdoc_apispec.py
> 
> diff --git a/Documentation/dev-tools/kernel-api-spec.rst b/Documentation/dev-tools/kernel-api-spec.rst
> index 395c2294d5209..479bc78797ba8 100644
> --- a/Documentation/dev-tools/kernel-api-spec.rst
> +++ b/Documentation/dev-tools/kernel-api-spec.rst
> @@ -239,6 +239,17 @@ execution context, and return values. Parameter violations are reported via
>  ``pr_warn_ratelimited`` and return value violations via ``WARN_ONCE`` to avoid
>  flooding the kernel log.
>  
> +.. warning::
> +
> +   Userspace errno is affected when this option is on. For syscalls that
> +   violate their parameter specification, KAPI short-circuits the call and
> +   returns ``-EINVAL`` from the validator **before** the real handler runs.
> +   That errno can differ from what the real handler would have produced for
> +   the same condition (for example, ``-ENOMEM`` from an allocation path or
> +   ``-EFAULT`` from a deeper copy-in). ``CONFIG_KAPI_RUNTIME_CHECKS`` is a
> +   debug-only option; do not enable it on production kernels or in
> +   userspace-visible test environments where error-code fidelity matters.
> +
>  Custom Validators
>  -----------------
>  
> diff --git a/scripts/Makefile.build b/scripts/Makefile.build
> index 3652b85be5459..ef203e490c797 100644
> --- a/scripts/Makefile.build
> +++ b/scripts/Makefile.build
> @@ -174,6 +174,37 @@ ifneq ($(KBUILD_EXTRA_WARN),)
>  endif
>  endif
>  
> +# Generate API spec headers from kernel-doc comments
> +ifeq ($(CONFIG_KAPI_SPEC),y)
> +# Function to check if a file has API specifications
> +has-apispec = $(shell grep -qE '^\s*\*\s*context-flags:' $(src)/$(1) 2>/dev/null && echo $(1))
> +
> +# Get base names without directory prefix
> +c-objs-base := $(notdir $(real-obj-y) $(real-obj-m))
> +# Filter to only .o files with corresponding .c source files
> +c-files := $(foreach o,$(c-objs-base),$(if $(wildcard $(src)/$(o:.o=.c)),$(o:.o=.c)))

Looks to me as if the two lines above are redundant, since 'find'
(below) will find all files gathered in $(c-files).


> +# Also check for any additional .c files that contain API specs but are included
> +extra-c-files := $(shell find $(src) -maxdepth 1 -name "*.c" -exec grep -l '^\s*\*\s*\(long-desc\|context-flags\|state-trans\):' {} \; 2>/dev/null | xargs -r basename -a)
> +# Combine both lists and remove duplicates
> +all-c-files := $(sort $(c-files) $(extra-c-files))
> +# Only include files that actually have API specifications
> +apispec-files := $(foreach f,$(all-c-files),$(call has-apispec,$(f)))
> +# Generate apispec targets with proper directory prefix
> +apispec-y := $(addprefix $(obj)/,$(apispec-files:.c=.apispec.h))

To goal is to find any relevant C file in $(src)/ (but not deeper below)
that holds KAPI documentation, right?

I do not like the find call, as it picks up anything.  Might it make
sense to evaluate $(obj-) along with $(obj-y) and $(obj-m) to pick up
all C files that are references in kbuild?



# in top definition block -- before 'include $(kbuild-file)' et al.
obj- :=

# below the definitions of real-obj-{y,m}
real-obj-any := $(call real-search, $(obj-y) $(obj-m) $(obj-), .o, -objs -y -m -)

has-apispec = $(shell grep -lE '^\s*\*\s*context-flags:' $(1) 2>/dev/null)
apispec-y := $(patsubst $(src)/%.c, $(obj)/%.apispec.h, $(call has-apispec,
		    $(patsubst $(obj)/%.o, $(src)/%.c, $(real-obj-any))))

#...

# Source files that include their own apispec.h need to depend on it
$(apispec-y:.apispec.h=.o): $(obj)/%.o: $(obj)/%.apispec.h

(untested)

> +always-y += $(apispec-y)
> +targets += $(apispec-y)
> +
> +quiet_cmd_apispec = APISPEC $@
> +      cmd_apispec = PYTHONDONTWRITEBYTECODE=1 $(KERNELDOC) -apispec \
> +                    $(KDOCFLAGS) $< > $@ || rm -f $@
> +
> +$(obj)/%.apispec.h: $(src)/%.c $(KERNELDOC) FORCE
> +	$(call if_changed,apispec)
> +
> +# Source files that include their own apispec.h need to depend on it
> +$(foreach f,$(apispec-files),$(eval $(obj)/$(f:.c=.o): $(obj)/$(f:.c=.apispec.h)))
> +endif
> +
>  # Compile C sources (.c)
>  # ---------------------------------------------------------------------------
>  
> diff --git a/scripts/Makefile.clean b/scripts/Makefile.clean
> index 6ead00ec7313b..f78dbbe637f27 100644
> --- a/scripts/Makefile.clean
> +++ b/scripts/Makefile.clean
> @@ -35,6 +35,9 @@ __clean-files   := $(filter-out $(no-clean-files), $(__clean-files))
>  
>  __clean-files   := $(wildcard $(addprefix $(obj)/, $(__clean-files)))
>  
> +# Also clean generated apispec headers (computed dynamically in Makefile.build)
> +__clean-files   += $(wildcard $(obj)/*.apispec.h)

We have a list of wildcard clean patterns in top-level Makefile
(line 2114 ff.); please add '*.apispec.h' there instead.



When I apply the series on top of v7.1, compilation fails with

../fs/open.c:2148:10: fatal error: open.apispec.h: No such file or directory
../fs/read_write.c:2519:10: fatal error: read_write.apispec.h: No such file or directory

Kind regards,
Nicolas
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.