Re: [RFC v3 2/4] kernel/api: enable kerneldoc-based API specifications
From: Sasha Levin <sashal@kernel.org>
Date: 2025-07-21 02:54:34
Also in:
linux-doc, lkml, tools
On Sun, Jul 20, 2025 at 05:55:05PM -0700, Randy Dunlap wrote:
Hi Sasha, I would like to ask a few questions to try to clarify/understand, please. On 7/11/25 4:42 AM, Sasha Levin wrote:quoted
Allow kernel developers to write API specifications directly in kerneldoc comments, which are automatically converted to machine-readable C macros during build. Signed-off-by: Sasha Levin <sashal@kernel.org> --- kernel/api/Makefile | 21 +- scripts/Makefile.build | 28 ++ scripts/generate_api_specs.sh | 59 +++ scripts/kernel-doc.py | 5 + scripts/lib/kdoc/kdoc_apispec.py | 623 +++++++++++++++++++++++++++++++ scripts/lib/kdoc/kdoc_output.py | 5 +- scripts/lib/kdoc/kdoc_parser.py | 54 ++- 7 files changed, 791 insertions(+), 4 deletions(-) create mode 100755 scripts/generate_api_specs.sh create mode 100644 scripts/lib/kdoc/kdoc_apispec.py[snip]quoted
diff --git a/scripts/Makefile.build b/scripts/Makefile.build index a6461ea411f7a..5c0e44d1b6dbc 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build@@ -172,6 +172,34 @@ ifneq ($(KBUILD_EXTRA_WARN),) $< 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*(api-type|long-desc|context-flags|param-type|error-code|capability|signal|lock|side-effect|state-trans):' $(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)))1. One must build a kernel (with some desired .config file) to use/test this, correct?
Mostly yes, but another option is to use the kapi tool (which I haven't updated and sent out as part of v3, but you can see it in v2: https://lore.kernel.org/tools/20250624180742.5795-23-sashal@kernel.org/T/#u (local)). With the kapi tool, you can also run it on a source tree to extract the same information that you'd have in a built vmlinux.
2. It looks like it only checks .c files, omitting header files. (?) Some APIs are only present in header files (e.g., all of <linux/list.h> is either macros or inline functions).
I was trying to focus on the userspace side of things, so I didn't think we'll have anything in header files, but I also don't have an objection to extending it to scan headers too.
quoted
+# 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*\(api-type\|long-desc\|context-flags\|param-type\|error-code\|capability\|signal\|lock\|side-effect\|state-trans\):' {} \; 2>/dev/null | xargs -r basename -a)3a. included files: does this catch the (rare) use of a C file doing #include <path to some other C file> ?
Yes! Jon suggested I apply this to a kernel/sched/ syscall to see how it handles complex syscalls, but it also added another complexity because sched does exactly what you described (kernel/sched/build_policy.c includes a bunch of other .c files including syscalls.c). See the 4th patch in the series.
3b. Quite a few makefiles generate final .o files with a different name from the source files. It looks like that is handled above by looking for the first (or intermediate) .o file for each .c file, so the final .o file with a different name is ignored (or at least doesn't come into play here). Yes?
Yes, exactly. The code looks for .o files that have directly corresponding .c files with the same base name. When makefiles generate final .o files with different names (like when multiple .c files are combined into a single .o, or when the output name is changed), those renamed .o files won't have a matching .c file and will be filtered out by the $(if $(wildcard $(src)/$(o:.o=.c)),$(o:.o=.c)) check.
Thanks.
Thanks for looking into it! -- Thanks, Sasha