From 1243d0d91658685716eb070df66761110aa00c27 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 15 Apr 2026 10:52:17 +0200 Subject: [PATCH 1/8] docs: maintainers_include: auto-generate maintainer profile TOC Add a feature to allow auto-generating media entry profiles from the corresponding field inside MAINTAINERS file(s). Suggested-by: Dan Williams Closes: https://lore.kernel.org/linux-doc/69dd6299440be_147c801005b@djbw-dev.notmuch/ Acked-by: Dan Williams Signed-off-by: Mauro Carvalho Chehab Message-ID: <4e9512a3d05942c98361d06d60a118d7c78762b6.1776176108.git.mchehab+huawei@kernel.org> Signed-off-by: Linux RISC-V bot --- Documentation/sphinx/maintainers_include.py | 93 +++++++++++++++++---- 1 file changed, 76 insertions(+), 17 deletions(-) diff --git a/Documentation/sphinx/maintainers_include.py b/Documentation/sphinx/maintainers_include.py index 519ad18685b23f..1dac83bf1a65bf 100755 --- a/Documentation/sphinx/maintainers_include.py +++ b/Documentation/sphinx/maintainers_include.py @@ -21,6 +21,8 @@ import re import os.path +from textwrap import indent + from docutils import statemachine from docutils.parsers.rst import Directive from docutils.parsers.rst.directives.misc import Include @@ -30,20 +32,11 @@ def ErrorString(exc): # Shamelessly stolen from docutils __version__ = '1.0' -def setup(app): - app.add_directive("maintainers-include", MaintainersInclude) - return dict( - version = __version__, - parallel_read_safe = True, - parallel_write_safe = True - ) +class MaintainersParser: + """Parse MAINTAINERS file(s) content""" -class MaintainersInclude(Include): - """MaintainersInclude (``maintainers-include``) directive""" - required_arguments = 0 - - def parse_maintainers(self, path): - """Parse all the MAINTAINERS lines into ReST for human-readability""" + def __init__(self, base_path, path): + self.profiles = list() result = list() result.append(".. _maintainers:") @@ -78,6 +71,12 @@ def parse_maintainers(self, path): # Drop needless input whitespace. line = line.rstrip() + match = re.match(r"P:\s*(Documentation/\S+)\.rst", line) + if match: + fname = os.path.relpath(match.group(1), base_path) + if fname not in self.profiles: + self.profiles.append(fname) + # Linkify all non-wildcard refs to ReST files in Documentation/. pat = r'(Documentation/([^\s\?\*]*)\.rst)' m = re.search(pat, line) @@ -165,12 +164,62 @@ def parse_maintainers(self, path): for separated in field_content.split('\n'): result.append(separated) - output = "\n".join(result) + self.output = "\n".join(result) + + # Create a TOC class + +class MaintainersInclude(Include): + """MaintainersInclude (``maintainers-include``) directive""" + required_arguments = 0 + + def emit(self, base_path, path): + """Parse all the MAINTAINERS lines into ReST for human-readability""" + + output = MaintainersParser(base_path, path).output + # For debugging the pre-rendered results... #print(output, file=open("/tmp/MAINTAINERS.rst", "w")) - self.state_machine.insert_input( - statemachine.string2lines(output), path) + self.state_machine.insert_input(statemachine.string2lines(output), path) + + def run(self): + """Include the MAINTAINERS file as part of this reST file.""" + if not self.state.document.settings.file_insertion_enabled: + raise self.warning('"%s" directive disabled.' % self.name) + + # Walk up source path directories to find Documentation/../ + path = self.state_machine.document.attributes['source'] + path = os.path.realpath(path) + tail = path + while tail != "Documentation" and tail != "": + (path, tail) = os.path.split(path) + + # Append "MAINTAINERS" + path = os.path.join(path, "MAINTAINERS") + base_path = os.path.dirname(self.state.document.document.current_source) + + try: + self.state.document.settings.record_dependencies.add(path) + lines = self.emit(base_path, path) + except IOError as error: + raise self.severe('Problems with "%s" directive path:\n%s.' % + (self.name, ErrorString(error))) + + return [] + +class MaintainersProfile(Include): + required_arguments = 0 + + def emit(self, base_path, path): + """Parse all the MAINTAINERS lines looking for profile entries""" + + profiles = MaintainersParser(base_path, path).profiles + + output = ".. toctree::\n" + output += " :maxdepth: 2\n\n" + output += indent("\n".join(profiles), " ") + + self.state_machine.insert_input(statemachine.string2lines(output), path) def run(self): """Include the MAINTAINERS file as part of this reST file.""" @@ -186,12 +235,22 @@ def run(self): # Append "MAINTAINERS" path = os.path.join(path, "MAINTAINERS") + base_path = os.path.dirname(self.state.document.document.current_source) try: self.state.document.settings.record_dependencies.add(path) - lines = self.parse_maintainers(path) + lines = self.emit(base_path, path) except IOError as error: raise self.severe('Problems with "%s" directive path:\n%s.' % (self.name, ErrorString(error))) return [] + +def setup(app): + app.add_directive("maintainers-include", MaintainersInclude) + app.add_directive("maintainers-profile-toc", MaintainersProfile) + return dict( + version = __version__, + parallel_read_safe = True, + parallel_write_safe = True + ) From 945af6cf46cd6927dd97f07356839f35e0a4252c Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 15 Apr 2026 10:52:18 +0200 Subject: [PATCH 2/8] MAINTAINERS: add an entry for media maintainers profile The media subsystem has a maintainers entry profile, but its entry is missing at MAINTAINERS. Add it. Acked-by: Randy Dunlap Signed-off-by: Mauro Carvalho Chehab Message-ID: <5af4aa6a716228eea4d59dc26b97d642e1e7d419.1776176108.git.mchehab+huawei@kernel.org> Signed-off-by: Linux RISC-V bot --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index 7d10988cbc62b7..feae5f3d422738 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -16108,6 +16108,7 @@ S: Maintained W: https://linuxtv.org Q: http://patchwork.kernel.org/project/linux-media/list/ T: git git://linuxtv.org/media.git +P: Documentation/driver-api/media/maintainer-entry-profile.rst F: Documentation/admin-guide/media/ F: Documentation/devicetree/bindings/media/ F: Documentation/driver-api/media/ From fc04f5db3a94b691be5582f916b394392fced2c4 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 15 Apr 2026 10:52:19 +0200 Subject: [PATCH 3/8] MAINTAINERS: add maintainer-tip.rst to X86 The X86 subsystem has a maintainers entry profile, but its entry is missing at MAINTAINERS. Add it. Acked-by: Randy Dunlap Acked-by: Dan Williams Signed-off-by: Mauro Carvalho Chehab Message-ID: <970434c647aa1e1e9a81c87b4d5fed934d4018a7.1776176108.git.mchehab+huawei@kernel.org> Signed-off-by: Linux RISC-V bot --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS index feae5f3d422738..27a61cc65e428b 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -28548,6 +28548,7 @@ M: Ingo Molnar M: Borislav Petkov M: Dave Hansen M: x86@kernel.org +P: Documentation/process/maintainer-tip.rst R: "H. Peter Anvin" L: linux-kernel@vger.kernel.org S: Maintained From a8f3fdeb3cd2688034a6b86a9e315c33691f4c5e Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 15 Apr 2026 10:52:20 +0200 Subject: [PATCH 4/8] docs: auto-generate maintainer entry profile links Instead of manually creating a TOC tree for them, use the new tag to auto-generate its TOC. Co-developed-by: Dan Williams Signed-off-by: Dan Williams Signed-off-by: Mauro Carvalho Chehab Message-ID: <9228f77b0339b8e5dea4a201ab6d4feb30cef5c2.1776176108.git.mchehab+huawei@kernel.org> Signed-off-by: Linux RISC-V bot --- .../maintainer/maintainer-entry-profile.rst | 26 ++++--------------- .../process/maintainer-handbooks.rst | 19 +++++++------- 2 files changed, 15 insertions(+), 30 deletions(-) diff --git a/Documentation/maintainer/maintainer-entry-profile.rst b/Documentation/maintainer/maintainer-entry-profile.rst index 6020d188e13de1..58e2af333692dc 100644 --- a/Documentation/maintainer/maintainer-entry-profile.rst +++ b/Documentation/maintainer/maintainer-entry-profile.rst @@ -92,24 +92,8 @@ full series, or privately send a reminder email. This section might also list how review works for this code area and methods to get feedback that are not directly from the maintainer. -Existing profiles ------------------ - -For now, existing maintainer profiles are listed here; we will likely want -to do something different in the near future. - -.. toctree:: - :maxdepth: 1 - - ../doc-guide/maintainer-profile - ../nvdimm/maintainer-entry-profile - ../arch/riscv/patch-acceptance - ../process/maintainer-soc - ../process/maintainer-soc-clean-dts - ../driver-api/media/maintainer-entry-profile - ../process/maintainer-netdev - ../driver-api/vfio-pci-device-specific-driver-acceptance - ../nvme/feature-and-quirk-policy - ../filesystems/nfs/nfsd-maintainer-entry-profile - ../filesystems/xfs/xfs-maintainer-entry-profile - ../mm/damon/maintainer-profile +Maintainer Handbooks +-------------------- + +For examples of other subsystem handbooks see +Documentation/process/maintainer-handbooks.rst. diff --git a/Documentation/process/maintainer-handbooks.rst b/Documentation/process/maintainer-handbooks.rst index 976391cec528e1..a8418e7955ed93 100644 --- a/Documentation/process/maintainer-handbooks.rst +++ b/Documentation/process/maintainer-handbooks.rst @@ -9,14 +9,15 @@ The purpose of this document is to provide subsystem specific information which is supplementary to the general development process handbook :ref:`Documentation/process `. -Contents: +For developers, see below for all the known subsystem specific guides. +If the subsystem you are contributing to does not have a guide listed +here, it is fair to seek clarification of questions raised in +Documentation/maintainer/maintainer-entry-profile.rst. + +For maintainers, consider documenting additional requirements and +expectations if submissions routinely overlook specific submission +criteria. See Documentation/maintainer/maintainer-entry-profile.rst. -.. toctree:: - :numbered: - :maxdepth: 2 +Contents: - maintainer-netdev - maintainer-soc - maintainer-soc-clean-dts - maintainer-tip - maintainer-kvm-x86 +.. maintainers-profile-toc:: From 8a2c60575680dff7a40f05119178f546715df206 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 15 Apr 2026 10:52:21 +0200 Subject: [PATCH 5/8] docs: maintainers_include: use a better title for profiles As we're picking the name of the subsystem from MAINTAINERS, also use its subsystem name for the titles. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Linux RISC-V bot --- Documentation/sphinx/maintainers_include.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/Documentation/sphinx/maintainers_include.py b/Documentation/sphinx/maintainers_include.py index 1dac83bf1a65bf..cf428db7599cc1 100755 --- a/Documentation/sphinx/maintainers_include.py +++ b/Documentation/sphinx/maintainers_include.py @@ -36,7 +36,7 @@ class MaintainersParser: """Parse MAINTAINERS file(s) content""" def __init__(self, base_path, path): - self.profiles = list() + self.profiles = {} result = list() result.append(".. _maintainers:") @@ -54,6 +54,7 @@ def __init__(self, base_path, path): prev = None field_prev = "" field_content = "" + subsystem_name = None for line in open(path): # Have we reached the end of the preformatted Descriptions text? @@ -75,7 +76,10 @@ def __init__(self, base_path, path): if match: fname = os.path.relpath(match.group(1), base_path) if fname not in self.profiles: - self.profiles.append(fname) + if self.profiles.get(fname) is None: + self.profiles[fname] = subsystem_name + else: + self.profiles[fname] += f", {subsystem_name}" # Linkify all non-wildcard refs to ReST files in Documentation/. pat = r'(Documentation/([^\s\?\*]*)\.rst)' @@ -112,6 +116,8 @@ def __init__(self, base_path, path): output = field_content + "\n\n" field_content = "" + subsystem_name = line.title() + # Collapse whitespace in subsystem name. heading = re.sub(r"\s+", " ", line) output = output + "%s\n%s" % (heading, "~" * len(heading)) @@ -217,7 +223,13 @@ def emit(self, base_path, path): output = ".. toctree::\n" output += " :maxdepth: 2\n\n" - output += indent("\n".join(profiles), " ") + + items = sorted(profiles.items(), key=lambda kv: (kv[1] or "", kv[0])) + for fname, profile in items: + if profile: + output += f" {profile} <{fname}>\n" + else: + output += f" {fname}\n" self.state_machine.insert_input(statemachine.string2lines(output), path) From 2d4003e93f2ca7012074618766dec8f2737cddf6 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 15 Apr 2026 10:52:22 +0200 Subject: [PATCH 6/8] docs: maintainers_include: add external profile URLs Some subsystem profiles are maintained elsewhere. Add them to the output. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Linux RISC-V bot --- Documentation/sphinx/maintainers_include.py | 28 +++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/Documentation/sphinx/maintainers_include.py b/Documentation/sphinx/maintainers_include.py index cf428db7599cc1..f1b8d4b00c2adc 100755 --- a/Documentation/sphinx/maintainers_include.py +++ b/Documentation/sphinx/maintainers_include.py @@ -37,6 +37,7 @@ class MaintainersParser: def __init__(self, base_path, path): self.profiles = {} + self.profile_urls = {} result = list() result.append(".. _maintainers:") @@ -81,6 +82,16 @@ def __init__(self, base_path, path): else: self.profiles[fname] += f", {subsystem_name}" + match = re.match(r"P:\s*(https?://.*)", line) + if match: + url = match.group(1).strip() + if url not in self.profile_urls: + if self.profile_urls.get(url) is None: + self.profile_urls[url] = subsystem_name + else: + self.profile_urls[url] += f", {subsystem_name}" + + # Linkify all non-wildcard refs to ReST files in Documentation/. pat = r'(Documentation/([^\s\?\*]*)\.rst)' m = re.search(pat, line) @@ -219,18 +230,31 @@ class MaintainersProfile(Include): def emit(self, base_path, path): """Parse all the MAINTAINERS lines looking for profile entries""" - profiles = MaintainersParser(base_path, path).profiles + maint = MaintainersParser(base_path, path) output = ".. toctree::\n" output += " :maxdepth: 2\n\n" - items = sorted(profiles.items(), key=lambda kv: (kv[1] or "", kv[0])) + items = sorted(maint.profiles.items(), + key=lambda kv: (kv[1] or "", kv[0])) for fname, profile in items: if profile: output += f" {profile} <{fname}>\n" else: output += f" {fname}\n" + output += "\n**External profiles**\n\n" + + items = sorted(maint.profile_urls.items(), + key=lambda kv: (kv[1] or "", kv[0])) + for url, profile in items: + if profile: + output += f"- {profile} <{url}>\n" + else: + output += f"- {url}\n" + + output += "\n" + self.state_machine.insert_input(statemachine.string2lines(output), path) def run(self): From 51ca9cfa9d5ce1ed844c45f3dda0787ef1a9e7e7 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 15 Apr 2026 10:52:23 +0200 Subject: [PATCH 7/8] docs: maintainers_include: preserve names for files under process/ When a maintainer's profile is stored outside process, they're already included on some other book and the name of the filesystem may not be there. That's why the logic picks the name from the subsystem's name. However, files directly placed together with maintainers-handbooks.rst (e.g. under Documentation/process/) is a different history: those aren't placed anywhere, so we can keep using their own names, letting Sphinx do his thing. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Linux RISC-V bot --- Documentation/sphinx/maintainers_include.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/sphinx/maintainers_include.py b/Documentation/sphinx/maintainers_include.py index f1b8d4b00c2adc..948746b998a358 100755 --- a/Documentation/sphinx/maintainers_include.py +++ b/Documentation/sphinx/maintainers_include.py @@ -76,11 +76,13 @@ def __init__(self, base_path, path): match = re.match(r"P:\s*(Documentation/\S+)\.rst", line) if match: fname = os.path.relpath(match.group(1), base_path) - if fname not in self.profiles: + if fname.startswith("../"): if self.profiles.get(fname) is None: self.profiles[fname] = subsystem_name else: self.profiles[fname] += f", {subsystem_name}" + else: + self.profiles[fname] = None match = re.match(r"P:\s*(https?://.*)", line) if match: From ea89aab2a40c7889310f79fe8ce5093d70394713 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Wed, 15 Apr 2026 10:52:24 +0200 Subject: [PATCH 8/8] docs: maintainers_include: Only show main entry for profiles Instead of showing as a "Contents:" with 2 identation levels, drop its title and show profiles as a list of entries. Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Linux RISC-V bot --- Documentation/process/maintainer-handbooks.rst | 2 -- Documentation/sphinx/maintainers_include.py | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Documentation/process/maintainer-handbooks.rst b/Documentation/process/maintainer-handbooks.rst index a8418e7955ed93..a66f99ad114567 100644 --- a/Documentation/process/maintainer-handbooks.rst +++ b/Documentation/process/maintainer-handbooks.rst @@ -18,6 +18,4 @@ For maintainers, consider documenting additional requirements and expectations if submissions routinely overlook specific submission criteria. See Documentation/maintainer/maintainer-entry-profile.rst. -Contents: - .. maintainers-profile-toc:: diff --git a/Documentation/sphinx/maintainers_include.py b/Documentation/sphinx/maintainers_include.py index 948746b998a358..7ab92182061277 100755 --- a/Documentation/sphinx/maintainers_include.py +++ b/Documentation/sphinx/maintainers_include.py @@ -235,7 +235,7 @@ def emit(self, base_path, path): maint = MaintainersParser(base_path, path) output = ".. toctree::\n" - output += " :maxdepth: 2\n\n" + output += " :maxdepth: 1\n\n" items = sorted(maint.profiles.items(), key=lambda kv: (kv[1] or "", kv[0]))