Re: [PATCH] kernel-doc: add support for handling global variables

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Mauro,

I have a few patch nits below, then some testing info.


On 9/7/25 9:22 AM, Mauro Carvalho Chehab wrote:
> Specially on kAPI, sometimes it is desirable to be able to
> describe global variables that are part of kAPI.
> 
> Documenting vars with Sphinx is simple, as we don't need
> to parse a data struct. All we need is the variable
> declaration and use natice C domain ::c:var: to format it
> for us.
> 
> Add support for it.
> 
> Link: https://lore.kernel.org/linux-doc/491c3022-cef8-4860-a945-c9c4a3b63c09@xxxxxxxxxxxxx/T/#m947c25d95cb1d96a394410ab1131dc8e9e5013f1
> Suggested-by: Randy Dunlap <rdunlap@xxxxxxxxxxxxx>
> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@xxxxxxxxxx>
> ---
>  scripts/lib/kdoc/kdoc_output.py | 31 +++++++++++++++++++++++++++++++
>  scripts/lib/kdoc/kdoc_parser.py | 25 ++++++++++++++++++++++++-
>  2 files changed, 55 insertions(+), 1 deletion(-)
> 
> diff --git a/scripts/lib/kdoc/kdoc_output.py b/scripts/lib/kdoc/kdoc_output.py
> index 1eca9a918558..405a5c407522 100644
> --- a/scripts/lib/kdoc/kdoc_output.py
> +++ b/scripts/lib/kdoc/kdoc_output.py
> @@ -199,6 +199,10 @@ class OutputFormat:
>              self.out_enum(fname, name, args)
>              return self.data
>  
> +        if dtype == "global":
> +            self.out_global(fname, name, args)
> +            return self.data
> +
>          if dtype == "typedef":
>              self.out_typedef(fname, name, args)
>              return self.data
> @@ -227,6 +231,9 @@ class OutputFormat:
>      def out_enum(self, fname, name, args):
>          """Outputs an enum"""
>  
> +    def out_global(self, fname, name, args):
> +        """Outputs a global variable"""
> +
>      def out_typedef(self, fname, name, args):
>          """Outputs a typedef"""
>  
> @@ -472,6 +479,18 @@ class RestFormat(OutputFormat):
>          self.lineprefix = oldprefix
>          self.out_section(args)
>  
> +    def out_global(self, fname, name, args):
> +        oldprefix = self.lineprefix
> +        ln = args.declaration_start_line
> +        prototype = args.other_stuff["var_type"]
> +
> +        self.data += f"
> 
> .. c:var:: {prototype}
> 
> "

Are the 5 lines above supposed to be on one line?  Did git send-email split that up for you?
There are a few others like this below.
patch(1) complains when I try to apply the patch from this email.

> +
> +        self.print_lineno(ln)
> +        self.lineprefix = "  "
> +        self.output_highlight(args.get('purpose', ''))
> +        self.data += "
> "
> +
>      def out_typedef(self, fname, name, args):
>  
>          oldprefix = self.lineprefix
> @@ -772,6 +791,18 @@ class ManFormat(OutputFormat):
>              self.data += f'.SH "{section}"' + "
> "
>              self.output_highlight(text)
>  
> +    def out_global(self, fname, name, args):
> +        out_name = self.arg_name(args, name)
> +        prototype = args.other_stuff["var_type"]
> +
> +        self.data += f'.TH "{self.modulename}" 9 "{out_name}" "{self.man_date}" "API Manual" LINUX' + "
> "
> +
> +        self.data += ".SH NAME
> "
> +        self.data += f"{prototype} \- {args['purpose']}

Python complains about the "\-" above. Other places nearby use "\\-"
so I changed it to that instead. Hope that's OK.

> "
> +
> +        self.data += ".SH SYNOPSIS
> "
> +        self.data += f"enum {name}" + " {
> "
> +
>      def out_typedef(self, fname, name, args):
>          module = self.modulename
>          purpose = args.get('purpose')
> diff --git a/scripts/lib/kdoc/kdoc_parser.py b/scripts/lib/kdoc/kdoc_parser.py
> index 574972e1f741..e2a3f4574894 100644
> --- a/scripts/lib/kdoc/kdoc_parser.py
> +++ b/scripts/lib/kdoc/kdoc_parser.py
> @@ -64,7 +64,7 @@ type_param = KernRe(r"@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)", cache=False)
>  # Tests for the beginning of a kerneldoc block in its various forms.
>  #
>  doc_block = doc_com + KernRe(r'DOC:\s*(.*)?', cache=False)
> -doc_begin_data = KernRe(r"^\s*\*?\s*(struct|union|enum|typedef)\s*(\w*)", cache = False)
> +doc_begin_data = KernRe(r"^\s*\*?\s*(struct|union|enum|typedef|global)\s*(\w*)", cache = False)
>  doc_begin_func = KernRe(str(doc_com) +			# initial " * '
>                          r"(?:\w+\s*\*\s*)?" + 		# type (not captured)
>                          r'(?:define\s+)?' + 		# possible "define" (not captured)
> @@ -886,6 +886,27 @@ class KernelDoc:
>          self.output_declaration('enum', declaration_name,
>                                  purpose=self.entry.declaration_purpose)
>  
> +    def dump_global(self, ln, proto):
> +        """
> +        Stores global variables that are part of kAPI.
> +        """
> +        VAR_ATTRIBS = [
> +            "extern",
> +        ]
> +        OPTIONAL_VAR_ATTR = "^(?:" + "|".join(VAR_ATTRIBS) + ")?"
> +
> +        r= KernRe(OPTIONAL_VAR_ATTR + r"(\w.*)\s+([\w_]+)[\d\]\[]*\s*;(?:#.*)?$")
> +        if not r.match(proto):
> +           self.emit_msg(ln,f"{proto}: can't parse variable")
> +           return
> +
> +        declaration_name = r.group(2)
> +        var_type = r.group(0)
> +
> +        self.output_declaration("global", declaration_name,
> +                                var_type=var_type,
> +                                purpose=self.entry.declaration_purpose)
> +
>      def dump_declaration(self, ln, prototype):
>          """
>          Stores a data declaration inside self.entries array.
> @@ -897,6 +918,8 @@ class KernelDoc:
>              self.dump_typedef(ln, prototype)
>          elif self.entry.decl_type in ["union", "struct"]:
>              self.dump_struct(ln, prototype)
> +        elif self.entry.decl_type == "global":
> +            self.dump_global(ln, prototype)
>          else:
>              # This would be a bug
>              self.emit_message(ln, f'Unknown declaration type: {self.entry.decl_type}')
So, I grabbed some global data from 6-8 places in the kernel and put them intoinit/kdoc-globals-test.c. Then I modified Documentation/core-api/kernel-api.rst
like this at the end of that file:

+
+Kernel Globals
+==========================
+
+.. kernel-doc:: init/kdoc-globals-test.c
+   :identifiers:

The html output says
"Kernel Globals"
but nothing else.

My test files are attached. I dumbed down (simplified) a few
of the globals from fancy types to just unsigned long, but that
didn't help the output results any.

What's happening?
Thanks.

-- 
~Randy
---
 Documentation/core-api/kernel-api.rst |    6 +
 init/kdoc-globals-test.c              |   96 ++++++++++++++++++++++++
 2 files changed, 102 insertions(+)

--- /dev/null
+++ linux-next-20250908/init/kdoc-globals-test.c
@@ -0,0 +1,96 @@
+// kdoc-globals-test.c:
+// test kernel-doc "global" keyword.
+
+// from init/do_mounts.c:
+/**
+ * global ROOT_DEV - system root device
+ *
+ * @ROOT_DEV is either the successful root device or the root device
+ * that failed boot in the boot failure message.
+ */
+unsigned long ROOT_DEV;
+//dev_t ROOT_DEV;
+
+// from init/main.c:
+/**
+ * global system_state - system state used during boot or suspend/hibernate/resume
+ *
+ * @system_state can be used during boot to determine if it is safe to
+ * make certain calls to other parts of the kernel. It can also be used
+ * during suspend/hibernate or resume to determine the order of actions
+ * that need to be executed. The numerical values of system_state are
+ * sometimes used in numerical ordering tests, so the relative values
+ * must not be altered.
+ */
+enum system_states system_state __read_mostly;
+
+/**
+ * global saved_command_line - kernel's command line, saved from use at
+ * any later time in the kernel.
+ */
+char *saved_command_line __ro_after_init;
+
+/**
+ * global loop_per_jiffy - calculated loop count needed to consume one jiffy
+ * of time
+ */
+unsigned long loops_per_jiffy = (1<<12);
+
+// from init/calibrate.c:
+/**
+ * global preset_lpj - lpj (loops per jiffy) value set from kernel
+ * command line using "lpj=VALUE"
+ *
+ * See Documentation/admin-guide/kernel-parameters.txt ("lpj=") for details.
+ */
+unsigned long preset_lpj;
+
+// from init/version.c:
+/**
+ * global linux_proc_banner - text used from /proc/version file
+ *
+ * * first %s is sysname (e.g., "Linux")
+ * * second %s is release
+ * * third %s is version
+ */
+char linux_proc_banner[];
+#if 0
+const char linux_proc_banner[] =
+	"%s version %s"
+	" (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ")"
+	" (" LINUX_COMPILER ") %s\n";
+#endif
+
+// from init/version-timestamp.c:
+/**
+ * global linux_banner - Linux boot banner, usually printed at boot time
+ */
+const char linux_banner[];
+#if 0
+const char linux_banner[] =
+	"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
+	LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n";
+#endif
+
+// from block/genhd.c:
+/**
+ * global diskseq - unique sequence number for block device instances
+ *
+ * Allows userspace to associate uevents to the lifetime of a device
+ */
+static atomic64_t diskseq;
+
+// from net/core/rtnetlink.c:
+/**
+ * global rtnl_mutex - historical global lock for networking control operations.
+ *
+ * @rtnl_mutex is used to serialize rtnetlink requests
+ * and protect all kernel internal data structures related to networking.
+ *
+ * See Documentation/networking/netdevices.rst for details.
+ * Often known as the rtnl_lock, although rtnl_lock is a kernel function.
+ */
+unsigned long rtnl_mutex;
+//static DEFINE_MUTEX(rtnl_mutex);
+
+// end test.
--- linux-next-20250908.orig/Documentation/core-api/kernel-api.rst
+++ linux-next-20250908/Documentation/core-api/kernel-api.rst
@@ -428,3 +428,9 @@ Read-Copy Update (RCU)
 .. kernel-doc:: include/linux/rcuref.h
 
 .. kernel-doc:: include/linux/rcutree.h
+
+Kernel Globals
+==========================
+
+.. kernel-doc:: init/kdoc-globals-test.c
+   :identifiers:

[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite Forum]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux