linux-doc.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 0/2] kernel-doc: add support for documenting vars
@ 2025-11-16 11:23 Mauro Carvalho Chehab
  2025-11-16 11:23 ` [PATCH v3 1/2] kernel-doc: add support for handling global variables Mauro Carvalho Chehab
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Mauro Carvalho Chehab @ 2025-11-16 11:23 UTC (permalink / raw)
  To: Linux Doc Mailing List, Jonathan Corbet
  Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab, linux-kernel,
	Randy Dunlap

Hi Jon,

As suggested and discussed with Randy, this small series add support
for documenting variables using kernel-doc.

The first patch adds support for it.
The second one documents two variables from media. 

While two documented variables are part of kAPI, I'm documenting them
mostly aiming to test the new feature, as those are meant to be used for
debugging messages, so we could live without having them documented.

I'm pretty sure we'll likely need to improve the parser regexes to
catch everything. For instance, I had to add a logic on v3 due to the
choice I did for the vars, which are pointers.

Mauro Carvalho Chehab (2):
  kernel-doc: add support for handling global variables
  docs: media: v4l2-ioctl.h: document two global variables

 include/media/v4l2-ioctl.h      | 15 +++++++++
 scripts/lib/kdoc/kdoc_output.py | 45 ++++++++++++++++++++++++++
 scripts/lib/kdoc/kdoc_parser.py | 56 ++++++++++++++++++++++++++++++++-
 3 files changed, 115 insertions(+), 1 deletion(-)

-- 
2.51.1



^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v3 1/2] kernel-doc: add support for handling global variables
  2025-11-16 11:23 [PATCH v3 0/2] kernel-doc: add support for documenting vars Mauro Carvalho Chehab
@ 2025-11-16 11:23 ` Mauro Carvalho Chehab
  2025-11-18  6:59   ` Randy Dunlap
  2025-11-16 11:23 ` [PATCH v3 2/2] docs: media: v4l2-ioctl.h: document two " Mauro Carvalho Chehab
  2025-11-21 17:50 ` [PATCH v3 0/2] kernel-doc: add support for documenting vars Jonathan Corbet
  2 siblings, 1 reply; 10+ messages in thread
From: Mauro Carvalho Chehab @ 2025-11-16 11:23 UTC (permalink / raw)
  To: Linux Doc Mailing List, Jonathan Corbet
  Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab, Randy Dunlap,
	linux-kernel

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@infradead.org/T/#m947c25d95cb1d96a394410ab1131dc8e9e5013f1
Suggested-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 scripts/lib/kdoc/kdoc_output.py | 45 ++++++++++++++++++++++++++
 scripts/lib/kdoc/kdoc_parser.py | 56 ++++++++++++++++++++++++++++++++-
 2 files changed, 100 insertions(+), 1 deletion(-)

diff --git a/scripts/lib/kdoc/kdoc_output.py b/scripts/lib/kdoc/kdoc_output.py
index 58f115059e93..1d97a3f2c738 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 == "var":
+            self.out_var(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_var(self, fname, name, args):
+        """Outputs a variable"""
+
     def out_typedef(self, fname, name, args):
         """Outputs a typedef"""
 
@@ -472,6 +479,24 @@ class RestFormat(OutputFormat):
         self.lineprefix = oldprefix
         self.out_section(args)
 
+    def out_var(self, fname, name, args):
+        oldprefix = self.lineprefix
+        ln = args.declaration_start_line
+        prototype = args.other_stuff["var_type"]
+
+        self.data += f"\n\n.. c:var:: {prototype}\n\n"
+
+        self.print_lineno(ln)
+        self.lineprefix = "  "
+        self.output_highlight(args.get('purpose', ''))
+        self.data += "\n"
+
+        if args.other_stuff["default_val"]:
+            self.data += f'{self.lineprefix}**Initialization**\n\n'
+            self.output_highlight(f'default: ``{args.other_stuff["default_val"]}``')
+
+        self.out_section(args)
+
     def out_typedef(self, fname, name, args):
 
         oldprefix = self.lineprefix
@@ -773,6 +798,26 @@ class ManFormat(OutputFormat):
             self.data += f'.SH "{section}"' + "\n"
             self.output_highlight(text)
 
+    def out_var(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' + "\n"
+
+        self.data += ".SH NAME\n"
+        self.data += f"{prototype} \\- {args['purpose']}\n"
+
+        self.data += ".SH SYNOPSIS\n"
+        self.data += f"{prototype};\n"
+
+        if args.other_stuff["default_val"]:
+            self.data += f'.SH "Initialization"' + "\n"
+            self.output_highlight(f'default: {args.other_stuff["default_val"]}')
+
+        for section, text in args.sections.items():
+            self.data += f'.SH "{section}"' + "\n"
+            self.output_highlight(text)
+
     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 f7dbb0868367..26f529e58eee 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)\b\s*(\w*)", cache = False)
+doc_begin_data = KernRe(r"^\s*\*?\s*(struct|union|enum|typedef|var)\b\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)
@@ -924,6 +924,58 @@ class KernelDoc:
         self.output_declaration('enum', declaration_name,
                                 purpose=self.entry.declaration_purpose)
 
+    def dump_var(self, ln, proto):
+        """
+        Store variables that are part of kAPI.
+        """
+        VAR_ATTRIBS = [
+            "extern",
+        ]
+        OPTIONAL_VAR_ATTR = "^(?:" + "|".join(VAR_ATTRIBS) + ")?"
+
+        sub_prefixes = [
+            (KernRe(r"__read_mostly"), ""),
+            (KernRe(r"__ro_after_init"), ""),
+            (KernRe(r"(?://.*)$"), ""),
+            (KernRe(r"(?:/\*.*\*/)"), ""),
+            (KernRe(r";$"), ""),
+            (KernRe(r"=.*"), ""),
+        ]
+
+        #
+        # Store the full prototype before modifying it
+        #
+        full_proto = proto
+
+        #
+        # Drop comments and macros to have a pure C prototype
+        #
+        for search, sub in sub_prefixes:
+            proto = search.sub(sub, proto)
+
+        proto = proto.rstrip()
+
+        #
+        # Variable name is at the end of the declaration
+        #
+
+        r= KernRe(OPTIONAL_VAR_ATTR + r"\w.*\s+(?:\*+)?([\w_]+)\s*[\d\]\[]*\s*(=.*)?")
+        if not r.match(proto):
+           self.emit_msg(ln,f"{proto}: can't parse variable")
+           return
+
+        var_type = r.group(0)
+        declaration_name = r.group(1)
+        default_val = r.group(2)
+        if default_val:
+            default_val = default_val.lstrip("=").strip()
+
+        self.output_declaration("var", declaration_name,
+                                full_proto=full_proto,
+                                var_type=var_type,
+                                default_val=default_val,
+                                purpose=self.entry.declaration_purpose)
+
     def dump_declaration(self, ln, prototype):
         """
         Stores a data declaration inside self.entries array.
@@ -935,6 +987,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 == "var":
+            self.dump_var(ln, prototype)
         else:
             # This would be a bug
             self.emit_message(ln, f'Unknown declaration type: {self.entry.decl_type}')
-- 
2.51.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v3 2/2] docs: media: v4l2-ioctl.h: document two global variables
  2025-11-16 11:23 [PATCH v3 0/2] kernel-doc: add support for documenting vars Mauro Carvalho Chehab
  2025-11-16 11:23 ` [PATCH v3 1/2] kernel-doc: add support for handling global variables Mauro Carvalho Chehab
@ 2025-11-16 11:23 ` Mauro Carvalho Chehab
  2025-11-18  6:52   ` Randy Dunlap
  2025-11-21 17:50 ` [PATCH v3 0/2] kernel-doc: add support for documenting vars Jonathan Corbet
  2 siblings, 1 reply; 10+ messages in thread
From: Mauro Carvalho Chehab @ 2025-11-16 11:23 UTC (permalink / raw)
  To: Linux Doc Mailing List, Jonathan Corbet
  Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab, Randy Dunlap,
	linux-kernel, linux-media

The media kAPI has two global variables at v4l2-ioctl.h. Document
them.

Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
---
 include/media/v4l2-ioctl.h | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
index 6f7a58350441..ed63841a100c 100644
--- a/include/media/v4l2-ioctl.h
+++ b/include/media/v4l2-ioctl.h
@@ -663,7 +663,22 @@ void v4l_printk_ioctl(const char *prefix, unsigned int cmd);
 struct video_device;
 
 /* names for fancy debug output */
+
+/**
+ * var v4l2_field_names - Helper array mapping V4L2_FIELD_* to strings.
+ *
+ * Specially when printing debug messages, it is interesting to output
+ * the field order at the V4L2 buffers. This array associates all possible
+ * values of field pix format from V4L2 API into a string.
+ */
 extern const char *v4l2_field_names[];
+
+/**
+ * var v4l2_type_names - Helper array mapping V4L2_BUF_TYPE_* to strings.
+ *
+ * When printing debug messages, it is interesting to output the V4L2 buffer
+ * type number with a name that represents its content.
+ */
 extern const char *v4l2_type_names[];
 
 #ifdef CONFIG_COMPAT
-- 
2.51.1


^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v3 2/2] docs: media: v4l2-ioctl.h: document two global variables
  2025-11-16 11:23 ` [PATCH v3 2/2] docs: media: v4l2-ioctl.h: document two " Mauro Carvalho Chehab
@ 2025-11-18  6:52   ` Randy Dunlap
  0 siblings, 0 replies; 10+ messages in thread
From: Randy Dunlap @ 2025-11-18  6:52 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Linux Doc Mailing List, Jonathan Corbet
  Cc: Mauro Carvalho Chehab, linux-kernel, linux-media



On 11/16/25 3:23 AM, Mauro Carvalho Chehab wrote:
> The media kAPI has two global variables at v4l2-ioctl.h. Document
> them.
> 
> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>

LGTM.

Tested-by: Randy Dunlap <rdunlap@infradead.org>

> ---
>  include/media/v4l2-ioctl.h | 15 +++++++++++++++
>  1 file changed, 15 insertions(+)
> 
> diff --git a/include/media/v4l2-ioctl.h b/include/media/v4l2-ioctl.h
> index 6f7a58350441..ed63841a100c 100644
> --- a/include/media/v4l2-ioctl.h
> +++ b/include/media/v4l2-ioctl.h
> @@ -663,7 +663,22 @@ void v4l_printk_ioctl(const char *prefix, unsigned int cmd);
>  struct video_device;
>  
>  /* names for fancy debug output */
> +
> +/**
> + * var v4l2_field_names - Helper array mapping V4L2_FIELD_* to strings.
> + *
> + * Specially when printing debug messages, it is interesting to output
> + * the field order at the V4L2 buffers. This array associates all possible
> + * values of field pix format from V4L2 API into a string.
> + */
>  extern const char *v4l2_field_names[];
> +
> +/**
> + * var v4l2_type_names - Helper array mapping V4L2_BUF_TYPE_* to strings.
> + *
> + * When printing debug messages, it is interesting to output the V4L2 buffer
> + * type number with a name that represents its content.
> + */
>  extern const char *v4l2_type_names[];
>  
>  #ifdef CONFIG_COMPAT

-- 
~Randy

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v3 1/2] kernel-doc: add support for handling global variables
  2025-11-16 11:23 ` [PATCH v3 1/2] kernel-doc: add support for handling global variables Mauro Carvalho Chehab
@ 2025-11-18  6:59   ` Randy Dunlap
  2025-11-18  9:02     ` Mauro Carvalho Chehab
  0 siblings, 1 reply; 10+ messages in thread
From: Randy Dunlap @ 2025-11-18  6:59 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Linux Doc Mailing List, Jonathan Corbet
  Cc: Mauro Carvalho Chehab, linux-kernel

Hi,

On 11/16/25 3:23 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@infradead.org/T/#m947c25d95cb1d96a394410ab1131dc8e9e5013f1
> Suggested-by: Randy Dunlap <rdunlap@infradead.org>
> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
> ---
>  scripts/lib/kdoc/kdoc_output.py | 45 ++++++++++++++++++++++++++
>  scripts/lib/kdoc/kdoc_parser.py | 56 ++++++++++++++++++++++++++++++++-
>  2 files changed, 100 insertions(+), 1 deletion(-)

Thanks for the update. It's looking much better.
I have a few comments/questions, all about typedefs.


type vs typedef in output (html)

typedefs are usually output as "type":
Example 1:

	type func_desc_t

although thp_order_fn_t is output as:
Example 2:

	thp_order_fn_t
	Typedef: Get the suggested THP orders from a BPF program for allocation
+ more syntax and description.

Is the difference in the 2 examples above just that the first one has
no additional description or parameters?

3. typedef struct msi_alloc_info isn't output as a typedef at all,
but instead as a struct. But the kernel-doc for this typedef is
messed up (as taken from include/asm-generic/msi.h):

/**
 * struct msi_alloc_info - Default structure for MSI interrupt allocation.
 * @desc:	Pointer to msi descriptor
 * @hwirq:	Associated hw interrupt number in the domain
 * @scratchpad:	Storage for implementation specific scratch data
 *
 * Architectures can provide their own implementation by not including
 * asm-generic/msi.h into their arch specific header file.
 */
typedef struct msi_alloc_info {
	struct msi_desc			*desc;
	irq_hw_number_t			hwirq;
	unsigned long			flags;
	union {
		unsigned long		ul;
		void			*ptr;
	} scratchpad[NUM_MSI_ALLOC_SCRATCHPAD_REGS];
} msi_alloc_info_t;

a. It's a typedef, not a struct -- but we may want to print the struct (?).
b. The first line of the comment should be:
 * typedef msi_alloc_info_t - Default structure for MSI interrupt allocation.

Hopefully a warning can be printed for this.





-- 
~Randy


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v3 1/2] kernel-doc: add support for handling global variables
  2025-11-18  6:59   ` Randy Dunlap
@ 2025-11-18  9:02     ` Mauro Carvalho Chehab
  2025-11-18 23:50       ` Randy Dunlap
  2025-11-19  5:18       ` Randy Dunlap
  0 siblings, 2 replies; 10+ messages in thread
From: Mauro Carvalho Chehab @ 2025-11-18  9:02 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: Linux Doc Mailing List, Jonathan Corbet, Mauro Carvalho Chehab,
	linux-kernel

Em Mon, 17 Nov 2025 22:59:24 -0800
Randy Dunlap <rdunlap@infradead.org> escreveu:

> Hi,
> 
> On 11/16/25 3:23 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@infradead.org/T/#m947c25d95cb1d96a394410ab1131dc8e9e5013f1
> > Suggested-by: Randy Dunlap <rdunlap@infradead.org>
> > Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
> > ---
> >  scripts/lib/kdoc/kdoc_output.py | 45 ++++++++++++++++++++++++++
> >  scripts/lib/kdoc/kdoc_parser.py | 56 ++++++++++++++++++++++++++++++++-
> >  2 files changed, 100 insertions(+), 1 deletion(-)  
> 
> Thanks for the update. It's looking much better.

Great!

> I have a few comments/questions, all about typedefs.

The new version was made to be bug-compatible with the Perl version,
so it just mimics whatever it was there. Both Jon and I verified
to be sure that the output was identical (except for whitespaces).

If you look at dump_typedef(), typedefs can be mapped on different ways,
depending on its actual meaning:

    def dump_typedef(self, ln, proto):
...

	# Parse function typedef prototypes
...
            self.output_declaration('function', declaration_name,
                                    typedef=True,
                                    functiontype=return_type,
                                    purpose=self.entry.declaration_purpose)
...
        #
        # Not a function, try to parse a simple typedef.
        #
...
            self.output_declaration('typedef', declaration_name,
                                    purpose=self.entry.declaration_purpose)

Also, the actual output is modified by the highlight logic at kdoc_output:

	# match expressions used to find embedded type information
	type_constant = KernRe(r"\b``([^\`]+)``\b", cache=False)
	type_constant2 = KernRe(r"\%([-_*\w]+)", cache=False)
	type_func = KernRe(r"(\w+)\(\)", cache=False)
	type_param_ref = KernRe(r"([\!~\*]?)\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)", cache=False)

	# Special RST handling for func ptr params
	type_fp_param = KernRe(r"\@(\w+)\(\)", cache=False)

	# Special RST handling for structs with func ptr params
	type_fp_param2 = KernRe(r"\@(\w+->\S+)\(\)", cache=False)

	type_env = KernRe(r"(\$\w+)", cache=False)
	type_enum = KernRe(r"\&(enum\s*([_\w]+))", cache=False)
	type_struct = KernRe(r"\&(struct\s*([_\w]+))", cache=False)
	type_typedef = KernRe(r"\&(typedef\s*([_\w]+))", cache=False)
	type_union = KernRe(r"\&(union\s*([_\w]+))", cache=False)
	type_member = KernRe(r"\&([_\w]+)(\.|->)([_\w]+)", cache=False)
	type_fallback = KernRe(r"\&([_\w]+)", cache=False)
	type_member_func = type_member + KernRe(r"\(\)", cache=False)

	highlights = [
	    (type_constant, r"``\1``"),
	    (type_constant2, r"``\1``"),

	    # Note: need to escape () to avoid func matching later
	    (type_member_func, r":c:type:`\1\2\3\\(\\) <\1>`"),
	    (type_member, r":c:type:`\1\2\3 <\1>`"),
	    (type_fp_param, r"**\1\\(\\)**"),
	    (type_fp_param2, r"**\1\\(\\)**"),
	    (type_func, r"\1()"),
	    (type_enum, r":c:type:`\1 <\2>`"),
	    (type_struct, r":c:type:`\1 <\2>`"),
	    (type_typedef, r":c:type:`\1 <\2>`"),
	    (type_union, r":c:type:`\1 <\2>`"),

	    # in rst this can refer to any type
	    (type_fallback, r":c:type:`\1`"),
	    (type_param_ref, r"**\1\2**")
	]

On other words, "normal" typedefs use:

	type_typedef = KernRe(r"\&(typedef\s*([_\w]+))", cache=False)
	(type_typedef, r":c:type:`\1 <\2>`"),


but function typedefs have a different threatment (see out_function) at
the RestFormat class.

> 
> 
> type vs typedef in output (html)
> 
> typedefs are usually output as "type":
> Example 1:
> 
> 	type func_desc_t
> 
> although thp_order_fn_t is output as:
> Example 2:
> 
> 	thp_order_fn_t
> 	Typedef: Get the suggested THP orders from a BPF program for allocation
> + more syntax and description.

I was unable to find kernel-doc markups for the above at linux-next
or at docs-next.

Hard to tell without seeing the exact kernel-doc markups you're
referring to, but see my comments above.

> 
> Is the difference in the 2 examples above just that the first one has
> no additional description or parameters?
> 
> 3. typedef struct msi_alloc_info isn't output as a typedef at all,
> but instead as a struct. But the kernel-doc for this typedef is
> messed up (as taken from include/asm-generic/msi.h):
> 
> /**
>  * struct msi_alloc_info - Default structure for MSI interrupt allocation.
>  * @desc:	Pointer to msi descriptor
>  * @hwirq:	Associated hw interrupt number in the domain
>  * @scratchpad:	Storage for implementation specific scratch data
>  *
>  * Architectures can provide their own implementation by not including
>  * asm-generic/msi.h into their arch specific header file.
>  */
> typedef struct msi_alloc_info {
> 	struct msi_desc			*desc;
> 	irq_hw_number_t			hwirq;
> 	unsigned long			flags;
> 	union {
> 		unsigned long		ul;
> 		void			*ptr;
> 	} scratchpad[NUM_MSI_ALLOC_SCRATCHPAD_REGS];
> } msi_alloc_info_t;
> 
> a. It's a typedef, not a struct -- but we may want to print the struct (?).

It is both:

	struct msi_alloc_info
	typedef msi_alloc_info_t

The kernel-doc declaration is for the struct, not for the typedef.

Ok, one could have two kernel-doc markups if this would be declared
in separate:
	 /**
	  * struct msi_alloc_info - Default structure for MSI interrupt allocation.
...
	  */
	struct msi_alloc_info {
	 	struct msi_desc			*desc;
	 	irq_hw_number_t			hwirq;
	 	unsigned long			flags;
	 	union {
	 		unsigned long		ul;
	 		void			*ptr;
	 	} scratchpad[NUM_MSI_ALLOC_SCRATCHPAD_REGS];
	};

	 /**
	  * typedef msi_alloc_info_t - Default typedef for MSI interrupt allocation.
...
	  */
	typedef struct msi_alloc_info msi_alloc_info_t;

> b. The first line of the comment should be:
>  * typedef msi_alloc_info_t - Default structure for MSI interrupt allocation.
> 
> Hopefully a warning can be printed for this.

It won't be hard to add a warning, but the point is that, in this
specific case, the intent seems to document only the struct to
ensure that newer usages won't use typedef anymore.

Also, right now, we don't produce any warning if one does:

	 /**
	  * struct msi_alloc_info - Default structure for MSI interrupt allocation.
...
	  */
	struct msi_alloc_info {
	 	struct msi_desc			*desc;
	 	irq_hw_number_t			hwirq;
	 	unsigned long			flags;
	 	union {
	 		unsigned long		ul;
	 		void			*ptr;
	 	} scratchpad[NUM_MSI_ALLOC_SCRATCHPAD_REGS];
	};

	typedef struct msi_alloc_info msi_alloc_info_t;

So, what's the point of having a warning?

Thanks,
Mauro

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v3 1/2] kernel-doc: add support for handling global variables
  2025-11-18  9:02     ` Mauro Carvalho Chehab
@ 2025-11-18 23:50       ` Randy Dunlap
  2025-11-19  5:18       ` Randy Dunlap
  1 sibling, 0 replies; 10+ messages in thread
From: Randy Dunlap @ 2025-11-18 23:50 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Linux Doc Mailing List, Jonathan Corbet, Mauro Carvalho Chehab,
	linux-kernel



On 11/18/25 1:02 AM, Mauro Carvalho Chehab wrote:
> Em Mon, 17 Nov 2025 22:59:24 -0800
> Randy Dunlap <rdunlap@infradead.org> escreveu:
> 
>> Hi,
>>
>> On 11/16/25 3:23 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@infradead.org/T/#m947c25d95cb1d96a394410ab1131dc8e9e5013f1
>>> Suggested-by: Randy Dunlap <rdunlap@infradead.org>
>>> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
>>> ---
>>>  scripts/lib/kdoc/kdoc_output.py | 45 ++++++++++++++++++++++++++
>>>  scripts/lib/kdoc/kdoc_parser.py | 56 ++++++++++++++++++++++++++++++++-
>>>  2 files changed, 100 insertions(+), 1 deletion(-)  
>>
>> Thanks for the update. It's looking much better.
> 
> Great!
> 
>> I have a few comments/questions, all about typedefs.
> 
> The new version was made to be bug-compatible with the Perl version,
> so it just mimics whatever it was there. Both Jon and I verified
> to be sure that the output was identical (except for whitespaces).

I see.

> If you look at dump_typedef(), typedefs can be mapped on different ways,
> depending on its actual meaning:
> 
>     def dump_typedef(self, ln, proto):
> ...
> 
> 	# Parse function typedef prototypes
> ...
>             self.output_declaration('function', declaration_name,
>                                     typedef=True,
>                                     functiontype=return_type,
>                                     purpose=self.entry.declaration_purpose)
> ...
>         #
>         # Not a function, try to parse a simple typedef.
>         #
> ...
>             self.output_declaration('typedef', declaration_name,
>                                     purpose=self.entry.declaration_purpose)
> 
> Also, the actual output is modified by the highlight logic at kdoc_output:
> 
> 	# match expressions used to find embedded type information
> 	type_constant = KernRe(r"\b``([^\`]+)``\b", cache=False)
> 	type_constant2 = KernRe(r"\%([-_*\w]+)", cache=False)
> 	type_func = KernRe(r"(\w+)\(\)", cache=False)
> 	type_param_ref = KernRe(r"([\!~\*]?)\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)", cache=False)
> 
> 	# Special RST handling for func ptr params
> 	type_fp_param = KernRe(r"\@(\w+)\(\)", cache=False)
> 
> 	# Special RST handling for structs with func ptr params
> 	type_fp_param2 = KernRe(r"\@(\w+->\S+)\(\)", cache=False)
> 
> 	type_env = KernRe(r"(\$\w+)", cache=False)
> 	type_enum = KernRe(r"\&(enum\s*([_\w]+))", cache=False)
> 	type_struct = KernRe(r"\&(struct\s*([_\w]+))", cache=False)
> 	type_typedef = KernRe(r"\&(typedef\s*([_\w]+))", cache=False)
> 	type_union = KernRe(r"\&(union\s*([_\w]+))", cache=False)
> 	type_member = KernRe(r"\&([_\w]+)(\.|->)([_\w]+)", cache=False)
> 	type_fallback = KernRe(r"\&([_\w]+)", cache=False)
> 	type_member_func = type_member + KernRe(r"\(\)", cache=False)
> 
> 	highlights = [
> 	    (type_constant, r"``\1``"),
> 	    (type_constant2, r"``\1``"),
> 
> 	    # Note: need to escape () to avoid func matching later
> 	    (type_member_func, r":c:type:`\1\2\3\\(\\) <\1>`"),
> 	    (type_member, r":c:type:`\1\2\3 <\1>`"),
> 	    (type_fp_param, r"**\1\\(\\)**"),
> 	    (type_fp_param2, r"**\1\\(\\)**"),
> 	    (type_func, r"\1()"),
> 	    (type_enum, r":c:type:`\1 <\2>`"),
> 	    (type_struct, r":c:type:`\1 <\2>`"),
> 	    (type_typedef, r":c:type:`\1 <\2>`"),
> 	    (type_union, r":c:type:`\1 <\2>`"),
> 
> 	    # in rst this can refer to any type
> 	    (type_fallback, r":c:type:`\1`"),
> 	    (type_param_ref, r"**\1\2**")
> 	]
> 
> On other words, "normal" typedefs use:
> 
> 	type_typedef = KernRe(r"\&(typedef\s*([_\w]+))", cache=False)
> 	(type_typedef, r":c:type:`\1 <\2>`"),
> 
> 
> but function typedefs have a different threatment (see out_function) at
> the RestFormat class.
> 
>>
>>
>> type vs typedef in output (html)
>>
>> typedefs are usually output as "type":
>> Example 1:
>>
>> 	type func_desc_t
>>
>> although thp_order_fn_t is output as:
>> Example 2:
>>
>> 	thp_order_fn_t
>> 	Typedef: Get the suggested THP orders from a BPF program for allocation
>> + more syntax and description.
> 
> I was unable to find kernel-doc markups for the above at linux-next
> or at docs-next.

Yeah, I couldn't find it in the kernel source tree either. Maybe I took
some existing source code and modified it. IDK.

> Hard to tell without seeing the exact kernel-doc markups you're
> referring to, but see my comments above.
> 
>>
>> Is the difference in the 2 examples above just that the first one has
>> no additional description or parameters?
>>
>> 3. typedef struct msi_alloc_info isn't output as a typedef at all,
>> but instead as a struct. But the kernel-doc for this typedef is
>> messed up (as taken from include/asm-generic/msi.h):
>>
>> /**
>>  * struct msi_alloc_info - Default structure for MSI interrupt allocation.
>>  * @desc:	Pointer to msi descriptor
>>  * @hwirq:	Associated hw interrupt number in the domain
>>  * @scratchpad:	Storage for implementation specific scratch data
>>  *
>>  * Architectures can provide their own implementation by not including
>>  * asm-generic/msi.h into their arch specific header file.
>>  */
>> typedef struct msi_alloc_info {
>> 	struct msi_desc			*desc;
>> 	irq_hw_number_t			hwirq;
>> 	unsigned long			flags;
>> 	union {
>> 		unsigned long		ul;
>> 		void			*ptr;
>> 	} scratchpad[NUM_MSI_ALLOC_SCRATCHPAD_REGS];
>> } msi_alloc_info_t;
>>
>> a. It's a typedef, not a struct -- but we may want to print the struct (?).
> 
> It is both:
> 
> 	struct msi_alloc_info
> 	typedef msi_alloc_info_t

OK.

> The kernel-doc declaration is for the struct, not for the typedef.

Oh.

> Ok, one could have two kernel-doc markups if this would be declared
> in separate:
> 	 /**
> 	  * struct msi_alloc_info - Default structure for MSI interrupt allocation.
> ...
> 	  */
> 	struct msi_alloc_info {
> 	 	struct msi_desc			*desc;
> 	 	irq_hw_number_t			hwirq;
> 	 	unsigned long			flags;
> 	 	union {
> 	 		unsigned long		ul;
> 	 		void			*ptr;
> 	 	} scratchpad[NUM_MSI_ALLOC_SCRATCHPAD_REGS];
> 	};
> 
> 	 /**
> 	  * typedef msi_alloc_info_t - Default typedef for MSI interrupt allocation.
> ...
> 	  */
> 	typedef struct msi_alloc_info msi_alloc_info_t;
> 
>> b. The first line of the comment should be:
>>  * typedef msi_alloc_info_t - Default structure for MSI interrupt allocation.

OK.

>> Hopefully a warning can be printed for this.
> 
> It won't be hard to add a warning, but the point is that, in this
> specific case, the intent seems to document only the struct to
> ensure that newer usages won't use typedef anymore.
> 
> Also, right now, we don't produce any warning if one does:
> 
> 	 /**
> 	  * struct msi_alloc_info - Default structure for MSI interrupt allocation.
> ...
> 	  */
> 	struct msi_alloc_info {
> 	 	struct msi_desc			*desc;
> 	 	irq_hw_number_t			hwirq;
> 	 	unsigned long			flags;
> 	 	union {
> 	 		unsigned long		ul;
> 	 		void			*ptr;
> 	 	} scratchpad[NUM_MSI_ALLOC_SCRATCHPAD_REGS];
> 	};
> 
> 	typedef struct msi_alloc_info msi_alloc_info_t;
> 
> So, what's the point of having a warning?
I think that you have already explained what's going on, so
no point.

Thanks for your assistance.

-- 
~Randy


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v3 1/2] kernel-doc: add support for handling global variables
  2025-11-18  9:02     ` Mauro Carvalho Chehab
  2025-11-18 23:50       ` Randy Dunlap
@ 2025-11-19  5:18       ` Randy Dunlap
  2025-11-19  7:30         ` Mauro Carvalho Chehab
  1 sibling, 1 reply; 10+ messages in thread
From: Randy Dunlap @ 2025-11-19  5:18 UTC (permalink / raw)
  To: Mauro Carvalho Chehab
  Cc: Linux Doc Mailing List, Jonathan Corbet, Mauro Carvalho Chehab,
	linux-kernel



On 11/18/25 1:02 AM, Mauro Carvalho Chehab wrote:
> Em Mon, 17 Nov 2025 22:59:24 -0800
> Randy Dunlap <rdunlap@infradead.org> escreveu:
> 
>> Hi,
>>
>> On 11/16/25 3:23 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@infradead.org/T/#m947c25d95cb1d96a394410ab1131dc8e9e5013f1
>>> Suggested-by: Randy Dunlap <rdunlap@infradead.org>
>>> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
>>> ---
>>>  scripts/lib/kdoc/kdoc_output.py | 45 ++++++++++++++++++++++++++
>>>  scripts/lib/kdoc/kdoc_parser.py | 56 ++++++++++++++++++++++++++++++++-
>>>  2 files changed, 100 insertions(+), 1 deletion(-)  
>>
>> Thanks for the update. It's looking much better.
> 
> Great!
> 
>> I have a few comments/questions, all about typedefs.
> 

Hi Mauro,

I just noticed that in my sample init/kdoc-globals-test.c file
(I have s/global/var/ in it), there is one global var that is missing
or misparsed:

// from net/core/rtnetlink.c:
/**
 * var 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.
 */
static DEFINE_MUTEX(rtnl_mutex);

This var is completely missing in the html output. In the man output,
it is rendered like this:

NAME
       static DEFINE_MUTEX - historical global lock for networking control  op‐
       erations.

SYNOPSIS
       static DEFINE_MUTEX;

Description
       rtnl_mutex  is used to serialize rtnetlink requests and protect all ker‐
       nel internal data structures  related  to  networking.   See  Documenta‐
       tion/networking/netdevices.rst   for   details.    Often  known  as  the
       rtnl_lock, although rtnl_lock is a kernel function.


-- 
~Randy


^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v3 1/2] kernel-doc: add support for handling global variables
  2025-11-19  5:18       ` Randy Dunlap
@ 2025-11-19  7:30         ` Mauro Carvalho Chehab
  0 siblings, 0 replies; 10+ messages in thread
From: Mauro Carvalho Chehab @ 2025-11-19  7:30 UTC (permalink / raw)
  To: Randy Dunlap
  Cc: Linux Doc Mailing List, Jonathan Corbet, Mauro Carvalho Chehab,
	linux-kernel

Hi Randy,

Em Tue, 18 Nov 2025 21:18:06 -0800
Randy Dunlap <rdunlap@infradead.org> escreveu:

> On 11/18/25 1:02 AM, Mauro Carvalho Chehab wrote:
> > Em Mon, 17 Nov 2025 22:59:24 -0800
> > Randy Dunlap <rdunlap@infradead.org> escreveu:
> >   
> >> Hi,
> >>
> >> On 11/16/25 3:23 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@infradead.org/T/#m947c25d95cb1d96a394410ab1131dc8e9e5013f1
> >>> Suggested-by: Randy Dunlap <rdunlap@infradead.org>
> >>> Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
> >>> ---
> >>>  scripts/lib/kdoc/kdoc_output.py | 45 ++++++++++++++++++++++++++
> >>>  scripts/lib/kdoc/kdoc_parser.py | 56 ++++++++++++++++++++++++++++++++-
> >>>  2 files changed, 100 insertions(+), 1 deletion(-)    
> >>
> >> Thanks for the update. It's looking much better.  
> > 
> > Great!
> >   
> >> I have a few comments/questions, all about typedefs.  
> >   
> 
> Hi Mauro,
> 
> I just noticed that in my sample init/kdoc-globals-test.c file
> (I have s/global/var/ in it), there is one global var that is missing
> or misparsed:
> 
> // from net/core/rtnetlink.c:
> /**
>  * var 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.
>  */
> static DEFINE_MUTEX(rtnl_mutex);

Just like we have it for functions, we'll need special regex when
macros are in use.

I guess we can have a generic one to cover multiple defines, like:

	DEFINE_\w+\((\w+)\)

This should be enough to pick the name of the var. We might try
a more generic approach that would be expecting:

	<some macro>(<name>)

but IMHO this could be harder to maintain in long term.

> This var is completely missing in the html output.

Now, even if we pick it correctly, Sphinx C domain is not enough for
things like this, e.g.:

+        self.data += f"\n\n.. c:var:: {prototype}\n\n"

will fail if prototype is "DEFINE_MUTEX(rtnl_mutex)", as c:var::
will try to parse it without using macros.

See:
	https://www.sphinx-doc.org/en/master/usage/domains/c.html
	
On such case, we'll likely need to use:

	.. c:macro:: {name}

To generate the cross reference and then output the prototype or
":c:type:", which is what we use on several places where the C domain
parser won't work.

Maybe an alternate would be to use:

	.. c:macro:: name(arg list)

But it may be hard to see that this is a variable and not a macro
declaration.

Hmm... looking at https://www.sphinx-doc.org/en/master/usage/domains/c.html#directive-c-alias
it seems that Sphinx 3.2 and above introduced "c:alias:". Maybe it might
be helpful. 

> In the man output,
> it is rendered like this:

On man output, we don't need cross-references, so, we can change the
logic to output the full prototype before being parsed.

> 
> NAME
>        static DEFINE_MUTEX - historical global lock for networking control  op‐
>        erations.

Once we get the name properly parsed, this should be easy to fix.

> 
> SYNOPSIS
>        static DEFINE_MUTEX;

Yeah, it would need some tweaks for the macro case. Synopsis should be
easy to fix: instead of {prototype}, we can use {full_proto}, which is
also at the dict.

> 
> Description
>        rtnl_mutex  is used to serialize rtnetlink requests and protect all ker‐
>        nel internal data structures  related  to  networking.   See  Documenta‐
>        tion/networking/netdevices.rst   for   details.    Often  known  as  the
>        rtnl_lock, although rtnl_lock is a kernel function.
> 
> 



Thanks,
Mauro

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v3 0/2] kernel-doc: add support for documenting vars
  2025-11-16 11:23 [PATCH v3 0/2] kernel-doc: add support for documenting vars Mauro Carvalho Chehab
  2025-11-16 11:23 ` [PATCH v3 1/2] kernel-doc: add support for handling global variables Mauro Carvalho Chehab
  2025-11-16 11:23 ` [PATCH v3 2/2] docs: media: v4l2-ioctl.h: document two " Mauro Carvalho Chehab
@ 2025-11-21 17:50 ` Jonathan Corbet
  2 siblings, 0 replies; 10+ messages in thread
From: Jonathan Corbet @ 2025-11-21 17:50 UTC (permalink / raw)
  To: Mauro Carvalho Chehab, Linux Doc Mailing List
  Cc: Mauro Carvalho Chehab, Mauro Carvalho Chehab, linux-kernel,
	Randy Dunlap

Mauro Carvalho Chehab <mchehab+huawei@kernel.org> writes:

> Hi Jon,
>
> As suggested and discussed with Randy, this small series add support
> for documenting variables using kernel-doc.
>
> The first patch adds support for it.
> The second one documents two variables from media. 
>
> While two documented variables are part of kAPI, I'm documenting them
> mostly aiming to test the new feature, as those are meant to be used for
> debugging messages, so we could live without having them documented.
>
> I'm pretty sure we'll likely need to improve the parser regexes to
> catch everything. For instance, I had to add a logic on v3 due to the
> choice I did for the vars, which are pointers.
>
> Mauro Carvalho Chehab (2):
>   kernel-doc: add support for handling global variables
>   docs: media: v4l2-ioctl.h: document two global variables
>
>  include/media/v4l2-ioctl.h      | 15 +++++++++
>  scripts/lib/kdoc/kdoc_output.py | 45 ++++++++++++++++++++++++++
>  scripts/lib/kdoc/kdoc_parser.py | 56 ++++++++++++++++++++++++++++++++-
>  3 files changed, 115 insertions(+), 1 deletion(-)

This all seems fine at a first glance ... except I'm missing the update
to Documentation/doc-guide/kernel-doc.rst.  If we don't document the
documentation system, our moral position when we fault others for not
using it is ... weak ... :)

Thanks,

jon

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2025-11-21 17:50 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-11-16 11:23 [PATCH v3 0/2] kernel-doc: add support for documenting vars Mauro Carvalho Chehab
2025-11-16 11:23 ` [PATCH v3 1/2] kernel-doc: add support for handling global variables Mauro Carvalho Chehab
2025-11-18  6:59   ` Randy Dunlap
2025-11-18  9:02     ` Mauro Carvalho Chehab
2025-11-18 23:50       ` Randy Dunlap
2025-11-19  5:18       ` Randy Dunlap
2025-11-19  7:30         ` Mauro Carvalho Chehab
2025-11-16 11:23 ` [PATCH v3 2/2] docs: media: v4l2-ioctl.h: document two " Mauro Carvalho Chehab
2025-11-18  6:52   ` Randy Dunlap
2025-11-21 17:50 ` [PATCH v3 0/2] kernel-doc: add support for documenting vars Jonathan Corbet

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).