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: