History

Merge tag 'docs-6.18' of git://git.lwn.net/linux

Pull documentation updates from Jonathan Corbet: "It has been a relatively busy cycle in docsland, with changes all over: - Bring the kernel memory-model docs into the Sphinx build in the "literal include" mode. - Lots of build-infrastructure work, further cleaning up long-term kernel-doc technical debt. The sphinx-pre-install tool has been converted to Python and updated for current systems. - A new tool to detect when documents have been moved and generate HTML redirects; this can be used on kernel.org (or any other site hosting the rendered docs) to avoid breaking links. - Automated processing of the YAML files describing the netlink protocol. - A significant update of the maintainer's PGP guide. ... and a seemingly endless series of typo fixes, build-problem fixes, etc" * tag 'docs-6.18' of git://git.lwn.net/linux: (193 commits) Documentation/features: Update feature lists for 6.17-rc7 docs: remove cdomain.py Documentation/process: submitting-patches: fix typo in "were do" docs: dev-tools/lkmm: Fix typo of missing file extension Documentation: trace: histogram: Convert ftrace docs cross-reference Documentation: trace: histogram-design: Wrap introductory note in note:: directive Documentation: trace: historgram-design: Separate sched_waking histogram section heading and the following diagram Documentation: trace: histogram-design: Trim trailing vertices in diagram explanation text Documentation: trace: histogram: Fix histogram trigger subsection number order docs: driver-api: fix spelling of "buses". Documentation: fbcon: Use admonition directives Documentation: fbcon: Reindent 8th step of attach/detach/unload Documentation: fbcon: Add boot options and attach/detach/unload section headings docs: filesystems: sysfs: add remaining top level sysfs directory descriptions docs: filesystems: sysfs: clarify symlink destinations in dev and bus/devices descriptions docs: filesystems: sysfs: remove top level sysfs net directory docs: maintainer: Fix ambiguous subheading formatting docs: kdoc: a few more dump_typedef() tweaks docs: kdoc: remove redundant comment stripping in dump_typedef() docs: kdoc: remove some dead code in dump_typedef() ...

Linus Torvalds committed 1 year ago

Commit ee2fe812 parents 50647a1 99510c3173 files · +7050 −3564Browse files

Unified · Split

173 files
  1. .pylintrc +1 −1
  2. Documentation/.renames.txt +1191 −0
  3. Documentation/Makefile +7 −4
  4. Documentation/PCI/endpoint/pci-endpoint-cfs.rst +2 −2
  5. Documentation/PCI/endpoint/pci-endpoint.rst +3 −3
  6. Documentation/RCU/lockdep.rst +1 −1
  7. Documentation/RCU/stallwarn.rst +1 −1
  8. Documentation/admin-guide/LSM/SafeSetID.rst +1 −1
  9. Documentation/admin-guide/RAS/main.rst +1 −1
  10. Documentation/admin-guide/aoe/udev.txt +3 −3
  11. Documentation/admin-guide/blockdev/paride.rst +1 −1
  12. Documentation/admin-guide/device-mapper/vdo-design.rst +1 −1
  13. Documentation/admin-guide/ext4.rst +1 −1
  14. Documentation/admin-guide/hw-vuln/mds.rst +1 −1
  15. Documentation/admin-guide/hw-vuln/spectre.rst +3 −3
  16. Documentation/admin-guide/kdump/kdump.rst +1 −1
  17. Documentation/admin-guide/kernel-parameters.rst +3 −1
  18. Documentation/admin-guide/kernel-parameters.txt +6 −6
  19. Documentation/admin-guide/laptops/laptop-mode.rst +4 −4
  20. Documentation/admin-guide/laptops/sonypi.rst +1 −1
  21. Documentation/admin-guide/md.rst +1 −1
  22. Documentation/admin-guide/media/imx.rst +1 −1
  23. Documentation/admin-guide/media/si4713.rst +3 −3
  24. Documentation/admin-guide/mm/damon/usage.rst +1 −1
  25. Documentation/admin-guide/nfs/nfsroot.rst +1 −1
  26. Documentation/admin-guide/perf/hisi-pmu.rst +2 −2
  27. Documentation/admin-guide/quickly-build-trimmed-linux.rst +2 −2
  28. Documentation/admin-guide/reporting-issues.rst +2 −2
  29. Documentation/admin-guide/sysctl/fs.rst +2 −2
  30. Documentation/admin-guide/sysctl/index.rst +12 −6
  31. Documentation/admin-guide/verify-bugs-and-bisect-regressions.rst +1 −1
  32. Documentation/arch/arm/stm32/stm32f746-overview.rst +1 −1
  33. Documentation/arch/arm/stm32/stm32f769-overview.rst +1 −1
  34. Documentation/arch/arm/stm32/stm32h743-overview.rst +1 −1
  35. Documentation/arch/arm/stm32/stm32h750-overview.rst +1 −1
  36. Documentation/arch/arm/stm32/stm32mp13-overview.rst +1 −1
  37. Documentation/arch/arm/stm32/stm32mp151-overview.rst +1 −1
  38. Documentation/arch/loongarch/irq-chip-model.rst +2 −2
  39. Documentation/arch/powerpc/eeh-pci-error-recovery.rst +0 −1
  40. Documentation/arch/x86/cpuinfo.rst +1 −1
  41. Documentation/conf.py +61 −45
  42. Documentation/core-api/folio_queue.rst +1 −1
  43. Documentation/core-api/index.rst +1 −0
  44. Documentation/core-api/irq/irq-affinity.rst +3 −3
  45. Documentation/core-api/irq/irq-domain.rst +19 −19
  46. Documentation/core-api/printk-formats.rst +1 −1
  47. Documentation/core-api/real-time/architecture-porting.rst +109 −0
  48. Documentation/core-api/real-time/differences.rst +242 −0
  49. Documentation/core-api/real-time/index.rst +16 −0
  50. Documentation/core-api/real-time/theory.rst +116 −0
  51. Documentation/dev-tools/autofdo.rst +2 −2
  52. Documentation/dev-tools/index.rst +1 −0
  53. Documentation/dev-tools/ktap.rst +4 −1
  54. Documentation/dev-tools/lkmm/docs/access-marking.rst +11 −0
  55. Documentation/dev-tools/lkmm/docs/cheatsheet.rst +11 −0
  56. Documentation/dev-tools/lkmm/docs/control-dependencies.rst +11 −0
  57. Documentation/dev-tools/lkmm/docs/explanation.rst +11 −0
  58. Documentation/dev-tools/lkmm/docs/glossary.rst +11 −0
  59. Documentation/dev-tools/lkmm/docs/herd-representation.rst +11 −0
  60. Documentation/dev-tools/lkmm/docs/index.rst +21 −0
  61. Documentation/dev-tools/lkmm/docs/litmus-tests.rst +11 −0
  62. Documentation/dev-tools/lkmm/docs/locking.rst +11 −0
  63. Documentation/dev-tools/lkmm/docs/ordering.rst +11 −0
  64. Documentation/dev-tools/lkmm/docs/readme.rst +11 −0
  65. Documentation/dev-tools/lkmm/docs/recipes.rst +11 −0
  66. Documentation/dev-tools/lkmm/docs/references.rst +11 −0
  67. Documentation/dev-tools/lkmm/docs/simple.rst +11 −0
  68. Documentation/dev-tools/lkmm/index.rst +15 −0
  69. Documentation/dev-tools/lkmm/readme.rst +11 −0
  70. Documentation/devicetree/bindings/submitting-patches.rst +1 −1
  71. Documentation/driver-api/cxl/devices/device-types.rst +1 −1
  72. Documentation/driver-api/cxl/platform/example-configurations/one-dev-per-hb.rst +1 −1
  73. Documentation/driver-api/device-io.rst +2 −2
  74. Documentation/driver-api/driver-model/overview.rst +1 −1
  75. Documentation/driver-api/driver-model/platform.rst +1 −1
  76. Documentation/driver-api/eisa.rst +3 −3
  77. Documentation/driver-api/i3c/protocol.rst +2 −2
  78. Documentation/driver-api/ipmi.rst +2 −2
  79. Documentation/driver-api/media/tx-rx.rst +2 −2
  80. Documentation/driver-api/nvdimm/nvdimm.rst +1 −1
  81. Documentation/driver-api/pin-control.rst +6 −4
  82. Documentation/driver-api/pm/devices.rst +2 −2
  83. Documentation/driver-api/scsi.rst +2 −2
  84. Documentation/driver-api/spi.rst +1 −1
  85. Documentation/driver-api/thermal/exynos_thermal_emulation.rst +7 −7
  86. Documentation/driver-api/usb/hotplug.rst +1 −1
  87. Documentation/driver-api/usb/index.rst +1 −0
  88. Documentation/driver-api/usb/usb.rst +2 −2
  89. Documentation/fb/fbcon.rst +24 −18
  90. Documentation/features/core/eBPF-JIT/arch-support.txt +2 −2
  91. Documentation/features/core/mseal_sys_mappings/arch-support.txt +1 −1
  92. Documentation/features/core/thread-info-in-task/arch-support.txt +1 −1
  93. Documentation/features/core/tracehook/arch-support.txt +1 −1
  94. Documentation/features/perf/kprobes-event/arch-support.txt +1 −1
  95. Documentation/features/time/clockevents/arch-support.txt +1 −1
  96. Documentation/filesystems/erofs.rst +1 −1
  97. Documentation/filesystems/ext4/atomic_writes.rst +3 −3
  98. Documentation/filesystems/gfs2-glocks.rst +1 −1
  99. Documentation/filesystems/hpfs.rst +1 −1
  100. Documentation/filesystems/iomap/operations.rst +1 −1
  101. Documentation/filesystems/ocfs2-online-filecheck.rst +10 −10
  102. Documentation/filesystems/proc.rst +0 −21
  103. Documentation/filesystems/propagate_umount.txt +3 −3
  104. Documentation/filesystems/resctrl.rst +1 −1
  105. Documentation/filesystems/sharedsubtree.rst +671 −676
  106. Documentation/filesystems/sysfs.rst +19 −6
  107. Documentation/filesystems/xfs/xfs-online-fsck-design.rst +4 −4
  108. Documentation/locking/locktypes.rst +21 −0
  109. Documentation/locking/seqlock.rst +2 −0
  110. Documentation/maintainer/configure-git.rst +0 −28
  111. Documentation/maintainer/maintainer-entry-profile.rst +2 −0
  112. Documentation/mm/physical_memory.rst +2 −0
  113. Documentation/networking/can.rst +1 −1
  114. Documentation/networking/device_drivers/ethernet/ti/am65_nuss_cpsw_switchdev.rst +1 −1
  115. Documentation/networking/device_drivers/ethernet/ti/cpsw_switchdev.rst +1 −1
  116. Documentation/networking/rds.rst +1 −1
  117. Documentation/power/pci.rst +2 −2
  118. Documentation/power/suspend-and-cpuhotplug.rst +1 −1
  119. Documentation/process/5.Posting.rst +3 −4
  120. Documentation/process/changes.rst +8 −1
  121. Documentation/process/maintainer-pgp-guide.rst +75 −83
  122. Documentation/process/submitting-patches.rst +3 −3
  123. Documentation/sphinx/automarkup.py +1 −1
  124. Documentation/sphinx/cdomain.py +0 −247
  125. Documentation/sphinx/kernel_feat.py +3 −1
  126. Documentation/sphinx/kernel_include.py +392 −136
  127. Documentation/sphinx/maintainers_include.py +3 −1
  128. Documentation/sphinx/parse-headers.pl +0 −404
  129. Documentation/sphinx/templates/kernel-toc.html +2 −1
  130. Documentation/sphinx/templates/translations.html +2 −2
  131. Documentation/staging/remoteproc.rst +1 −1
  132. Documentation/trace/boottime-trace.rst +1 −1
  133. Documentation/trace/debugging.rst +1 −1
  134. Documentation/trace/events.rst +4 −4
  135. Documentation/trace/fprobe.rst +1 −1
  136. Documentation/trace/ftrace-uses.rst +1 −1
  137. Documentation/trace/ftrace.rst +7 −7
  138. Documentation/trace/histogram-design.rst +89 −86
  139. Documentation/trace/histogram.rst +20 −20
  140. Documentation/trace/rv/monitor_synthesis.rst +1 −1
  141. Documentation/translations/it_IT/process/changes.rst +0 −14
  142. Documentation/userspace-api/media/Makefile +0 −64
  143. Documentation/userspace-api/media/cec/cec-header.rst +3 −2
  144. Documentation/userspace-api/media/cec/cec.h.rst.exceptions +0 −0
  145. Documentation/userspace-api/media/dvb/ca.h.rst.exceptions +0 −0
  146. Documentation/userspace-api/media/dvb/dmx.h.rst.exceptions +0 −0
  147. Documentation/userspace-api/media/dvb/frontend.h.rst.exceptions +0 −0
  148. Documentation/userspace-api/media/dvb/headers.rst +13 −4
  149. Documentation/userspace-api/media/dvb/net.h.rst.exceptions +0 −0
  150. Documentation/userspace-api/media/mediactl/media-header.rst +3 −2
  151. Documentation/userspace-api/media/mediactl/media.h.rst.exceptions +0 −0
  152. Documentation/userspace-api/media/rc/lirc-header.rst +3 −1
  153. Documentation/userspace-api/media/rc/lirc.h.rst.exceptions +0 −0
  154. Documentation/userspace-api/media/v4l/videodev.rst +3 −1
  155. Documentation/userspace-api/media/v4l/videodev2.h.rst.exceptions +0 −0
  156. Documentation/virt/kvm/review-checklist.rst +1 −1
  157. Documentation/w1/masters/ds2482.rst +1 −1
  158. Documentation/w1/masters/index.rst +1 −1
  159. Documentation/w1/slaves/index.rst +1 −1
  160. MAINTAINERS +3 −0
  161. Makefile +3 −2
  162. fs/btrfs/tree-log.c +1 −1
  163. scripts/kernel-doc.py +24 −10
  164. scripts/lib/kdoc/kdoc_parser.py +414 −434
  165. scripts/selinux/install_policy.sh +1 −1
  166. scripts/sphinx-build-wrapper +719 −0
  167. scripts/sphinx-pre-install +1617 −1052
  168. tools/docs/gen-redirects.py +54 −0
  169. tools/docs/gen-renames.py +130 −0
  170. tools/docs/lib/__init__.py +0 −0
  171. tools/docs/lib/enrich_formatter.py +70 −0
  172. tools/docs/lib/parse_data_structs.py +452 −0
  173. tools/docs/parse-headers.py +60 −0
.pylintrc+1−1
@@ -1,2 +1,2 @@
1[MASTER]1[MASTER]
2init-hook='import sys; sys.path += ["scripts/lib/kdoc", "scripts/lib/abi"]'2init-hook='import sys; sys.path += ["scripts/lib/kdoc", "scripts/lib/abi", "tools/docs/lib"]'
Documentation/.renames.txt+1191−0
@@ -0,0 +1,1191 @@
180211/cfg80211 driver-api/80211/cfg80211
280211/index driver-api/80211/index
380211/introduction driver-api/80211/introduction
480211/mac80211 driver-api/80211/mac80211
580211/mac80211-advanced driver-api/80211/mac80211-advanced
6EDID/howto admin-guide/edid
7PCI/picebus-howto PCI/pciebus-howto
8RAS/address-translation admin-guide/RAS/address-translation
9RAS/error-decoding admin-guide/RAS/error-decoding
10RAS/ras admin-guide/RAS/error-decoding
11accelerators/ocxl userspace-api/accelerators/ocxl
12admin-guide/gpio/sysfs userspace-api/gpio/sysfs
13admin-guide/l1tf admin-guide/hw-vuln/l1tf
14admin-guide/media/v4l-with-ir admin-guide/media/remote-controller
15admin-guide/ras admin-guide/RAS/main
16admin-guide/security-bugs process/security-bugs
17aoe/aoe admin-guide/aoe/aoe
18aoe/examples admin-guide/aoe/examples
19aoe/index admin-guide/aoe/index
20aoe/todo admin-guide/aoe/todo
21arc/arc arch/arc/arc
22arc/features arch/arc/features
23arc/index arch/arc/index
24arch/x86/resctrl filesystems/resctrl
25arm/arm arch/arm/arm
26arm/booting arch/arm/booting
27arm/cluster-pm-race-avoidance arch/arm/cluster-pm-race-avoidance
28arm/features arch/arm/features
29arm/firmware arch/arm/firmware
30arm/google/chromebook-boot-flow arch/arm/google/chromebook-boot-flow
31arm/index arch/arm/index
32arm/interrupts arch/arm/interrupts
33arm/ixp4xx arch/arm/ixp4xx
34arm/kernel_mode_neon arch/arm/kernel_mode_neon
35arm/kernel_user_helpers arch/arm/kernel_user_helpers
36arm/keystone/knav-qmss arch/arm/keystone/knav-qmss
37arm/keystone/overview arch/arm/keystone/overview
38arm/marvel arch/arm/marvell
39arm/marvell arch/arm/marvell
40arm/mem_alignment arch/arm/mem_alignment
41arm/memory arch/arm/memory
42arm/microchip arch/arm/microchip
43arm/netwinder arch/arm/netwinder
44arm/nwfpe/index arch/arm/nwfpe/index
45arm/nwfpe/netwinder-fpe arch/arm/nwfpe/netwinder-fpe
46arm/nwfpe/notes arch/arm/nwfpe/notes
47arm/nwfpe/nwfpe arch/arm/nwfpe/nwfpe
48arm/nwfpe/todo arch/arm/nwfpe/todo
49arm/omap/dss arch/arm/omap/dss
50arm/omap/index arch/arm/omap/index
51arm/omap/omap arch/arm/omap/omap
52arm/omap/omap_pm arch/arm/omap/omap_pm
53arm/porting arch/arm/porting
54arm/pxa/mfp arch/arm/pxa/mfp
55arm/sa1100/assabet arch/arm/sa1100/assabet
56arm/sa1100/cerf arch/arm/sa1100/cerf
57arm/sa1100/index arch/arm/sa1100/index
58arm/sa1100/lart arch/arm/sa1100/lart
59arm/sa1100/serial_uart arch/arm/sa1100/serial_uart
60arm/samsung/bootloader-interface arch/arm/samsung/bootloader-interface
61arm/samsung/gpio arch/arm/samsung/gpio
62arm/samsung/index arch/arm/samsung/index
63arm/samsung/overview arch/arm/samsung/overview
64arm/setup arch/arm/setup
65arm/spear/overview arch/arm/spear/overview
66arm/sti/overview arch/arm/sti/overview
67arm/sti/stih407-overview arch/arm/sti/stih407-overview
68arm/sti/stih418-overview arch/arm/sti/stih418-overview
69arm/stm32/overview arch/arm/stm32/overview
70arm/stm32/stm32-dma-mdma-chaining arch/arm/stm32/stm32-dma-mdma-chaining
71arm/stm32/stm32f429-overview arch/arm/stm32/stm32f429-overview
72arm/stm32/stm32f746-overview arch/arm/stm32/stm32f746-overview
73arm/stm32/stm32f769-overview arch/arm/stm32/stm32f769-overview
74arm/stm32/stm32h743-overview arch/arm/stm32/stm32h743-overview
75arm/stm32/stm32h750-overview arch/arm/stm32/stm32h750-overview
76arm/stm32/stm32mp13-overview arch/arm/stm32/stm32mp13-overview
77arm/stm32/stm32mp151-overview arch/arm/stm32/stm32mp151-overview
78arm/stm32/stm32mp157-overview arch/arm/stm32/stm32mp157-overview
79arm/sunxi arch/arm/sunxi
80arm/sunxi/clocks arch/arm/sunxi/clocks
81arm/swp_emulation arch/arm/swp_emulation
82arm/tcm arch/arm/tcm
83arm/uefi arch/arm/uefi
84arm/vfp/release-notes arch/arm/vfp/release-notes
85arm/vlocks arch/arm/vlocks
86arm64/acpi_object_usage arch/arm64/acpi_object_usage
87arm64/amu arch/arm64/amu
88arm64/arm-acpi arch/arm64/arm-acpi
89arm64/asymmetric-32bit arch/arm64/asymmetric-32bit
90arm64/booting arch/arm64/booting
91arm64/cpu-feature-registers arch/arm64/cpu-feature-registers
92arm64/elf_hwcaps arch/arm64/elf_hwcaps
93arm64/features arch/arm64/features
94arm64/hugetlbpage arch/arm64/hugetlbpage
95arm64/index arch/arm64/index
96arm64/legacy_instructions arch/arm64/legacy_instructions
97arm64/memory arch/arm64/memory
98arm64/memory-tagging-extension arch/arm64/memory-tagging-extension
99arm64/perf arch/arm64/perf
100arm64/pointer-authentication arch/arm64/pointer-authentication
101arm64/silicon-errata arch/arm64/silicon-errata
102arm64/sme arch/arm64/sme
103arm64/sve arch/arm64/sve
104arm64/tagged-address-abi arch/arm64/tagged-address-abi
105arm64/tagged-pointers arch/arm64/tagged-pointers
106asm-annotations core-api/asm-annotations
107auxdisplay/lcd-panel-cgram admin-guide/lcd-panel-cgram
108backlight/lp855x-driver driver-api/backlight/lp855x-driver
109blockdev/drbd/data-structure-v9 admin-guide/blockdev/drbd/data-structure-v9
110blockdev/drbd/figures admin-guide/blockdev/drbd/figures
111blockdev/drbd/index admin-guide/blockdev/drbd/index
112blockdev/floppy admin-guide/blockdev/floppy
113blockdev/index admin-guide/blockdev/index
114blockdev/nbd admin-guide/blockdev/nbd
115blockdev/paride admin-guide/blockdev/paride
116blockdev/ramdisk admin-guide/blockdev/ramdisk
117blockdev/zram admin-guide/blockdev/zram
118bpf/README bpf/index
119bpf/bpf_lsm bpf/prog_lsm
120bpf/instruction-set bpf/standardization/instruction-set
121bpf/libbpf/libbpf bpf/libbpf/index
122bpf/standardization/linux-notes bpf/linux-notes
123bus-devices/ti-gpmc driver-api/memory-devices/ti-gpmc
124cgroup-v1/blkio-controller admin-guide/cgroup-v1/blkio-controller
125cgroup-v1/cgroups admin-guide/cgroup-v1/cgroups
126cgroup-v1/cpuacct admin-guide/cgroup-v1/cpuacct
127cgroup-v1/cpusets admin-guide/cgroup-v1/cpusets
128cgroup-v1/devices admin-guide/cgroup-v1/devices
129cgroup-v1/freezer-subsystem admin-guide/cgroup-v1/freezer-subsystem
130cgroup-v1/hugetlb admin-guide/cgroup-v1/hugetlb
131cgroup-v1/index admin-guide/cgroup-v1/index
132cgroup-v1/memcg_test admin-guide/cgroup-v1/memcg_test
133cgroup-v1/memory admin-guide/cgroup-v1/memory
134cgroup-v1/net_cls admin-guide/cgroup-v1/net_cls
135cgroup-v1/net_prio admin-guide/cgroup-v1/net_prio
136cgroup-v1/pids admin-guide/cgroup-v1/pids
137cgroup-v1/rdma admin-guide/cgroup-v1/rdma
138cma/debugfs admin-guide/mm/cma_debugfs
139connector/connector driver-api/connector
140console/console driver-api/console
141core-api/gcc-plugins kbuild/gcc-plugins
142core-api/ioctl driver-api/ioctl
143core-api/memory-hotplug-notifier core-api/memory-hotplug
144dev-tools/gdb-kernel-debugging process/debugging/gdb-kernel-debugging
145dev-tools/kgdb process/debugging/kgdb
146dev-tools/tools dev-tools/index
147development-process/1.Intro process/1.Intro
148development-process/2.Process process/2.Process
149development-process/3.Early-stage process/3.Early-stage
150development-process/4.Coding process/4.Coding
151development-process/5.Posting process/5.Posting
152development-process/6.Followthrough process/6.Followthrough
153development-process/7.AdvancedTopics process/7.AdvancedTopics
154development-process/8.Conclusion process/8.Conclusion
155development-process/development-process process/development-process
156development-process/index process/index
157device-mapper/cache admin-guide/device-mapper/cache
158device-mapper/cache-policies admin-guide/device-mapper/cache-policies
159device-mapper/delay admin-guide/device-mapper/delay
160device-mapper/dm-crypt admin-guide/device-mapper/dm-crypt
161device-mapper/dm-flakey admin-guide/device-mapper/dm-flakey
162device-mapper/dm-init admin-guide/device-mapper/dm-init
163device-mapper/dm-integrity admin-guide/device-mapper/dm-integrity
164device-mapper/dm-io admin-guide/device-mapper/dm-io
165device-mapper/dm-log admin-guide/device-mapper/dm-log
166device-mapper/dm-queue-length admin-guide/device-mapper/dm-queue-length
167device-mapper/dm-raid admin-guide/device-mapper/dm-raid
168device-mapper/dm-service-time admin-guide/device-mapper/dm-service-time
169device-mapper/dm-uevent admin-guide/device-mapper/dm-uevent
170device-mapper/dm-zoned admin-guide/device-mapper/dm-zoned
171device-mapper/era admin-guide/device-mapper/era
172device-mapper/index admin-guide/device-mapper/index
173device-mapper/kcopyd admin-guide/device-mapper/kcopyd
174device-mapper/linear admin-guide/device-mapper/linear
175device-mapper/log-writes admin-guide/device-mapper/log-writes
176device-mapper/persistent-data admin-guide/device-mapper/persistent-data
177device-mapper/snapshot admin-guide/device-mapper/snapshot
178device-mapper/statistics admin-guide/device-mapper/statistics
179device-mapper/striped admin-guide/device-mapper/striped
180device-mapper/switch admin-guide/device-mapper/switch
181device-mapper/thin-provisioning admin-guide/device-mapper/thin-provisioning
182device-mapper/unstriped admin-guide/device-mapper/unstriped
183device-mapper/verity admin-guide/device-mapper/verity
184device-mapper/writecache admin-guide/device-mapper/writecache
185device-mapper/zero admin-guide/device-mapper/zero
186devicetree/writing-schema devicetree/bindings/writing-schema
187driver-api/bt8xxgpio driver-api/gpio/bt8xxgpio
188driver-api/cxl/access-coordinates driver-api/cxl/linux/access-coordinates
189driver-api/cxl/memory-devices driver-api/cxl/theory-of-operation
190driver-api/dcdbas userspace-api/dcdbas
191driver-api/dell_rbu admin-guide/dell_rbu
192driver-api/edid admin-guide/edid
193driver-api/gpio driver-api/gpio/index
194driver-api/hte/tegra194-hte driver-api/hte/tegra-hte
195driver-api/isapnp userspace-api/isapnp
196driver-api/media/drivers/v4l-drivers/zoran driver-api/media/drivers/zoran
197driver-api/mtd/intel-spi driver-api/mtd/spi-intel
198driver-api/pci driver-api/pci/pci
199driver-api/pinctl driver-api/pin-control
200driver-api/rapidio admin-guide/rapidio
201driver-api/serial/moxa-smartio driver-api/tty/moxa-smartio
202driver-api/serial/n_gsm driver-api/tty/n_gsm
203driver-api/serial/tty driver-api/tty/tty_ldisc
204driver-api/thermal/intel_powerclamp admin-guide/thermal/intel_powerclamp
205driver-api/usb driver-api/usb/usb
206driver-model/binding driver-api/driver-model/binding
207driver-model/bus driver-api/driver-model/bus
208driver-model/design-patterns driver-api/driver-model/design-patterns
209driver-model/device driver-api/driver-model/device
210driver-model/devres driver-api/driver-model/devres
211driver-model/driver driver-api/driver-model/driver
212driver-model/index driver-api/driver-model/index
213driver-model/overview driver-api/driver-model/overview
214driver-model/platform driver-api/driver-model/platform
215driver-model/porting driver-api/driver-model/porting
216early-userspace/buffer-format driver-api/early-userspace/buffer-format
217early-userspace/early_userspace_support driver-api/early-userspace/early_userspace_support
218early-userspace/index driver-api/early-userspace/index
219errseq core-api/errseq
220filesystems/binderfs admin-guide/binderfs
221filesystems/cifs/cifsd filesystems/smb/ksmbd
222filesystems/cifs/cifsroot filesystems/smb/cifsroot
223filesystems/cifs/index filesystems/smb/index
224filesystems/cifs/ksmbd filesystems/smb/ksmbd
225filesystems/ext4/ext4 admin-guide/ext4
226filesystems/ext4/ondisk/about filesystems/ext4/about
227filesystems/ext4/ondisk/allocators filesystems/ext4/allocators
228filesystems/ext4/ondisk/attributes filesystems/ext4/attributes
229filesystems/ext4/ondisk/bigalloc filesystems/ext4/bigalloc
230filesystems/ext4/ondisk/bitmaps filesystems/ext4/bitmaps
231filesystems/ext4/ondisk/blockgroup filesystems/ext4/blockgroup
232filesystems/ext4/ondisk/blockmap filesystems/ext4/blockmap
233filesystems/ext4/ondisk/blocks filesystems/ext4/blocks
234filesystems/ext4/ondisk/checksums filesystems/ext4/checksums
235filesystems/ext4/ondisk/directory filesystems/ext4/directory
236filesystems/ext4/ondisk/dynamic filesystems/ext4/dynamic
237filesystems/ext4/ondisk/eainode filesystems/ext4/eainode
238filesystems/ext4/ondisk/globals filesystems/ext4/globals
239filesystems/ext4/ondisk/group_descr filesystems/ext4/group_descr
240filesystems/ext4/ondisk/ifork filesystems/ext4/ifork
241filesystems/ext4/ondisk/inlinedata filesystems/ext4/inlinedata
242filesystems/ext4/ondisk/inodes filesystems/ext4/inodes
243filesystems/ext4/ondisk/journal filesystems/ext4/journal
244filesystems/ext4/ondisk/mmp filesystems/ext4/mmp
245filesystems/ext4/ondisk/overview filesystems/ext4/overview
246filesystems/ext4/ondisk/special_inodes filesystems/ext4/special_inodes
247filesystems/ext4/ondisk/super filesystems/ext4/super
248filesystems/sysfs-pci PCI/sysfs-pci
249filesystems/sysfs-tagging networking/sysfs-tagging
250filesystems/xfs-delayed-logging-design filesystems/xfs/xfs-delayed-logging-design
251filesystems/xfs-maintainer-entry-profile filesystems/xfs/xfs-maintainer-entry-profile
252filesystems/xfs-online-fsck-design filesystems/xfs/xfs-online-fsck-design
253filesystems/xfs-self-describing-metadata filesystems/xfs/xfs-self-describing-metadata
254gpio/index admin-guide/gpio/index
255gpio/sysfs userspace-api/gpio/sysfs
256gpu/amdgpu gpu/amdgpu/index
257hte/hte driver-api/hte/hte
258hte/index driver-api/hte/index
259hte/tegra194-hte driver-api/hte/tegra-hte
260input/alps input/devices/alps
261input/amijoy input/devices/amijoy
262input/appletouch input/devices/appletouch
263input/atarikbd input/devices/atarikbd
264input/bcm5974 input/devices/bcm5974
265input/cma3000_d0x input/devices/cma3000_d0x
266input/cs461x input/devices/cs461x
267input/edt-ft5x06 input/devices/edt-ft5x06
268input/elantech input/devices/elantech
269input/iforce-protocol input/devices/iforce-protocol
270input/joystick input/joydev/joystick
271input/joystick-api input/joydev/joystick-api
272input/joystick-parport input/devices/joystick-parport
273input/ntrig input/devices/ntrig
274input/rotary-encoder input/devices/rotary-encoder
275input/sentelic input/devices/sentelic
276input/walkera0701 input/devices/walkera0701
277input/xpad input/devices/xpad
278input/yealink input/devices/yealink
279interconnect/interconnect driver-api/interconnect
280ioctl/botching-up-ioctls process/botching-up-ioctls
281ioctl/cdrom userspace-api/ioctl/cdrom
282ioctl/hdio userspace-api/ioctl/hdio
283ioctl/index userspace-api/ioctl/index
284ioctl/ioctl-decoding userspace-api/ioctl/ioctl-decoding
285ioctl/ioctl-number userspace-api/ioctl/ioctl-number
286kbuild/namespaces core-api/symbol-namespaces
287kdump/index admin-guide/kdump/index
288kdump/kdump admin-guide/kdump/kdump
289kdump/vmcoreinfo admin-guide/kdump/vmcoreinfo
290kernel-documentation doc-guide/kernel-doc
291laptops/asus-laptop admin-guide/laptops/asus-laptop
292laptops/disk-shock-protection admin-guide/laptops/disk-shock-protection
293laptops/index admin-guide/laptops/index
294laptops/laptop-mode admin-guide/laptops/laptop-mode
295laptops/lg-laptop admin-guide/laptops/lg-laptop
296laptops/sony-laptop admin-guide/laptops/sony-laptop
297laptops/sonypi admin-guide/laptops/sonypi
298laptops/thinkpad-acpi admin-guide/laptops/thinkpad-acpi
299laptops/toshiba_haps admin-guide/laptops/toshiba_haps
300loongarch/booting arch/loongarch/booting
301loongarch/features arch/loongarch/features
302loongarch/index arch/loongarch/index
303loongarch/introduction arch/loongarch/introduction
304loongarch/irq-chip-model arch/loongarch/irq-chip-model
305m68k/buddha-driver arch/m68k/buddha-driver
306m68k/features arch/m68k/features
307m68k/index arch/m68k/index
308m68k/kernel-options arch/m68k/kernel-options
309md/index driver-api/md/index
310md/md-cluster driver-api/md/md-cluster
311md/raid5-cache driver-api/md/raid5-cache
312md/raid5-ppl driver-api/md/raid5-ppl
313media/dvb-drivers/avermedia admin-guide/media/avermedia
314media/dvb-drivers/bt8xx admin-guide/media/bt8xx
315media/dvb-drivers/ci admin-guide/media/ci
316media/dvb-drivers/contributors driver-api/media/drivers/contributors
317media/dvb-drivers/dvb-usb driver-api/media/drivers/dvb-usb
318media/dvb-drivers/faq admin-guide/media/faq
319media/dvb-drivers/frontends driver-api/media/drivers/frontends
320media/dvb-drivers/index driver-api/media/drivers/index
321media/dvb-drivers/lmedm04 admin-guide/media/lmedm04
322media/dvb-drivers/opera-firmware admin-guide/media/opera-firmware
323media/dvb-drivers/technisat admin-guide/media/technisat
324media/dvb-drivers/ttusb-dec admin-guide/media/ttusb-dec
325media/intro userspace-api/media/intro
326media/kapi/cec-core driver-api/media/cec-core
327media/kapi/dtv-ca driver-api/media/dtv-ca
328media/kapi/dtv-common driver-api/media/dtv-common
329media/kapi/dtv-core driver-api/media/dtv-core
330media/kapi/dtv-demux driver-api/media/dtv-demux
331media/kapi/dtv-frontend driver-api/media/dtv-frontend
332media/kapi/dtv-net driver-api/media/dtv-net
333media/kapi/mc-core driver-api/media/mc-core
334media/kapi/rc-core driver-api/media/rc-core
335media/kapi/v4l2-async driver-api/media/v4l2-async
336media/kapi/v4l2-common driver-api/media/v4l2-common
337media/kapi/v4l2-controls driver-api/media/v4l2-controls
338media/kapi/v4l2-core driver-api/media/v4l2-core
339media/kapi/v4l2-dev driver-api/media/v4l2-dev
340media/kapi/v4l2-device driver-api/media/v4l2-device
341media/kapi/v4l2-dv-timings driver-api/media/v4l2-dv-timings
342media/kapi/v4l2-event driver-api/media/v4l2-event
343media/kapi/v4l2-fh driver-api/media/v4l2-fh
344media/kapi/v4l2-flash-led-class driver-api/media/v4l2-flash-led-class
345media/kapi/v4l2-fwnode driver-api/media/v4l2-fwnode
346media/kapi/v4l2-intro driver-api/media/v4l2-intro
347media/kapi/v4l2-mc driver-api/media/v4l2-mc
348media/kapi/v4l2-mediabus driver-api/media/v4l2-mediabus
349media/kapi/v4l2-mem2mem driver-api/media/v4l2-mem2mem
350media/kapi/v4l2-rect driver-api/media/v4l2-rect
351media/kapi/v4l2-subdev driver-api/media/v4l2-subdev
352media/kapi/v4l2-tuner driver-api/media/v4l2-tuner
353media/kapi/v4l2-tveeprom driver-api/media/v4l2-tveeprom
354media/kapi/v4l2-videobuf2 driver-api/media/v4l2-videobuf2
355media/media_kapi driver-api/media/index
356media/media_uapi userspace-api/media/index
357media/uapi/cec/cec-api userspace-api/media/cec/cec-api
358media/uapi/cec/cec-func-close userspace-api/media/cec/cec-func-close
359media/uapi/cec/cec-func-ioctl userspace-api/media/cec/cec-func-ioctl
360media/uapi/cec/cec-func-open userspace-api/media/cec/cec-func-open
361media/uapi/cec/cec-func-poll userspace-api/media/cec/cec-func-poll
362media/uapi/cec/cec-funcs userspace-api/media/cec/cec-funcs
363media/uapi/cec/cec-header userspace-api/media/cec/cec-header
364media/uapi/cec/cec-intro userspace-api/media/cec/cec-intro
365media/uapi/cec/cec-ioc-adap-g-caps userspace-api/media/cec/cec-ioc-adap-g-caps
366media/uapi/cec/cec-ioc-adap-g-conn-info userspace-api/media/cec/cec-ioc-adap-g-conn-info
367media/uapi/cec/cec-ioc-adap-g-log-addrs userspace-api/media/cec/cec-ioc-adap-g-log-addrs
368media/uapi/cec/cec-ioc-adap-g-phys-addr userspace-api/media/cec/cec-ioc-adap-g-phys-addr
369media/uapi/cec/cec-ioc-dqevent userspace-api/media/cec/cec-ioc-dqevent
370media/uapi/cec/cec-ioc-g-mode userspace-api/media/cec/cec-ioc-g-mode
371media/uapi/cec/cec-ioc-receive userspace-api/media/cec/cec-ioc-receive
372media/uapi/cec/cec-pin-error-inj userspace-api/media/cec/cec-pin-error-inj
373media/uapi/dvb/ca userspace-api/media/dvb/ca
374media/uapi/dvb/ca-fclose userspace-api/media/dvb/ca-fclose
375media/uapi/dvb/ca-fopen userspace-api/media/dvb/ca-fopen
376media/uapi/dvb/ca-get-cap userspace-api/media/dvb/ca-get-cap
377media/uapi/dvb/ca-get-descr-info userspace-api/media/dvb/ca-get-descr-info
378media/uapi/dvb/ca-get-msg userspace-api/media/dvb/ca-get-msg
379media/uapi/dvb/ca-get-slot-info userspace-api/media/dvb/ca-get-slot-info
380media/uapi/dvb/ca-reset userspace-api/media/dvb/ca-reset
381media/uapi/dvb/ca-send-msg userspace-api/media/dvb/ca-send-msg
382media/uapi/dvb/ca-set-descr userspace-api/media/dvb/ca-set-descr
383media/uapi/dvb/ca_data_types userspace-api/media/dvb/ca_data_types
384media/uapi/dvb/ca_function_calls userspace-api/media/dvb/ca_function_calls
385media/uapi/dvb/ca_high_level userspace-api/media/dvb/ca_high_level
386media/uapi/dvb/demux userspace-api/media/dvb/demux
387media/uapi/dvb/dmx-add-pid userspace-api/media/dvb/dmx-add-pid
388media/uapi/dvb/dmx-expbuf userspace-api/media/dvb/dmx-expbuf
389media/uapi/dvb/dmx-fclose userspace-api/media/dvb/dmx-fclose
390media/uapi/dvb/dmx-fopen userspace-api/media/dvb/dmx-fopen
391media/uapi/dvb/dmx-fread userspace-api/media/dvb/dmx-fread
392media/uapi/dvb/dmx-fwrite userspace-api/media/dvb/dmx-fwrite
393media/uapi/dvb/dmx-get-pes-pids userspace-api/media/dvb/dmx-get-pes-pids
394media/uapi/dvb/dmx-get-stc userspace-api/media/dvb/dmx-get-stc
395media/uapi/dvb/dmx-mmap userspace-api/media/dvb/dmx-mmap
396media/uapi/dvb/dmx-munmap userspace-api/media/dvb/dmx-munmap
397media/uapi/dvb/dmx-qbuf userspace-api/media/dvb/dmx-qbuf
398media/uapi/dvb/dmx-querybuf userspace-api/media/dvb/dmx-querybuf
399media/uapi/dvb/dmx-remove-pid userspace-api/media/dvb/dmx-remove-pid
400media/uapi/dvb/dmx-reqbufs userspace-api/media/dvb/dmx-reqbufs
401media/uapi/dvb/dmx-set-buffer-size userspace-api/media/dvb/dmx-set-buffer-size
402media/uapi/dvb/dmx-set-filter userspace-api/media/dvb/dmx-set-filter
403media/uapi/dvb/dmx-set-pes-filter userspace-api/media/dvb/dmx-set-pes-filter
404media/uapi/dvb/dmx-start userspace-api/media/dvb/dmx-start
405media/uapi/dvb/dmx-stop userspace-api/media/dvb/dmx-stop
406media/uapi/dvb/dmx_fcalls userspace-api/media/dvb/dmx_fcalls
407media/uapi/dvb/dmx_types userspace-api/media/dvb/dmx_types
408media/uapi/dvb/dvb-fe-read-status userspace-api/media/dvb/dvb-fe-read-status
409media/uapi/dvb/dvb-frontend-event userspace-api/media/dvb/dvb-frontend-event
410media/uapi/dvb/dvb-frontend-parameters userspace-api/media/dvb/dvb-frontend-parameters
411media/uapi/dvb/dvbapi userspace-api/media/dvb/dvbapi
412media/uapi/dvb/dvbproperty userspace-api/media/dvb/dvbproperty
413media/uapi/dvb/examples userspace-api/media/dvb/examples
414media/uapi/dvb/fe-bandwidth-t userspace-api/media/dvb/fe-bandwidth-t
415media/uapi/dvb/fe-diseqc-recv-slave-reply userspace-api/media/dvb/fe-diseqc-recv-slave-reply
416media/uapi/dvb/fe-diseqc-reset-overload userspace-api/media/dvb/fe-diseqc-reset-overload
417media/uapi/dvb/fe-diseqc-send-burst userspace-api/media/dvb/fe-diseqc-send-burst
418media/uapi/dvb/fe-diseqc-send-master-cmd userspace-api/media/dvb/fe-diseqc-send-master-cmd
419media/uapi/dvb/fe-dishnetwork-send-legacy-cmd userspace-api/media/dvb/fe-dishnetwork-send-legacy-cmd
420media/uapi/dvb/fe-enable-high-lnb-voltage userspace-api/media/dvb/fe-enable-high-lnb-voltage
421media/uapi/dvb/fe-get-event userspace-api/media/dvb/fe-get-event
422media/uapi/dvb/fe-get-frontend userspace-api/media/dvb/fe-get-frontend
423media/uapi/dvb/fe-get-info userspace-api/media/dvb/fe-get-info
424media/uapi/dvb/fe-get-property userspace-api/media/dvb/fe-get-property
425media/uapi/dvb/fe-read-ber userspace-api/media/dvb/fe-read-ber
426media/uapi/dvb/fe-read-signal-strength userspace-api/media/dvb/fe-read-signal-strength
427media/uapi/dvb/fe-read-snr userspace-api/media/dvb/fe-read-snr
428media/uapi/dvb/fe-read-status userspace-api/media/dvb/fe-read-status
429media/uapi/dvb/fe-read-uncorrected-blocks userspace-api/media/dvb/fe-read-uncorrected-blocks
430media/uapi/dvb/fe-set-frontend userspace-api/media/dvb/fe-set-frontend
431media/uapi/dvb/fe-set-frontend-tune-mode userspace-api/media/dvb/fe-set-frontend-tune-mode
432media/uapi/dvb/fe-set-tone userspace-api/media/dvb/fe-set-tone
433media/uapi/dvb/fe-set-voltage userspace-api/media/dvb/fe-set-voltage
434media/uapi/dvb/fe-type-t userspace-api/media/dvb/fe-type-t
435media/uapi/dvb/fe_property_parameters userspace-api/media/dvb/fe_property_parameters
436media/uapi/dvb/frontend userspace-api/media/dvb/frontend
437media/uapi/dvb/frontend-header userspace-api/media/dvb/frontend-header
438media/uapi/dvb/frontend-property-cable-systems userspace-api/media/dvb/frontend-property-cable-systems
439media/uapi/dvb/frontend-property-satellite-systems userspace-api/media/dvb/frontend-property-satellite-systems
440media/uapi/dvb/frontend-property-terrestrial-systems userspace-api/media/dvb/frontend-property-terrestrial-systems
441media/uapi/dvb/frontend-stat-properties userspace-api/media/dvb/frontend-stat-properties
442media/uapi/dvb/frontend_f_close userspace-api/media/dvb/frontend_f_close
443media/uapi/dvb/frontend_f_open userspace-api/media/dvb/frontend_f_open
444media/uapi/dvb/frontend_fcalls userspace-api/media/dvb/frontend_fcalls
445media/uapi/dvb/frontend_legacy_api userspace-api/media/dvb/frontend_legacy_api
446media/uapi/dvb/frontend_legacy_dvbv3_api userspace-api/media/dvb/frontend_legacy_dvbv3_api
447media/uapi/dvb/headers userspace-api/media/dvb/headers
448media/uapi/dvb/intro userspace-api/media/dvb/intro
449media/uapi/dvb/legacy_dvb_apis userspace-api/media/dvb/legacy_dvb_apis
450media/uapi/dvb/net userspace-api/media/dvb/net
451media/uapi/dvb/net-add-if userspace-api/media/dvb/net-add-if
452media/uapi/dvb/net-get-if userspace-api/media/dvb/net-get-if
453media/uapi/dvb/net-remove-if userspace-api/media/dvb/net-remove-if
454media/uapi/dvb/net-types userspace-api/media/dvb/net-types
455media/uapi/dvb/query-dvb-frontend-info userspace-api/media/dvb/query-dvb-frontend-info
456media/uapi/fdl-appendix userspace-api/media/fdl-appendix
457media/uapi/gen-errors userspace-api/media/gen-errors
458media/uapi/mediactl/media-controller userspace-api/media/mediactl/media-controller
459media/uapi/mediactl/media-controller-intro userspace-api/media/mediactl/media-controller-intro
460media/uapi/mediactl/media-controller-model userspace-api/media/mediactl/media-controller-model
461media/uapi/mediactl/media-func-close userspace-api/media/mediactl/media-func-close
462media/uapi/mediactl/media-func-ioctl userspace-api/media/mediactl/media-func-ioctl
463media/uapi/mediactl/media-func-open userspace-api/media/mediactl/media-func-open
464media/uapi/mediactl/media-funcs userspace-api/media/mediactl/media-funcs
465media/uapi/mediactl/media-header userspace-api/media/mediactl/media-header
466media/uapi/mediactl/media-ioc-device-info userspace-api/media/mediactl/media-ioc-device-info
467media/uapi/mediactl/media-ioc-enum-entities userspace-api/media/mediactl/media-ioc-enum-entities
468media/uapi/mediactl/media-ioc-enum-links userspace-api/media/mediactl/media-ioc-enum-links
469media/uapi/mediactl/media-ioc-g-topology userspace-api/media/mediactl/media-ioc-g-topology
470media/uapi/mediactl/media-ioc-request-alloc userspace-api/media/mediactl/media-ioc-request-alloc
471media/uapi/mediactl/media-ioc-setup-link userspace-api/media/mediactl/media-ioc-setup-link
472media/uapi/mediactl/media-request-ioc-queue userspace-api/media/mediactl/media-request-ioc-queue
473media/uapi/mediactl/media-request-ioc-reinit userspace-api/media/mediactl/media-request-ioc-reinit
474media/uapi/mediactl/media-types userspace-api/media/mediactl/media-types
475media/uapi/mediactl/request-api userspace-api/media/mediactl/request-api
476media/uapi/mediactl/request-func-close userspace-api/media/mediactl/request-func-close
477media/uapi/mediactl/request-func-ioctl userspace-api/media/mediactl/request-func-ioctl
478media/uapi/mediactl/request-func-poll userspace-api/media/mediactl/request-func-poll
479media/uapi/rc/keytable.c userspace-api/media/rc/keytable.c
480media/uapi/rc/lirc-dev userspace-api/media/rc/lirc-dev
481media/uapi/rc/lirc-dev-intro userspace-api/media/rc/lirc-dev-intro
482media/uapi/rc/lirc-func userspace-api/media/rc/lirc-func
483media/uapi/rc/lirc-get-features userspace-api/media/rc/lirc-get-features
484media/uapi/rc/lirc-get-rec-mode userspace-api/media/rc/lirc-get-rec-mode
485media/uapi/rc/lirc-get-rec-resolution userspace-api/media/rc/lirc-get-rec-resolution
486media/uapi/rc/lirc-get-send-mode userspace-api/media/rc/lirc-get-send-mode
487media/uapi/rc/lirc-get-timeout userspace-api/media/rc/lirc-get-timeout
488media/uapi/rc/lirc-header userspace-api/media/rc/lirc-header
489media/uapi/rc/lirc-read userspace-api/media/rc/lirc-read
490media/uapi/rc/lirc-set-measure-carrier-mode userspace-api/media/rc/lirc-set-measure-carrier-mode
491media/uapi/rc/lirc-set-rec-carrier userspace-api/media/rc/lirc-set-rec-carrier
492media/uapi/rc/lirc-set-rec-carrier-range userspace-api/media/rc/lirc-set-rec-carrier-range
493media/uapi/rc/lirc-set-rec-timeout userspace-api/media/rc/lirc-set-rec-timeout
494media/uapi/rc/lirc-set-send-carrier userspace-api/media/rc/lirc-set-send-carrier
495media/uapi/rc/lirc-set-send-duty-cycle userspace-api/media/rc/lirc-set-send-duty-cycle
496media/uapi/rc/lirc-set-transmitter-mask userspace-api/media/rc/lirc-set-transmitter-mask
497media/uapi/rc/lirc-set-wideband-receiver userspace-api/media/rc/lirc-set-wideband-receiver
498media/uapi/rc/lirc-write userspace-api/media/rc/lirc-write
499media/uapi/rc/rc-intro userspace-api/media/rc/rc-intro
500media/uapi/rc/rc-protos userspace-api/media/rc/rc-protos
501media/uapi/rc/rc-sysfs-nodes userspace-api/media/rc/rc-sysfs-nodes
502media/uapi/rc/rc-table-change userspace-api/media/rc/rc-table-change
503media/uapi/rc/rc-tables userspace-api/media/rc/rc-tables
504media/uapi/rc/remote_controllers userspace-api/media/rc/remote_controllers
505media/uapi/v4l/app-pri userspace-api/media/v4l/app-pri
506media/uapi/v4l/audio userspace-api/media/v4l/audio
507media/uapi/v4l/biblio userspace-api/media/v4l/biblio
508media/uapi/v4l/buffer userspace-api/media/v4l/buffer
509media/uapi/v4l/capture-example userspace-api/media/v4l/capture-example
510media/uapi/v4l/capture.c userspace-api/media/v4l/capture.c
511media/uapi/v4l/colorspaces userspace-api/media/v4l/colorspaces
512media/uapi/v4l/colorspaces-defs userspace-api/media/v4l/colorspaces-defs
513media/uapi/v4l/colorspaces-details userspace-api/media/v4l/colorspaces-details
514media/uapi/v4l/common userspace-api/media/v4l/common
515media/uapi/v4l/common-defs userspace-api/media/v4l/common-defs
516media/uapi/v4l/compat userspace-api/media/v4l/compat
517media/uapi/v4l/control userspace-api/media/v4l/control
518media/uapi/v4l/crop userspace-api/media/v4l/crop
519media/uapi/v4l/depth-formats userspace-api/media/v4l/depth-formats
520media/uapi/v4l/dev-capture userspace-api/media/v4l/dev-capture
521media/uapi/v4l/dev-codec userspace-api/media/v4l/dev-mem2mem
522media/uapi/v4l/dev-decoder userspace-api/media/v4l/dev-decoder
523media/uapi/v4l/dev-event userspace-api/media/v4l/dev-event
524media/uapi/v4l/dev-mem2mem userspace-api/media/v4l/dev-mem2mem
525media/uapi/v4l/dev-meta userspace-api/media/v4l/dev-meta
526media/uapi/v4l/dev-osd userspace-api/media/v4l/dev-osd
527media/uapi/v4l/dev-output userspace-api/media/v4l/dev-output
528media/uapi/v4l/dev-overlay userspace-api/media/v4l/dev-overlay
529media/uapi/v4l/dev-radio userspace-api/media/v4l/dev-radio
530media/uapi/v4l/dev-raw-vbi userspace-api/media/v4l/dev-raw-vbi
531media/uapi/v4l/dev-rds userspace-api/media/v4l/dev-rds
532media/uapi/v4l/dev-sdr userspace-api/media/v4l/dev-sdr
533media/uapi/v4l/dev-sliced-vbi userspace-api/media/v4l/dev-sliced-vbi
534media/uapi/v4l/dev-stateless-decoder userspace-api/media/v4l/dev-stateless-decoder
535media/uapi/v4l/dev-subdev userspace-api/media/v4l/dev-subdev
536media/uapi/v4l/dev-touch userspace-api/media/v4l/dev-touch
537media/uapi/v4l/devices userspace-api/media/v4l/devices
538media/uapi/v4l/diff-v4l userspace-api/media/v4l/diff-v4l
539media/uapi/v4l/dmabuf userspace-api/media/v4l/dmabuf
540media/uapi/v4l/dv-timings userspace-api/media/v4l/dv-timings
541media/uapi/v4l/ext-ctrls-camera userspace-api/media/v4l/ext-ctrls-camera
542media/uapi/v4l/ext-ctrls-codec userspace-api/media/v4l/ext-ctrls-codec
543media/uapi/v4l/ext-ctrls-detect userspace-api/media/v4l/ext-ctrls-detect
544media/uapi/v4l/ext-ctrls-dv userspace-api/media/v4l/ext-ctrls-dv
545media/uapi/v4l/ext-ctrls-flash userspace-api/media/v4l/ext-ctrls-flash
546media/uapi/v4l/ext-ctrls-fm-rx userspace-api/media/v4l/ext-ctrls-fm-rx
547media/uapi/v4l/ext-ctrls-fm-tx userspace-api/media/v4l/ext-ctrls-fm-tx
548media/uapi/v4l/ext-ctrls-image-process userspace-api/media/v4l/ext-ctrls-image-process
549media/uapi/v4l/ext-ctrls-image-source userspace-api/media/v4l/ext-ctrls-image-source
550media/uapi/v4l/ext-ctrls-jpeg userspace-api/media/v4l/ext-ctrls-jpeg
551media/uapi/v4l/ext-ctrls-rf-tuner userspace-api/media/v4l/ext-ctrls-rf-tuner
552media/uapi/v4l/extended-controls userspace-api/media/v4l/extended-controls
553media/uapi/v4l/field-order userspace-api/media/v4l/field-order
554media/uapi/v4l/format userspace-api/media/v4l/format
555media/uapi/v4l/func-close userspace-api/media/v4l/func-close
556media/uapi/v4l/func-ioctl userspace-api/media/v4l/func-ioctl
557media/uapi/v4l/func-mmap userspace-api/media/v4l/func-mmap
558media/uapi/v4l/func-munmap userspace-api/media/v4l/func-munmap
559media/uapi/v4l/func-open userspace-api/media/v4l/func-open
560media/uapi/v4l/func-poll userspace-api/media/v4l/func-poll
561media/uapi/v4l/func-read userspace-api/media/v4l/func-read
562media/uapi/v4l/func-select userspace-api/media/v4l/func-select
563media/uapi/v4l/func-write userspace-api/media/v4l/func-write
564media/uapi/v4l/hist-v4l2 userspace-api/media/v4l/hist-v4l2
565media/uapi/v4l/hsv-formats userspace-api/media/v4l/hsv-formats
566media/uapi/v4l/io userspace-api/media/v4l/io
567media/uapi/v4l/libv4l userspace-api/media/v4l/libv4l
568media/uapi/v4l/libv4l-introduction userspace-api/media/v4l/libv4l-introduction
569media/uapi/v4l/meta-formats userspace-api/media/v4l/meta-formats
570media/uapi/v4l/mmap userspace-api/media/v4l/mmap
571media/uapi/v4l/open userspace-api/media/v4l/open
572media/uapi/v4l/pixfmt userspace-api/media/v4l/pixfmt
573media/uapi/v4l/pixfmt-002 userspace-api/media/v4l/pixfmt-v4l2
574media/uapi/v4l/pixfmt-003 userspace-api/media/v4l/pixfmt-v4l2-mplane
575media/uapi/v4l/pixfmt-004 userspace-api/media/v4l/pixfmt-intro
576media/uapi/v4l/pixfmt-006 userspace-api/media/v4l/colorspaces-defs
577media/uapi/v4l/pixfmt-007 userspace-api/media/v4l/colorspaces-details
578media/uapi/v4l/pixfmt-013 userspace-api/media/v4l/pixfmt-compressed
579media/uapi/v4l/pixfmt-bayer userspace-api/media/v4l/pixfmt-bayer
580media/uapi/v4l/pixfmt-cnf4 userspace-api/media/v4l/pixfmt-cnf4
581media/uapi/v4l/pixfmt-compressed userspace-api/media/v4l/pixfmt-compressed
582media/uapi/v4l/pixfmt-indexed userspace-api/media/v4l/pixfmt-indexed
583media/uapi/v4l/pixfmt-intro userspace-api/media/v4l/pixfmt-intro
584media/uapi/v4l/pixfmt-inzi userspace-api/media/v4l/pixfmt-inzi
585media/uapi/v4l/pixfmt-m420 userspace-api/media/v4l/pixfmt-m420
586media/uapi/v4l/pixfmt-meta-d4xx userspace-api/media/v4l/metafmt-d4xx
587media/uapi/v4l/pixfmt-meta-intel-ipu3 userspace-api/media/v4l/metafmt-intel-ipu3
588media/uapi/v4l/pixfmt-meta-uvc userspace-api/media/v4l/metafmt-uvc
589media/uapi/v4l/pixfmt-meta-vivid userspace-api/media/v4l/metafmt-vivid
590media/uapi/v4l/pixfmt-meta-vsp1-hgo userspace-api/media/v4l/metafmt-vsp1-hgo
591media/uapi/v4l/pixfmt-meta-vsp1-hgt userspace-api/media/v4l/metafmt-vsp1-hgt
592media/uapi/v4l/pixfmt-packed-hsv userspace-api/media/v4l/pixfmt-packed-hsv
593media/uapi/v4l/pixfmt-packed-yuv userspace-api/media/v4l/pixfmt-packed-yuv
594media/uapi/v4l/pixfmt-reserved userspace-api/media/v4l/pixfmt-reserved
595media/uapi/v4l/pixfmt-rgb userspace-api/media/v4l/pixfmt-rgb
596media/uapi/v4l/pixfmt-sbggr16 userspace-api/media/v4l/pixfmt-srggb16
597media/uapi/v4l/pixfmt-sdr-cs08 userspace-api/media/v4l/pixfmt-sdr-cs08
598media/uapi/v4l/pixfmt-sdr-cs14le userspace-api/media/v4l/pixfmt-sdr-cs14le
599media/uapi/v4l/pixfmt-sdr-cu08 userspace-api/media/v4l/pixfmt-sdr-cu08
600media/uapi/v4l/pixfmt-sdr-cu16le userspace-api/media/v4l/pixfmt-sdr-cu16le
601media/uapi/v4l/pixfmt-sdr-pcu16be userspace-api/media/v4l/pixfmt-sdr-pcu16be
602media/uapi/v4l/pixfmt-sdr-pcu18be userspace-api/media/v4l/pixfmt-sdr-pcu18be
603media/uapi/v4l/pixfmt-sdr-pcu20be userspace-api/media/v4l/pixfmt-sdr-pcu20be
604media/uapi/v4l/pixfmt-sdr-ru12le userspace-api/media/v4l/pixfmt-sdr-ru12le
605media/uapi/v4l/pixfmt-srggb10 userspace-api/media/v4l/pixfmt-srggb10
606media/uapi/v4l/pixfmt-srggb10-ipu3 userspace-api/media/v4l/pixfmt-srggb10-ipu3
607media/uapi/v4l/pixfmt-srggb10alaw8 userspace-api/media/v4l/pixfmt-srggb10alaw8
608media/uapi/v4l/pixfmt-srggb10dpcm8 userspace-api/media/v4l/pixfmt-srggb10dpcm8
609media/uapi/v4l/pixfmt-srggb10p userspace-api/media/v4l/pixfmt-srggb10p
610media/uapi/v4l/pixfmt-srggb12 userspace-api/media/v4l/pixfmt-srggb12
611media/uapi/v4l/pixfmt-srggb12p userspace-api/media/v4l/pixfmt-srggb12p
612media/uapi/v4l/pixfmt-srggb14 userspace-api/media/v4l/pixfmt-srggb14
613media/uapi/v4l/pixfmt-srggb14p userspace-api/media/v4l/pixfmt-srggb14p
614media/uapi/v4l/pixfmt-srggb16 userspace-api/media/v4l/pixfmt-srggb16
615media/uapi/v4l/pixfmt-srggb8 userspace-api/media/v4l/pixfmt-srggb8
616media/uapi/v4l/pixfmt-tch-td08 userspace-api/media/v4l/pixfmt-tch-td08
617media/uapi/v4l/pixfmt-tch-td16 userspace-api/media/v4l/pixfmt-tch-td16
618media/uapi/v4l/pixfmt-tch-tu08 userspace-api/media/v4l/pixfmt-tch-tu08
619media/uapi/v4l/pixfmt-tch-tu16 userspace-api/media/v4l/pixfmt-tch-tu16
620media/uapi/v4l/pixfmt-uv8 userspace-api/media/v4l/pixfmt-uv8
621media/uapi/v4l/pixfmt-v4l2 userspace-api/media/v4l/pixfmt-v4l2
622media/uapi/v4l/pixfmt-v4l2-mplane userspace-api/media/v4l/pixfmt-v4l2-mplane
623media/uapi/v4l/pixfmt-y12i userspace-api/media/v4l/pixfmt-y12i
624media/uapi/v4l/pixfmt-y8i userspace-api/media/v4l/pixfmt-y8i
625media/uapi/v4l/pixfmt-z16 userspace-api/media/v4l/pixfmt-z16
626media/uapi/v4l/planar-apis userspace-api/media/v4l/planar-apis
627media/uapi/v4l/querycap userspace-api/media/v4l/querycap
628media/uapi/v4l/rw userspace-api/media/v4l/rw
629media/uapi/v4l/sdr-formats userspace-api/media/v4l/sdr-formats
630media/uapi/v4l/selection-api userspace-api/media/v4l/selection-api
631media/uapi/v4l/selection-api-002 userspace-api/media/v4l/selection-api-intro
632media/uapi/v4l/selection-api-003 userspace-api/media/v4l/selection-api-targets
633media/uapi/v4l/selection-api-004 userspace-api/media/v4l/selection-api-configuration
634media/uapi/v4l/selection-api-005 userspace-api/media/v4l/selection-api-vs-crop-api
635media/uapi/v4l/selection-api-006 userspace-api/media/v4l/selection-api-examples
636media/uapi/v4l/selection-api-configuration userspace-api/media/v4l/selection-api-configuration
637media/uapi/v4l/selection-api-examples userspace-api/media/v4l/selection-api-examples
638media/uapi/v4l/selection-api-intro userspace-api/media/v4l/selection-api-intro
639media/uapi/v4l/selection-api-targets userspace-api/media/v4l/selection-api-targets
640media/uapi/v4l/selection-api-vs-crop-api userspace-api/media/v4l/selection-api-vs-crop-api
641media/uapi/v4l/selections-common userspace-api/media/v4l/selections-common
642media/uapi/v4l/standard userspace-api/media/v4l/standard
643media/uapi/v4l/streaming-par userspace-api/media/v4l/streaming-par
644media/uapi/v4l/subdev-formats userspace-api/media/v4l/subdev-formats
645media/uapi/v4l/tch-formats userspace-api/media/v4l/tch-formats
646media/uapi/v4l/tuner userspace-api/media/v4l/tuner
647media/uapi/v4l/user-func userspace-api/media/v4l/user-func
648media/uapi/v4l/userp userspace-api/media/v4l/userp
649media/uapi/v4l/v4l2 userspace-api/media/v4l/v4l2
650media/uapi/v4l/v4l2-selection-flags userspace-api/media/v4l/v4l2-selection-flags
651media/uapi/v4l/v4l2-selection-targets userspace-api/media/v4l/v4l2-selection-targets
652media/uapi/v4l/v4l2grab-example userspace-api/media/v4l/v4l2grab-example
653media/uapi/v4l/v4l2grab.c userspace-api/media/v4l/v4l2grab.c
654media/uapi/v4l/video userspace-api/media/v4l/video
655media/uapi/v4l/videodev userspace-api/media/v4l/videodev
656media/uapi/v4l/vidioc-create-bufs userspace-api/media/v4l/vidioc-create-bufs
657media/uapi/v4l/vidioc-cropcap userspace-api/media/v4l/vidioc-cropcap
658media/uapi/v4l/vidioc-dbg-g-chip-info userspace-api/media/v4l/vidioc-dbg-g-chip-info
659media/uapi/v4l/vidioc-dbg-g-register userspace-api/media/v4l/vidioc-dbg-g-register
660media/uapi/v4l/vidioc-decoder-cmd userspace-api/media/v4l/vidioc-decoder-cmd
661media/uapi/v4l/vidioc-dqevent userspace-api/media/v4l/vidioc-dqevent
662media/uapi/v4l/vidioc-dv-timings-cap userspace-api/media/v4l/vidioc-dv-timings-cap
663media/uapi/v4l/vidioc-encoder-cmd userspace-api/media/v4l/vidioc-encoder-cmd
664media/uapi/v4l/vidioc-enum-dv-timings userspace-api/media/v4l/vidioc-enum-dv-timings
665media/uapi/v4l/vidioc-enum-fmt userspace-api/media/v4l/vidioc-enum-fmt
666media/uapi/v4l/vidioc-enum-frameintervals userspace-api/media/v4l/vidioc-enum-frameintervals
667media/uapi/v4l/vidioc-enum-framesizes userspace-api/media/v4l/vidioc-enum-framesizes
668media/uapi/v4l/vidioc-enum-freq-bands userspace-api/media/v4l/vidioc-enum-freq-bands
669media/uapi/v4l/vidioc-enumaudio userspace-api/media/v4l/vidioc-enumaudio
670media/uapi/v4l/vidioc-enumaudioout userspace-api/media/v4l/vidioc-enumaudioout
671media/uapi/v4l/vidioc-enuminput userspace-api/media/v4l/vidioc-enuminput
672media/uapi/v4l/vidioc-enumoutput userspace-api/media/v4l/vidioc-enumoutput
673media/uapi/v4l/vidioc-enumstd userspace-api/media/v4l/vidioc-enumstd
674media/uapi/v4l/vidioc-expbuf userspace-api/media/v4l/vidioc-expbuf
675media/uapi/v4l/vidioc-g-audio userspace-api/media/v4l/vidioc-g-audio
676media/uapi/v4l/vidioc-g-audioout userspace-api/media/v4l/vidioc-g-audioout
677media/uapi/v4l/vidioc-g-crop userspace-api/media/v4l/vidioc-g-crop
678media/uapi/v4l/vidioc-g-ctrl userspace-api/media/v4l/vidioc-g-ctrl
679media/uapi/v4l/vidioc-g-dv-timings userspace-api/media/v4l/vidioc-g-dv-timings
680media/uapi/v4l/vidioc-g-edid userspace-api/media/v4l/vidioc-g-edid
681media/uapi/v4l/vidioc-g-enc-index userspace-api/media/v4l/vidioc-g-enc-index
682media/uapi/v4l/vidioc-g-ext-ctrls userspace-api/media/v4l/vidioc-g-ext-ctrls
683media/uapi/v4l/vidioc-g-fbuf userspace-api/media/v4l/vidioc-g-fbuf
684media/uapi/v4l/vidioc-g-fmt userspace-api/media/v4l/vidioc-g-fmt
685media/uapi/v4l/vidioc-g-frequency userspace-api/media/v4l/vidioc-g-frequency
686media/uapi/v4l/vidioc-g-input userspace-api/media/v4l/vidioc-g-input
687media/uapi/v4l/vidioc-g-jpegcomp userspace-api/media/v4l/vidioc-g-jpegcomp
688media/uapi/v4l/vidioc-g-modulator userspace-api/media/v4l/vidioc-g-modulator
689media/uapi/v4l/vidioc-g-output userspace-api/media/v4l/vidioc-g-output
690media/uapi/v4l/vidioc-g-parm userspace-api/media/v4l/vidioc-g-parm
691media/uapi/v4l/vidioc-g-priority userspace-api/media/v4l/vidioc-g-priority
692media/uapi/v4l/vidioc-g-selection userspace-api/media/v4l/vidioc-g-selection
693media/uapi/v4l/vidioc-g-sliced-vbi-cap userspace-api/media/v4l/vidioc-g-sliced-vbi-cap
694media/uapi/v4l/vidioc-g-std userspace-api/media/v4l/vidioc-g-std
695media/uapi/v4l/vidioc-g-tuner userspace-api/media/v4l/vidioc-g-tuner
696media/uapi/v4l/vidioc-log-status userspace-api/media/v4l/vidioc-log-status
697media/uapi/v4l/vidioc-overlay userspace-api/media/v4l/vidioc-overlay
698media/uapi/v4l/vidioc-prepare-buf userspace-api/media/v4l/vidioc-prepare-buf
699media/uapi/v4l/vidioc-qbuf userspace-api/media/v4l/vidioc-qbuf
700media/uapi/v4l/vidioc-query-dv-timings userspace-api/media/v4l/vidioc-query-dv-timings
701media/uapi/v4l/vidioc-querybuf userspace-api/media/v4l/vidioc-querybuf
702media/uapi/v4l/vidioc-querycap userspace-api/media/v4l/vidioc-querycap
703media/uapi/v4l/vidioc-queryctrl userspace-api/media/v4l/vidioc-queryctrl
704media/uapi/v4l/vidioc-querystd userspace-api/media/v4l/vidioc-querystd
705media/uapi/v4l/vidioc-reqbufs userspace-api/media/v4l/vidioc-reqbufs
706media/uapi/v4l/vidioc-s-hw-freq-seek userspace-api/media/v4l/vidioc-s-hw-freq-seek
707media/uapi/v4l/vidioc-streamon userspace-api/media/v4l/vidioc-streamon
708media/uapi/v4l/vidioc-subdev-enum-frame-interval userspace-api/media/v4l/vidioc-subdev-enum-frame-interval
709media/uapi/v4l/vidioc-subdev-enum-frame-size userspace-api/media/v4l/vidioc-subdev-enum-frame-size
710media/uapi/v4l/vidioc-subdev-enum-mbus-code userspace-api/media/v4l/vidioc-subdev-enum-mbus-code
711media/uapi/v4l/vidioc-subdev-g-crop userspace-api/media/v4l/vidioc-subdev-g-crop
712media/uapi/v4l/vidioc-subdev-g-fmt userspace-api/media/v4l/vidioc-subdev-g-fmt
713media/uapi/v4l/vidioc-subdev-g-frame-interval userspace-api/media/v4l/vidioc-subdev-g-frame-interval
714media/uapi/v4l/vidioc-subdev-g-selection userspace-api/media/v4l/vidioc-subdev-g-selection
715media/uapi/v4l/vidioc-subscribe-event userspace-api/media/v4l/vidioc-subscribe-event
716media/uapi/v4l/yuv-formats userspace-api/media/v4l/yuv-formats
717media/v4l-drivers/au0828-cardlist admin-guide/media/au0828-cardlist
718media/v4l-drivers/bttv admin-guide/media/bttv
719media/v4l-drivers/bttv-cardlist admin-guide/media/bttv-cardlist
720media/v4l-drivers/bttv-devel driver-api/media/drivers/bttv-devel
721media/v4l-drivers/cafe_ccic admin-guide/media/cafe_ccic
722media/v4l-drivers/cardlist admin-guide/media/cardlist
723media/v4l-drivers/cx2341x driver-api/media/drivers/cx2341x-devel
724media/v4l-drivers/cx2341x-devel driver-api/media/drivers/cx2341x-devel
725media/v4l-drivers/cx2341x-uapi userspace-api/media/drivers/cx2341x-uapi
726media/v4l-drivers/cx23885-cardlist admin-guide/media/cx23885-cardlist
727media/v4l-drivers/cx88 admin-guide/media/cx88
728media/v4l-drivers/cx88-cardlist admin-guide/media/cx88-cardlist
729media/v4l-drivers/cx88-devel driver-api/media/drivers/cx88-devel
730media/v4l-drivers/em28xx-cardlist admin-guide/media/em28xx-cardlist
731media/v4l-drivers/fimc admin-guide/media/fimc
732media/v4l-drivers/fimc-devel driver-api/media/drivers/fimc-devel
733media/v4l-drivers/fourcc userspace-api/media/v4l/fourcc
734media/v4l-drivers/gspca-cardlist admin-guide/media/gspca-cardlist
735media/v4l-drivers/imx admin-guide/media/imx
736media/v4l-drivers/imx-uapi userspace-api/media/drivers/imx-uapi
737media/v4l-drivers/imx7 admin-guide/media/imx7
738media/v4l-drivers/index userspace-api/media/drivers/index
739media/v4l-drivers/ipu3 admin-guide/media/ipu3
740media/v4l-drivers/ivtv admin-guide/media/ivtv
741media/v4l-drivers/ivtv-cardlist admin-guide/media/ivtv-cardlist
742media/v4l-drivers/max2175 userspace-api/media/drivers/max2175
743media/v4l-drivers/omap3isp admin-guide/media/omap3isp
744media/v4l-drivers/omap3isp-uapi userspace-api/media/drivers/omap3isp-uapi
745media/v4l-drivers/philips admin-guide/media/philips
746media/v4l-drivers/pvrusb2 driver-api/media/drivers/pvrusb2
747media/v4l-drivers/pxa_camera driver-api/media/drivers/pxa_camera
748media/v4l-drivers/qcom_camss admin-guide/media/qcom_camss
749media/v4l-drivers/radiotrack driver-api/media/drivers/radiotrack
750media/v4l-drivers/rcar-fdp1 admin-guide/media/rcar-fdp1
751media/v4l-drivers/saa7134 admin-guide/media/saa7134
752media/v4l-drivers/saa7134-cardlist admin-guide/media/saa7134-cardlist
753media/v4l-drivers/saa7134-devel driver-api/media/drivers/saa7134-devel
754media/v4l-drivers/saa7164-cardlist admin-guide/media/saa7164-cardlist
755media/v4l-drivers/sh_mobile_ceu_camera driver-api/media/drivers/sh_mobile_ceu_camera
756media/v4l-drivers/si470x admin-guide/media/si470x
757media/v4l-drivers/si4713 admin-guide/media/si4713
758media/v4l-drivers/si476x admin-guide/media/si476x
759media/v4l-drivers/tuner-cardlist admin-guide/media/tuner-cardlist
760media/v4l-drivers/tuners driver-api/media/drivers/tuners
761media/v4l-drivers/uvcvideo userspace-api/media/drivers/uvcvideo
762media/v4l-drivers/v4l-with-ir admin-guide/media/remote-controller
763media/v4l-drivers/vimc admin-guide/media/vimc
764media/v4l-drivers/vimc-devel driver-api/media/drivers/vimc-devel
765media/v4l-drivers/vivid admin-guide/media/vivid
766media/v4l-drivers/zoran driver-api/media/drivers/zoran
767memory-devices/ti-emif driver-api/memory-devices/ti-emif
768mips/booting arch/mips/booting
769mips/features arch/mips/features
770mips/index arch/mips/index
771mips/ingenic-tcu arch/mips/ingenic-tcu
772mm/slub admin-guide/mm/slab
773mmc/index driver-api/mmc/index
774mmc/mmc-async-req driver-api/mmc/mmc-async-req
775mmc/mmc-dev-attrs driver-api/mmc/mmc-dev-attrs
776mmc/mmc-dev-parts driver-api/mmc/mmc-dev-parts
777mmc/mmc-tools driver-api/mmc/mmc-tools
778mtd/index driver-api/mtd/index
779mtd/intel-spi driver-api/mtd/spi-intel
780mtd/nand_ecc driver-api/mtd/nand_ecc
781mtd/spi-nor driver-api/mtd/spi-nor
782namespaces/compatibility-list admin-guide/namespaces/compatibility-list
783namespaces/index admin-guide/namespaces/index
784namespaces/resource-control admin-guide/namespaces/resource-control
785networking/altera_tse networking/device_drivers/ethernet/altera/altera_tse
786networking/baycom networking/device_drivers/hamradio/baycom
787networking/bpf_flow_dissector bpf/prog_flow_dissector
788networking/cxacru networking/device_drivers/atm/cxacru
789networking/defza networking/device_drivers/fddi/defza
790networking/device_drivers/3com/3c509 networking/device_drivers/ethernet/3com/3c509
791networking/device_drivers/3com/vortex networking/device_drivers/ethernet/3com/vortex
792networking/device_drivers/amazon/ena networking/device_drivers/ethernet/amazon/ena
793networking/device_drivers/aquantia/atlantic networking/device_drivers/ethernet/aquantia/atlantic
794networking/device_drivers/chelsio/cxgb networking/device_drivers/ethernet/chelsio/cxgb
795networking/device_drivers/cirrus/cs89x0 networking/device_drivers/ethernet/cirrus/cs89x0
796networking/device_drivers/davicom/dm9000 networking/device_drivers/ethernet/davicom/dm9000
797networking/device_drivers/dec/dmfe networking/device_drivers/ethernet/dec/dmfe
798networking/device_drivers/dlink/dl2k networking/device_drivers/ethernet/dlink/dl2k
799networking/device_drivers/freescale/dpaa networking/device_drivers/ethernet/freescale/dpaa
800networking/device_drivers/freescale/dpaa2/dpio-driver networking/device_drivers/ethernet/freescale/dpaa2/dpio-driver
801networking/device_drivers/freescale/dpaa2/ethernet-driver networking/device_drivers/ethernet/freescale/dpaa2/ethernet-driver
802networking/device_drivers/freescale/dpaa2/index networking/device_drivers/ethernet/freescale/dpaa2/index
803networking/device_drivers/freescale/dpaa2/mac-phy-support networking/device_drivers/ethernet/freescale/dpaa2/mac-phy-support
804networking/device_drivers/freescale/dpaa2/overview networking/device_drivers/ethernet/freescale/dpaa2/overview
805networking/device_drivers/freescale/gianfar networking/device_drivers/ethernet/freescale/gianfar
806networking/device_drivers/google/gve networking/device_drivers/ethernet/google/gve
807networking/device_drivers/intel/e100 networking/device_drivers/ethernet/intel/e100
808networking/device_drivers/intel/e1000 networking/device_drivers/ethernet/intel/e1000
809networking/device_drivers/intel/e1000e networking/device_drivers/ethernet/intel/e1000e
810networking/device_drivers/intel/fm10k networking/device_drivers/ethernet/intel/fm10k
811networking/device_drivers/intel/i40e networking/device_drivers/ethernet/intel/i40e
812networking/device_drivers/intel/iavf networking/device_drivers/ethernet/intel/iavf
813networking/device_drivers/intel/ice networking/device_drivers/ethernet/intel/ice
814networking/device_drivers/intel/igb networking/device_drivers/ethernet/intel/igb
815networking/device_drivers/intel/igbvf networking/device_drivers/ethernet/intel/igbvf
816networking/device_drivers/intel/ipw2100 networking/device_drivers/wifi/intel/ipw2100
817networking/device_drivers/intel/ipw2200 networking/device_drivers/wifi/intel/ipw2200
818networking/device_drivers/intel/ixgbe networking/device_drivers/ethernet/intel/ixgbe
819networking/device_drivers/intel/ixgbevf networking/device_drivers/ethernet/intel/ixgbevf
820networking/device_drivers/marvell/octeontx2 networking/device_drivers/ethernet/marvell/octeontx2
821networking/device_drivers/microsoft/netvsc networking/device_drivers/ethernet/microsoft/netvsc
822networking/device_drivers/neterion/s2io networking/device_drivers/ethernet/neterion/s2io
823networking/device_drivers/netronome/nfp networking/device_drivers/ethernet/netronome/nfp
824networking/device_drivers/pensando/ionic networking/device_drivers/ethernet/pensando/ionic
825networking/device_drivers/qualcomm/rmnet networking/device_drivers/cellular/qualcomm/rmnet
826networking/device_drivers/smsc/smc9 networking/device_drivers/ethernet/smsc/smc9
827networking/device_drivers/stmicro/stmmac networking/device_drivers/ethernet/stmicro/stmmac
828networking/device_drivers/ti/cpsw networking/device_drivers/ethernet/ti/cpsw
829networking/device_drivers/ti/cpsw_switchdev networking/device_drivers/ethernet/ti/cpsw_switchdev
830networking/device_drivers/ti/tlan networking/device_drivers/ethernet/ti/tlan
831networking/devlink-trap networking/devlink/devlink-trap
832networking/dpaa2/dpio-driver networking/device_drivers/ethernet/freescale/dpaa2/dpio-driver
833networking/dpaa2/ethernet-driver networking/device_drivers/ethernet/freescale/dpaa2/ethernet-driver
834networking/dpaa2/index networking/device_drivers/ethernet/freescale/dpaa2/index
835networking/dpaa2/overview networking/device_drivers/ethernet/freescale/dpaa2/overview
836networking/e100 networking/device_drivers/ethernet/intel/e100
837networking/e1000 networking/device_drivers/ethernet/intel/e1000
838networking/e1000e networking/device_drivers/ethernet/intel/e1000e
839networking/fm10k networking/device_drivers/ethernet/intel/fm10k
840networking/fore200e networking/device_drivers/atm/fore200e
841networking/hinic networking/device_drivers/ethernet/huawei/hinic
842networking/i40e networking/device_drivers/ethernet/intel/i40e
843networking/iavf networking/device_drivers/ethernet/intel/iavf
844networking/ice networking/device_drivers/ethernet/intel/ice
845networking/igb networking/device_drivers/ethernet/intel/igb
846networking/igbvf networking/device_drivers/ethernet/intel/igbvf
847networking/iphase networking/device_drivers/atm/iphase
848networking/ixgbe networking/device_drivers/ethernet/intel/ixgbe
849networking/ixgbevf networking/device_drivers/ethernet/intel/ixgbevf
850networking/netdev-FAQ process/maintainer-netdev
851networking/skfp networking/device_drivers/fddi/skfp
852networking/z8530drv networking/device_drivers/hamradio/z8530drv
853nfc/index driver-api/nfc/index
854nfc/nfc-hci driver-api/nfc/nfc-hci
855nfc/nfc-pn544 driver-api/nfc/nfc-pn544
856nios2/features arch/nios2/features
857nios2/index arch/nios2/index
858nios2/nios2 arch/nios2/nios2
859nvdimm/btt driver-api/nvdimm/btt
860nvdimm/index driver-api/nvdimm/index
861nvdimm/nvdimm driver-api/nvdimm/nvdimm
862nvdimm/security driver-api/nvdimm/security
863nvmem/nvmem driver-api/nvmem
864openrisc/features arch/openrisc/features
865openrisc/index arch/openrisc/index
866openrisc/openrisc_port arch/openrisc/openrisc_port
867openrisc/todo arch/openrisc/todo
868parisc/debugging arch/parisc/debugging
869parisc/features arch/parisc/features
870parisc/index arch/parisc/index
871parisc/registers arch/parisc/registers
872perf/arm-ccn admin-guide/perf/arm-ccn
873perf/arm_dsu_pmu admin-guide/perf/arm_dsu_pmu
874perf/hisi-pmu admin-guide/perf/hisi-pmu
875perf/index admin-guide/perf/index
876perf/qcom_l2_pmu admin-guide/perf/qcom_l2_pmu
877perf/qcom_l3_pmu admin-guide/perf/qcom_l3_pmu
878perf/thunderx2-pmu admin-guide/perf/thunderx2-pmu
879perf/xgene-pmu admin-guide/perf/xgene-pmu
880phy/samsung-usb2 driver-api/phy/samsung-usb2
881powerpc/associativity arch/powerpc/associativity
882powerpc/booting arch/powerpc/booting
883powerpc/bootwrapper arch/powerpc/bootwrapper
884powerpc/cpu_families arch/powerpc/cpu_families
885powerpc/cpu_features arch/powerpc/cpu_features
886powerpc/dawr-power9 arch/powerpc/dawr-power9
887powerpc/dexcr arch/powerpc/dexcr
888powerpc/dscr arch/powerpc/dscr
889powerpc/eeh-pci-error-recovery arch/powerpc/eeh-pci-error-recovery
890powerpc/elf_hwcaps arch/powerpc/elf_hwcaps
891powerpc/elfnote arch/powerpc/elfnote
892powerpc/features arch/powerpc/features
893powerpc/firmware-assisted-dump arch/powerpc/firmware-assisted-dump
894powerpc/hvcs arch/powerpc/hvcs
895powerpc/imc arch/powerpc/imc
896powerpc/index arch/powerpc/index
897powerpc/isa-versions arch/powerpc/isa-versions
898powerpc/kaslr-booke32 arch/powerpc/kaslr-booke32
899powerpc/mpc52xx arch/powerpc/mpc52xx
900powerpc/papr_hcalls arch/powerpc/papr_hcalls
901powerpc/pci_iov_resource_on_powernv arch/powerpc/pci_iov_resource_on_powernv
902powerpc/pmu-ebb arch/powerpc/pmu-ebb
903powerpc/ptrace arch/powerpc/ptrace
904powerpc/qe_firmware arch/powerpc/qe_firmware
905powerpc/syscall64-abi arch/powerpc/syscall64-abi
906powerpc/transactional_memory arch/powerpc/transactional_memory
907powerpc/ultravisor arch/powerpc/ultravisor
908powerpc/vas-api arch/powerpc/vas-api
909powerpc/vcpudispatch_stats arch/powerpc/vcpudispatch_stats
910powerpc/vmemmap_dedup arch/powerpc/vmemmap_dedup
911process/clang-format dev-tools/clang-format
912process/magic-number staging/magic-number
913process/unaligned-memory-access core-api/unaligned-memory-access
914rapidio/index driver-api/rapidio/index
915rapidio/mport_cdev driver-api/rapidio/mport_cdev
916rapidio/rapidio driver-api/rapidio/rapidio
917rapidio/rio_cm driver-api/rapidio/rio_cm
918rapidio/sysfs driver-api/rapidio/sysfs
919rapidio/tsi721 driver-api/rapidio/tsi721
920riscv/acpi arch/riscv/acpi
921riscv/boot arch/riscv/boot
922riscv/boot-image-header arch/riscv/boot-image-header
923riscv/features arch/riscv/features
924riscv/hwprobe arch/riscv/hwprobe
925riscv/index arch/riscv/index
926riscv/patch-acceptance arch/riscv/patch-acceptance
927riscv/uabi arch/riscv/uabi
928riscv/vector arch/riscv/vector
929riscv/vm-layout arch/riscv/vm-layout
930s390/3270 arch/s390/3270
931s390/cds arch/s390/cds
932s390/common_io arch/s390/common_io
933s390/driver-model arch/s390/driver-model
934s390/features arch/s390/features
935s390/index arch/s390/index
936s390/monreader arch/s390/monreader
937s390/pci arch/s390/pci
938s390/qeth arch/s390/qeth
939s390/s390dbf arch/s390/s390dbf
940s390/text_files arch/s390/text_files
941s390/vfio-ap arch/s390/vfio-ap
942s390/vfio-ap-locking arch/s390/vfio-ap-locking
943s390/vfio-ccw arch/s390/vfio-ccw
944s390/zfcpdump arch/s390/zfcpdump
945security/LSM security/lsm-development
946security/LSM-sctp security/SCTP
947serial/driver driver-api/serial/driver
948serial/index driver-api/serial/index
949serial/moxa-smartio driver-api/tty/moxa-smartio
950serial/n_gsm driver-api/tty/n_gsm
951serial/serial-iso7816 driver-api/serial/serial-iso7816
952serial/serial-rs485 driver-api/serial/serial-rs485
953serial/tty driver-api/tty/tty_ldisc
954sh/booting arch/sh/booting
955sh/features arch/sh/features
956sh/index arch/sh/index
957sh/new-machine arch/sh/new-machine
958sh/register-banks arch/sh/register-banks
959sparc/adi arch/sparc/adi
960sparc/console arch/sparc/console
961sparc/features arch/sparc/features
962sparc/index arch/sparc/index
963sparc/oradax/oracle-dax arch/sparc/oradax/oracle-dax
964staging/kprobes trace/kprobes
965sysctl/abi admin-guide/sysctl/abi
966sysctl/fs admin-guide/sysctl/fs
967sysctl/index admin-guide/sysctl/index
968sysctl/kernel admin-guide/sysctl/kernel
969sysctl/net admin-guide/sysctl/net
970sysctl/sunrpc admin-guide/sysctl/sunrpc
971sysctl/user admin-guide/sysctl/user
972sysctl/vm admin-guide/sysctl/vm
973thermal/cpu-cooling-api driver-api/thermal/cpu-cooling-api
974thermal/exynos_thermal driver-api/thermal/exynos_thermal
975thermal/exynos_thermal_emulation driver-api/thermal/exynos_thermal_emulation
976thermal/index driver-api/thermal/index
977thermal/intel_powerclamp admin-guide/thermal/intel_powerclamp
978thermal/nouveau_thermal driver-api/thermal/nouveau_thermal
979thermal/power_allocator driver-api/thermal/power_allocator
980thermal/sysfs-api driver-api/thermal/sysfs-api
981thermal/x86_pkg_temperature_thermal driver-api/thermal/x86_pkg_temperature_thermal
982tpm/index security/tpm/index
983tpm/tpm_vtpm_proxy security/tpm/tpm_vtpm_proxy
984trace/coresight trace/coresight/coresight
985trace/coresight-cpu-debug trace/coresight/coresight-cpu-debug
986trace/rv/da_monitor_synthesis trace/rv/monitor_synthesis
987translations/it_IT/admin-guide/security-bugs translations/it_IT/process/security-bugs
988translations/it_IT/process/clang-format translations/it_IT/dev-tools/clang-format
989translations/it_IT/process/magic-number translations/it_IT/staging/magic-number
990translations/it_IT/riscv/patch-acceptance translations/it_IT/arch/riscv/patch-acceptance
991translations/ja_JP/howto translations/ja_JP/process/howto
992translations/ko_KR/howto translations/ko_KR/process/howto
993translations/sp_SP/howto translations/sp_SP/process/howto
994translations/sp_SP/submitting-patches translations/sp_SP/process/submitting-patches
995translations/zh_CN/admin-guide/security-bugs translations/zh_CN/process/security-bugs
996translations/zh_CN/arch translations/zh_CN/arch/index
997translations/zh_CN/arm64/amu translations/zh_CN/arch/arm64/amu
998translations/zh_CN/arm64/elf_hwcaps translations/zh_CN/arch/arm64/elf_hwcaps
999translations/zh_CN/arm64/hugetlbpage translations/zh_CN/arch/arm64/hugetlbpage
1000translations/zh_CN/arm64/index translations/zh_CN/arch/arm64/index
1001translations/zh_CN/arm64/perf translations/zh_CN/arch/arm64/perf
1002translations/zh_CN/coding-style translations/zh_CN/process/coding-style
1003translations/zh_CN/loongarch/booting translations/zh_CN/arch/loongarch/booting
1004translations/zh_CN/loongarch/features translations/zh_CN/arch/loongarch/features
1005translations/zh_CN/loongarch/index translations/zh_CN/arch/loongarch/index
1006translations/zh_CN/loongarch/introduction translations/zh_CN/arch/loongarch/introduction
1007translations/zh_CN/loongarch/irq-chip-model translations/zh_CN/arch/loongarch/irq-chip-model
1008translations/zh_CN/mips/booting translations/zh_CN/arch/mips/booting
1009translations/zh_CN/mips/features translations/zh_CN/arch/mips/features
1010translations/zh_CN/mips/index translations/zh_CN/arch/mips/index
1011translations/zh_CN/mips/ingenic-tcu translations/zh_CN/arch/mips/ingenic-tcu
1012translations/zh_CN/openrisc/index translations/zh_CN/arch/openrisc/index
1013translations/zh_CN/openrisc/openrisc_port translations/zh_CN/arch/openrisc/openrisc_port
1014translations/zh_CN/openrisc/todo translations/zh_CN/arch/openrisc/todo
1015translations/zh_CN/parisc/debugging translations/zh_CN/arch/parisc/debugging
1016translations/zh_CN/parisc/index translations/zh_CN/arch/parisc/index
1017translations/zh_CN/parisc/registers translations/zh_CN/arch/parisc/registers
1018translations/zh_CN/riscv/boot-image-header translations/zh_CN/arch/riscv/boot-image-header
1019translations/zh_CN/riscv/index translations/zh_CN/arch/riscv/index
1020translations/zh_CN/riscv/patch-acceptance translations/zh_CN/arch/riscv/patch-acceptance
1021translations/zh_CN/riscv/vm-layout translations/zh_CN/arch/riscv/vm-layout
1022translations/zh_CN/vm/active_mm translations/zh_CN/mm/active_mm
1023translations/zh_CN/vm/balance translations/zh_CN/mm/balance
1024translations/zh_CN/vm/damon/api translations/zh_CN/mm/damon/api
1025translations/zh_CN/vm/damon/design translations/zh_CN/mm/damon/design
1026translations/zh_CN/vm/damon/faq translations/zh_CN/mm/damon/faq
1027translations/zh_CN/vm/damon/index translations/zh_CN/mm/damon/index
1028translations/zh_CN/vm/free_page_reporting translations/zh_CN/mm/free_page_reporting
1029translations/zh_CN/vm/highmem translations/zh_CN/mm/highmem
1030translations/zh_CN/vm/hmm translations/zh_CN/mm/hmm
1031translations/zh_CN/vm/hugetlbfs_reserv translations/zh_CN/mm/hugetlbfs_reserv
1032translations/zh_CN/vm/hwpoison translations/zh_CN/mm/hwpoison
1033translations/zh_CN/vm/index translations/zh_CN/mm/index
1034translations/zh_CN/vm/ksm translations/zh_CN/mm/ksm
1035translations/zh_CN/vm/memory-model translations/zh_CN/mm/memory-model
1036translations/zh_CN/vm/mmu_notifier translations/zh_CN/mm/mmu_notifier
1037translations/zh_CN/vm/numa translations/zh_CN/mm/numa
1038translations/zh_CN/vm/overcommit-accounting translations/zh_CN/mm/overcommit-accounting
1039translations/zh_CN/vm/page_frags translations/zh_CN/mm/page_frags
1040translations/zh_CN/vm/page_owner translations/zh_CN/mm/page_owner
1041translations/zh_CN/vm/page_table_check translations/zh_CN/mm/page_table_check
1042translations/zh_CN/vm/remap_file_pages translations/zh_CN/mm/remap_file_pages
1043translations/zh_CN/vm/split_page_table_lock translations/zh_CN/mm/split_page_table_lock
1044translations/zh_CN/vm/zsmalloc translations/zh_CN/mm/zsmalloc
1045translations/zh_TW/arm64/amu translations/zh_TW/arch/arm64/amu
1046translations/zh_TW/arm64/elf_hwcaps translations/zh_TW/arch/arm64/elf_hwcaps
1047translations/zh_TW/arm64/hugetlbpage translations/zh_TW/arch/arm64/hugetlbpage
1048translations/zh_TW/arm64/index translations/zh_TW/arch/arm64/index
1049translations/zh_TW/arm64/perf translations/zh_TW/arch/arm64/perf
1050tty/device_drivers/oxsemi-tornado misc-devices/oxsemi-tornado
1051tty/index driver-api/tty/index
1052tty/n_tty driver-api/tty/n_tty
1053tty/tty_buffer driver-api/tty/tty_buffer
1054tty/tty_driver driver-api/tty/tty_driver
1055tty/tty_internals driver-api/tty/tty_internals
1056tty/tty_ldisc driver-api/tty/tty_ldisc
1057tty/tty_port driver-api/tty/tty_port
1058tty/tty_struct driver-api/tty/tty_struct
1059usb/typec driver-api/usb/typec
1060usb/usb3-debug-port driver-api/usb/usb3-debug-port
1061userspace-api/media/drivers/st-vgxy61 userspace-api/media/drivers/vgxy61
1062userspace-api/media/v4l/pixfmt-meta-d4xx userspace-api/media/v4l/metafmt-d4xx
1063userspace-api/media/v4l/pixfmt-meta-intel-ipu3 userspace-api/media/v4l/metafmt-intel-ipu3
1064userspace-api/media/v4l/pixfmt-meta-rkisp1 userspace-api/media/v4l/metafmt-rkisp1
1065userspace-api/media/v4l/pixfmt-meta-uvc userspace-api/media/v4l/metafmt-uvc
1066userspace-api/media/v4l/pixfmt-meta-vivid userspace-api/media/v4l/metafmt-vivid
1067userspace-api/media/v4l/pixfmt-meta-vsp1-hgo userspace-api/media/v4l/metafmt-vsp1-hgo
1068userspace-api/media/v4l/pixfmt-meta-vsp1-hgt userspace-api/media/v4l/metafmt-vsp1-hgt
1069virt/coco/sevguest virt/coco/sev-guest
1070virt/kvm/amd-memory-encryption virt/kvm/x86/amd-memory-encryption
1071virt/kvm/arm/psci virt/kvm/arm/fw-pseudo-registers
1072virt/kvm/cpuid virt/kvm/x86/cpuid
1073virt/kvm/hypercalls virt/kvm/x86/hypercalls
1074virt/kvm/mmu virt/kvm/x86/mmu
1075virt/kvm/msr virt/kvm/x86/msr
1076virt/kvm/nested-vmx virt/kvm/x86/nested-vmx
1077virt/kvm/running-nested-guests virt/kvm/x86/running-nested-guests
1078virt/kvm/s390-diag virt/kvm/s390/s390-diag
1079virt/kvm/s390-pv virt/kvm/s390/s390-pv
1080virt/kvm/s390-pv-boot virt/kvm/s390/s390-pv-boot
1081virt/kvm/timekeeping virt/kvm/x86/timekeeping
1082virt/kvm/x86/halt-polling virt/kvm/halt-polling
1083virtual/index virt/index
1084virtual/kvm/amd-memory-encryption virt/kvm/x86/amd-memory-encryption
1085virtual/kvm/cpuid virt/kvm/x86/cpuid
1086virtual/kvm/index virt/kvm/index
1087virtual/kvm/vcpu-requests virt/kvm/vcpu-requests
1088virtual/paravirt_ops virt/paravirt_ops
1089vm/active_mm mm/active_mm
1090vm/arch_pgtable_helpers mm/arch_pgtable_helpers
1091vm/balance mm/balance
1092vm/bootmem mm/bootmem
1093vm/damon/api mm/damon/api
1094vm/damon/design mm/damon/design
1095vm/damon/faq mm/damon/faq
1096vm/damon/index mm/damon/index
1097vm/free_page_reporting mm/free_page_reporting
1098vm/highmem mm/highmem
1099vm/hmm mm/hmm
1100vm/hugetlbfs_reserv mm/hugetlbfs_reserv
1101vm/hugetlbpage admin-guide/mm/hugetlbpage
1102vm/hwpoison mm/hwpoison
1103vm/idle_page_tracking admin-guide/mm/idle_page_tracking
1104vm/index mm/index
1105vm/ksm mm/ksm
1106vm/memory-model mm/memory-model
1107vm/mmu_notifier mm/mmu_notifier
1108vm/numa mm/numa
1109vm/numa_memory_policy admin-guide/mm/numa_memory_policy
1110vm/oom mm/oom
1111vm/overcommit-accounting mm/overcommit-accounting
1112vm/page_allocation mm/page_allocation
1113vm/page_cache mm/page_cache
1114vm/page_frags mm/page_frags
1115vm/page_migration mm/page_migration
1116vm/page_owner mm/page_owner
1117vm/page_reclaim mm/page_reclaim
1118vm/page_table_check mm/page_table_check
1119vm/page_tables mm/page_tables
1120vm/pagemap admin-guide/mm/pagemap
1121vm/physical_memory mm/physical_memory
1122vm/process_addrs mm/process_addrs
1123vm/remap_file_pages mm/remap_file_pages
1124vm/shmfs mm/shmfs
1125vm/slab mm/slab
1126vm/slub admin-guide/mm/slab
1127vm/soft-dirty admin-guide/mm/soft-dirty
1128vm/split_page_table_lock mm/split_page_table_lock
1129vm/swap mm/swap
1130vm/swap_numa admin-guide/mm/swap_numa
1131vm/transhuge mm/transhuge
1132vm/unevictable-lru mm/unevictable-lru
1133vm/userfaultfd admin-guide/mm/userfaultfd
1134vm/vmalloc mm/vmalloc
1135vm/vmalloced-kernel-stacks mm/vmalloced-kernel-stacks
1136vm/vmemmap_dedup mm/vmemmap_dedup
1137vm/zsmalloc mm/zsmalloc
1138vm/zswap admin-guide/mm/zswap
1139watch_queue core-api/watch_queue
1140x86/amd-memory-encryption arch/x86/amd-memory-encryption
1141x86/amd_hsmp arch/x86/amd_hsmp
1142x86/boot arch/x86/boot
1143x86/booting-dt arch/x86/booting-dt
1144x86/buslock arch/x86/buslock
1145x86/cpuinfo arch/x86/cpuinfo
1146x86/earlyprintk arch/x86/earlyprintk
1147x86/elf_auxvec arch/x86/elf_auxvec
1148x86/entry_64 arch/x86/entry_64
1149x86/exception-tables arch/x86/exception-tables
1150x86/features arch/x86/features
1151x86/i386/IO-APIC arch/x86/i386/IO-APIC
1152x86/i386/index arch/x86/i386/index
1153x86/ifs arch/x86/ifs
1154x86/index arch/x86/index
1155x86/intel-hfi arch/x86/intel-hfi
1156x86/intel_txt arch/x86/intel_txt
1157x86/iommu arch/x86/iommu
1158x86/kernel-stacks arch/x86/kernel-stacks
1159x86/mds arch/x86/mds
1160x86/microcode arch/x86/microcode
1161x86/mtrr arch/x86/mtrr
1162x86/orc-unwinder arch/x86/orc-unwinder
1163x86/pat arch/x86/pat
1164x86/protection-keys core-api/protection-keys
1165x86/pti arch/x86/pti
1166x86/resctrl filesystems/resctrl
1167x86/resctrl_ui filesystems/resctrl
1168x86/sgx arch/x86/sgx
1169x86/sva arch/x86/sva
1170x86/tdx arch/x86/tdx
1171x86/tlb arch/x86/tlb
1172x86/topology arch/x86/topology
1173x86/tsx_async_abort arch/x86/tsx_async_abort
1174x86/usb-legacy-support arch/x86/usb-legacy-support
1175x86/x86_64/5level-paging arch/x86/x86_64/5level-paging
1176x86/x86_64/cpu-hotplug-spec arch/x86/x86_64/cpu-hotplug-spec
1177x86/x86_64/fake-numa-for-cpusets arch/x86/x86_64/fake-numa-for-cpusets
1178x86/x86_64/fsgs arch/x86/x86_64/fsgs
1179x86/x86_64/index arch/x86/x86_64/index
1180x86/x86_64/machinecheck arch/x86/x86_64/machinecheck
1181x86/x86_64/mm arch/x86/x86_64/mm
1182x86/x86_64/uefi arch/x86/x86_64/uefi
1183x86/xstate arch/x86/xstate
1184x86/zero-page arch/x86/zero-page
1185xilinx/eemi driver-api/xilinx/eemi
1186xilinx/index driver-api/xilinx/index
1187xtensa/atomctl arch/xtensa/atomctl
1188xtensa/booting arch/xtensa/booting
1189xtensa/features arch/xtensa/features
1190xtensa/index arch/xtensa/index
1191xtensa/mmu arch/xtensa/mmu
Documentation/Makefile+7−4
@@ -60,8 +60,8 @@ ifeq ($(HAVE_LATEXMK),1) · 59 unmodified lines
60endif #HAVE_LATEXMK60endif #HAVE_LATEXMK
61 61
62# Internal variables.62# Internal variables.
63PAPEROPT_a4 = -D latex_paper_size=a463PAPEROPT_a4 = -D latex_elements.papersize=a4paper
64PAPEROPT_letter = -D latex_paper_size=letter64PAPEROPT_letter = -D latex_elements.papersize=letterpaper
65ALLSPHINXOPTS = -D kerneldoc_srctree=$(srctree) -D kerneldoc_bin=$(KERNELDOC)65ALLSPHINXOPTS = -D kerneldoc_srctree=$(srctree) -D kerneldoc_bin=$(KERNELDOC)
66ALLSPHINXOPTS += $(PAPEROPT_$(PAPER)) $(SPHINXOPTS)66ALLSPHINXOPTS += $(PAPEROPT_$(PAPER)) $(SPHINXOPTS)
67ifneq ($(wildcard $(srctree)/.config),)67ifneq ($(wildcard $(srctree)/.config),)
@@ -87,7 +87,7 @@ loop_cmd = $(echo-cmd) $(cmd_$(1)) || exit; · 19 unmodified lines
87PYTHONPYCACHEPREFIX ?= $(abspath $(BUILDDIR)/__pycache__)87PYTHONPYCACHEPREFIX ?= $(abspath $(BUILDDIR)/__pycache__)
88 88
89quiet_cmd_sphinx = SPHINX $@ --> file://$(abspath $(BUILDDIR)/$3/$4)89quiet_cmd_sphinx = SPHINX $@ --> file://$(abspath $(BUILDDIR)/$3/$4)
90 cmd_sphinx = $(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/userspace-api/media $2 && \90 cmd_sphinx = \
91 PYTHONPYCACHEPREFIX="$(PYTHONPYCACHEPREFIX)" \91 PYTHONPYCACHEPREFIX="$(PYTHONPYCACHEPREFIX)" \
92 BUILDDIR=$(abspath $(BUILDDIR)) SPHINX_CONF=$(abspath $(src)/$5/$(SPHINX_CONF)) \92 BUILDDIR=$(abspath $(BUILDDIR)) SPHINX_CONF=$(abspath $(src)/$5/$(SPHINX_CONF)) \
93 $(PYTHON3) $(srctree)/scripts/jobserver-exec \93 $(PYTHON3) $(srctree)/scripts/jobserver-exec \
@@ -108,6 +108,9 @@ htmldocs: · 14 unmodified lines
108 @$(srctree)/scripts/sphinx-pre-install --version-check108 @$(srctree)/scripts/sphinx-pre-install --version-check
109 @+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,html,$(var),,$(var)))109 @+$(foreach var,$(SPHINXDIRS),$(call loop_cmd,sphinx,html,$(var),,$(var)))
110 110
111htmldocs-redirects: $(srctree)/Documentation/.renames.txt
112 @tools/docs/gen-redirects.py --output $(BUILDDIR) < $<
113
111# If Rust support is available and .config exists, add rustdoc generated contents.114# If Rust support is available and .config exists, add rustdoc generated contents.
112# If there are any, the errors from this make rustdoc will be displayed but115# If there are any, the errors from this make rustdoc will be displayed but
113# won't stop the execution of htmldocs116# won't stop the execution of htmldocs
@@ -171,11 +174,11 @@ refcheckdocs: · 57 unmodified lines
171 174
172cleandocs:175cleandocs:
173 $(Q)rm -rf $(BUILDDIR)176 $(Q)rm -rf $(BUILDDIR)
174 $(Q)$(MAKE) BUILDDIR=$(abspath $(BUILDDIR)) $(build)=Documentation/userspace-api/media clean
175 177
176dochelp:178dochelp:
177 @echo ' Linux kernel internal documentation in different formats from ReST:'179 @echo ' Linux kernel internal documentation in different formats from ReST:'
178 @echo ' htmldocs - HTML'180 @echo ' htmldocs - HTML'
181 @echo ' htmldocs-redirects - generate HTML redirects for moved pages'
179 @echo ' texinfodocs - Texinfo'182 @echo ' texinfodocs - Texinfo'
180 @echo ' infodocs - Info'183 @echo ' infodocs - Info'
181 @echo ' latexdocs - LaTeX'184 @echo ' latexdocs - LaTeX'
Documentation/PCI/endpoint/pci-endpoint-cfs.rst+2−2
@@ -86,7 +86,7 @@ The <EPF Device> directory can have a list of symbolic links · 85 unmodified lines
86be created by the user to represent the virtual functions that are bound to86be created by the user to represent the virtual functions that are bound to
87the physical function. In the above directory structure <EPF Device 11> is a87the physical function. In the above directory structure <EPF Device 11> is a
88physical function and <EPF Device 31> is a virtual function. An EPF device once88physical function and <EPF Device 31> is a virtual function. An EPF device once
89it's linked to another EPF device, cannot be linked to a EPC device.89it's linked to another EPF device, cannot be linked to an EPC device.
90 90
91EPC Device91EPC Device
92==========92==========
@@ -108,7 +108,7 @@ entries corresponding to EPC device will be created by the EPC core. · 15 unmodified lines
108The <EPC Device> directory will have a list of symbolic links to108The <EPC Device> directory will have a list of symbolic links to
109<EPF Device>. These symbolic links should be created by the user to109<EPF Device>. These symbolic links should be created by the user to
110represent the functions present in the endpoint device. Only <EPF Device>110represent the functions present in the endpoint device. Only <EPF Device>
111that represents a physical function can be linked to a EPC device.111that represents a physical function can be linked to an EPC device.
112 112
113The <EPC Device> directory will also have a *start* field. Once113The <EPC Device> directory will also have a *start* field. Once
114"1" is written to this field, the endpoint device will be ready to114"1" is written to this field, the endpoint device will be ready to
Documentation/PCI/endpoint/pci-endpoint.rst+3−3
@@ -197,8 +197,8 @@ by the PCI endpoint function driver. · 196 unmodified lines
197* pci_epf_register_driver()197* pci_epf_register_driver()
198 198
199 The PCI Endpoint Function driver should implement the following ops:199 The PCI Endpoint Function driver should implement the following ops:
200 * bind: ops to perform when a EPC device has been bound to EPF device200 * bind: ops to perform when an EPC device has been bound to EPF device
201 * unbind: ops to perform when a binding has been lost between a EPC201 * unbind: ops to perform when a binding has been lost between an EPC
202 device and EPF device202 device and EPF device
203 * add_cfs: optional ops to create function specific configfs203 * add_cfs: optional ops to create function specific configfs
204 attributes204 attributes
@@ -251,7 +251,7 @@ pci-ep-cfs.c can be used as reference for using these APIs. · 46 unmodified lines
251* pci_epf_bind()251* pci_epf_bind()
252 252
253 pci_epf_bind() should be invoked when the EPF device has been bound to253 pci_epf_bind() should be invoked when the EPF device has been bound to
254 a EPC device.254 an EPC device.
255 255
256* pci_epf_unbind()256* pci_epf_unbind()
257 257
Documentation/RCU/lockdep.rst+1−1
@@ -106,7 +106,7 @@ or the RCU-protected data that it points to can change concurrently. · 105 unmodified lines
106Like rcu_dereference(), when lockdep is enabled, RCU list and hlist106Like rcu_dereference(), when lockdep is enabled, RCU list and hlist
107traversal primitives check for being called from within an RCU read-side107traversal primitives check for being called from within an RCU read-side
108critical section. However, a lockdep expression can be passed to them108critical section. However, a lockdep expression can be passed to them
109as a additional optional argument. With this lockdep expression, these109as an additional optional argument. With this lockdep expression, these
110traversal primitives will complain only if the lockdep expression is110traversal primitives will complain only if the lockdep expression is
111false and they are called from outside any RCU read-side critical section.111false and they are called from outside any RCU read-side critical section.
112 112
Documentation/RCU/stallwarn.rst+1−1
@@ -119,7 +119,7 @@ warnings: · 118 unmodified lines
119 uncommon in large datacenter. In one memorable case some decades119 uncommon in large datacenter. In one memorable case some decades
120 back, a CPU failed in a running system, becoming unresponsive,120 back, a CPU failed in a running system, becoming unresponsive,
121 but not causing an immediate crash. This resulted in a series121 but not causing an immediate crash. This resulted in a series
122 of RCU CPU stall warnings, eventually leading the realization122 of RCU CPU stall warnings, eventually leading to the realization
123 that the CPU had failed.123 that the CPU had failed.
124 124
125The RCU, RCU-sched, RCU-tasks, and RCU-tasks-trace implementations have125The RCU, RCU-sched, RCU-tasks, and RCU-tasks-trace implementations have
Documentation/admin-guide/LSM/SafeSetID.rst+1−1
@@ -41,7 +41,7 @@ namespace). The higher level goal is to allow for uid-based sandboxing of system · 40 unmodified lines
41services without having to give out CAP_SETUID all over the place just so that41services without having to give out CAP_SETUID all over the place just so that
42non-root programs can drop to even-lesser-privileged uids. This is especially42non-root programs can drop to even-lesser-privileged uids. This is especially
43relevant when one non-root daemon on the system should be allowed to spawn other43relevant when one non-root daemon on the system should be allowed to spawn other
44processes as different uids, but its undesirable to give the daemon a44processes as different uids, but it's undesirable to give the daemon a
45basically-root-equivalent CAP_SETUID.45basically-root-equivalent CAP_SETUID.
46 46
47 47
Documentation/admin-guide/RAS/main.rst+1−1
@@ -253,7 +253,7 @@ interface. · 252 unmodified lines
253Some architectures have ECC detectors for L1, L2 and L3 caches,253Some architectures have ECC detectors for L1, L2 and L3 caches,
254along with DMA engines, fabric switches, main data path switches,254along with DMA engines, fabric switches, main data path switches,
255interconnections, and various other hardware data paths. If the hardware255interconnections, and various other hardware data paths. If the hardware
256reports it, then a edac_device device probably can be constructed to256reports it, then an edac_device device probably can be constructed to
257harvest and present that to userspace.257harvest and present that to userspace.
258 258
259 259
Documentation/admin-guide/aoe/udev.txt+3−3
@@ -2,7 +2,7 @@ · 1 unmodified line
2# They may be installed along the following lines. Check the section2# They may be installed along the following lines. Check the section
3# 8 udev manpage to see whether your udev supports SUBSYSTEM, and3# 8 udev manpage to see whether your udev supports SUBSYSTEM, and
4# whether it uses one or two equal signs for SUBSYSTEM and KERNEL.4# whether it uses one or two equal signs for SUBSYSTEM and KERNEL.
5# 5#
6# ecashin@makki ~$ su6# ecashin@makki ~$ su
7# Password:7# Password:
8# bash# find /etc -type f -name udev.conf8# bash# find /etc -type f -name udev.conf
@@ -13,7 +13,7 @@ · 4 unmodified lines
13# 10-wacom.rules 50-udev.rules13# 10-wacom.rules 50-udev.rules
14# bash# cp /path/to/linux/Documentation/admin-guide/aoe/udev.txt \14# bash# cp /path/to/linux/Documentation/admin-guide/aoe/udev.txt \
15# /etc/udev/rules.d/60-aoe.rules15# /etc/udev/rules.d/60-aoe.rules
16# 16#
17 17
18# aoe char devices18# aoe char devices
19SUBSYSTEM=="aoe", KERNEL=="discover", NAME="etherd/%k", GROUP="disk", MODE="0220"19SUBSYSTEM=="aoe", KERNEL=="discover", NAME="etherd/%k", GROUP="disk", MODE="0220"
@@ -22,5 +22,5 @@ SUBSYSTEM=="aoe", KERNEL=="interfaces", NAME="etherd/%k", GROUP="disk", MODE="02 · 2 unmodified lines
22SUBSYSTEM=="aoe", KERNEL=="revalidate", NAME="etherd/%k", GROUP="disk", MODE="0220"22SUBSYSTEM=="aoe", KERNEL=="revalidate", NAME="etherd/%k", GROUP="disk", MODE="0220"
23SUBSYSTEM=="aoe", KERNEL=="flush", NAME="etherd/%k", GROUP="disk", MODE="0220"23SUBSYSTEM=="aoe", KERNEL=="flush", NAME="etherd/%k", GROUP="disk", MODE="0220"
24 24
25# aoe block devices 25# aoe block devices
26KERNEL=="etherd*", GROUP="disk"26KERNEL=="etherd*", GROUP="disk"
Documentation/admin-guide/blockdev/paride.rst+1−1
@@ -118,7 +118,7 @@ and high-level drivers that you would use: · 117 unmodified lines
118 ================ ============ ========118 ================ ============ ========
119 119
120All parports and all protocol drivers are probed automatically unless probe=0120All parports and all protocol drivers are probed automatically unless probe=0
121parameter is used. So just "modprobe epat" is enough for a Imation SuperDisk121parameter is used. So just "modprobe epat" is enough for an Imation SuperDisk
122drive to work.122drive to work.
123 123
124Manual device creation::124Manual device creation::
Documentation/admin-guide/device-mapper/vdo-design.rst+1−1
@@ -600,7 +600,7 @@ lock and return itself to the pool. · 599 unmodified lines
600All storage within vdo is managed as 4KB blocks, but it can accept writes600All storage within vdo is managed as 4KB blocks, but it can accept writes
601as small as 512 bytes. Processing a write that is smaller than 4K requires601as small as 512 bytes. Processing a write that is smaller than 4K requires
602a read-modify-write operation that reads the relevant 4K block, copies the602a read-modify-write operation that reads the relevant 4K block, copies the
603new data over the approriate sectors of the block, and then launches a603new data over the appropriate sectors of the block, and then launches a
604write operation for the modified data block. The read and write stages of604write operation for the modified data block. The read and write stages of
605this operation are nearly identical to the normal read and write605this operation are nearly identical to the normal read and write
606operations, and a single data_vio is used throughout this operation.606operations, and a single data_vio is used throughout this operation.
Documentation/admin-guide/ext4.rst+1−1
@@ -398,7 +398,7 @@ There are 3 different data modes: · 397 unmodified lines
398* writeback mode398* writeback mode
399 399
400 In data=writeback mode, ext4 does not journal data at all. This mode provides400 In data=writeback mode, ext4 does not journal data at all. This mode provides
401 a similar level of journaling as that of XFS, JFS, and ReiserFS in its default401 a similar level of journaling as that of XFS and JFS in its default
402 mode - metadata journaling. A crash+recovery can cause incorrect data to402 mode - metadata journaling. A crash+recovery can cause incorrect data to
403 appear in files which were written shortly before the crash. This mode will403 appear in files which were written shortly before the crash. This mode will
404 typically provide the best ext4 performance.404 typically provide the best ext4 performance.
Documentation/admin-guide/hw-vuln/mds.rst+1−1
@@ -214,7 +214,7 @@ XEON PHI specific considerations · 213 unmodified lines
214 command line with the 'ring3mwait=disable' command line option.214 command line with the 'ring3mwait=disable' command line option.
215 215
216 XEON PHI is not affected by the other MDS variants and MSBDS is mitigated216 XEON PHI is not affected by the other MDS variants and MSBDS is mitigated
217 before the CPU enters a idle state. As XEON PHI is not affected by L1TF217 before the CPU enters an idle state. As XEON PHI is not affected by L1TF
218 either disabling SMT is not required for full protection.218 either disabling SMT is not required for full protection.
219 219
220.. _mds_smt_control:220.. _mds_smt_control:
Documentation/admin-guide/hw-vuln/spectre.rst+3−3
@@ -664,7 +664,7 @@ Intel white papers: · 663 unmodified lines
664 664
665.. _spec_ref1:665.. _spec_ref1:
666 666
667[1] `Intel analysis of speculative execution side channels <https://newsroom.intel.com/wp-content/uploads/sites/11/2018/01/Intel-Analysis-of-Speculative-Execution-Side-Channels.pdf>`_.667[1] `Intel analysis of speculative execution side channels <https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/analysis-of-speculative-execution-side-channels-white-paper.pdf>`_.
668 668
669.. _spec_ref2:669.. _spec_ref2:
670 670
@@ -682,7 +682,7 @@ AMD white papers: · 11 unmodified lines
682 682
683.. _spec_ref5:683.. _spec_ref5:
684 684
685[5] `AMD64 technology indirect branch control extension <https://developer.amd.com/wp-content/resources/Architecture_Guidelines_Update_Indirect_Branch_Control.pdf>`_.685[5] `AMD64 technology indirect branch control extension <https://www.amd.com/content/dam/amd/en/documents/processor-tech-docs/white-papers/111006-architecture-guidelines-update-amd64-technology-indirect-branch-control-extension.pdf>`_.
686 686
687.. _spec_ref6:687.. _spec_ref6:
688 688
@@ -708,7 +708,7 @@ MIPS white paper: · 19 unmodified lines
708 708
709.. _spec_ref10:709.. _spec_ref10:
710 710
711[10] `MIPS: response on speculative execution and side channel vulnerabilities <https://www.mips.com/blog/mips-response-on-speculative-execution-and-side-channel-vulnerabilities/>`_.711[10] `MIPS: response on speculative execution and side channel vulnerabilities <https://web.archive.org/web/20220512003005if_/https://www.mips.com/blog/mips-response-on-speculative-execution-and-side-channel-vulnerabilities/>`_.
712 712
713Academic papers:713Academic papers:
714 714
Documentation/admin-guide/kdump/kdump.rst+1−1
@@ -471,7 +471,7 @@ Notes on loading the dump-capture kernel: · 470 unmodified lines
471 performance degradation. To enable multi-cpu support, you should bring up an471 performance degradation. To enable multi-cpu support, you should bring up an
472 SMP dump-capture kernel and specify maxcpus/nr_cpus options while loading it.472 SMP dump-capture kernel and specify maxcpus/nr_cpus options while loading it.
473 473
474* For s390x there are two kdump modes: If a ELF header is specified with474* For s390x there are two kdump modes: If an ELF header is specified with
475 the elfcorehdr= kernel parameter, it is used by the kdump kernel as it475 the elfcorehdr= kernel parameter, it is used by the kdump kernel as it
476 is done on all other architectures. If no elfcorehdr= kernel parameter is476 is done on all other architectures. If no elfcorehdr= kernel parameter is
477 specified, the s390x kdump kernel dynamically creates the header. The477 specified, the s390x kdump kernel dynamically creates the header. The
Documentation/admin-guide/kernel-parameters.rst+3−1
@@ -1,3 +1,5 @@
1.. SPDX-License-Identifier: GPL-2.0
2
1.. _kernelparameters:3.. _kernelparameters:
2 4
3The kernel's command-line parameters5The kernel's command-line parameters
@@ -213,7 +215,7 @@ need or coordination with <Documentation/arch/x86/boot.rst>. · 209 unmodified lines
213There are also arch-specific kernel-parameters not documented here.215There are also arch-specific kernel-parameters not documented here.
214 216
215Note that ALL kernel parameters listed below are CASE SENSITIVE, and that217Note that ALL kernel parameters listed below are CASE SENSITIVE, and that
216a trailing = on the name of any parameter states that that parameter will218a trailing = on the name of any parameter states that the parameter will
217be entered as an environment variable, whereas its absence indicates that219be entered as an environment variable, whereas its absence indicates that
218it will appear as a kernel argument readable via /proc/cmdline by programs220it will appear as a kernel argument readable via /proc/cmdline by programs
219running once the system is up.221running once the system is up.
Documentation/admin-guide/kernel-parameters.txt+6−6
@@ -3705,7 +3705,7 @@ · 3704 unmodified lines
3705 looking for corruption. Enabling this will3705 looking for corruption. Enabling this will
3706 both detect corruption and prevent the kernel3706 both detect corruption and prevent the kernel
3707 from using the memory being corrupted.3707 from using the memory being corrupted.
3708 However, its intended as a diagnostic tool; if3708 However, it's intended as a diagnostic tool; if
3709 repeatable BIOS-originated corruption always3709 repeatable BIOS-originated corruption always
3710 affects the same memory, you can use memmap=3710 affects the same memory, you can use memmap=
3711 to prevent the kernel from using that memory.3711 to prevent the kernel from using that memory.
@@ -7400,7 +7400,7 @@ · 3688 unmodified lines
7400 (converted into nanoseconds). Fast, but7400 (converted into nanoseconds). Fast, but
7401 depending on the architecture, may not be7401 depending on the architecture, may not be
7402 in sync between CPUs.7402 in sync between CPUs.
7403 global - Event time stamps are synchronize across7403 global - Event time stamps are synchronized across
7404 CPUs. May be slower than the local clock,7404 CPUs. May be slower than the local clock,
7405 but better for some race conditions.7405 but better for some race conditions.
7406 counter - Simple counting of events (1, 2, ..)7406 counter - Simple counting of events (1, 2, ..)
@@ -7520,12 +7520,12 @@ · 113 unmodified lines
7520 section.7520 section.
7521 7521
7522 trace_trigger=[trigger-list]7522 trace_trigger=[trigger-list]
7523 [FTRACE] Add a event trigger on specific events.7523 [FTRACE] Add an event trigger on specific events.
7524 Set a trigger on top of a specific event, with an optional7524 Set a trigger on top of a specific event, with an optional
7525 filter.7525 filter.
7526 7526
7527 The format is is "trace_trigger=<event>.<trigger>[ if <filter>],..."7527 The format is "trace_trigger=<event>.<trigger>[ if <filter>],..."
7528 Where more than one trigger may be specified that are comma deliminated.7528 Where more than one trigger may be specified that are comma delimited.
7529 7529
7530 For example:7530 For example:
7531 7531
@@ -7533,7 +7533,7 @@ · 1 unmodified line
7533 7533
7534 The above will enable the "stacktrace" trigger on the "sched_switch"7534 The above will enable the "stacktrace" trigger on the "sched_switch"
7535 event but only trigger it if the "prev_state" of the "sched_switch"7535 event but only trigger it if the "prev_state" of the "sched_switch"
7536 event is "2" (TASK_UNINTERUPTIBLE).7536 event is "2" (TASK_UNINTERRUPTIBLE).
7537 7537
7538 See also "Event triggers" in Documentation/trace/events.rst7538 See also "Event triggers" in Documentation/trace/events.rst
7539 7539
Documentation/admin-guide/laptops/laptop-mode.rst+4−4
@@ -61,7 +61,7 @@ Caveats · 60 unmodified lines
61 Check your drive's rating, and don't wear down your drive's lifetime if you61 Check your drive's rating, and don't wear down your drive's lifetime if you
62 don't need to.62 don't need to.
63 63
64* If you mount some of your ext3/reiserfs filesystems with the -n option, then64* If you mount some of your ext3 filesystems with the -n option, then
65 the control script will not be able to remount them correctly. You must set65 the control script will not be able to remount them correctly. You must set
66 DO_REMOUNTS=0 in the control script, otherwise it will remount them with the66 DO_REMOUNTS=0 in the control script, otherwise it will remount them with the
67 wrong options -- or it will fail because it cannot write to /etc/mtab.67 wrong options -- or it will fail because it cannot write to /etc/mtab.
@@ -96,7 +96,7 @@ control script increases dirty_expire_centisecs and dirty_writeback_centisecs in · 28 unmodified lines
96dirtied are not forced to be written to disk as often. The control script also96dirtied are not forced to be written to disk as often. The control script also
97changes the dirty background ratio, so that background writeback of dirty pages97changes the dirty background ratio, so that background writeback of dirty pages
98is not done anymore. Combined with a higher commit value (also 10 minutes) for98is not done anymore. Combined with a higher commit value (also 10 minutes) for
99ext3 or ReiserFS filesystems (also done automatically by the control script),99ext3 filesystem (also done automatically by the control script),
100this results in concentration of disk activity in a small time interval which100this results in concentration of disk activity in a small time interval which
101occurs only once every 10 minutes, or whenever the disk is forced to spin up by101occurs only once every 10 minutes, or whenever the disk is forced to spin up by
102a cache miss. The disk can then be spun down in the periods of inactivity.102a cache miss. The disk can then be spun down in the periods of inactivity.
@@ -587,7 +587,7 @@ Control script:: · 484 unmodified lines
587 FST=$(deduce_fstype $MP)587 FST=$(deduce_fstype $MP)
588 fi588 fi
589 case "$FST" in589 case "$FST" in
590 "ext3"|"reiserfs")590 "ext3")
591 PARSEDOPTS="$(parse_mount_opts commit "$OPTS")"591 PARSEDOPTS="$(parse_mount_opts commit "$OPTS")"
592 mount $DEV -t $FST $MP -o remount,$PARSEDOPTS,commit=$MAX_AGE$NOATIME_OPT592 mount $DEV -t $FST $MP -o remount,$PARSEDOPTS,commit=$MAX_AGE$NOATIME_OPT
593 ;;593 ;;
@@ -647,7 +647,7 @@ Control script:: · 53 unmodified lines
647 FST=$(deduce_fstype $MP)647 FST=$(deduce_fstype $MP)
648 fi648 fi
649 case "$FST" in649 case "$FST" in
650 "ext3"|"reiserfs")650 "ext3")
651 PARSEDOPTS="$(parse_mount_opts_wfstab $DEV commit $OPTS)"651 PARSEDOPTS="$(parse_mount_opts_wfstab $DEV commit $OPTS)"
652 PARSEDOPTS="$(parse_yesno_opts_wfstab $DEV atime atime $PARSEDOPTS)"652 PARSEDOPTS="$(parse_yesno_opts_wfstab $DEV atime atime $PARSEDOPTS)"
653 mount $DEV -t $FST $MP -o remount,$PARSEDOPTS653 mount $DEV -t $FST $MP -o remount,$PARSEDOPTS
Documentation/admin-guide/laptops/sonypi.rst+1−1
@@ -25,7 +25,7 @@ generate, like: · 24 unmodified lines
25 (when available)25 (when available)
26 26
27Those events (see linux/sonypi.h) can be polled using the character device node27Those events (see linux/sonypi.h) can be polled using the character device node
28/dev/sonypi (major 10, minor auto allocated or specified as a option).28/dev/sonypi (major 10, minor auto allocated or specified as an option).
29A simple daemon which translates the jogdial movements into mouse wheel events29A simple daemon which translates the jogdial movements into mouse wheel events
30can be downloaded at: <http://popies.net/sonypi/>30can be downloaded at: <http://popies.net/sonypi/>
31 31
Documentation/admin-guide/md.rst+1−1
@@ -794,7 +794,7 @@ These currently include: · 793 unmodified lines
794 794
795 journal_mode (currently raid5 only)795 journal_mode (currently raid5 only)
796 The cache mode for raid5. raid5 could include an extra disk for796 The cache mode for raid5. raid5 could include an extra disk for
797 caching. The mode can be "write-throuth" and "write-back". The797 caching. The mode can be "write-through" or "write-back". The
798 default is "write-through".798 default is "write-through".
799 799
800 ppl_write_hint800 ppl_write_hint
Documentation/admin-guide/media/imx.rst+1−1
@@ -96,7 +96,7 @@ Some of the features of this driver include: · 95 unmodified lines
96 motion compensation modes: low, medium, and high motion. Pipelines are96 motion compensation modes: low, medium, and high motion. Pipelines are
97 defined that allow sending frames to the VDIC subdev directly from the97 defined that allow sending frames to the VDIC subdev directly from the
98 CSI. There is also support in the future for sending frames to the98 CSI. There is also support in the future for sending frames to the
99 VDIC from memory buffers via a output/mem2mem devices.99 VDIC from memory buffers via output/mem2mem devices.
100 100
101- Includes a Frame Interval Monitor (FIM) that can correct vertical sync101- Includes a Frame Interval Monitor (FIM) that can correct vertical sync
102 problems with the ADV718x video decoders.102 problems with the ADV718x video decoders.
Documentation/admin-guide/media/si4713.rst+3−3
@@ -13,7 +13,7 @@ Contact: Eduardo Valentin <eduardo.valentin@nokia.com> · 12 unmodified lines
13Information about the Device13Information about the Device
14----------------------------14----------------------------
15 15
16This chip is a Silicon Labs product. It is a I2C device, currently on 0x63 address.16This chip is a Silicon Labs product. It is an I2C device, currently on 0x63 address.
17Basically, it has transmission and signal noise level measurement features.17Basically, it has transmission and signal noise level measurement features.
18 18
19The Si4713 integrates transmit functions for FM broadcast stereo transmission.19The Si4713 integrates transmit functions for FM broadcast stereo transmission.
@@ -28,7 +28,7 @@ Users must comply with local regulations on radio frequency (RF) transmission. · 8 unmodified lines
28Device driver description28Device driver description
29-------------------------29-------------------------
30 30
31There are two modules to handle this device. One is a I2C device driver31There are two modules to handle this device. One is an I2C device driver
32and the other is a platform driver.32and the other is a platform driver.
33 33
34The I2C device driver exports a v4l2-subdev interface to the kernel.34The I2C device driver exports a v4l2-subdev interface to the kernel.
@@ -113,7 +113,7 @@ Here is a summary of them: · 78 unmodified lines
113- acomp_attack_time - Sets the attack time for audio dynamic range control.113- acomp_attack_time - Sets the attack time for audio dynamic range control.
114- acomp_release_time - Sets the release time for audio dynamic range control.114- acomp_release_time - Sets the release time for audio dynamic range control.
115 115
116* Limiter setups audio deviation limiter feature. Once a over deviation occurs,116* Limiter sets up the audio deviation limiter feature. Once an over deviation occurs,
117 it is possible to adjust the front-end gain of the audio input and always117 it is possible to adjust the front-end gain of the audio input and always
118 prevent over deviation.118 prevent over deviation.
119 119
Documentation/admin-guide/mm/damon/usage.rst+1−1
@@ -360,7 +360,7 @@ The directory for the :ref:`quotas <damon_design_damos_quotas>` of the given · 359 unmodified lines
360DAMON-based operation scheme.360DAMON-based operation scheme.
361 361
362Under ``quotas`` directory, four files (``ms``, ``bytes``,362Under ``quotas`` directory, four files (``ms``, ``bytes``,
363``reset_interval_ms``, ``effective_bytes``) and two directores (``weights`` and363``reset_interval_ms``, ``effective_bytes``) and two directories (``weights`` and
364``goals``) exist.364``goals``) exist.
365 365
366You can set the ``time quota`` in milliseconds, ``size quota`` in bytes, and366You can set the ``time quota`` in milliseconds, ``size quota`` in bytes, and
Documentation/admin-guide/nfs/nfsroot.rst+1−1
@@ -342,7 +342,7 @@ They depend on various facilities being available: · 341 unmodified lines
342 When using pxelinux, the kernel image is specified using342 When using pxelinux, the kernel image is specified using
343 "kernel <relative-path-below /tftpboot>". The nfsroot parameters343 "kernel <relative-path-below /tftpboot>". The nfsroot parameters
344 are passed to the kernel by adding them to the "append" line.344 are passed to the kernel by adding them to the "append" line.
345 It is common to use serial console in conjunction with pxeliunx,345 It is common to use serial console in conjunction with pxelinux,
346 see Documentation/admin-guide/serial-console.rst for more information.346 see Documentation/admin-guide/serial-console.rst for more information.
347 347
348 For more information on isolinux, including how to create bootdisks348 For more information on isolinux, including how to create bootdisks
Documentation/admin-guide/perf/hisi-pmu.rst+2−2
@@ -110,8 +110,8 @@ uring channel. It is 2 bits. Some important codes are as follows: · 109 unmodified lines
110- 2'b11: count the events which sent to the uring_ext (MATA) channel;110- 2'b11: count the events which sent to the uring_ext (MATA) channel;
111- 2'b01: is the same as 2'b11;111- 2'b01: is the same as 2'b11;
112- 2'b10: count the events which sent to the uring (non-MATA) channel;112- 2'b10: count the events which sent to the uring (non-MATA) channel;
113- 2'b00: default value, count the events which sent to the both uring and113- 2'b00: default value, count the events which sent to both uring and
114 uring_ext channel;114 uring_ext channels;
115 115
1166. ch: NoC PMU supports filtering the event counts of certain transaction1166. ch: NoC PMU supports filtering the event counts of certain transaction
117channel with this option. The current supported channels are as follows:117channel with this option. The current supported channels are as follows:
Documentation/admin-guide/quickly-build-trimmed-linux.rst+2−2
@@ -273,7 +273,7 @@ again. · 272 unmodified lines
273 does nothing at all; in that case you have to manually install your kernel,273 does nothing at all; in that case you have to manually install your kernel,
274 as outlined in the reference section.274 as outlined in the reference section.
275 275
276 If you are running a immutable Linux distribution, check its documentation276 If you are running an immutable Linux distribution, check its documentation
277 and the web to find out how to install your own kernel there.277 and the web to find out how to install your own kernel there.
278 278
279 [:ref:`details<install>`]279 [:ref:`details<install>`]
@@ -884,7 +884,7 @@ When a build error occurs, it might be caused by some aspect of your machine's · 604 unmodified lines
884setup that often can be fixed quickly; other times though the problem lies in884setup that often can be fixed quickly; other times though the problem lies in
885the code and can only be fixed by a developer. A close examination of the885the code and can only be fixed by a developer. A close examination of the
886failure messages coupled with some research on the internet will often tell you886failure messages coupled with some research on the internet will often tell you
887which of the two it is. To perform such a investigation, restart the build887which of the two it is. To perform such an investigation, restart the build
888process like this::888process like this::
889 889
890 make V=1890 make V=1
Documentation/admin-guide/reporting-issues.rst+2−2
@@ -611,7 +611,7 @@ better place. · 610 unmodified lines
611 611
612How to read the MAINTAINERS file612How to read the MAINTAINERS file
613~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~613~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
614To illustrate how to use the :ref:`MAINTAINERS <maintainers>` file, lets assume614To illustrate how to use the :ref:`MAINTAINERS <maintainers>` file, let's assume
615the WiFi in your Laptop suddenly misbehaves after updating the kernel. In that615the WiFi in your Laptop suddenly misbehaves after updating the kernel. In that
616case it's likely an issue in the WiFi driver. Obviously it could also be some616case it's likely an issue in the WiFi driver. Obviously it could also be some
617code it builds upon, but unless you suspect something like that stick to the617code it builds upon, but unless you suspect something like that stick to the
@@ -1543,7 +1543,7 @@ as well, because that will speed things up. · 925 unmodified lines
1543 1543
1544And note, it helps developers a great deal if you can specify the exact version1544And note, it helps developers a great deal if you can specify the exact version
1545that introduced the problem. Hence if possible within a reasonable time frame,1545that introduced the problem. Hence if possible within a reasonable time frame,
1546try to find that version using vanilla kernels. Lets assume something broke when1546try to find that version using vanilla kernels. Let's assume something broke when
1547your distributor released a update from Linux kernel 5.10.5 to 5.10.8. Then as1547your distributor released a update from Linux kernel 5.10.5 to 5.10.8. Then as
1548instructed above go and check the latest kernel from that version line, say1548instructed above go and check the latest kernel from that version line, say
15495.10.9. If it shows the problem, try a vanilla 5.10.5 to ensure that no patches15495.10.9. If it shows the problem, try a vanilla 5.10.5 to ensure that no patches
Documentation/admin-guide/sysctl/fs.rst+2−2
@@ -164,8 +164,8 @@ pipe-user-pages-soft · 163 unmodified lines
164--------------------164--------------------
165 165
166Maximum total number of pages a non-privileged user may allocate for pipes166Maximum total number of pages a non-privileged user may allocate for pipes
167before the pipe size gets limited to a single page. Once this limit is reached,167before the pipe size gets limited to two pages. Once this limit is reached,
168new pipes will be limited to a single page in size for this user in order to168new pipes will be limited to two pages in size for this user in order to
169limit total memory usage, and trying to increase them using ``fcntl()`` will be169limit total memory usage, and trying to increase them using ``fcntl()`` will be
170denied until usage goes below the limit again. The default value allows to170denied until usage goes below the limit again. The default value allows to
171allocate up to 1024 pipes at their default size. When set to 0, no limit is171allocate up to 1024 pipes at their default size. When set to 0, no limit is
Documentation/admin-guide/sysctl/index.rst+12−6
@@ -66,25 +66,31 @@ This documentation is about: · 65 unmodified lines
66 66
67=============== ===============================================================67=============== ===============================================================
68abi/ execution domains & personalities68abi/ execution domains & personalities
69debug/ <empty>69<$ARCH> tuning controls for various CPU architecture (e.g. csky, s390)
70dev/ device specific information (eg dev/cdrom/info)70crypto/ <undocumented>
71debug/ <undocumented>
72dev/ device specific information (e.g. dev/cdrom/info)
71fs/ specific filesystems73fs/ specific filesystems
72 filehandle, inode, dentry and quota tuning74 filehandle, inode, dentry and quota tuning
73 binfmt_misc <Documentation/admin-guide/binfmt-misc.rst>75 binfmt_misc <Documentation/admin-guide/binfmt-misc.rst>
74kernel/ global kernel info / tuning76kernel/ global kernel info / tuning
75 miscellaneous stuff77 miscellaneous stuff
78 some architecture-specific controls
79 security (LSM) stuff
76net/ networking stuff, for documentation look in:80net/ networking stuff, for documentation look in:
77 <Documentation/networking/>81 <Documentation/networking/>
78proc/ <empty>82proc/ <empty>
79sunrpc/ SUN Remote Procedure Call (NFS)83sunrpc/ SUN Remote Procedure Call (NFS)
84user/ Per user namespace limits
80vm/ memory management tuning85vm/ memory management tuning
81 buffer and cache management86 buffer and cache management
82user/ Per user per user namespace limits87xen/ <undocumented>
83=============== ===============================================================88=============== ===============================================================
84 89
85These are the subdirs I have on my system. There might be more90These are the subdirs I have on my system or have been discovered by
86or other subdirs in another setup. If you see another dir, I'd91searching through the source code. There might be more or other subdirs
87really like to hear about it :-)92in another setup. If you see another dir, I'd really like to hear about
93it :-)
88 94
89.. toctree::95.. toctree::
90 :maxdepth: 196 :maxdepth: 1
Documentation/admin-guide/verify-bugs-and-bisect-regressions.rst+1−1
@@ -1757,7 +1757,7 @@ or all of these tasks: · 1756 unmodified lines
1757 to your bootloader's configuration.1757 to your bootloader's configuration.
1758 1758
1759You have to take care of some or all of the tasks yourself, if your1759You have to take care of some or all of the tasks yourself, if your
1760distribution lacks a installkernel script or does only handle part of them.1760distribution lacks an installkernel script or does only handle part of them.
1761Consult the distribution's documentation for details. If in doubt, install the1761Consult the distribution's documentation for details. If in doubt, install the
1762kernel manually::1762kernel manually::
1763 1763
Documentation/arch/arm/stm32/stm32f746-overview.rst+1−1
@@ -15,7 +15,7 @@ It features: · 14 unmodified lines
15- SD/MMC/SDIO support15- SD/MMC/SDIO support
16- Ethernet controller16- Ethernet controller
17- USB OTFG FS & HS controllers17- USB OTFG FS & HS controllers
18- I2C, SPI, CAN busses support18- I2C, SPI, CAN buses support
19- Several 16 & 32 bits general purpose timers19- Several 16 & 32 bits general purpose timers
20- Serial Audio interface20- Serial Audio interface
21- LCD controller21- LCD controller
Documentation/arch/arm/stm32/stm32f769-overview.rst+1−1
@@ -15,7 +15,7 @@ It features: · 14 unmodified lines
15- SD/MMC/SDIO support*215- SD/MMC/SDIO support*2
16- Ethernet controller16- Ethernet controller
17- USB OTFG FS & HS controllers17- USB OTFG FS & HS controllers
18- I2C*4, SPI*6, CAN*3 busses support18- I2C*4, SPI*6, CAN*3 buses support
19- Several 16 & 32 bits general purpose timers19- Several 16 & 32 bits general purpose timers
20- Serial Audio interface*220- Serial Audio interface*2
21- LCD controller21- LCD controller
Documentation/arch/arm/stm32/stm32h743-overview.rst+1−1
@@ -15,7 +15,7 @@ It features: · 14 unmodified lines
15- SD/MMC/SDIO support15- SD/MMC/SDIO support
16- Ethernet controller16- Ethernet controller
17- USB OTFG FS & HS controllers17- USB OTFG FS & HS controllers
18- I2C, SPI, CAN busses support18- I2C, SPI, CAN buses support
19- Several 16 & 32 bits general purpose timers19- Several 16 & 32 bits general purpose timers
20- Serial Audio interface20- Serial Audio interface
21- LCD controller21- LCD controller
Documentation/arch/arm/stm32/stm32h750-overview.rst+1−1
@@ -15,7 +15,7 @@ It features: · 14 unmodified lines
15- SD/MMC/SDIO support15- SD/MMC/SDIO support
16- Ethernet controller16- Ethernet controller
17- USB OTFG FS & HS controllers17- USB OTFG FS & HS controllers
18- I2C, SPI, CAN busses support18- I2C, SPI, CAN buses support
19- Several 16 & 32 bits general purpose timers19- Several 16 & 32 bits general purpose timers
20- Serial Audio interface20- Serial Audio interface
21- LCD controller21- LCD controller
Documentation/arch/arm/stm32/stm32mp13-overview.rst+1−1
@@ -24,7 +24,7 @@ More details: · 23 unmodified lines
24- ADC/DAC24- ADC/DAC
25- USB EHCI/OHCI controllers25- USB EHCI/OHCI controllers
26- USB OTG26- USB OTG
27- I2C, SPI, CAN busses support27- I2C, SPI, CAN buses support
28- Several general purpose timers28- Several general purpose timers
29- Serial Audio interface29- Serial Audio interface
30- LCD controller30- LCD controller
Documentation/arch/arm/stm32/stm32mp151-overview.rst+1−1
@@ -23,7 +23,7 @@ More details: · 22 unmodified lines
23- ADC/DAC23- ADC/DAC
24- USB EHCI/OHCI controllers24- USB EHCI/OHCI controllers
25- USB OTG25- USB OTG
26- I2C, SPI busses support26- I2C, SPI buses support
27- Several general purpose timers27- Several general purpose timers
28- Serial Audio interface28- Serial Audio interface
29- LCD-TFT controller29- LCD-TFT controller
Documentation/arch/loongarch/irq-chip-model.rst+2−2
@@ -139,13 +139,13 @@ Feature EXTIOI_HAS_INT_ENCODE is part of standard EIOINTC. If it is 1, it · 138 unmodified lines
139indicates that CPU Interrupt Pin selection can be normal method rather than139indicates that CPU Interrupt Pin selection can be normal method rather than
140bitmap method, so interrupt can be routed to IP0 - IP15.140bitmap method, so interrupt can be routed to IP0 - IP15.
141 141
142Feature EXTIOI_HAS_CPU_ENCODE is entension of V-EIOINTC. If it is 1, it142Feature EXTIOI_HAS_CPU_ENCODE is extension of V-EIOINTC. If it is 1, it
143indicates that CPU selection can be normal method rather than bitmap method,143indicates that CPU selection can be normal method rather than bitmap method,
144so interrupt can be routed to CPU0 - CPU255.144so interrupt can be routed to CPU0 - CPU255.
145 145
146EXTIOI_VIRT_CONFIG146EXTIOI_VIRT_CONFIG
147------------------147------------------
148This register is read-write register, for compatibility intterupt routed uses148This register is read-write register, for compatibility interrupt routed uses
149the default method which is the same with standard EIOINTC. If the bit is set149the default method which is the same with standard EIOINTC. If the bit is set
150with 1, it indicated HW to use normal method rather than bitmap method.150with 1, it indicated HW to use normal method rather than bitmap method.
151 151
Documentation/arch/powerpc/eeh-pci-error-recovery.rst+0−1
@@ -315,7 +315,6 @@ network daemons and file systems that didn't need to be disturbed. · 314 unmodified lines
315 ideally, the reset should happen at or below the block layer,315 ideally, the reset should happen at or below the block layer,
316 so that the file systems are not disturbed.316 so that the file systems are not disturbed.
317 317
318 Reiserfs does not tolerate errors returned from the block device.
319 Ext3fs seems to be tolerant, retrying reads/writes until it does318 Ext3fs seems to be tolerant, retrying reads/writes until it does
320 succeed. Both have been only lightly tested in this scenario.319 succeed. Both have been only lightly tested in this scenario.
321 320
Documentation/arch/x86/cpuinfo.rst+1−1
@@ -11,7 +11,7 @@ The list of feature flags in /proc/cpuinfo is not complete and · 10 unmodified lines
11represents an ill-fated attempt from long time ago to put feature flags11represents an ill-fated attempt from long time ago to put feature flags
12in an easy to find place for userspace.12in an easy to find place for userspace.
13 13
14However, the amount of feature flags is growing by the CPU generation,14However, the number of feature flags is growing with each CPU generation,
15leading to unparseable and unwieldy /proc/cpuinfo.15leading to unparseable and unwieldy /proc/cpuinfo.
16 16
17What is more, those feature flags do not even need to be in that file17What is more, those feature flags do not even need to be in that file
Documentation/conf.py+61−45
@@ -9,6 +9,8 @@ import os · 8 unmodified lines
9import shutil9import shutil
10import sys10import sys
11 11
12from textwrap import dedent
13
12import sphinx14import sphinx
13 15
14# If extensions (or modules to document with autodoc) are in another directory,16# If extensions (or modules to document with autodoc) are in another directory,
@@ -51,11 +53,13 @@ else: · 36 unmodified lines
51 dyn_exclude_patterns.append("devicetree/bindings/**.yaml")53 dyn_exclude_patterns.append("devicetree/bindings/**.yaml")
52 dyn_exclude_patterns.append("core-api/kho/bindings/**.yaml")54 dyn_exclude_patterns.append("core-api/kho/bindings/**.yaml")
53 55
54# Properly handle include/exclude patterns56# Properly handle directory patterns and LaTeX docs
55# ----------------------------------------57# -------------------------------------------------
56 58
57def update_patterns(app, config):59def config_init(app, config):
58 """60 """
61 Initialize path-dependent variabled
62
59 On Sphinx, all directories are relative to what it is passed as63 On Sphinx, all directories are relative to what it is passed as
60 SOURCEDIR parameter for sphinx-build. Due to that, all patterns64 SOURCEDIR parameter for sphinx-build. Due to that, all patterns
61 that have directory names on it need to be dynamically set, after65 that have directory names on it need to be dynamically set, after
@@ -86,6 +90,38 @@ def update_patterns(app, config): · 24 unmodified lines
86 90
87 config.exclude_patterns.append(rel_path)91 config.exclude_patterns.append(rel_path)
88 92
93 # LaTeX and PDF output require a list of documents with are dependent
94 # of the app.srcdir. Add them here
95
96 # When SPHINXDIRS is used, we just need to get index.rst, if it exists
97 if not os.path.samefile(doctree, app.srcdir):
98 doc = os.path.basename(app.srcdir)
99 fname = "index"
100 if os.path.exists(os.path.join(app.srcdir, fname + ".rst")):
101 latex_documents.append((fname, doc + ".tex",
102 "Linux %s Documentation" % doc.capitalize(),
103 "The kernel development community",
104 "manual"))
105 return
106
107 # When building all docs, or when a main index.rst doesn't exist, seek
108 # for it on subdirectories
109 for doc in os.listdir(app.srcdir):
110 fname = os.path.join(doc, "index")
111 if not os.path.exists(os.path.join(app.srcdir, fname + ".rst")):
112 continue
113
114 has = False
115 for l in latex_documents:
116 if l[0] == fname:
117 has = True
118 break
119
120 if not has:
121 latex_documents.append((fname, doc + ".tex",
122 "Linux %s Documentation" % doc.capitalize(),
123 "The kernel development community",
124 "manual"))
89 125
90# helper126# helper
91# ------127# ------
@@ -234,7 +270,7 @@ author = "The kernel development community" · 142 unmodified lines
234# |version| and |release|, also used in various other places throughout the270# |version| and |release|, also used in various other places throughout the
235# built documents.271# built documents.
236#272#
237# In a normal build, version and release are are set to KERNELVERSION and273# In a normal build, version and release are set to KERNELVERSION and
238# KERNELRELEASE, respectively, from the Makefile via Sphinx command line274# KERNELRELEASE, respectively, from the Makefile via Sphinx command line
239# arguments.275# arguments.
240#276#
@@ -420,19 +456,25 @@ htmlhelp_basename = "TheLinuxKerneldoc" · 179 unmodified lines
420latex_elements = {456latex_elements = {
421 # The paper size ('letterpaper' or 'a4paper').457 # The paper size ('letterpaper' or 'a4paper').
422 "papersize": "a4paper",458 "papersize": "a4paper",
459 "passoptionstopackages": dedent(r"""
460 \PassOptionsToPackage{svgnames}{xcolor}
461 """),
423 # The font size ('10pt', '11pt' or '12pt').462 # The font size ('10pt', '11pt' or '12pt').
424 "pointsize": "11pt",463 "pointsize": "11pt",
464 # Needed to generate a .ind file
465 "printindex": r"\footnotesize\raggedright\printindex",
425 # Latex figure (float) alignment466 # Latex figure (float) alignment
426 # 'figure_align': 'htbp',467 # 'figure_align': 'htbp',
427 # Don't mangle with UTF-8 chars468 # Don't mangle with UTF-8 chars
469 "fontenc": "",
428 "inputenc": "",470 "inputenc": "",
429 "utf8extra": "",471 "utf8extra": "",
430 # Set document margins472 # Set document margins
431 "sphinxsetup": """473 "sphinxsetup": dedent(r"""
432 hmargin=0.5in, vmargin=1in,474 hmargin=0.5in, vmargin=1in,
433 parsedliteralwraps=true,475 parsedliteralwraps=true,
434 verbatimhintsturnover=false,476 verbatimhintsturnover=false,
435 """,477 """),
436 #478 #
437 # Some of our authors are fond of deep nesting; tell latex to479 # Some of our authors are fond of deep nesting; tell latex to
438 # cope.480 # cope.
@@ -440,48 +482,22 @@ latex_elements = { · 1 unmodified line
440 "maxlistdepth": "10",482 "maxlistdepth": "10",
441 # For CJK One-half spacing, need to be in front of hyperref483 # For CJK One-half spacing, need to be in front of hyperref
442 "extrapackages": r"\usepackage{setspace}",484 "extrapackages": r"\usepackage{setspace}",
443 # Additional stuff for the LaTeX preamble.485 "fontpkg": dedent(r"""
444 "preamble": """486 \usepackage{fontspec}
445 % Use some font with UTF-8 support with XeLaTeX487 \setmainfont{DejaVu Serif}
446 \\usepackage{fontspec}488 \setsansfont{DejaVu Sans}
447 \\setsansfont{DejaVu Sans}489 \setmonofont{DejaVu Sans Mono}
448 \\setromanfont{DejaVu Serif}490 \newfontfamily\headingfont{DejaVu Serif}
449 \\setmonofont{DejaVu Sans Mono}491 """),
450 """,492 "preamble": dedent(r"""
451}
452
453# Load kerneldoc specific LaTeX settings
454latex_elements["preamble"] += """
455 % Load kerneldoc specific LaTeX settings493 % Load kerneldoc specific LaTeX settings
456 \\input{kerneldoc-preamble.sty}494 \input{kerneldoc-preamble.sty}
457"""495 """)
496}
458 497
459# Grouping the document tree into LaTeX files. List of tuples498# This will be filled up by config-inited event
460# (source start file, target name, title,
461# author, documentclass [howto, manual, or own class]).
462# Sorted in alphabetical order
463latex_documents = []499latex_documents = []
464 500
465# Add all other index files from Documentation/ subdirectories
466for fn in os.listdir("."):
467 doc = os.path.join(fn, "index")
468 if os.path.exists(doc + ".rst"):
469 has = False
470 for l in latex_documents:
471 if l[0] == doc:
472 has = True
473 break
474 if not has:
475 latex_documents.append(
476 (
477 doc,
478 fn + ".tex",
479 "Linux %s Documentation" % fn.capitalize(),
480 "The kernel development community",
481 "manual",
482 )
483 )
484
485# The name of an image file (relative to this directory) to place at the top of501# The name of an image file (relative to this directory) to place at the top of
486# the title page.502# the title page.
487# latex_logo = None503# latex_logo = None
@@ -577,4 +593,4 @@ loadConfig(globals()) · 89 unmodified lines
577def setup(app):593def setup(app):
578 """Patterns need to be updated at init time on older Sphinx versions"""594 """Patterns need to be updated at init time on older Sphinx versions"""
579 595
580 app.connect('config-inited', update_patterns)596 app.connect('config-inited', config_init)
Documentation/core-api/folio_queue.rst+1−1
@@ -44,7 +44,7 @@ Each segment in the list also stores: · 43 unmodified lines
44 * the size of each folio and44 * the size of each folio and
45 * three 1-bit marks per folio,45 * three 1-bit marks per folio,
46 46
47but hese should not be accessed directly as the underlying data structure may47but these should not be accessed directly as the underlying data structure may
48change, but rather the access functions outlined below should be used.48change, but rather the access functions outlined below should be used.
49 49
50The facility can be made accessible by::50The facility can be made accessible by::
Documentation/core-api/index.rst+1−0
@@ -24,6 +24,7 @@ it. · 23 unmodified lines
24 printk-index24 printk-index
25 symbol-namespaces25 symbol-namespaces
26 asm-annotations26 asm-annotations
27 real-time/index
27 28
28Data structures and low-level utilities29Data structures and low-level utilities
29=======================================30=======================================
Documentation/core-api/irq/irq-affinity.rst+3−3
@@ -9,9 +9,9 @@ ChangeLog: · 8 unmodified lines
9 9
10/proc/irq/IRQ#/smp_affinity and /proc/irq/IRQ#/smp_affinity_list specify10/proc/irq/IRQ#/smp_affinity and /proc/irq/IRQ#/smp_affinity_list specify
11which target CPUs are permitted for a given IRQ source. It's a bitmask11which target CPUs are permitted for a given IRQ source. It's a bitmask
12(smp_affinity) or cpu list (smp_affinity_list) of allowed CPUs. It's not12(smp_affinity) or CPU list (smp_affinity_list) of allowed CPUs. It's not
13allowed to turn off all CPUs, and if an IRQ controller does not support13allowed to turn off all CPUs, and if an IRQ controller does not support
14IRQ affinity then the value will not change from the default of all cpus.14IRQ affinity then the value will not change from the default of all CPUs.
15 15
16/proc/irq/default_smp_affinity specifies default affinity mask that applies16/proc/irq/default_smp_affinity specifies default affinity mask that applies
17to all non-active IRQs. Once IRQ is allocated/activated its affinity bitmask17to all non-active IRQs. Once IRQ is allocated/activated its affinity bitmask
@@ -60,7 +60,7 @@ Now lets restrict that IRQ to CPU(4-7). · 42 unmodified lines
60This time around IRQ44 was delivered only to the last four processors.60This time around IRQ44 was delivered only to the last four processors.
61i.e counters for the CPU0-3 did not change.61i.e counters for the CPU0-3 did not change.
62 62
63Here is an example of limiting that same irq (44) to cpus 1024 to 1031::63Here is an example of limiting that same IRQ (44) to CPUs 1024 to 1031::
64 64
65 [root@moon 44]# echo 1024-1031 > smp_affinity_list65 [root@moon 44]# echo 1024-1031 > smp_affinity_list
66 [root@moon 44]# cat smp_affinity_list66 [root@moon 44]# cat smp_affinity_list
Documentation/core-api/irq/irq-domain.rst+19−19
@@ -18,8 +18,8 @@ handlers as irqchips. I.e. in effect cascading interrupt controllers. · 17 unmodified lines
18So in the past, IRQ numbers could be chosen so that they match the18So in the past, IRQ numbers could be chosen so that they match the
19hardware IRQ line into the root interrupt controller (i.e. the19hardware IRQ line into the root interrupt controller (i.e. the
20component actually firing the interrupt line to the CPU). Nowadays,20component actually firing the interrupt line to the CPU). Nowadays,
21this number is just a number and the number loose all kind of21this number is just a number and the number has no
22correspondence to hardware interrupt numbers.22relationship to hardware interrupt numbers.
23 23
24For this reason, we need a mechanism to separate controller-local24For this reason, we need a mechanism to separate controller-local
25interrupt numbers, called hardware IRQs, from Linux IRQ numbers.25interrupt numbers, called hardware IRQs, from Linux IRQ numbers.
@@ -77,15 +77,15 @@ Once a mapping has been established, it can be retrieved or used via a · 51 unmodified lines
77variety of methods:77variety of methods:
78 78
79- irq_resolve_mapping() returns a pointer to the irq_desc structure79- irq_resolve_mapping() returns a pointer to the irq_desc structure
80 for a given domain and hwirq number, and NULL if there was no80 for a given domain and hwirq number, or NULL if there was no
81 mapping.81 mapping.
82- irq_find_mapping() returns a Linux IRQ number for a given domain and82- irq_find_mapping() returns a Linux IRQ number for a given domain and
83 hwirq number, and 0 if there was no mapping83 hwirq number, or 0 if there was no mapping
84- generic_handle_domain_irq() handles an interrupt described by a84- generic_handle_domain_irq() handles an interrupt described by a
85 domain and a hwirq number85 domain and a hwirq number
86 86
87Note that irq domain lookups must happen in contexts that are87Note that irq_domain lookups must happen in contexts that are
88compatible with a RCU read-side critical section.88compatible with an RCU read-side critical section.
89 89
90The irq_create_mapping() function must be called *at least once*90The irq_create_mapping() function must be called *at least once*
91before any call to irq_find_mapping(), lest the descriptor will not91before any call to irq_find_mapping(), lest the descriptor will not
@@ -100,7 +100,7 @@ Types of irq_domain Mappings · 8 unmodified lines
100============================100============================
101 101
102There are several mechanisms available for reverse mapping from hwirq102There are several mechanisms available for reverse mapping from hwirq
103to Linux irq, and each mechanism uses a different allocation function.103to Linux IRQ, and each mechanism uses a different allocation function.
104Which reverse map type should be used depends on the use case. Each104Which reverse map type should be used depends on the use case. Each
105of the reverse map types are described below:105of the reverse map types are described below:
106 106
@@ -111,13 +111,13 @@ Linear · 4 unmodified lines
111 111
112 irq_domain_create_linear()112 irq_domain_create_linear()
113 113
114The linear reverse map maintains a fixed size table indexed by the114The linear reverse map maintains a fixed-size table indexed by the
115hwirq number. When a hwirq is mapped, an irq_desc is allocated for115hwirq number. When a hwirq is mapped, an irq_desc is allocated for
116the hwirq, and the IRQ number is stored in the table.116the hwirq, and the IRQ number is stored in the table.
117 117
118The Linear map is a good choice when the maximum number of hwirqs is118The Linear map is a good choice when the maximum number of hwirqs is
119fixed and a relatively small number (~ < 256). The advantages of this119fixed and a relatively small number (~ < 256). The advantages of this
120map are fixed time lookup for IRQ numbers, and irq_descs are only120map are fixed-time lookup for IRQ numbers, and irq_descs are only
121allocated for in-use IRQs. The disadvantage is that the table must be121allocated for in-use IRQs. The disadvantage is that the table must be
122as large as the largest possible hwirq number.122as large as the largest possible hwirq number.
123 123
@@ -134,7 +134,7 @@ The irq_domain maintains a radix tree map from hwirq numbers to Linux · 10 unmodified lines
134IRQs. When an hwirq is mapped, an irq_desc is allocated and the134IRQs. When an hwirq is mapped, an irq_desc is allocated and the
135hwirq is used as the lookup key for the radix tree.135hwirq is used as the lookup key for the radix tree.
136 136
137The tree map is a good choice if the hwirq number can be very large137The Tree map is a good choice if the hwirq number can be very large
138since it doesn't need to allocate a table as large as the largest138since it doesn't need to allocate a table as large as the largest
139hwirq number. The disadvantage is that hwirq to IRQ number lookup is139hwirq number. The disadvantage is that hwirq to IRQ number lookup is
140dependent on how many entries are in the table.140dependent on how many entries are in the table.
@@ -169,10 +169,10 @@ Legacy · 28 unmodified lines
169 169
170The Legacy mapping is a special case for drivers that already have a170The Legacy mapping is a special case for drivers that already have a
171range of irq_descs allocated for the hwirqs. It is used when the171range of irq_descs allocated for the hwirqs. It is used when the
172driver cannot be immediately converted to use the linear mapping. For172driver cannot be immediately converted to use the Linear mapping. For
173example, many embedded system board support files use a set of #defines173example, many embedded system board support files use a set of #defines
174for IRQ numbers that are passed to struct device registrations. In that174for IRQ numbers that are passed to struct device registrations. In that
175case the Linux IRQ numbers cannot be dynamically assigned and the legacy175case the Linux IRQ numbers cannot be dynamically assigned and the Legacy
176mapping should be used.176mapping should be used.
177 177
178As the name implies, the \*_legacy() functions are deprecated and only178As the name implies, the \*_legacy() functions are deprecated and only
@@ -180,15 +180,15 @@ exist to ease the support of ancient platforms. No new users should be · 1 unmodified line
180added. Same goes for the \*_simple() functions when their use results180added. Same goes for the \*_simple() functions when their use results
181in the legacy behaviour.181in the legacy behaviour.
182 182
183The legacy map assumes a contiguous range of IRQ numbers has already183The Legacy map assumes a contiguous range of IRQ numbers has already
184been allocated for the controller and that the IRQ number can be184been allocated for the controller and that the IRQ number can be
185calculated by adding a fixed offset to the hwirq number, and185calculated by adding a fixed offset to the hwirq number, and
186visa-versa. The disadvantage is that it requires the interrupt186visa-versa. The disadvantage is that it requires the interrupt
187controller to manage IRQ allocations and it requires an irq_desc to be187controller to manage IRQ allocations and it requires an irq_desc to be
188allocated for every hwirq, even if it is unused.188allocated for every hwirq, even if it is unused.
189 189
190The legacy map should only be used if fixed IRQ mappings must be190The Legacy map should only be used if fixed IRQ mappings must be
191supported. For example, ISA controllers would use the legacy map for191supported. For example, ISA controllers would use the Legacy map for
192mapping Linux IRQs 0-15 so that existing ISA drivers get the correct IRQ192mapping Linux IRQs 0-15 so that existing ISA drivers get the correct IRQ
193numbers.193numbers.
194 194
@@ -197,7 +197,7 @@ which will use a legacy domain only if an IRQ range is supplied by the · 2 unmodified lines
197system and will otherwise use a linear domain mapping. The semantics of197system and will otherwise use a linear domain mapping. The semantics of
198this call are such that if an IRQ range is specified then descriptors198this call are such that if an IRQ range is specified then descriptors
199will be allocated on-the-fly for it, and if no range is specified it199will be allocated on-the-fly for it, and if no range is specified it
200will fall through to irq_domain_create_linear() which means *no* irq200will fall through to irq_domain_create_linear() which means *no* IRQ
201descriptors will be allocated.201descriptors will be allocated.
202 202
203A typical use case for simple domains is where an irqchip provider203A typical use case for simple domains is where an irqchip provider
@@ -214,7 +214,7 @@ Hierarchy IRQ Domain · 10 unmodified lines
214 214
215On some architectures, there may be multiple interrupt controllers215On some architectures, there may be multiple interrupt controllers
216involved in delivering an interrupt from the device to the target CPU.216involved in delivering an interrupt from the device to the target CPU.
217Let's look at a typical interrupt delivering path on x86 platforms::217Let's look at a typical interrupt delivery path on x86 platforms::
218 218
219 Device --> IOAPIC -> Interrupt remapping Controller -> Local APIC -> CPU219 Device --> IOAPIC -> Interrupt remapping Controller -> Local APIC -> CPU
220 220
@@ -227,8 +227,8 @@ There are three interrupt controllers involved: · 6 unmodified lines
227To support such a hardware topology and make software architecture match227To support such a hardware topology and make software architecture match
228hardware architecture, an irq_domain data structure is built for each228hardware architecture, an irq_domain data structure is built for each
229interrupt controller and those irq_domains are organized into hierarchy.229interrupt controller and those irq_domains are organized into hierarchy.
230When building irq_domain hierarchy, the irq_domain near to the device is230When building irq_domain hierarchy, the irq_domain nearest the device is
231child and the irq_domain near to CPU is parent. So a hierarchy structure231child and the irq_domain nearest the CPU is parent. So a hierarchy structure
232as below will be built for the example above::232as below will be built for the example above::
233 233
234 CPU Vector irq_domain (root irq_domain to manage CPU vectors)234 CPU Vector irq_domain (root irq_domain to manage CPU vectors)
Documentation/core-api/printk-formats.rst+1−1
@@ -521,7 +521,7 @@ Fwnode handles · 520 unmodified lines
521 521
522 %pfw[fP]522 %pfw[fP]
523 523
524For printing information on fwnode handles. The default is to print the full524For printing information on an fwnode_handle. The default is to print the full
525node name, including the path. The modifiers are functionally equivalent to525node name, including the path. The modifiers are functionally equivalent to
526%pOF above.526%pOF above.
527 527
Documentation/core-api/real-time/architecture-porting.rst+109−0
@@ -0,0 +1,109 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3=============================================
4Porting an architecture to support PREEMPT_RT
5=============================================
6
7:Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
8
9This list outlines the architecture specific requirements that must be
10implemented in order to enable PREEMPT_RT. Once all required features are
11implemented, ARCH_SUPPORTS_RT can be selected in architecture’s Kconfig to make
12PREEMPT_RT selectable.
13Many prerequisites (genirq support for example) are enforced by the common code
14and are omitted here.
15
16The optional features are not strictly required but it is worth to consider
17them.
18
19Requirements
20------------
21
22Forced threaded interrupts
23 CONFIG_IRQ_FORCED_THREADING must be selected. Any interrupts that must
24 remain in hard-IRQ context must be marked with IRQF_NO_THREAD. This
25 requirement applies for instance to clocksource event interrupts,
26 perf interrupts and cascading interrupt-controller handlers.
27
28PREEMPTION support
29 Kernel preemption must be supported and requires that
30 CONFIG_ARCH_NO_PREEMPT remain unselected. Scheduling requests, such as those
31 issued from an interrupt or other exception handler, must be processed
32 immediately.
33
34POSIX CPU timers and KVM
35 POSIX CPU timers must expire from thread context rather than directly within
36 the timer interrupt. This behavior is enabled by setting the configuration
37 option CONFIG_HAVE_POSIX_CPU_TIMERS_TASK_WORK.
38 When KVM is enabled, CONFIG_KVM_XFER_TO_GUEST_WORK must also be set to ensure
39 that any pending work, such as POSIX timer expiration, is handled before
40 transitioning into guest mode.
41
42Hard-IRQ and Soft-IRQ stacks
43 Soft interrupts are handled in the thread context in which they are raised. If
44 a soft interrupt is triggered from hard-IRQ context, its execution is deferred
45 to the ksoftirqd thread. Preemption is never disabled during soft interrupt
46 handling, which makes soft interrupts preemptible.
47 If an architecture provides a custom __do_softirq() implementation that uses a
48 separate stack, it must select CONFIG_HAVE_SOFTIRQ_ON_OWN_STACK. The
49 functionality should only be enabled when CONFIG_SOFTIRQ_ON_OWN_STACK is set.
50
51FPU and SIMD access in kernel mode
52 FPU and SIMD registers are typically not used in kernel mode and are therefore
53 not saved during kernel preemption. As a result, any kernel code that uses
54 these registers must be enclosed within a kernel_fpu_begin() and
55 kernel_fpu_end() section.
56 The kernel_fpu_begin() function usually invokes local_bh_disable() to prevent
57 interruptions from softirqs and to disable regular preemption. This allows the
58 protected code to run safely in both thread and softirq contexts.
59 On PREEMPT_RT kernels, however, kernel_fpu_begin() must not call
60 local_bh_disable(). Instead, it should use preempt_disable(), since softirqs
61 are always handled in thread context under PREEMPT_RT. In this case, disabling
62 preemption alone is sufficient.
63 The crypto subsystem operates on memory pages and requires users to "walk and
64 map" these pages while processing a request. This operation must occur outside
65 the kernel_fpu_begin()/ kernel_fpu_end() section because it requires preemption
66 to be enabled. These preemption points are generally sufficient to avoid
67 excessive scheduling latency.
68
69Exception handlers
70 Exception handlers, such as the page fault handler, typically enable interrupts
71 early, before invoking any generic code to process the exception. This is
72 necessary because handling a page fault may involve operations that can sleep.
73 Enabling interrupts is especially important on PREEMPT_RT, where certain
74 locks, such as spinlock_t, become sleepable. For example, handling an
75 invalid opcode may result in sending a SIGILL signal to the user task. A
76 debug excpetion will send a SIGTRAP signal.
77 In both cases, if the exception occurred in user space, it is safe to enable
78 interrupts early. Sending a signal requires both interrupts and kernel
79 preemption to be enabled.
80
81Optional features
82-----------------
83
84Timer and clocksource
85 A high-resolution clocksource and clockevents device are recommended. The
86 clockevents device should support the CLOCK_EVT_FEAT_ONESHOT feature for
87 optimal timer behavior. In most cases, microsecond-level accuracy is
88 sufficient
89
90Lazy preemption
91 This mechanism allows an in-kernel scheduling request for non-real-time tasks
92 to be delayed until the task is about to return to user space. It helps avoid
93 preempting a task that holds a sleeping lock at the time of the scheduling
94 request.
95 With CONFIG_GENERIC_IRQ_ENTRY enabled, supporting this feature requires
96 defining a bit for TIF_NEED_RESCHED_LAZY, preferably near TIF_NEED_RESCHED.
97
98Serial console with NBCON
99 With PREEMPT_RT enabled, all console output is handled by a dedicated thread
100 rather than directly from the context in which printk() is invoked. This design
101 allows printk() to be safely used in atomic contexts.
102 However, this also means that if the kernel crashes and cannot switch to the
103 printing thread, no output will be visible preventing the system from printing
104 its final messages.
105 There are exceptions for immediate output, such as during panic() handling. To
106 support this, the console driver must implement new-style lock handling. This
107 involves setting the CON_NBCON flag in console::flags and providing
108 implementations for the write_atomic, write_thread, device_lock, and
109 device_unlock callbacks.
Documentation/core-api/real-time/differences.rst+242−0
@@ -0,0 +1,242 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3===========================
4How realtime kernels differ
5===========================
6
7:Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
8
9Preface
10=======
11
12With forced-threaded interrupts and sleeping spin locks, code paths that
13previously caused long scheduling latencies have been made preemptible and
14moved into process context. This allows the scheduler to manage them more
15effectively and respond to higher-priority tasks with reduced latency.
16
17The following chapters provide an overview of key differences between a
18PREEMPT_RT kernel and a standard, non-PREEMPT_RT kernel.
19
20Locking
21=======
22
23Spinning locks such as spinlock_t are used to provide synchronization for data
24structures accessed from both interrupt context and process context. For this
25reason, locking functions are also available with the _irq() or _irqsave()
26suffixes, which disable interrupts before acquiring the lock. This ensures that
27the lock can be safely acquired in process context when interrupts are enabled.
28
29However, on a PREEMPT_RT system, interrupts are forced-threaded and no longer
30run in hard IRQ context. As a result, there is no need to disable interrupts as
31part of the locking procedure when using spinlock_t.
32
33For low-level core components such as interrupt handling, the scheduler, or the
34timer subsystem the kernel uses raw_spinlock_t. This lock type preserves
35traditional semantics: it disables preemption and, when used with _irq() or
36_irqsave(), also disables interrupts. This ensures proper synchronization in
37critical sections that must remain non-preemptible or with interrupts disabled.
38
39Execution context
40=================
41
42Interrupt handling in a PREEMPT_RT system is invoked in process context through
43the use of threaded interrupts. Other parts of the kernel also shift their
44execution into threaded context by different mechanisms. The goal is to keep
45execution paths preemptible, allowing the scheduler to interrupt them when a
46higher-priority task needs to run.
47
48Below is an overview of the kernel subsystems involved in this transition to
49threaded, preemptible execution.
50
51Interrupt handling
52------------------
53
54All interrupts are forced-threaded in a PREEMPT_RT system. The exceptions are
55interrupts that are requested with the IRQF_NO_THREAD, IRQF_PERCPU, or
56IRQF_ONESHOT flags.
57
58The IRQF_ONESHOT flag is used together with threaded interrupts, meaning those
59registered using request_threaded_irq() and providing only a threaded handler.
60Its purpose is to keep the interrupt line masked until the threaded handler has
61completed.
62
63If a primary handler is also provided in this case, it is essential that the
64handler does not acquire any sleeping locks, as it will not be threaded. The
65handler should be minimal and must avoid introducing delays, such as
66busy-waiting on hardware registers.
67
68
69Soft interrupts, bottom half handling
70-------------------------------------
71
72Soft interrupts are raised by the interrupt handler and are executed after the
73handler returns. Since they run in thread context, they can be preempted by
74other threads. Do not assume that softirq context runs with preemption
75disabled. This means you must not rely on mechanisms like local_bh_disable() in
76process context to protect per-CPU variables. Because softirq handlers are
77preemptible under PREEMPT_RT, this approach does not provide reliable
78synchronization.
79
80If this kind of protection is required for performance reasons, consider using
81local_lock_nested_bh(). On non-PREEMPT_RT kernels, this allows lockdep to
82verify that bottom halves are disabled. On PREEMPT_RT systems, it adds the
83necessary locking to ensure proper protection.
84
85Using local_lock_nested_bh() also makes the locking scope explicit and easier
86for readers and maintainers to understand.
87
88
89per-CPU variables
90-----------------
91
92Protecting access to per-CPU variables solely by using preempt_disable() should
93be avoided, especially if the critical section has unbounded runtime or may
94call APIs that can sleep.
95
96If using a spinlock_t is considered too costly for performance reasons,
97consider using local_lock_t. On non-PREEMPT_RT configurations, this introduces
98no runtime overhead when lockdep is disabled. With lockdep enabled, it verifies
99that the lock is only acquired in process context and never from softirq or
100hard IRQ context.
101
102On a PREEMPT_RT kernel, local_lock_t is implemented using a per-CPU spinlock_t,
103which provides safe local protection for per-CPU data while keeping the system
104preemptible.
105
106Because spinlock_t on PREEMPT_RT does not disable preemption, it cannot be used
107to protect per-CPU data by relying on implicit preemption disabling. If this
108inherited preemption disabling is essential and if local_lock_t cannot be used
109due to performance constraints, brevity of the code, or abstraction boundaries
110within an API then preempt_disable_nested() may be a suitable alternative. On
111non-PREEMPT_RT kernels, it verifies with lockdep that preemption is already
112disabled. On PREEMPT_RT, it explicitly disables preemption.
113
114Timers
115------
116
117By default, an hrtimer is executed in hard interrupt context. The exception is
118timers initialized with the HRTIMER_MODE_SOFT flag, which are executed in
119softirq context.
120
121On a PREEMPT_RT kernel, this behavior is reversed: hrtimers are executed in
122softirq context by default, typically within the ktimersd thread. This thread
123runs at the lowest real-time priority, ensuring it executes before any
124SCHED_OTHER tasks but does not interfere with higher-priority real-time
125threads. To explicitly request execution in hard interrupt context on
126PREEMPT_RT, the timer must be marked with the HRTIMER_MODE_HARD flag.
127
128Memory allocation
129-----------------
130
131The memory allocation APIs, such as kmalloc() and alloc_pages(), require a
132gfp_t flag to indicate the allocation context. On non-PREEMPT_RT kernels, it is
133necessary to use GFP_ATOMIC when allocating memory from interrupt context or
134from sections where preemption is disabled. This is because the allocator must
135not sleep in these contexts waiting for memory to become available.
136
137However, this approach does not work on PREEMPT_RT kernels. The memory
138allocator in PREEMPT_RT uses sleeping locks internally, which cannot be
139acquired when preemption is disabled. Fortunately, this is generally not a
140problem, because PREEMPT_RT moves most contexts that would traditionally run
141with preemption or interrupts disabled into threaded context, where sleeping is
142allowed.
143
144What remains problematic is code that explicitly disables preemption or
145interrupts. In such cases, memory allocation must be performed outside the
146critical section.
147
148This restriction also applies to memory deallocation routines such as kfree()
149and free_pages(), which may also involve internal locking and must not be
150called from non-preemptible contexts.
151
152IRQ work
153--------
154
155The irq_work API provides a mechanism to schedule a callback in interrupt
156context. It is designed for use in contexts where traditional scheduling is not
157possible, such as from within NMI handlers or from inside the scheduler, where
158using a workqueue would be unsafe.
159
160On non-PREEMPT_RT systems, all irq_work items are executed immediately in
161interrupt context. Items marked with IRQ_WORK_LAZY are deferred until the next
162timer tick but are still executed in interrupt context.
163
164On PREEMPT_RT systems, the execution model changes. Because irq_work callbacks
165may acquire sleeping locks or have unbounded execution time, they are handled
166in thread context by a per-CPU irq_work kernel thread. This thread runs at the
167lowest real-time priority, ensuring it executes before any SCHED_OTHER tasks
168but does not interfere with higher-priority real-time threads.
169
170The exception are work items marked with IRQ_WORK_HARD_IRQ, which are still
171executed in hard interrupt context. Lazy items (IRQ_WORK_LAZY) continue to be
172deferred until the next timer tick and are also executed by the irq_work/
173thread.
174
175RCU callbacks
176-------------
177
178RCU callbacks are invoked by default in softirq context. Their execution is
179important because, depending on the use case, they either free memory or ensure
180progress in state transitions. Running these callbacks as part of the softirq
181chain can lead to undesired situations, such as contention for CPU resources
182with other SCHED_OTHER tasks when executed within ksoftirqd.
183
184To avoid running callbacks in softirq context, the RCU subsystem provides a
185mechanism to execute them in process context instead. This behavior can be
186enabled by setting the boot command-line parameter rcutree.use_softirq=0. This
187setting is enforced in kernels configured with PREEMPT_RT.
188
189Spin until ready
190================
191
192The "spin until ready" pattern involves repeatedly checking (spinning on) the
193state of a data structure until it becomes available. This pattern assumes that
194preemption, soft interrupts, or interrupts are disabled. If the data structure
195is marked busy, it is presumed to be in use by another CPU, and spinning should
196eventually succeed as that CPU makes progress.
197
198Some examples are hrtimer_cancel() or timer_delete_sync(). These functions
199cancel timers that execute with interrupts or soft interrupts disabled. If a
200thread attempts to cancel a timer and finds it active, spinning until the
201callback completes is safe because the callback can only run on another CPU and
202will eventually finish.
203
204On PREEMPT_RT kernels, however, timer callbacks run in thread context. This
205introduces a challenge: a higher-priority thread attempting to cancel the timer
206may preempt the timer callback thread. Since the scheduler cannot migrate the
207callback thread to another CPU due to affinity constraints, spinning can result
208in livelock even on multiprocessor systems.
209
210To avoid this, both the canceling and callback sides must use a handshake
211mechanism that supports priority inheritance. This allows the canceling thread
212to suspend until the callback completes, ensuring forward progress without
213risking livelock.
214
215In order to solve the problem at the API level, the sequence locks were extended
216to allow a proper handover between the the spinning reader and the maybe
217blocked writer.
218
219Sequence locks
220--------------
221
222Sequence counters and sequential locks are documented in
223Documentation/locking/seqlock.rst.
224
225The interface has been extended to ensure proper preemption states for the
226writer and spinning reader contexts. This is achieved by embedding the writer
227serialization lock directly into the sequence counter type, resulting in
228composite types such as seqcount_spinlock_t or seqcount_mutex_t.
229
230These composite types allow readers to detect an ongoing write and actively
231boost the writer’s priority to help it complete its update instead of spinning
232and waiting for its completion.
233
234If the plain seqcount_t is used, extra care must be taken to synchronize the
235reader with the writer during updates. The writer must ensure its update is
236serialized and non-preemptible relative to the reader. This cannot be achieved
237using a regular spinlock_t because spinlock_t on PREEMPT_RT does not disable
238preemption. In such cases, using seqcount_spinlock_t is the preferred solution.
239
240However, if there is no spinning involved i.e., if the reader only needs to
241detect whether a write has started and not serialize against it then using
242seqcount_t is reasonable.
Documentation/core-api/real-time/index.rst+16−0
@@ -0,0 +1,16 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3=====================
4Real-time preemption
5=====================
6
7This documentation is intended for Linux kernel developers and contributors
8interested in the inner workings of PREEMPT_RT. It explains key concepts and
9the required changes compared to a non-PREEMPT_RT configuration.
10
11.. toctree::
12 :maxdepth: 2
13
14 theory
15 differences
16 architecture-porting
Documentation/core-api/real-time/theory.rst+116−0
@@ -0,0 +1,116 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3=====================
4Theory of operation
5=====================
6
7:Author: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
8
9Preface
10=======
11
12PREEMPT_RT transforms the Linux kernel into a real-time kernel. It achieves
13this by replacing locking primitives, such as spinlock_t, with a preemptible
14and priority-inheritance aware implementation known as rtmutex, and by enforcing
15the use of threaded interrupts. As a result, the kernel becomes fully
16preemptible, with the exception of a few critical code paths, including entry
17code, the scheduler, and low-level interrupt handling routines.
18
19This transformation places the majority of kernel execution contexts under the
20control of the scheduler and significantly increasing the number of preemption
21points. Consequently, it reduces the latency between a high-priority task
22becoming runnable and its actual execution on the CPU.
23
24Scheduling
25==========
26
27The core principles of Linux scheduling and the associated user-space API are
28documented in the man page sched(7)
29`sched(7) <https://man7.org/linux/man-pages/man7/sched.7.html>`_.
30By default, the Linux kernel uses the SCHED_OTHER scheduling policy. Under
31this policy, a task is preempted when the scheduler determines that it has
32consumed a fair share of CPU time relative to other runnable tasks. However,
33the policy does not guarantee immediate preemption when a new SCHED_OTHER task
34becomes runnable. The currently running task may continue executing.
35
36This behavior differs from that of real-time scheduling policies such as
37SCHED_FIFO. When a task with a real-time policy becomes runnable, the
38scheduler immediately selects it for execution if it has a higher priority than
39the currently running task. The task continues to run until it voluntarily
40yields the CPU, typically by blocking on an event.
41
42Sleeping spin locks
43===================
44
45The various lock types and their behavior under real-time configurations are
46described in detail in Documentation/locking/locktypes.rst.
47In a non-PREEMPT_RT configuration, a spinlock_t is acquired by first disabling
48preemption and then actively spinning until the lock becomes available. Once
49the lock is released, preemption is enabled. From a real-time perspective,
50this approach is undesirable because disabling preemption prevents the
51scheduler from switching to a higher-priority task, potentially increasing
52latency.
53
54To address this, PREEMPT_RT replaces spinning locks with sleeping spin locks
55that do not disable preemption. On PREEMPT_RT, spinlock_t is implemented using
56rtmutex. Instead of spinning, a task attempting to acquire a contended lock
57disables CPU migration, donates its priority to the lock owner (priority
58inheritance), and voluntarily schedules out while waiting for the lock to
59become available.
60
61Disabling CPU migration provides the same effect as disabling preemption, while
62still allowing preemption and ensuring that the task continues to run on the
63same CPU while holding a sleeping lock.
64
65Priority inheritance
66====================
67
68Lock types such as spinlock_t and mutex_t in a PREEMPT_RT enabled kernel are
69implemented on top of rtmutex, which provides support for priority inheritance
70(PI). When a task blocks on such a lock, the PI mechanism temporarily
71propagates the blocked task’s scheduling parameters to the lock owner.
72
73For example, if a SCHED_FIFO task A blocks on a lock currently held by a
74SCHED_OTHER task B, task A’s scheduling policy and priority are temporarily
75inherited by task B. After this inheritance, task A is put to sleep while
76waiting for the lock, and task B effectively becomes the highest-priority task
77in the system. This allows B to continue executing, make progress, and
78eventually release the lock.
79
80Once B releases the lock, it reverts to its original scheduling parameters, and
81task A can resume execution.
82
83Threaded interrupts
84===================
85
86Interrupt handlers are another source of code that executes with preemption
87disabled and outside the control of the scheduler. To bring interrupt handling
88under scheduler control, PREEMPT_RT enforces threaded interrupt handlers.
89
90With forced threading, interrupt handling is split into two stages. The first
91stage, the primary handler, is executed in IRQ context with interrupts disabled.
92Its sole responsibility is to wake the associated threaded handler. The second
93stage, the threaded handler, is the function passed to request_irq() as the
94interrupt handler. It runs in process context, scheduled by the kernel.
95
96From waking the interrupt thread until threaded handling is completed, the
97interrupt source is masked in the interrupt controller. This ensures that the
98device interrupt remains pending but does not retrigger the CPU, allowing the
99system to exit IRQ context and handle the interrupt in a scheduled thread.
100
101By default, the threaded handler executes with the SCHED_FIFO scheduling policy
102and a priority of 50 (MAX_RT_PRIO / 2), which is midway between the minimum and
103maximum real-time priorities.
104
105If the threaded interrupt handler raises any soft interrupts during its
106execution, those soft interrupt routines are invoked after the threaded handler
107completes, within the same thread. Preemption remains enabled during the
108execution of the soft interrupt handler.
109
110Summary
111=======
112
113By using sleeping locks and forced-threaded interrupts, PREEMPT_RT
114significantly reduces sections of code where interrupts or preemption is
115disabled, allowing the scheduler to preempt the current execution context and
116switch to a higher-priority task.
Documentation/dev-tools/autofdo.rst+2−2
@@ -131,11 +131,11 @@ Here is an example workflow for AutoFDO kernel: · 130 unmodified lines
131 131
132 For Zen3::132 For Zen3::
133 133
134 $ cat proc/cpuinfo | grep " brs"134 $ cat /proc/cpuinfo | grep " brs"
135 135
136 For Zen4::136 For Zen4::
137 137
138 $ cat proc/cpuinfo | grep amd_lbr_v2138 $ cat /proc/cpuinfo | grep amd_lbr_v2
139 139
140 The following command generated the perf data file::140 The following command generated the perf data file::
141 141
Documentation/dev-tools/index.rst+1−0
@@ -29,6 +29,7 @@ Documentation/process/debugging/index.rst · 28 unmodified lines
29 ubsan29 ubsan
30 kmemleak30 kmemleak
31 kcsan31 kcsan
32 lkmm/index
32 kfence33 kfence
33 kselftest34 kselftest
34 kunit/index35 kunit/index
Documentation/dev-tools/ktap.rst+4−1
@@ -5,7 +5,7 @@ The Kernel Test Anything Protocol (KTAP), version 1 · 4 unmodified lines
5===================================================5===================================================
6 6
7TAP, or the Test Anything Protocol is a format for specifying test results used7TAP, or the Test Anything Protocol is a format for specifying test results used
8by a number of projects. It's website and specification are found at this `link8by a number of projects. Its website and specification are found at this `link
9<https://testanything.org/>`_. The Linux Kernel largely uses TAP output for test9<https://testanything.org/>`_. The Linux Kernel largely uses TAP output for test
10results. However, Kernel testing frameworks have special needs for test results10results. However, Kernel testing frameworks have special needs for test results
11which don't align with the original TAP specification. Thus, a "Kernel TAP"11which don't align with the original TAP specification. Thus, a "Kernel TAP"
@@ -20,6 +20,7 @@ machine-readable, whereas the diagnostic data is unstructured and is there to · 8 unmodified lines
20aid human debugging.20aid human debugging.
21 21
22KTAP output is built from four different types of lines:22KTAP output is built from four different types of lines:
23
23- Version lines24- Version lines
24- Plan lines25- Plan lines
25- Test case result lines26- Test case result lines
@@ -38,6 +39,7 @@ All KTAP-formatted results begin with a "version line" which specifies which · 12 unmodified lines
38version of the (K)TAP standard the result is compliant with.39version of the (K)TAP standard the result is compliant with.
39 40
40For example:41For example:
42
41- "KTAP version 1"43- "KTAP version 1"
42- "TAP version 13"44- "TAP version 13"
43- "TAP version 14"45- "TAP version 14"
@@ -276,6 +278,7 @@ Example KTAP output · 232 unmodified lines
276This output defines the following hierarchy:278This output defines the following hierarchy:
277 279
278A single test called "main_test", which fails, and has three subtests:280A single test called "main_test", which fails, and has three subtests:
281
279- "example_test_1", which passes, and has one subtest:282- "example_test_1", which passes, and has one subtest:
280 283
281 - "test_1", which passes, and outputs the diagnostic message "test_1: initializing test_1"284 - "test_1", which passes, and outputs the diagnostic message "test_1: initializing test_1"
Documentation/dev-tools/lkmm/docs/access-marking.rst+11−0
@@ -0,0 +1,11 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3Access Marking
4--------------
5
6Literal include of ``tools/memory-model/Documentation/access-marking.txt``.
7
8------------------------------------------------------------------
9
10.. kernel-include:: tools/memory-model/Documentation/access-marking.txt
11 :literal:
Documentation/dev-tools/lkmm/docs/cheatsheet.rst+11−0
@@ -0,0 +1,11 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3Cheatsheet
4----------
5
6Literal include of ``tools/memory-model/Documentation/cheatsheet.txt``.
7
8------------------------------------------------------------------
9
10.. kernel-include:: tools/memory-model/Documentation/cheatsheet.txt
11 :literal:
Documentation/dev-tools/lkmm/docs/control-dependencies.rst+11−0
@@ -0,0 +1,11 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3Control Dependencies
4--------------------
5
6Literal include of ``tools/memory-model/Documentation/control-dependencies.txt``.
7
8------------------------------------------------------------------
9
10.. kernel-include:: tools/memory-model/Documentation/control-dependencies.txt
11 :literal:
Documentation/dev-tools/lkmm/docs/explanation.rst+11−0
@@ -0,0 +1,11 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3Explanation
4-----------
5
6Literal include of ``tools/memory-model/Documentation/explanation.txt``.
7
8------------------------------------------------------------------
9
10.. kernel-include:: tools/memory-model/Documentation/explanation.txt
11 :literal:
Documentation/dev-tools/lkmm/docs/glossary.rst+11−0
@@ -0,0 +1,11 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3Glossary
4--------
5
6Literal include of ``tools/memory-model/Documentation/glossary.txt``.
7
8------------------------------------------------------------------
9
10.. kernel-include:: tools/memory-model/Documentation/glossary.txt
11 :literal:
Documentation/dev-tools/lkmm/docs/herd-representation.rst+11−0
@@ -0,0 +1,11 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3herd-representation
4-------------------
5
6Literal include of ``tools/memory-model/Documentation/herd-representation.txt``.
7
8------------------------------------------------------------------
9
10.. kernel-include:: tools/memory-model/Documentation/herd-representation.txt
11 :literal:
Documentation/dev-tools/lkmm/docs/index.rst+21−0
@@ -0,0 +1,21 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3Documentation
4=============
5
6.. toctree::
7 :maxdepth: 1
8
9 readme
10 simple
11 ordering
12 litmus-tests
13 locking
14 recipes
15 control-dependencies
16 access-marking
17 cheatsheet
18 explanation
19 herd-representation
20 glossary
21 references
Documentation/dev-tools/lkmm/docs/litmus-tests.rst+11−0
@@ -0,0 +1,11 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3Litmus Tests
4------------
5
6Literal include of ``tools/memory-model/Documentation/litmus-tests.txt``.
7
8------------------------------------------------------------------
9
10.. kernel-include:: tools/memory-model/Documentation/litmus-tests.txt
11 :literal:
Documentation/dev-tools/lkmm/docs/locking.rst+11−0
@@ -0,0 +1,11 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3Locking
4-------
5
6Literal include of ``tools/memory-model/Documentation/locking.txt``.
7
8------------------------------------------------------------------
9
10.. kernel-include:: tools/memory-model/Documentation/locking.txt
11 :literal:
Documentation/dev-tools/lkmm/docs/ordering.rst+11−0
@@ -0,0 +1,11 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3Ordering
4--------
5
6Literal include of ``tools/memory-model/Documentation/ordering.txt``.
7
8------------------------------------------------------------------
9
10.. kernel-include:: tools/memory-model/Documentation/ordering.txt
11 :literal:
Documentation/dev-tools/lkmm/docs/readme.rst+11−0
@@ -0,0 +1,11 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3README (for LKMM Documentation)
4-------------------------------
5
6Literal include of ``tools/memory-model/Documentation/README``.
7
8------------------------------------------------------------------
9
10.. kernel-include:: tools/memory-model/Documentation/README
11 :literal:
Documentation/dev-tools/lkmm/docs/recipes.rst+11−0
@@ -0,0 +1,11 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3Recipes
4-------
5
6Literal include of ``tools/memory-model/Documentation/recipes.txt``.
7
8------------------------------------------------------------------
9
10.. kernel-include:: tools/memory-model/Documentation/recipes.txt
11 :literal:
Documentation/dev-tools/lkmm/docs/references.rst+11−0
@@ -0,0 +1,11 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3References
4----------
5
6Literal include of ``tools/memory-model/Documentation/references.txt``.
7
8------------------------------------------------------------------
9
10.. kernel-include:: tools/memory-model/Documentation/references.txt
11 :literal:
Documentation/dev-tools/lkmm/docs/simple.rst+11−0
@@ -0,0 +1,11 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3Simple
4------
5
6Literal include of ``tools/memory-model/Documentation/simple.txt``.
7
8------------------------------------------------------------------
9
10.. kernel-include:: tools/memory-model/Documentation/simple.txt
11 :literal:
Documentation/dev-tools/lkmm/index.rst+15−0
@@ -0,0 +1,15 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3============================================
4Linux Kernel Memory Consistency Model (LKMM)
5============================================
6
7This section literally renders documents under ``tools/memory-model/``
8and ``tools/memory-model/Documentation/``, which are maintained in
9the *pure* plain text form.
10
11.. toctree::
12 :maxdepth: 2
13
14 readme
15 docs/index
Documentation/dev-tools/lkmm/readme.rst+11−0
@@ -0,0 +1,11 @@
1.. SPDX-License-Identifier: GPL-2.0
2
3README (for LKMM)
4=================
5
6Literal include of ``tools/memory-model/README``.
7
8------------------------------------------------------------
9
10.. kernel-include:: tools/memory-model/README
11 :literal:
Documentation/devicetree/bindings/submitting-patches.rst+1−1
@@ -66,7 +66,7 @@ I. For patch submitters · 65 unmodified lines
66 any DTS patches, regardless whether using existing or new bindings, should66 any DTS patches, regardless whether using existing or new bindings, should
67 be placed at the end of patchset to indicate no dependency of drivers on67 be placed at the end of patchset to indicate no dependency of drivers on
68 the DTS. DTS will be anyway applied through separate tree or branch, so68 the DTS. DTS will be anyway applied through separate tree or branch, so
69 different order would indicate the serie is non-bisectable.69 different order would indicate the series is non-bisectable.
70 70
71 If a driver subsystem maintainer prefers to apply entire set, instead of71 If a driver subsystem maintainer prefers to apply entire set, instead of
72 their relevant portion of patchset, please split the DTS patches into72 their relevant portion of patchset, please split the DTS patches into
Documentation/driver-api/cxl/devices/device-types.rst+1−1
@@ -22,7 +22,7 @@ The basic interaction protocol, similar to PCIe configuration mechanisms. · 21 unmodified lines
22Typically used for initialization, configuration, and I/O access for anything22Typically used for initialization, configuration, and I/O access for anything
23other than memory (CXL.mem) or cache (CXL.cache) operations.23other than memory (CXL.mem) or cache (CXL.cache) operations.
24 24
25The Linux CXL driver exposes access to .io functionalty via the various sysfs25The Linux CXL driver exposes access to .io functionality via the various sysfs
26interfaces and /dev/cxl/ devices (which exposes direct access to device26interfaces and /dev/cxl/ devices (which exposes direct access to device
27mailboxes).27mailboxes).
28 28
Documentation/driver-api/cxl/platform/example-configurations/one-dev-per-hb.rst+1−1
@@ -10,7 +10,7 @@ has a single CXL memory expander with a 4GB of memory. · 9 unmodified lines
10Things to note:10Things to note:
11 11
12* Cross-Bridge interleave is not being used.12* Cross-Bridge interleave is not being used.
13* The expanders are in two separate but adjascent memory regions.13* The expanders are in two separate but adjacent memory regions.
14* This CEDT/SRAT describes one node per device14* This CEDT/SRAT describes one node per device
15* The expanders have the same performance and will be in the same memory tier.15* The expanders have the same performance and will be in the same memory tier.
16 16
Documentation/driver-api/device-io.rst+2−2
@@ -16,7 +16,7 @@ Bus-Independent Device Accesses · 15 unmodified lines
16Introduction16Introduction
17============17============
18 18
19Linux provides an API which abstracts performing IO across all busses19Linux provides an API which abstracts performing IO across all buses
20and devices, allowing device drivers to be written independently of bus20and devices, allowing device drivers to be written independently of bus
21type.21type.
22 22
@@ -71,7 +71,7 @@ can be compiler optimised, you can use __readb() and friends to · 48 unmodified lines
71indicate the relaxed ordering. Use this with care.71indicate the relaxed ordering. Use this with care.
72 72
73While the basic functions are defined to be synchronous with respect to73While the basic functions are defined to be synchronous with respect to
74each other and ordered with respect to each other the busses the devices74each other and ordered with respect to each other the buses the devices
75sit on may themselves have asynchronicity. In particular many authors75sit on may themselves have asynchronicity. In particular many authors
76are burned by the fact that PCI bus writes are posted asynchronously. A76are burned by the fact that PCI bus writes are posted asynchronously. A
77driver author must issue a read from the same device to ensure that77driver author must issue a read from the same device to ensure that
Documentation/driver-api/driver-model/overview.rst+1−1
@@ -22,7 +22,7 @@ uniformity across the different bus types. · 21 unmodified lines
22 22
23The current driver model provides a common, uniform data model for describing23The current driver model provides a common, uniform data model for describing
24a bus and the devices that can appear under the bus. The unified bus24a bus and the devices that can appear under the bus. The unified bus
25model includes a set of common attributes which all busses carry, and a set25model includes a set of common attributes which all buses carry, and a set
26of common callbacks, such as device discovery during bus probing, bus26of common callbacks, such as device discovery during bus probing, bus
27shutdown, bus power management, etc.27shutdown, bus power management, etc.
28 28
Documentation/driver-api/driver-model/platform.rst+1−1
@@ -4,7 +4,7 @@ Platform Devices and Drivers · 3 unmodified lines
4 4
5See <linux/platform_device.h> for the driver model interface to the5See <linux/platform_device.h> for the driver model interface to the
6platform bus: platform_device, and platform_driver. This pseudo-bus6platform bus: platform_device, and platform_driver. This pseudo-bus
7is used to connect devices on busses with minimal infrastructure,7is used to connect devices on buses with minimal infrastructure,
8like those used to integrate peripherals on many system-on-chip8like those used to integrate peripherals on many system-on-chip
9processors, or some "legacy" PC interconnects; as opposed to large9processors, or some "legacy" PC interconnects; as opposed to large
10formally specified ones like PCI or USB.10formally specified ones like PCI or USB.
Documentation/driver-api/eisa.rst+3−3
@@ -8,9 +8,9 @@ This document groups random notes about porting EISA drivers to the · 7 unmodified lines
8new EISA/sysfs API.8new EISA/sysfs API.
9 9
10Starting from version 2.5.59, the EISA bus is almost given the same10Starting from version 2.5.59, the EISA bus is almost given the same
11status as other much more mainstream busses such as PCI or USB. This11status as other much more mainstream buses such as PCI or USB. This
12has been possible through sysfs, which defines a nice enough set of12has been possible through sysfs, which defines a nice enough set of
13abstractions to manage busses, devices and drivers.13abstractions to manage buses, devices and drivers.
14 14
15Although the new API is quite simple to use, converting existing15Although the new API is quite simple to use, converting existing
16drivers to the new infrastructure is not an easy task (mostly because16drivers to the new infrastructure is not an easy task (mostly because
@@ -205,7 +205,7 @@ Random notes · 188 unmodified lines
205Converting an EISA driver to the new API mostly involves *deleting*205Converting an EISA driver to the new API mostly involves *deleting*
206code (since probing is now in the core EISA code). Unfortunately, most206code (since probing is now in the core EISA code). Unfortunately, most
207drivers share their probing routine between ISA, and EISA. Special207drivers share their probing routine between ISA, and EISA. Special
208care must be taken when ripping out the EISA code, so other busses208care must be taken when ripping out the EISA code, so other buses
209won't suffer from these surgical strikes...209won't suffer from these surgical strikes...
210 210
211You *must not* expect any EISA device to be detected when returning211You *must not* expect any EISA device to be detected when returning
Documentation/driver-api/i3c/protocol.rst+2−2
@@ -165,8 +165,8 @@ The first thing attached to an HDR command is the HDR mode. There are currently · 164 unmodified lines
165for more details):165for more details):
166 166
167* HDR-DDR: Double Data Rate mode167* HDR-DDR: Double Data Rate mode
168* HDR-TSP: Ternary Symbol Pure. Only usable on busses with no I2C devices168* HDR-TSP: Ternary Symbol Pure. Only usable on buses with no I2C devices
169* HDR-TSL: Ternary Symbol Legacy. Usable on busses with I2C devices169* HDR-TSL: Ternary Symbol Legacy. Usable on buses with I2C devices
170 170
171When sending an HDR command, the whole bus has to enter HDR mode, which is done171When sending an HDR command, the whole bus has to enter HDR mode, which is done
172using a broadcast CCC command.172using a broadcast CCC command.
Documentation/driver-api/ipmi.rst+2−2
@@ -617,12 +617,12 @@ Note that the address you give here is the I2C address, not the IPMI · 616 unmodified lines
617address. So if you want your MC address to be 0x60, you put 0x30617address. So if you want your MC address to be 0x60, you put 0x30
618here. See the I2C driver info for more details.618here. See the I2C driver info for more details.
619 619
620Command bridging to other IPMB busses through this interface does not620Command bridging to other IPMB buses through this interface does not
621work. The receive message queue is not implemented, by design. There621work. The receive message queue is not implemented, by design. There
622is only one receive message queue on a BMC, and that is meant for the622is only one receive message queue on a BMC, and that is meant for the
623host drivers, not something on the IPMB bus.623host drivers, not something on the IPMB bus.
624 624
625A BMC may have multiple IPMB busses, which bus your device sits on625A BMC may have multiple IPMB buses, which bus your device sits on
626depends on how the system is wired. You can fetch the channels with626depends on how the system is wired. You can fetch the channels with
627"ipmitool channel info <n>" where <n> is the channel, with the627"ipmitool channel info <n>" where <n> is the channel, with the
628channels being 0-7 and try the IPMB channels.628channels being 0-7 and try the IPMB channels.
Documentation/driver-api/media/tx-rx.rst+2−2
@@ -12,7 +12,7 @@ CSI-2 receiver in an SoC. · 11 unmodified lines
12Bus types12Bus types
13---------13---------
14 14
15The following busses are the most common. This section discusses these two only.15The following buses are the most common. This section discusses these two only.
16 16
17MIPI CSI-217MIPI CSI-2
18^^^^^^^^^^18^^^^^^^^^^
@@ -36,7 +36,7 @@ Transmitter drivers · 17 unmodified lines
36 36
37Transmitter drivers generally need to provide the receiver drivers with the37Transmitter drivers generally need to provide the receiver drivers with the
38configuration of the transmitter. What is required depends on the type of the38configuration of the transmitter. What is required depends on the type of the
39bus. These are common for both busses.39bus. These are common for both buses.
40 40
41Media bus pixel code41Media bus pixel code
42^^^^^^^^^^^^^^^^^^^^42^^^^^^^^^^^^^^^^^^^^
Documentation/driver-api/nvdimm/nvdimm.rst+1−1
@@ -230,7 +230,7 @@ LIBNVDIMM/LIBNDCTL: Bus · 229 unmodified lines
230A bus has a 1:1 relationship with an NFIT. The current expectation for230A bus has a 1:1 relationship with an NFIT. The current expectation for
231ACPI based systems is that there is only ever one platform-global NFIT.231ACPI based systems is that there is only ever one platform-global NFIT.
232That said, it is trivial to register multiple NFITs, the specification232That said, it is trivial to register multiple NFITs, the specification
233does not preclude it. The infrastructure supports multiple busses and233does not preclude it. The infrastructure supports multiple buses and
234we use this capability to test multiple NFIT configurations in the unit234we use this capability to test multiple NFIT configurations in the unit
235test.235test.
236 236
Documentation/driver-api/pin-control.rst+6−4
@@ -1202,22 +1202,24 @@ default state like this: · 1201 unmodified lines
1202 {1202 {
1203 /* Allocate a state holder named "foo" etc */1203 /* Allocate a state holder named "foo" etc */
1204 struct foo_state *foo = ...;1204 struct foo_state *foo = ...;
1205 int ret;
1205 1206
1206 foo->p = devm_pinctrl_get(&device);1207 foo->p = devm_pinctrl_get(&device);
1207 if (IS_ERR(foo->p)) {1208 if (IS_ERR(foo->p)) {
1208 /* FIXME: clean up "foo" here */1209 ret = PTR_ERR(foo->p);
1209 return PTR_ERR(foo->p);1210 foo->p = NULL;
1211 return ret;
1210 }1212 }
1211 1213
1212 foo->s = pinctrl_lookup_state(foo->p, PINCTRL_STATE_DEFAULT);1214 foo->s = pinctrl_lookup_state(foo->p, PINCTRL_STATE_DEFAULT);
1213 if (IS_ERR(foo->s)) {1215 if (IS_ERR(foo->s)) {
1214 /* FIXME: clean up "foo" here */1216 devm_pinctrl_put(foo->p);
1215 return PTR_ERR(foo->s);1217 return PTR_ERR(foo->s);
1216 }1218 }
1217 1219
1218 ret = pinctrl_select_state(foo->p, foo->s);1220 ret = pinctrl_select_state(foo->p, foo->s);
1219 if (ret < 0) {1221 if (ret < 0) {
1220 /* FIXME: clean up "foo" here */1222 devm_pinctrl_put(foo->p);
1221 return ret;1223 return ret;
1222 }1224 }
1223 }1225 }
Documentation/driver-api/pm/devices.rst+2−2
@@ -255,7 +255,7 @@ get registered: a child can never be registered, probed or resumed before · 254 unmodified lines
255its parent; and can't be removed or suspended after that parent.255its parent; and can't be removed or suspended after that parent.
256 256
257The policy is that the device hierarchy should match hardware bus topology.257The policy is that the device hierarchy should match hardware bus topology.
258[Or at least the control bus, for devices which use multiple busses.]258[Or at least the control bus, for devices which use multiple buses.]
259In particular, this means that a device registration may fail if the parent of259In particular, this means that a device registration may fail if the parent of
260the device is suspending (i.e. has been chosen by the PM core as the next260the device is suspending (i.e. has been chosen by the PM core as the next
261device to suspend) or has already suspended, as well as after all of the other261device to suspend) or has already suspended, as well as after all of the other
@@ -493,7 +493,7 @@ states, like S3). · 231 unmodified lines
493 493
494Drivers must also be prepared to notice that the device has been removed494Drivers must also be prepared to notice that the device has been removed
495while the system was powered down, whenever that's physically possible.495while the system was powered down, whenever that's physically possible.
496PCMCIA, MMC, USB, Firewire, SCSI, and even IDE are common examples of busses496PCMCIA, MMC, USB, Firewire, SCSI, and even IDE are common examples of buses
497where common Linux platforms will see such removal. Details of how drivers497where common Linux platforms will see such removal. Details of how drivers
498will notice and handle such removals are currently bus-specific, and often498will notice and handle such removals are currently bus-specific, and often
499involve a separate thread.499involve a separate thread.
Documentation/driver-api/scsi.rst+2−2
@@ -18,7 +18,7 @@ optical drives, test equipment, and medical devices) to a host computer. · 17 unmodified lines
18 18
19Although the old parallel (fast/wide/ultra) SCSI bus has largely fallen19Although the old parallel (fast/wide/ultra) SCSI bus has largely fallen
20out of use, the SCSI command set is more widely used than ever to20out of use, the SCSI command set is more widely used than ever to
21communicate with devices over a number of different busses.21communicate with devices over a number of different buses.
22 22
23The `SCSI protocol <https://www.t10.org/scsi-3.htm>`__ is a big-endian23The `SCSI protocol <https://www.t10.org/scsi-3.htm>`__ is a big-endian
24peer-to-peer packet based protocol. SCSI commands are 6, 10, 12, or 1624peer-to-peer packet based protocol. SCSI commands are 6, 10, 12, or 16
@@ -286,7 +286,7 @@ Parallel SCSI (SPI) transport class · 261 unmodified lines
286~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~286~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
287 287
288The file drivers/scsi/scsi_transport_spi.c defines transport288The file drivers/scsi/scsi_transport_spi.c defines transport
289attributes for traditional (fast/wide/ultra) SCSI busses.289attributes for traditional (fast/wide/ultra) SCSI buses.
290 290
291.. kernel-doc:: drivers/scsi/scsi_transport_spi.c291.. kernel-doc:: drivers/scsi/scsi_transport_spi.c
292 :export:292 :export:
Documentation/driver-api/spi.rst+1−1
@@ -13,7 +13,7 @@ additional chipselect line is usually active-low (nCS); four signals are · 12 unmodified lines
13normally used for each peripheral, plus sometimes an interrupt.13normally used for each peripheral, plus sometimes an interrupt.
14 14
15The SPI bus facilities listed here provide a generalized interface to15The SPI bus facilities listed here provide a generalized interface to
16declare SPI busses and devices, manage them according to the standard16declare SPI buses and devices, manage them according to the standard
17Linux driver model, and perform input/output operations. At this time,17Linux driver model, and perform input/output operations. At this time,
18only "master" side interfaces are supported, where Linux talks to SPI18only "master" side interfaces are supported, where Linux talks to SPI
19peripherals and does not implement such a peripheral itself. (Interfaces19peripherals and does not implement such a peripheral itself. (Interfaces
Documentation/driver-api/thermal/exynos_thermal_emulation.rst+7−7
@@ -28,13 +28,13 @@ changed into it. · 27 unmodified lines
28delay of changing temperature. However, this node only uses same delay28delay of changing temperature. However, this node only uses same delay
29of real sensing time, 938us.)29of real sensing time, 938us.)
30 30
31Exynos emulation mode requires synchronous of value changing and31Exynos emulation mode requires that value changes and enabling are performed
32enabling. It means when you want to update the any value of delay or32synchronously. This means that when you want to update any value, such as the
33next temperature, then you have to enable emulation mode at the same33delay or the next temperature, you must enable emulation mode at the same
34time. (Or you have to keep the mode enabling.) If you don't, it fails to34time (or keep the mode enabled). If you do not, the value will fail to update
35change the value to updated one and just use last succeessful value35and the last successful value will continue to be used. For this reason,
36repeatedly. That's why this node gives users the right to change36this node only allows users to change the temperature. Providing a single
37termerpature only. Just one interface makes it more simply to use.37interface makes it simpler to use.
38 38
39Disabling emulation mode only requires writing value 0 to sysfs node.39Disabling emulation mode only requires writing value 0 to sysfs node.
40 40
Documentation/driver-api/usb/hotplug.rst+1−1
@@ -5,7 +5,7 @@ Linux Hotplugging · 4 unmodified lines
5=================5=================
6 6
7 7
8In hotpluggable busses like USB (and Cardbus PCI), end-users plug devices8In hotpluggable buses like USB (and Cardbus PCI), end-users plug devices
9into the bus with power on. In most cases, users expect the devices to become9into the bus with power on. In most cases, users expect the devices to become
10immediately usable. That means the system must do many things, including:10immediately usable. That means the system must do many things, including:
11 11
Documentation/driver-api/usb/index.rst+1−0
@@ -3,6 +3,7 @@ Linux USB API · 2 unmodified lines
3=============3=============
4 4
5.. toctree::5.. toctree::
6 :maxdepth: 1
6 7
7 usb8 usb
8 gadget9 gadget
Documentation/driver-api/usb/usb.rst+2−2
@@ -13,7 +13,7 @@ structure, with the host as the root (the system's master), hubs as · 12 unmodified lines
13interior nodes, and peripherals as leaves (and slaves). Modern PCs13interior nodes, and peripherals as leaves (and slaves). Modern PCs
14support several such trees of USB devices, usually14support several such trees of USB devices, usually
15a few USB 3.0 (5 GBit/s) or USB 3.1 (10 GBit/s) and some legacy15a few USB 3.0 (5 GBit/s) or USB 3.1 (10 GBit/s) and some legacy
16USB 2.0 (480 MBit/s) busses just in case.16USB 2.0 (480 MBit/s) buses just in case.
17 17
18That master/slave asymmetry was designed-in for a number of reasons, one18That master/slave asymmetry was designed-in for a number of reasons, one
19being ease of use. It is not physically possible to mistake upstream and19being ease of use. It is not physically possible to mistake upstream and
@@ -42,7 +42,7 @@ two. One is intended for *general-purpose* drivers (exposed through · 22 unmodified lines
42driver frameworks), and the other is for drivers that are *part of the42driver frameworks), and the other is for drivers that are *part of the
43core*. Such core drivers include the *hub* driver (which manages trees43core*. Such core drivers include the *hub* driver (which manages trees
44of USB devices) and several different kinds of *host controller44of USB devices) and several different kinds of *host controller
45drivers*, which control individual busses.45drivers*, which control individual buses.
46 46
47The device model seen by USB drivers is relatively complex.47The device model seen by USB drivers is relatively complex.
48 48
Documentation/fb/fbcon.rst+24−18
@@ -39,11 +39,13 @@ Also, you will need to select at least one compiled-in font, but if · 38 unmodified lines
39you don't do anything, the kernel configuration tool will select one for you,39you don't do anything, the kernel configuration tool will select one for you,
40usually an 8x16 font.40usually an 8x16 font.
41 41
42GOTCHA: A common bug report is enabling the framebuffer without enabling the42.. admonition:: GOTCHA
43framebuffer console. Depending on the driver, you may get a blanked or43
44garbled display, but the system still boots to completion. If you are44 A common bug report is enabling the framebuffer without enabling the
45fortunate to have a driver that does not alter the graphics chip, then you45 framebuffer console. Depending on the driver, you may get a blanked or
46will still get a VGA console.46 garbled display, but the system still boots to completion. If you are
47 fortunate to have a driver that does not alter the graphics chip, then you
48 will still get a VGA console.
47 49
48B. Loading50B. Loading
49==========51==========
@@ -74,6 +76,7 @@ Possible scenarios: · 24 unmodified lines
74 over the console.76 over the console.
75 77
76C. Boot options78C. Boot options
79===============
77 80
78 The framebuffer console has several, largely unknown, boot options81 The framebuffer console has several, largely unknown, boot options
79 that can change its behavior.82 that can change its behavior.
@@ -116,9 +119,10 @@ C. Boot options · 36 unmodified lines
116 outside the given range will still be controlled by the standard119 outside the given range will still be controlled by the standard
117 console driver.120 console driver.
118 121
119 NOTE: For x86 machines, the standard console is the VGA console which122 .. note::
120 is typically located on the same video card. Thus, the consoles that123 For x86 machines, the standard console is the VGA console which
121 are controlled by the VGA console will be garbled.124 is typically located on the same video card. Thus, the consoles that
125 are controlled by the VGA console will be garbled.
122 126
1234. fbcon=rotate:<n>1274. fbcon=rotate:<n>
124 128
@@ -140,10 +144,11 @@ C. Boot options · 15 unmodified lines
140 Console rotation will only become available if Framebuffer Console144 Console rotation will only become available if Framebuffer Console
141 Rotation support is compiled in your kernel.145 Rotation support is compiled in your kernel.
142 146
143 NOTE: This is purely console rotation. Any other applications that147 .. note::
144 use the framebuffer will remain at their 'normal' orientation.148 This is purely console rotation. Any other applications that
145 Actually, the underlying fb driver is totally ignorant of console149 use the framebuffer will remain at their 'normal' orientation.
146 rotation.150 Actually, the underlying fb driver is totally ignorant of console
151 rotation.
147 152
1485. fbcon=margin:<color>1535. fbcon=margin:<color>
149 154
@@ -172,7 +177,8 @@ C. Boot options · 22 unmodified lines
172 The value 'n' overrides the number of bootup logos. 0 disables the177 The value 'n' overrides the number of bootup logos. 0 disables the
173 logo, and -1 gives the default which is the number of online CPUs.178 logo, and -1 gives the default which is the number of online CPUs.
174 179
175C. Attaching, Detaching and Unloading180D. Attaching, Detaching and Unloading
181=====================================
176 182
177Before going on to how to attach, detach and unload the framebuffer console, an183Before going on to how to attach, detach and unload the framebuffer console, an
178illustration of the dependencies may help.184illustration of the dependencies may help.
@@ -249,11 +255,11 @@ restored properly. The following is one of the several methods that you can do: · 70 unmodified lines
249 echo 1 > /sys/class/vtconsole/vtcon1/bind255 echo 1 > /sys/class/vtconsole/vtcon1/bind
250 256
2518. Once fbcon is unbound, all drivers registered to the system will also2578. Once fbcon is unbound, all drivers registered to the system will also
252become unbound. This means that fbcon and individual framebuffer drivers258 become unbound. This means that fbcon and individual framebuffer drivers
253can be unloaded or reloaded at will. Reloading the drivers or fbcon will259 can be unloaded or reloaded at will. Reloading the drivers or fbcon will
254automatically bind the console, fbcon and the drivers together. Unloading260 automatically bind the console, fbcon and the drivers together. Unloading
255all the drivers without unloading fbcon will make it impossible for the261 all the drivers without unloading fbcon will make it impossible for the
256console to bind fbcon.262 console to bind fbcon.
257 263
258Notes for vesafb users:264Notes for vesafb users:
259=======================265=======================
Documentation/features/core/eBPF-JIT/arch-support.txt+2−2
@@ -7,7 +7,7 @@ · 6 unmodified lines
7 | arch |status|7 | arch |status|
8 -----------------------8 -----------------------
9 | alpha: | TODO |9 | alpha: | TODO |
10 | arc: | TODO |10 | arc: | ok |
11 | arm: | ok |11 | arm: | ok |
12 | arm64: | ok |12 | arm64: | ok |
13 | csky: | TODO |13 | csky: | TODO |
@@ -18,7 +18,7 @@ · 4 unmodified lines
18 | mips: | ok |18 | mips: | ok |
19 | nios2: | TODO |19 | nios2: | TODO |
20 | openrisc: | TODO |20 | openrisc: | TODO |
21 | parisc: | TODO |21 | parisc: | ok |
22 | powerpc: | ok |22 | powerpc: | ok |
23 | riscv: | ok |23 | riscv: | ok |
24 | s390: | ok |24 | s390: | ok |
Documentation/features/core/mseal_sys_mappings/arch-support.txt+1−1
@@ -20,7 +20,7 @@ · 19 unmodified lines
20 | openrisc: | N/A |20 | openrisc: | N/A |
21 | parisc: | TODO |21 | parisc: | TODO |
22 | powerpc: | TODO |22 | powerpc: | TODO |
23 | riscv: | TODO |23 | riscv: | ok |
24 | s390: | ok |24 | s390: | ok |
25 | sh: | N/A |25 | sh: | N/A |
26 | sparc: | TODO |26 | sparc: | TODO |
Documentation/features/core/thread-info-in-task/arch-support.txt+1−1
@@ -24,7 +24,7 @@ · 23 unmodified lines
24 | s390: | ok |24 | s390: | ok |
25 | sh: | TODO |25 | sh: | TODO |
26 | sparc: | TODO |26 | sparc: | TODO |
27 | um: | TODO |27 | um: | ok |
28 | x86: | ok |28 | x86: | ok |
29 | xtensa: | TODO |29 | xtensa: | TODO |
30 -----------------------30 -----------------------
Documentation/features/core/tracehook/arch-support.txt+1−1
@@ -24,7 +24,7 @@ · 23 unmodified lines
24 | s390: | ok |24 | s390: | ok |
25 | sh: | ok |25 | sh: | ok |
26 | sparc: | ok |26 | sparc: | ok |
27 | um: | TODO |27 | um: | ok |
28 | x86: | ok |28 | x86: | ok |
29 | xtensa: | ok |29 | xtensa: | ok |
30 -----------------------30 -----------------------
Documentation/features/perf/kprobes-event/arch-support.txt+1−1
@@ -17,7 +17,7 @@ · 16 unmodified lines
17 | microblaze: | TODO |17 | microblaze: | TODO |
18 | mips: | ok |18 | mips: | ok |
19 | nios2: | TODO |19 | nios2: | TODO |
20 | openrisc: | TODO |20 | openrisc: | ok |
21 | parisc: | ok |21 | parisc: | ok |
22 | powerpc: | ok |22 | powerpc: | ok |
23 | riscv: | ok |23 | riscv: | ok |
Documentation/features/time/clockevents/arch-support.txt+1−1
@@ -18,7 +18,7 @@ · 17 unmodified lines
18 | mips: | ok |18 | mips: | ok |
19 | nios2: | ok |19 | nios2: | ok |
20 | openrisc: | ok |20 | openrisc: | ok |
21 | parisc: | TODO |21 | parisc: | ok |
22 | powerpc: | ok |22 | powerpc: | ok |
23 | riscv: | ok |23 | riscv: | ok |
24 | s390: | ok |24 | s390: | ok |
Documentation/filesystems/erofs.rst+1−1
@@ -116,7 +116,7 @@ cache_strategy=%s Select a strategy for cached decompression from now on: · 115 unmodified lines
116 cluster for further reading. It still does116 cluster for further reading. It still does
117 in-place I/O decompression for the rest117 in-place I/O decompression for the rest
118 compressed physical clusters;118 compressed physical clusters;
119 readaround Cache the both ends of incomplete compressed119 readaround Cache both ends of incomplete compressed
120 physical clusters for further reading.120 physical clusters for further reading.
121 It still does in-place I/O decompression121 It still does in-place I/O decompression
122 for the rest compressed physical clusters.122 for the rest compressed physical clusters.
Documentation/filesystems/ext4/atomic_writes.rst+3−3
@@ -14,7 +14,7 @@ I/O) on regular files with extents, provided the underlying storage device · 13 unmodified lines
14supports hardware atomic writes. This is supported in the following two ways:14supports hardware atomic writes. This is supported in the following two ways:
15 15
161. **Single-fsblock Atomic Writes**:161. **Single-fsblock Atomic Writes**:
17 EXT4's supports atomic write operations with a single filesystem block since17 EXT4 supports atomic write operations with a single filesystem block since
18 v6.13. In this the atomic write unit minimum and maximum sizes are both set18 v6.13. In this the atomic write unit minimum and maximum sizes are both set
19 to filesystem blocksize.19 to filesystem blocksize.
20 e.g. doing atomic write of 16KB with 16KB filesystem blocksize on 64KB20 e.g. doing atomic write of 16KB with 16KB filesystem blocksize on 64KB
@@ -50,7 +50,7 @@ Multi-fsblock Implementation Details · 29 unmodified lines
50 50
51The bigalloc feature changes ext4 to allocate in units of multiple filesystem51The bigalloc feature changes ext4 to allocate in units of multiple filesystem
52blocks, also known as clusters. With bigalloc each bit within block bitmap52blocks, also known as clusters. With bigalloc each bit within block bitmap
53represents cluster (power of 2 number of blocks) rather than individual53represents a cluster (power of 2 number of blocks) rather than individual
54filesystem blocks.54filesystem blocks.
55EXT4 supports multi-fsblock atomic writes with bigalloc, subject to the55EXT4 supports multi-fsblock atomic writes with bigalloc, subject to the
56following constraints. The minimum atomic write size is the larger of the fs56following constraints. The minimum atomic write size is the larger of the fs
@@ -189,7 +189,7 @@ The write must be aligned to the filesystem's block size and not exceed the · 132 unmodified lines
189filesystem's maximum atomic write unit size.189filesystem's maximum atomic write unit size.
190See ``generic_atomic_write_valid()`` for more details.190See ``generic_atomic_write_valid()`` for more details.
191 191
192``statx()`` system call with ``STATX_WRITE_ATOMIC`` flag can provides following192``statx()`` system call with ``STATX_WRITE_ATOMIC`` flag can provide following
193details:193details:
194 194
195 * ``stx_atomic_write_unit_min``: Minimum size of an atomic write request.195 * ``stx_atomic_write_unit_min``: Minimum size of an atomic write request.
Documentation/filesystems/gfs2-glocks.rst+1−1
@@ -105,7 +105,7 @@ go_unlocked Yes No · 104 unmodified lines
105 Operations must not drop either the bit lock or the spinlock105 Operations must not drop either the bit lock or the spinlock
106 if its held on entry. go_dump and do_demote_ok must never block.106 if its held on entry. go_dump and do_demote_ok must never block.
107 Note that go_dump will only be called if the glock's state107 Note that go_dump will only be called if the glock's state
108 indicates that it is caching uptodate data.108 indicates that it is caching up-to-date data.
109 109
110Glock locking order within GFS2:110Glock locking order within GFS2:
111 111
Documentation/filesystems/hpfs.rst+1−1
@@ -65,7 +65,7 @@ are case sensitive, so for example when you create a file FOO, you can use · 64 unmodified lines
65'cat FOO', 'cat Foo', 'cat foo' or 'cat F*' but not 'cat f*'. Note, that you65'cat FOO', 'cat Foo', 'cat foo' or 'cat F*' but not 'cat f*'. Note, that you
66also won't be able to compile linux kernel (and maybe other things) on HPFS66also won't be able to compile linux kernel (and maybe other things) on HPFS
67because kernel creates different files with names like bootsect.S and67because kernel creates different files with names like bootsect.S and
68bootsect.s. When searching for file thats name has characters >= 128, codepages68bootsect.s. When searching for file whose name has characters >= 128, codepages
69are used - see below.69are used - see below.
70OS/2 ignores dots and spaces at the end of file name, so this driver does as70OS/2 ignores dots and spaces at the end of file name, so this driver does as
71well. If you create 'a. ...', the file 'a' will be created, but you can still71well. If you create 'a. ...', the file 'a' will be created, but you can still
Documentation/filesystems/iomap/operations.rst+1−1
@@ -321,7 +321,7 @@ The fields are as follows: · 320 unmodified lines
321 - ``writeback_submit``: Submit the previous built writeback context.321 - ``writeback_submit``: Submit the previous built writeback context.
322 Block based file systems should use the iomap_ioend_writeback_submit322 Block based file systems should use the iomap_ioend_writeback_submit
323 helper, other file system can implement their own.323 helper, other file system can implement their own.
324 File systems can optionall to hook into writeback bio submission.324 File systems can optionally hook into writeback bio submission.
325 This might include pre-write space accounting updates, or installing325 This might include pre-write space accounting updates, or installing
326 a custom ``->bi_end_io`` function for internal purposes, such as326 a custom ``->bi_end_io`` function for internal purposes, such as
327 deferring the ioend completion to a workqueue to run metadata update327 deferring the ioend completion to a workqueue to run metadata update
Documentation/filesystems/ocfs2-online-filecheck.rst+10−10
@@ -58,33 +58,33 @@ inode, fixing inode and setting the size of result record history. · 57 unmodified lines
58 # echo "<inode>" > /sys/fs/ocfs2/<devname>/filecheck/check58 # echo "<inode>" > /sys/fs/ocfs2/<devname>/filecheck/check
59 # cat /sys/fs/ocfs2/<devname>/filecheck/check59 # cat /sys/fs/ocfs2/<devname>/filecheck/check
60 60
61The output is like this::61 The output is like this::
62 62
63 INO DONE ERROR63 INO DONE ERROR
64 39502 1 GENERATION64 39502 1 GENERATION
65 65
66 <INO> lists the inode numbers.66 <INO> lists the inode numbers.
67 <DONE> indicates whether the operation has been finished.67 <DONE> indicates whether the operation has been finished.
68 <ERROR> says what kind of errors was found. For the detailed error numbers,68 <ERROR> says what kind of errors was found. For the detailed error numbers,
69 please refer to the file linux/fs/ocfs2/filecheck.h.69 please refer to the file linux/fs/ocfs2/filecheck.h.
70 70
712. If you determine to fix this inode, do::712. If you determine to fix this inode, do::
72 72
73 # echo "<inode>" > /sys/fs/ocfs2/<devname>/filecheck/fix73 # echo "<inode>" > /sys/fs/ocfs2/<devname>/filecheck/fix
74 # cat /sys/fs/ocfs2/<devname>/filecheck/fix74 # cat /sys/fs/ocfs2/<devname>/filecheck/fix
75 75
76The output is like this:::76 The output is like this::
77 77
78 INO DONE ERROR78 INO DONE ERROR
79 39502 1 SUCCESS79 39502 1 SUCCESS
80 80
81This time, the <ERROR> column indicates whether this fix is successful or not.81 This time, the <ERROR> column indicates whether this fix is successful or not.
82 82
833. The record cache is used to store the history of check/fix results. It's833. The record cache is used to store the history of check/fix results. It's
84default size is 10, and can be adjust between the range of 10 ~ 100. You can84 default size is 10, and can be adjust between the range of 10 ~ 100. You can
85adjust the size like this::85 adjust the size like this::
86 86
87 # echo "<size>" > /sys/fs/ocfs2/<devname>/filecheck/set87 # echo "<size>" > /sys/fs/ocfs2/<devname>/filecheck/set
88 88
89Fixing stuff89Fixing stuff
90============90============
Documentation/filesystems/proc.rst+0−21
@@ -61,19 +61,6 @@ Preface · 60 unmodified lines
610.1 Introduction/Credits610.1 Introduction/Credits
62------------------------62------------------------
63 63
64This documentation is part of a soon (or so we hope) to be released book on
65the SuSE Linux distribution. As there is no complete documentation for the
66/proc file system and we've used many freely available sources to write these
67chapters, it seems only fair to give the work back to the Linux community.
68This work is based on the 2.2.* kernel version and the upcoming 2.4.*. I'm
69afraid it's still far from complete, but we hope it will be useful. As far as
70we know, it is the first 'all-in-one' document about the /proc file system. It
71is focused on the Intel x86 hardware, so if you are looking for PPC, ARM,
72SPARC, AXP, etc., features, you probably won't find what you are looking for.
73It also only covers IPv4 networking, not IPv6 nor other protocols - sorry. But
74additions and patches are welcome and will be added to this document if you
75mail them to Bodo.
76
77We'd like to thank Alan Cox, Rik van Riel, and Alexey Kuznetsov and a lot of64We'd like to thank Alan Cox, Rik van Riel, and Alexey Kuznetsov and a lot of
78other people for help compiling this documentation. We'd also like to extend a65other people for help compiling this documentation. We'd also like to extend a
79special thank you to Andi Kleen for documentation, which we relied on heavily66special thank you to Andi Kleen for documentation, which we relied on heavily
@@ -81,17 +68,9 @@ to create this document, as well as the additional information he provided. · 1 unmodified line
81Thanks to everybody else who contributed source or docs to the Linux kernel68Thanks to everybody else who contributed source or docs to the Linux kernel
82and helped create a great piece of software... :)69and helped create a great piece of software... :)
83 70
84If you have any comments, corrections or additions, please don't hesitate to
85contact Bodo Bauer at bb@ricochet.net. We'll be happy to add them to this
86document.
87
88The latest version of this document is available online at71The latest version of this document is available online at
89https://www.kernel.org/doc/html/latest/filesystems/proc.html72https://www.kernel.org/doc/html/latest/filesystems/proc.html
90 73
91If the above direction does not works for you, you could try the kernel
92mailing list at linux-kernel@vger.kernel.org and/or try to reach me at
93comandante@zaralinux.com.
94
950.2 Legal Stuff740.2 Legal Stuff
96---------------75---------------
97 76
Documentation/filesystems/propagate_umount.txt+3−3
@@ -286,7 +286,7 @@ Trim_one(m) · 285 unmodified lines
286 strip the "seen by Trim_ancestors" mark from m286 strip the "seen by Trim_ancestors" mark from m
287 remove m from the Candidates list287 remove m from the Candidates list
288 return288 return
289 289
290 remove_this = false290 remove_this = false
291 found = false291 found = false
292 for each n in children(m)292 for each n in children(m)
@@ -312,7 +312,7 @@ Trim_ancestors(m) · 19 unmodified lines
312 }312 }
313 313
314 Terminating condition in the loop in Trim_ancestors() is correct,314 Terminating condition in the loop in Trim_ancestors() is correct,
315since that that loop will never run into p belonging to U - p is always315since that loop will never run into p belonging to U - p is always
316an ancestor of argument of Trim_one() and since U is closed, the argument316an ancestor of argument of Trim_one() and since U is closed, the argument
317of Trim_one() would also have to belong to U. But Trim_one() is never317of Trim_one() would also have to belong to U. But Trim_one() is never
318called for elements of U. In other words, p belongs to S if and only318called for elements of U. In other words, p belongs to S if and only
@@ -361,7 +361,7 @@ such removals. · 42 unmodified lines
361Proof: suppose S was non-shifting, x is a locked element of S, parent of x361Proof: suppose S was non-shifting, x is a locked element of S, parent of x
362is not in S and S - {x} is not non-shifting. Then there is an element m362is not in S and S - {x} is not non-shifting. Then there is an element m
363in S - {x} and a subtree mounted strictly inside m, such that m contains363in S - {x} and a subtree mounted strictly inside m, such that m contains
364an element not in in S - {x}. Since S is non-shifting, everything in364an element not in S - {x}. Since S is non-shifting, everything in
365that subtree must belong to S. But that means that this subtree must365that subtree must belong to S. But that means that this subtree must
366contain x somewhere *and* that parent of x either belongs that subtree366contain x somewhere *and* that parent of x either belongs that subtree
367or is equal to m. Either way it must belong to S. Contradiction.367or is equal to m. Either way it must belong to S. Contradiction.
Documentation/filesystems/resctrl.rst+1−1
@@ -769,7 +769,7 @@ this would be dependent on number of cores the benchmark is run on. · 768 unmodified lines
769 depending on # of threads:769 depending on # of threads:
770 770
771For the same SKU in #1, a 'single thread, with 10% bandwidth' and '4771For the same SKU in #1, a 'single thread, with 10% bandwidth' and '4
772thread, with 10% bandwidth' can consume upto 10GBps and 40GBps although772thread, with 10% bandwidth' can consume up to 10GBps and 40GBps although
773they have same percentage bandwidth of 10%. This is simply because as773they have same percentage bandwidth of 10%. This is simply because as
774threads start using more cores in an rdtgroup, the actual bandwidth may774threads start using more cores in an rdtgroup, the actual bandwidth may
775increase or vary although user specified bandwidth percentage is same.775increase or vary although user specified bandwidth percentage is same.
Documentation/filesystems/sharedsubtree.rst+671−676
@@ -31,965 +31,960 @@ and versioned filesystem. · 30 unmodified lines
31-----------31-----------
32 32
33Shared subtree provides four different flavors of mounts; struct vfsmount to be33Shared subtree provides four different flavors of mounts; struct vfsmount to be
34precise34precise:
35 35
36 a. shared mount
37 b. slave mount
38 c. private mount
39 d. unbindable mount
40 36
37a) A **shared mount** can be replicated to as many mountpoints and all the
38 replicas continue to be exactly same.
41 39
422a) A shared mount can be replicated to as many mountpoints and all the40 Here is an example:
43replicas continue to be exactly same.
44 41
45 Here is an example:42 Let's say /mnt has a mount that is shared::
46 43
47 Let's say /mnt has a mount that is shared::44 # mount --make-shared /mnt
48 45
49 mount --make-shared /mnt46 .. note::
47 mount(8) command now supports the --make-shared flag,
48 so the sample 'smount' program is no longer needed and has been
49 removed.
50 50
51 Note: mount(8) command now supports the --make-shared flag,51 ::
52 so the sample 'smount' program is no longer needed and has been
53 removed.
54 52
55 ::53 # mount --bind /mnt /tmp
56 54
57 # mount --bind /mnt /tmp55 The above command replicates the mount at /mnt to the mountpoint /tmp
56 and the contents of both the mounts remain identical.
58 57
59 The above command replicates the mount at /mnt to the mountpoint /tmp58 ::
60 and the contents of both the mounts remain identical.
61 59
62 ::60 #ls /mnt
61 a b c
63 62
64 #ls /mnt63 #ls /tmp
65 a b c64 a b c
66 65
67 #ls /tmp66 Now let's say we mount a device at /tmp/a::
68 a b c
69 67
70 Now let's say we mount a device at /tmp/a::68 # mount /dev/sd0 /tmp/a
71 69
72 # mount /dev/sd0 /tmp/a70 # ls /tmp/a
71 t1 t2 t3
73 72
74 #ls /tmp/a73 # ls /mnt/a
75 t1 t2 t374 t1 t2 t3
76 75
77 #ls /mnt/a76 Note that the mount has propagated to the mount at /mnt as well.
78 t1 t2 t3
79 77
80 Note that the mount has propagated to the mount at /mnt as well.78 And the same is true even when /dev/sd0 is mounted on /mnt/a. The
79 contents will be visible under /tmp/a too.
81 80
82 And the same is true even when /dev/sd0 is mounted on /mnt/a. The
83 contents will be visible under /tmp/a too.
84 81
82b) A **slave mount** is like a shared mount except that mount and umount events
83 only propagate towards it.
85 84
862b) A slave mount is like a shared mount except that mount and umount events85 All slave mounts have a master mount which is a shared.
87 only propagate towards it.
88 86
89 All slave mounts have a master mount which is a shared.87 Here is an example:
90 88
91 Here is an example:89 Let's say /mnt has a mount which is shared::
92 90
93 Let's say /mnt has a mount which is shared.91 # mount --make-shared /mnt
94 # mount --make-shared /mnt
95 92
96 Let's bind mount /mnt to /tmp93 Let's bind mount /mnt to /tmp::
97 # mount --bind /mnt /tmp
98 94
99 the new mount at /tmp becomes a shared mount and it is a replica of95 # mount --bind /mnt /tmp
100 the mount at /mnt.
101 96
102 Now let's make the mount at /tmp; a slave of /mnt97 the new mount at /tmp becomes a shared mount and it is a replica of
103 # mount --make-slave /tmp98 the mount at /mnt.
104 99
105 let's mount /dev/sd0 on /mnt/a100 Now let's make the mount at /tmp; a slave of /mnt::
106 # mount /dev/sd0 /mnt/a
107 101
108 #ls /mnt/a102 # mount --make-slave /tmp
109 t1 t2 t3
110 103
111 #ls /tmp/a104 let's mount /dev/sd0 on /mnt/a::
112 t1 t2 t3
113 105
114 Note the mount event has propagated to the mount at /tmp106 # mount /dev/sd0 /mnt/a
115 107
116 However let's see what happens if we mount something on the mount at /tmp108 # ls /mnt/a
109 t1 t2 t3
117 110
118 # mount /dev/sd1 /tmp/b111 # ls /tmp/a
112 t1 t2 t3
119 113
120 #ls /tmp/b114 Note the mount event has propagated to the mount at /tmp
121 s1 s2 s3
122 115
123 #ls /mnt/b116 However let's see what happens if we mount something on the mount at
117 /tmp::
124 118
125 Note how the mount event has not propagated to the mount at119 # mount /dev/sd1 /tmp/b
126 /mnt
127 120
121 # ls /tmp/b
122 s1 s2 s3
128 123
1292c) A private mount does not forward or receive propagation.124 # ls /mnt/b
130 125
131 This is the mount we are familiar with. Its the default type.126 Note how the mount event has not propagated to the mount at
127 /mnt
132 128
133 129
1342d) A unbindable mount is a unbindable private mount130c) A **private mount** does not forward or receive propagation.
135 131
136 let's say we have a mount at /mnt and we make it unbindable::132 This is the mount we are familiar with. Its the default type.
137 133
138 # mount --make-unbindable /mnt
139 134
140 Let's try to bind mount this mount somewhere else::135d) An **unbindable mount** is, as the name suggests, an unbindable private
136 mount.
141 137
142 # mount --bind /mnt /tmp138 let's say we have a mount at /mnt and we make it unbindable::
143 mount: wrong fs type, bad option, bad superblock on /mnt,
144 or too many mounted file systems
145 139
146 Binding a unbindable mount is a invalid operation.140 # mount --make-unbindable /mnt
141
142 Let's try to bind mount this mount somewhere else::
143
144 # mount --bind /mnt /tmp mount: wrong fs type, bad option, bad
145 superblock on /mnt, or too many mounted file systems
146
147 Binding a unbindable mount is a invalid operation.
147 148
148 149
1493) Setting mount states1503) Setting mount states
150-----------------------151-----------------------
151 152
152 The mount command (util-linux package) can be used to set mount153The mount command (util-linux package) can be used to set mount
153 states::154states::
154 155
155 mount --make-shared mountpoint156 mount --make-shared mountpoint
156 mount --make-slave mountpoint157 mount --make-slave mountpoint
157 mount --make-private mountpoint158 mount --make-private mountpoint
158 mount --make-unbindable mountpoint159 mount --make-unbindable mountpoint
159 160
160 161
1614) Use cases1624) Use cases
162------------163------------
163 164
164 A) A process wants to clone its own namespace, but still wants to165A) A process wants to clone its own namespace, but still wants to
165 access the CD that got mounted recently.166 access the CD that got mounted recently.
166 167
167 Solution:168 Solution:
168 169
169 The system administrator can make the mount at /cdrom shared::170 The system administrator can make the mount at /cdrom shared::
170 171
171 mount --bind /cdrom /cdrom172 mount --bind /cdrom /cdrom
172 mount --make-shared /cdrom173 mount --make-shared /cdrom
173 174
174 Now any process that clones off a new namespace will have a175 Now any process that clones off a new namespace will have a
175 mount at /cdrom which is a replica of the same mount in the176 mount at /cdrom which is a replica of the same mount in the
176 parent namespace.177 parent namespace.
177 178
178 So when a CD is inserted and mounted at /cdrom that mount gets179 So when a CD is inserted and mounted at /cdrom that mount gets
179 propagated to the other mount at /cdrom in all the other clone180 propagated to the other mount at /cdrom in all the other clone
180 namespaces.181 namespaces.
181 182
182 B) A process wants its mounts invisible to any other process, but183B) A process wants its mounts invisible to any other process, but
183 still be able to see the other system mounts.184 still be able to see the other system mounts.
184 185
185 Solution:186 Solution:
186 187
187 To begin with, the administrator can mark the entire mount tree188 To begin with, the administrator can mark the entire mount tree
188 as shareable::189 as shareable::
189 190
190 mount --make-rshared /191 mount --make-rshared /
191 192
192 A new process can clone off a new namespace. And mark some part193 A new process can clone off a new namespace. And mark some part
193 of its namespace as slave::194 of its namespace as slave::
194 195
195 mount --make-rslave /myprivatetree196 mount --make-rslave /myprivatetree
196 197
197 Hence forth any mounts within the /myprivatetree done by the198 Hence forth any mounts within the /myprivatetree done by the
198 process will not show up in any other namespace. However mounts199 process will not show up in any other namespace. However mounts
199 done in the parent namespace under /myprivatetree still shows200 done in the parent namespace under /myprivatetree still shows
200 up in the process's namespace.201 up in the process's namespace.
201 202
202 203
203 Apart from the above semantics this feature provides the204Apart from the above semantics this feature provides the
204 building blocks to solve the following problems:205building blocks to solve the following problems:
205 206
206 C) Per-user namespace207C) Per-user namespace
207 208
208 The above semantics allows a way to share mounts across209 The above semantics allows a way to share mounts across
209 namespaces. But namespaces are associated with processes. If210 namespaces. But namespaces are associated with processes. If
210 namespaces are made first class objects with user API to211 namespaces are made first class objects with user API to
211 associate/disassociate a namespace with userid, then each user212 associate/disassociate a namespace with userid, then each user
212 could have his/her own namespace and tailor it to his/her213 could have his/her own namespace and tailor it to his/her
213 requirements. This needs to be supported in PAM.214 requirements. This needs to be supported in PAM.
214 215
215 D) Versioned files216D) Versioned files
216 217
217 If the entire mount tree is visible at multiple locations, then218 If the entire mount tree is visible at multiple locations, then
218 an underlying versioning file system can return different219 an underlying versioning file system can return different
219 versions of the file depending on the path used to access that220 versions of the file depending on the path used to access that
220 file.221 file.
221 222
222 An example is::223 An example is::
223 224
224 mount --make-shared /225 mount --make-shared /
225 mount --rbind / /view/v1226 mount --rbind / /view/v1
226 mount --rbind / /view/v2227 mount --rbind / /view/v2
227 mount --rbind / /view/v3228 mount --rbind / /view/v3
228 mount --rbind / /view/v4229 mount --rbind / /view/v4
229 230
230 and if /usr has a versioning filesystem mounted, then that231 and if /usr has a versioning filesystem mounted, then that
231 mount appears at /view/v1/usr, /view/v2/usr, /view/v3/usr and232 mount appears at /view/v1/usr, /view/v2/usr, /view/v3/usr and
232 /view/v4/usr too233 /view/v4/usr too
233 234
234 A user can request v3 version of the file /usr/fs/namespace.c235 A user can request v3 version of the file /usr/fs/namespace.c
235 by accessing /view/v3/usr/fs/namespace.c . The underlying236 by accessing /view/v3/usr/fs/namespace.c . The underlying
236 versioning filesystem can then decipher that v3 version of the237 versioning filesystem can then decipher that v3 version of the
237 filesystem is being requested and return the corresponding238 filesystem is being requested and return the corresponding
238 inode.239 inode.
239 240
2405) Detailed semantics2415) Detailed semantics
241---------------------242---------------------
242 The section below explains the detailed semantics of243The section below explains the detailed semantics of
243 bind, rbind, move, mount, umount and clone-namespace operations.244bind, rbind, move, mount, umount and clone-namespace operations.
244
245 Note: the word 'vfsmount' and the noun 'mount' have been used
246 to mean the same thing, throughout this document.
247 245
2485a) Mount states246.. Note::
247 the word 'vfsmount' and the noun 'mount' have been used
248 to mean the same thing, throughout this document.
249 249
250 A given mount can be in one of the following states250a) Mount states
251 251
252 1) shared252 A **propagation event** is defined as event generated on a vfsmount
253 2) slave253 that leads to mount or unmount actions in other vfsmounts.
254 3) shared and slave
255 4) private
256 5) unbindable
257 254
258 A 'propagation event' is defined as event generated on a vfsmount255 A **peer group** is defined as a group of vfsmounts that propagate
259 that leads to mount or unmount actions in other vfsmounts.256 events to each other.
260 257
261 A 'peer group' is defined as a group of vfsmounts that propagate258 A given mount can be in one of the following states:
262 events to each other.
263 259
264 (1) Shared mounts260 (1) Shared mounts
265 261
266 A 'shared mount' is defined as a vfsmount that belongs to a262 A **shared mount** is defined as a vfsmount that belongs to a
267 'peer group'.263 peer group.
268 264
269 For example::265 For example::
270 266
271 mount --make-shared /mnt267 mount --make-shared /mnt
272 mount --bind /mnt /tmp268 mount --bind /mnt /tmp
273 269
274 The mount at /mnt and that at /tmp are both shared and belong270 The mount at /mnt and that at /tmp are both shared and belong
275 to the same peer group. Anything mounted or unmounted under271 to the same peer group. Anything mounted or unmounted under
276 /mnt or /tmp reflect in all the other mounts of its peer272 /mnt or /tmp reflect in all the other mounts of its peer
277 group.273 group.
278 274
279 275
280 (2) Slave mounts276 (2) Slave mounts
281 277
282 A 'slave mount' is defined as a vfsmount that receives278 A **slave mount** is defined as a vfsmount that receives
283 propagation events and does not forward propagation events.279 propagation events and does not forward propagation events.
284 280
285 A slave mount as the name implies has a master mount from which281 A slave mount as the name implies has a master mount from which
286 mount/unmount events are received. Events do not propagate from282 mount/unmount events are received. Events do not propagate from
287 the slave mount to the master. Only a shared mount can be made283 the slave mount to the master. Only a shared mount can be made
288 a slave by executing the following command::284 a slave by executing the following command::
289 285
290 mount --make-slave mount286 mount --make-slave mount
291 287
292 A shared mount that is made as a slave is no more shared unless288 A shared mount that is made as a slave is no more shared unless
293 modified to become shared.289 modified to become shared.
294 290
295 (3) Shared and Slave291 (3) Shared and Slave
296 292
297 A vfsmount can be both shared as well as slave. This state293 A vfsmount can be both **shared** as well as **slave**. This state
298 indicates that the mount is a slave of some vfsmount, and294 indicates that the mount is a slave of some vfsmount, and
299 has its own peer group too. This vfsmount receives propagation295 has its own peer group too. This vfsmount receives propagation
300 events from its master vfsmount, and also forwards propagation296 events from its master vfsmount, and also forwards propagation
301 events to its 'peer group' and to its slave vfsmounts.297 events to its 'peer group' and to its slave vfsmounts.
302 298
303 Strictly speaking, the vfsmount is shared having its own299 Strictly speaking, the vfsmount is shared having its own
304 peer group, and this peer-group is a slave of some other300 peer group, and this peer-group is a slave of some other
305 peer group.301 peer group.
306 302
307 Only a slave vfsmount can be made as 'shared and slave' by303 Only a slave vfsmount can be made as 'shared and slave' by
308 either executing the following command::304 either executing the following command::
309 305
310 mount --make-shared mount306 mount --make-shared mount
311 307
312 or by moving the slave vfsmount under a shared vfsmount.308 or by moving the slave vfsmount under a shared vfsmount.
313 309
314 (4) Private mount310 (4) Private mount
315 311
316 A 'private mount' is defined as vfsmount that does not312 A **private mount** is defined as vfsmount that does not
317 receive or forward any propagation events.313 receive or forward any propagation events.
318 314
319 (5) Unbindable mount315 (5) Unbindable mount
320 316
321 A 'unbindable mount' is defined as vfsmount that does not317 A **unbindable mount** is defined as vfsmount that does not
322 receive or forward any propagation events and cannot318 receive or forward any propagation events and cannot
323 be bind mounted.319 be bind mounted.
324 320
325 321
326 State diagram:322 State diagram:
327 323
328 The state diagram below explains the state transition of a mount,324 The state diagram below explains the state transition of a mount,
329 in response to various commands::325 in response to various commands::
330 326
331 -----------------------------------------------------------------------327 -----------------------------------------------------------------------
332 | |make-shared | make-slave | make-private |make-unbindab|328 | |make-shared | make-slave | make-private |make-unbindab|
333 --------------|------------|--------------|--------------|-------------|329 --------------|------------|--------------|--------------|-------------|
334 |shared |shared |*slave/private| private | unbindable |330 |shared |shared |*slave/private| private | unbindable |
335 | | | | | |331 | | | | | |
336 |-------------|------------|--------------|--------------|-------------|332 |-------------|------------|--------------|--------------|-------------|
337 |slave |shared | **slave | private | unbindable |333 |slave |shared | **slave | private | unbindable |
338 | |and slave | | | |334 | |and slave | | | |
339 |-------------|------------|--------------|--------------|-------------|335 |-------------|------------|--------------|--------------|-------------|
340 |shared |shared | slave | private | unbindable |336 |shared |shared | slave | private | unbindable |
341 |and slave |and slave | | | |337 |and slave |and slave | | | |
342 |-------------|------------|--------------|--------------|-------------|338 |-------------|------------|--------------|--------------|-------------|
343 |private |shared | **private | private | unbindable |339 |private |shared | **private | private | unbindable |
344 |-------------|------------|--------------|--------------|-------------|340 |-------------|------------|--------------|--------------|-------------|
345 |unbindable |shared |**unbindable | private | unbindable |341 |unbindable |shared |**unbindable | private | unbindable |
346 ------------------------------------------------------------------------342 ------------------------------------------------------------------------
347 343
348 * if the shared mount is the only mount in its peer group, making it344 * if the shared mount is the only mount in its peer group, making it
349 slave, makes it private automatically. Note that there is no master to345 slave, makes it private automatically. Note that there is no master to
350 which it can be slaved to.346 which it can be slaved to.
351 347
352 ** slaving a non-shared mount has no effect on the mount.348 ** slaving a non-shared mount has no effect on the mount.
353 349
354 Apart from the commands listed below, the 'move' operation also changes350 Apart from the commands listed below, the 'move' operation also changes
355 the state of a mount depending on type of the destination mount. Its351 the state of a mount depending on type of the destination mount. Its
356 explained in section 5d.352 explained in section 5d.
357 353
3585b) Bind semantics354b) Bind semantics
359 355
360 Consider the following command::356 Consider the following command::
361 357
362 mount --bind A/a B/b358 mount --bind A/a B/b
363 359
364 where 'A' is the source mount, 'a' is the dentry in the mount 'A', 'B'360 where 'A' is the source mount, 'a' is the dentry in the mount 'A', 'B'
365 is the destination mount and 'b' is the dentry in the destination mount.361 is the destination mount and 'b' is the dentry in the destination mount.
366 362
367 The outcome depends on the type of mount of 'A' and 'B'. The table363 The outcome depends on the type of mount of 'A' and 'B'. The table
368 below contains quick reference::364 below contains quick reference::
369 365
370 --------------------------------------------------------------------------366 --------------------------------------------------------------------------
371 | BIND MOUNT OPERATION |367 | BIND MOUNT OPERATION |
372 |************************************************************************|368 |************************************************************************|
373 |source(A)->| shared | private | slave | unbindable |369 |source(A)->| shared | private | slave | unbindable |
374 | dest(B) | | | | |370 | dest(B) | | | | |
375 | | | | | | |371 | | | | | | |
376 | v | | | | |372 | v | | | | |
377 |************************************************************************|373 |************************************************************************|
378 | shared | shared | shared | shared & slave | invalid |374 | shared | shared | shared | shared & slave | invalid |
379 | | | | | |375 | | | | | |
380 |non-shared| shared | private | slave | invalid |376 |non-shared| shared | private | slave | invalid |
381 **************************************************************************377 **************************************************************************
382 378
383 Details:379 Details:
384 380
385 1. 'A' is a shared mount and 'B' is a shared mount. A new mount 'C'381 1. 'A' is a shared mount and 'B' is a shared mount. A new mount 'C'
386 which is clone of 'A', is created. Its root dentry is 'a' . 'C' is382 which is clone of 'A', is created. Its root dentry is 'a' . 'C' is
387 mounted on mount 'B' at dentry 'b'. Also new mount 'C1', 'C2', 'C3' ...383 mounted on mount 'B' at dentry 'b'. Also new mount 'C1', 'C2', 'C3' ...
388 are created and mounted at the dentry 'b' on all mounts where 'B'384 are created and mounted at the dentry 'b' on all mounts where 'B'
389 propagates to. A new propagation tree containing 'C1',..,'Cn' is385 propagates to. A new propagation tree containing 'C1',..,'Cn' is
390 created. This propagation tree is identical to the propagation tree of386 created. This propagation tree is identical to the propagation tree of
391 'B'. And finally the peer-group of 'C' is merged with the peer group387 'B'. And finally the peer-group of 'C' is merged with the peer group
392 of 'A'.388 of 'A'.
393 389
394 2. 'A' is a private mount and 'B' is a shared mount. A new mount 'C'390 2. 'A' is a private mount and 'B' is a shared mount. A new mount 'C'
395 which is clone of 'A', is created. Its root dentry is 'a'. 'C' is391 which is clone of 'A', is created. Its root dentry is 'a'. 'C' is
396 mounted on mount 'B' at dentry 'b'. Also new mount 'C1', 'C2', 'C3' ...392 mounted on mount 'B' at dentry 'b'. Also new mount 'C1', 'C2', 'C3' ...
397 are created and mounted at the dentry 'b' on all mounts where 'B'393 are created and mounted at the dentry 'b' on all mounts where 'B'
398 propagates to. A new propagation tree is set containing all new mounts394 propagates to. A new propagation tree is set containing all new mounts
399 'C', 'C1', .., 'Cn' with exactly the same configuration as the395 'C', 'C1', .., 'Cn' with exactly the same configuration as the
400 propagation tree for 'B'.396 propagation tree for 'B'.
401 397
402 3. 'A' is a slave mount of mount 'Z' and 'B' is a shared mount. A new398 3. 'A' is a slave mount of mount 'Z' and 'B' is a shared mount. A new
403 mount 'C' which is clone of 'A', is created. Its root dentry is 'a' .399 mount 'C' which is clone of 'A', is created. Its root dentry is 'a' .
404 'C' is mounted on mount 'B' at dentry 'b'. Also new mounts 'C1', 'C2',400 'C' is mounted on mount 'B' at dentry 'b'. Also new mounts 'C1', 'C2',
405 'C3' ... are created and mounted at the dentry 'b' on all mounts where401 'C3' ... are created and mounted at the dentry 'b' on all mounts where
406 'B' propagates to. A new propagation tree containing the new mounts402 'B' propagates to. A new propagation tree containing the new mounts
407 'C','C1',.. 'Cn' is created. This propagation tree is identical to the403 'C','C1',.. 'Cn' is created. This propagation tree is identical to the
408 propagation tree for 'B'. And finally the mount 'C' and its peer group404 propagation tree for 'B'. And finally the mount 'C' and its peer group
409 is made the slave of mount 'Z'. In other words, mount 'C' is in the405 is made the slave of mount 'Z'. In other words, mount 'C' is in the
410 state 'slave and shared'.406 state 'slave and shared'.
411 407
412 4. 'A' is a unbindable mount and 'B' is a shared mount. This is a408 4. 'A' is a unbindable mount and 'B' is a shared mount. This is a
413 invalid operation.409 invalid operation.
414 410
415 5. 'A' is a private mount and 'B' is a non-shared(private or slave or411 5. 'A' is a private mount and 'B' is a non-shared(private or slave or
416 unbindable) mount. A new mount 'C' which is clone of 'A', is created.412 unbindable) mount. A new mount 'C' which is clone of 'A', is created.
417 Its root dentry is 'a'. 'C' is mounted on mount 'B' at dentry 'b'.413 Its root dentry is 'a'. 'C' is mounted on mount 'B' at dentry 'b'.
418 414
419 6. 'A' is a shared mount and 'B' is a non-shared mount. A new mount 'C'415 6. 'A' is a shared mount and 'B' is a non-shared mount. A new mount 'C'
420 which is a clone of 'A' is created. Its root dentry is 'a'. 'C' is416 which is a clone of 'A' is created. Its root dentry is 'a'. 'C' is
421 mounted on mount 'B' at dentry 'b'. 'C' is made a member of the417 mounted on mount 'B' at dentry 'b'. 'C' is made a member of the
422 peer-group of 'A'.418 peer-group of 'A'.
423 419
424 7. 'A' is a slave mount of mount 'Z' and 'B' is a non-shared mount. A420 7. 'A' is a slave mount of mount 'Z' and 'B' is a non-shared mount. A
425 new mount 'C' which is a clone of 'A' is created. Its root dentry is421 new mount 'C' which is a clone of 'A' is created. Its root dentry is
426 'a'. 'C' is mounted on mount 'B' at dentry 'b'. Also 'C' is set as a422 'a'. 'C' is mounted on mount 'B' at dentry 'b'. Also 'C' is set as a
427 slave mount of 'Z'. In other words 'A' and 'C' are both slave mounts of423 slave mount of 'Z'. In other words 'A' and 'C' are both slave mounts of
428 'Z'. All mount/unmount events on 'Z' propagates to 'A' and 'C'. But424 'Z'. All mount/unmount events on 'Z' propagates to 'A' and 'C'. But
429 mount/unmount on 'A' do not propagate anywhere else. Similarly425 mount/unmount on 'A' do not propagate anywhere else. Similarly
430 mount/unmount on 'C' do not propagate anywhere else.426 mount/unmount on 'C' do not propagate anywhere else.
431 427
432 8. 'A' is a unbindable mount and 'B' is a non-shared mount. This is a428 8. 'A' is a unbindable mount and 'B' is a non-shared mount. This is a
433 invalid operation. A unbindable mount cannot be bind mounted.429 invalid operation. A unbindable mount cannot be bind mounted.
434 430
4355c) Rbind semantics431c) Rbind semantics
436 432
437 rbind is same as bind. Bind replicates the specified mount. Rbind433 rbind is same as bind. Bind replicates the specified mount. Rbind
438 replicates all the mounts in the tree belonging to the specified mount.434 replicates all the mounts in the tree belonging to the specified mount.
439 Rbind mount is bind mount applied to all the mounts in the tree.435 Rbind mount is bind mount applied to all the mounts in the tree.
440 436
441 If the source tree that is rbind has some unbindable mounts,437 If the source tree that is rbind has some unbindable mounts,
442 then the subtree under the unbindable mount is pruned in the new438 then the subtree under the unbindable mount is pruned in the new
443 location.439 location.
444 440
445 eg:441 eg:
446 442
447 let's say we have the following mount tree::443 let's say we have the following mount tree::
448 444
449 A445 A
450 / \446 / \
451 B C447 B C
452 / \ / \448 / \ / \
453 D E F G449 D E F G
454 450
455 Let's say all the mount except the mount C in the tree are451 Let's say all the mount except the mount C in the tree are
456 of a type other than unbindable.452 of a type other than unbindable.
457 453
458 If this tree is rbound to say Z454 If this tree is rbound to say Z
459 455
460 We will have the following tree at the new location::456 We will have the following tree at the new location::
461 457
462 Z458 Z
463 |459 |
464 A'460 A'
465 /461 /
466 B' Note how the tree under C is pruned462 B' Note how the tree under C is pruned
467 / \ in the new location.463 / \ in the new location.
468 D' E'464 D' E'
469 465
470 466
471 467
4725d) Move semantics468d) Move semantics
473 469
474 Consider the following command470 Consider the following command::
475 471
476 mount --move A B/b472 mount --move A B/b
477 473
478 where 'A' is the source mount, 'B' is the destination mount and 'b' is474 where 'A' is the source mount, 'B' is the destination mount and 'b' is
479 the dentry in the destination mount.475 the dentry in the destination mount.
480 476
481 The outcome depends on the type of the mount of 'A' and 'B'. The table477 The outcome depends on the type of the mount of 'A' and 'B'. The table
482 below is a quick reference::478 below is a quick reference::
483 479
484 ---------------------------------------------------------------------------480 ---------------------------------------------------------------------------
485 | MOVE MOUNT OPERATION |481 | MOVE MOUNT OPERATION |
486 |**************************************************************************482 |**************************************************************************
487 | source(A)->| shared | private | slave | unbindable |483 | source(A)->| shared | private | slave | unbindable |
488 | dest(B) | | | | |484 | dest(B) | | | | |
489 | | | | | | |485 | | | | | | |
490 | v | | | | |486 | v | | | | |
491 |**************************************************************************487 |**************************************************************************
492 | shared | shared | shared |shared and slave| invalid |488 | shared | shared | shared |shared and slave| invalid |
493 | | | | | |489 | | | | | |
494 |non-shared| shared | private | slave | unbindable |490 |non-shared| shared | private | slave | unbindable |
495 ***************************************************************************491 ***************************************************************************
496 492
497 .. Note:: moving a mount residing under a shared mount is invalid.493 .. Note:: moving a mount residing under a shared mount is invalid.
498 494
499 Details follow:495 Details follow:
500 496
501 1. 'A' is a shared mount and 'B' is a shared mount. The mount 'A' is497 1. 'A' is a shared mount and 'B' is a shared mount. The mount 'A' is
502 mounted on mount 'B' at dentry 'b'. Also new mounts 'A1', 'A2'...'An'498 mounted on mount 'B' at dentry 'b'. Also new mounts 'A1', 'A2'...'An'
503 are created and mounted at dentry 'b' on all mounts that receive499 are created and mounted at dentry 'b' on all mounts that receive
504 propagation from mount 'B'. A new propagation tree is created in the500 propagation from mount 'B'. A new propagation tree is created in the
505 exact same configuration as that of 'B'. This new propagation tree501 exact same configuration as that of 'B'. This new propagation tree
506 contains all the new mounts 'A1', 'A2'... 'An'. And this new502 contains all the new mounts 'A1', 'A2'... 'An'. And this new
507 propagation tree is appended to the already existing propagation tree503 propagation tree is appended to the already existing propagation tree
508 of 'A'.504 of 'A'.
509 505
510 2. 'A' is a private mount and 'B' is a shared mount. The mount 'A' is506 2. 'A' is a private mount and 'B' is a shared mount. The mount 'A' is
511 mounted on mount 'B' at dentry 'b'. Also new mount 'A1', 'A2'... 'An'507 mounted on mount 'B' at dentry 'b'. Also new mount 'A1', 'A2'... 'An'
512 are created and mounted at dentry 'b' on all mounts that receive508 are created and mounted at dentry 'b' on all mounts that receive
513 propagation from mount 'B'. The mount 'A' becomes a shared mount and a509 propagation from mount 'B'. The mount 'A' becomes a shared mount and a
514 propagation tree is created which is identical to that of510 propagation tree is created which is identical to that of
515 'B'. This new propagation tree contains all the new mounts 'A1',511 'B'. This new propagation tree contains all the new mounts 'A1',
516 'A2'... 'An'.512 'A2'... 'An'.
517 513
518 3. 'A' is a slave mount of mount 'Z' and 'B' is a shared mount. The514 3. 'A' is a slave mount of mount 'Z' and 'B' is a shared mount. The
519 mount 'A' is mounted on mount 'B' at dentry 'b'. Also new mounts 'A1',515 mount 'A' is mounted on mount 'B' at dentry 'b'. Also new mounts 'A1',
520 'A2'... 'An' are created and mounted at dentry 'b' on all mounts that516 'A2'... 'An' are created and mounted at dentry 'b' on all mounts that
521 receive propagation from mount 'B'. A new propagation tree is created517 receive propagation from mount 'B'. A new propagation tree is created
522 in the exact same configuration as that of 'B'. This new propagation518 in the exact same configuration as that of 'B'. This new propagation
523 tree contains all the new mounts 'A1', 'A2'... 'An'. And this new519 tree contains all the new mounts 'A1', 'A2'... 'An'. And this new
524 propagation tree is appended to the already existing propagation tree of520 propagation tree is appended to the already existing propagation tree of
525 'A'. Mount 'A' continues to be the slave mount of 'Z' but it also521 'A'. Mount 'A' continues to be the slave mount of 'Z' but it also
526 becomes 'shared'.522 becomes 'shared'.
527 523
528 4. 'A' is a unbindable mount and 'B' is a shared mount. The operation524 4. 'A' is a unbindable mount and 'B' is a shared mount. The operation
529 is invalid. Because mounting anything on the shared mount 'B' can525 is invalid. Because mounting anything on the shared mount 'B' can
530 create new mounts that get mounted on the mounts that receive526 create new mounts that get mounted on the mounts that receive
531 propagation from 'B'. And since the mount 'A' is unbindable, cloning527 propagation from 'B'. And since the mount 'A' is unbindable, cloning
532 it to mount at other mountpoints is not possible.528 it to mount at other mountpoints is not possible.
533 529
534 5. 'A' is a private mount and 'B' is a non-shared(private or slave or530 5. 'A' is a private mount and 'B' is a non-shared(private or slave or
535 unbindable) mount. The mount 'A' is mounted on mount 'B' at dentry 'b'.531 unbindable) mount. The mount 'A' is mounted on mount 'B' at dentry 'b'.
536 532
537 6. 'A' is a shared mount and 'B' is a non-shared mount. The mount 'A'533 6. 'A' is a shared mount and 'B' is a non-shared mount. The mount 'A'
538 is mounted on mount 'B' at dentry 'b'. Mount 'A' continues to be a534 is mounted on mount 'B' at dentry 'b'. Mount 'A' continues to be a
539 shared mount.535 shared mount.
540 536
541 7. 'A' is a slave mount of mount 'Z' and 'B' is a non-shared mount.537 7. 'A' is a slave mount of mount 'Z' and 'B' is a non-shared mount.
542 The mount 'A' is mounted on mount 'B' at dentry 'b'. Mount 'A'538 The mount 'A' is mounted on mount 'B' at dentry 'b'. Mount 'A'
543 continues to be a slave mount of mount 'Z'.539 continues to be a slave mount of mount 'Z'.
544 540
545 8. 'A' is a unbindable mount and 'B' is a non-shared mount. The mount541 8. 'A' is a unbindable mount and 'B' is a non-shared mount. The mount
546 'A' is mounted on mount 'B' at dentry 'b'. Mount 'A' continues to be a542 'A' is mounted on mount 'B' at dentry 'b'. Mount 'A' continues to be a
547 unbindable mount.543 unbindable mount.
548 544
5495e) Mount semantics545e) Mount semantics
550 546
551 Consider the following command::547 Consider the following command::
552 548
553 mount device B/b549 mount device B/b
554 550
555 'B' is the destination mount and 'b' is the dentry in the destination551 'B' is the destination mount and 'b' is the dentry in the destination
556 mount.552 mount.
557 553
558 The above operation is the same as bind operation with the exception554 The above operation is the same as bind operation with the exception
559 that the source mount is always a private mount.555 that the source mount is always a private mount.
560 556
561 557
5625f) Unmount semantics558f) Unmount semantics
563 559
564 Consider the following command::560 Consider the following command::
565 561
566 umount A562 umount A
567 563
568 where 'A' is a mount mounted on mount 'B' at dentry 'b'.564 where 'A' is a mount mounted on mount 'B' at dentry 'b'.
569 565
570 If mount 'B' is shared, then all most-recently-mounted mounts at dentry566 If mount 'B' is shared, then all most-recently-mounted mounts at dentry
571 'b' on mounts that receive propagation from mount 'B' and does not have567 'b' on mounts that receive propagation from mount 'B' and does not have
572 sub-mounts within them are unmounted.568 sub-mounts within them are unmounted.
573 569
574 Example: Let's say 'B1', 'B2', 'B3' are shared mounts that propagate to570 Example: Let's say 'B1', 'B2', 'B3' are shared mounts that propagate to
575 each other.571 each other.
576 572
577 let's say 'A1', 'A2', 'A3' are first mounted at dentry 'b' on mount573 let's say 'A1', 'A2', 'A3' are first mounted at dentry 'b' on mount
578 'B1', 'B2' and 'B3' respectively.574 'B1', 'B2' and 'B3' respectively.
579 575
580 let's say 'C1', 'C2', 'C3' are next mounted at the same dentry 'b' on576 let's say 'C1', 'C2', 'C3' are next mounted at the same dentry 'b' on
581 mount 'B1', 'B2' and 'B3' respectively.577 mount 'B1', 'B2' and 'B3' respectively.
582 578
583 if 'C1' is unmounted, all the mounts that are most-recently-mounted on579 if 'C1' is unmounted, all the mounts that are most-recently-mounted on
584 'B1' and on the mounts that 'B1' propagates-to are unmounted.580 'B1' and on the mounts that 'B1' propagates-to are unmounted.
585 581
586 'B1' propagates to 'B2' and 'B3'. And the most recently mounted mount582 'B1' propagates to 'B2' and 'B3'. And the most recently mounted mount
587 on 'B2' at dentry 'b' is 'C2', and that of mount 'B3' is 'C3'.583 on 'B2' at dentry 'b' is 'C2', and that of mount 'B3' is 'C3'.
588 584
589 So all 'C1', 'C2' and 'C3' should be unmounted.585 So all 'C1', 'C2' and 'C3' should be unmounted.
590 586
591 If any of 'C2' or 'C3' has some child mounts, then that mount is not587 If any of 'C2' or 'C3' has some child mounts, then that mount is not
592 unmounted, but all other mounts are unmounted. However if 'C1' is told588 unmounted, but all other mounts are unmounted. However if 'C1' is told
593 to be unmounted and 'C1' has some sub-mounts, the umount operation is589 to be unmounted and 'C1' has some sub-mounts, the umount operation is
594 failed entirely.590 failed entirely.
595 591
5965g) Clone Namespace592g) Clone Namespace
597 593
598 A cloned namespace contains all the mounts as that of the parent594 A cloned namespace contains all the mounts as that of the parent
599 namespace.595 namespace.
600 596
601 Let's say 'A' and 'B' are the corresponding mounts in the parent and the597 Let's say 'A' and 'B' are the corresponding mounts in the parent and the
602 child namespace.598 child namespace.
603 599
604 If 'A' is shared, then 'B' is also shared and 'A' and 'B' propagate to600 If 'A' is shared, then 'B' is also shared and 'A' and 'B' propagate to
605 each other.601 each other.
606 602
607 If 'A' is a slave mount of 'Z', then 'B' is also the slave mount of603 If 'A' is a slave mount of 'Z', then 'B' is also the slave mount of
608 'Z'.604 'Z'.
609 605
610 If 'A' is a private mount, then 'B' is a private mount too.606 If 'A' is a private mount, then 'B' is a private mount too.
611 607
612 If 'A' is unbindable mount, then 'B' is a unbindable mount too.608 If 'A' is unbindable mount, then 'B' is a unbindable mount too.
613 609
614 610
6156) Quiz6116) Quiz
616-------612-------
617 613
618 A. What is the result of the following command sequence?614A. What is the result of the following command sequence?
619 615
620 ::616 ::
621 617
622 mount --bind /mnt /mnt618 mount --bind /mnt /mnt
623 mount --make-shared /mnt619 mount --make-shared /mnt
624 mount --bind /mnt /tmp620 mount --bind /mnt /tmp
625 mount --move /tmp /mnt/1621 mount --move /tmp /mnt/1
626 622
627 what should be the contents of /mnt /mnt/1 /mnt/1/1 should be?623 what should be the contents of /mnt /mnt/1 /mnt/1/1 should be?
628 Should they all be identical? or should /mnt and /mnt/1 be624 Should they all be identical? or should /mnt and /mnt/1 be
629 identical only?625 identical only?
630 626
631 627
632 B. What is the result of the following command sequence?628B. What is the result of the following command sequence?
633 629
634 ::630 ::
635 631
636 mount --make-rshared /632 mount --make-rshared /
637 mkdir -p /v/1633 mkdir -p /v/1
638 mount --rbind / /v/1634 mount --rbind / /v/1
639 635
640 what should be the content of /v/1/v/1 be?636 what should be the content of /v/1/v/1 be?
641 637
642 638
643 C. What is the result of the following command sequence?639C. What is the result of the following command sequence?
644 640
645 ::641 ::
646 642
647 mount --bind /mnt /mnt643 mount --bind /mnt /mnt
648 mount --make-shared /mnt644 mount --make-shared /mnt
649 mkdir -p /mnt/1/2/3 /mnt/1/test645 mkdir -p /mnt/1/2/3 /mnt/1/test
650 mount --bind /mnt/1 /tmp646 mount --bind /mnt/1 /tmp
651 mount --make-slave /mnt647 mount --make-slave /mnt
652 mount --make-shared /mnt648 mount --make-shared /mnt
653 mount --bind /mnt/1/2 /tmp1649 mount --bind /mnt/1/2 /tmp1
654 mount --make-slave /mnt650 mount --make-slave /mnt
655 651
656 At this point we have the first mount at /tmp and652 At this point we have the first mount at /tmp and
657 its root dentry is 1. Let's call this mount 'A'653 its root dentry is 1. Let's call this mount 'A'
658 And then we have a second mount at /tmp1 with root654 And then we have a second mount at /tmp1 with root
659 dentry 2. Let's call this mount 'B'655 dentry 2. Let's call this mount 'B'
660 Next we have a third mount at /mnt with root dentry656 Next we have a third mount at /mnt with root dentry
661 mnt. Let's call this mount 'C'657 mnt. Let's call this mount 'C'
662 658
663 'B' is the slave of 'A' and 'C' is a slave of 'B'659 'B' is the slave of 'A' and 'C' is a slave of 'B'
664 A -> B -> C660 A -> B -> C
665 661
666 at this point if we execute the following command662 at this point if we execute the following command::
667 663
668 mount --bind /bin /tmp/test664 mount --bind /bin /tmp/test
669 665
670 The mount is attempted on 'A'666 The mount is attempted on 'A'
671 667
672 will the mount propagate to 'B' and 'C' ?668 will the mount propagate to 'B' and 'C' ?
673 669
674 what would be the contents of670 what would be the contents of
675 /mnt/1/test be?671 /mnt/1/test be?
676 672
6777) FAQ6737) FAQ
678------674------
679 675
680 Q1. Why is bind mount needed? How is it different from symbolic links?6761. Why is bind mount needed? How is it different from symbolic links?
681 symbolic links can get stale if the destination mount gets
682 unmounted or moved. Bind mounts continue to exist even if the
683 other mount is unmounted or moved.
684 677
685 Q2. Why can't the shared subtree be implemented using exportfs?678 symbolic links can get stale if the destination mount gets
679 unmounted or moved. Bind mounts continue to exist even if the
680 other mount is unmounted or moved.
686 681
687 exportfs is a heavyweight way of accomplishing part of what6822. Why can't the shared subtree be implemented using exportfs?
688 shared subtree can do. I cannot imagine a way to implement the
689 semantics of slave mount using exportfs?
690 683
691 Q3 Why is unbindable mount needed?684 exportfs is a heavyweight way of accomplishing part of what
685 shared subtree can do. I cannot imagine a way to implement the
686 semantics of slave mount using exportfs?
692 687
693 Let's say we want to replicate the mount tree at multiple6883. Why is unbindable mount needed?
694 locations within the same subtree.
695 689
696 if one rbind mounts a tree within the same subtree 'n' times690 Let's say we want to replicate the mount tree at multiple
697 the number of mounts created is an exponential function of 'n'.691 locations within the same subtree.
698 Having unbindable mount can help prune the unneeded bind
699 mounts. Here is an example.
700 692
701 step 1:693 if one rbind mounts a tree within the same subtree 'n' times
702 let's say the root tree has just two directories with694 the number of mounts created is an exponential function of 'n'.
703 one vfsmount::695 Having unbindable mount can help prune the unneeded bind
696 mounts. Here is an example.
704 697
705 root698 step 1:
706 / \699 let's say the root tree has just two directories with
707 tmp usr700 one vfsmount::
708 701
709 And we want to replicate the tree at multiple702 root
710 mountpoints under /root/tmp703 / \
704 tmp usr
711 705
712 step 2:706 And we want to replicate the tree at multiple
713 ::707 mountpoints under /root/tmp
714 708
709 step 2:
710 ::
715 711
716 mount --make-shared /root
717 712
718 mkdir -p /tmp/m1713 mount --make-shared /root
719 714
720 mount --rbind /root /tmp/m1715 mkdir -p /tmp/m1
721 716
722 the new tree now looks like this::717 mount --rbind /root /tmp/m1
723 718
724 root719 the new tree now looks like this::
725 / \
726 tmp usr
727 /
728 m1
729 / \
730 tmp usr
731 /
732 m1
733 720
734 it has two vfsmounts721 root
722 / \
723 tmp usr
724 /
725 m1
726 / \
727 tmp usr
728 /
729 m1
735 730
736 step 3:731 it has two vfsmounts
737 ::
738 732
739 mkdir -p /tmp/m2733 step 3:
740 mount --rbind /root /tmp/m2734 ::
741 735
742 the new tree now looks like this::736 mkdir -p /tmp/m2
737 mount --rbind /root /tmp/m2
743 738
744 root739 the new tree now looks like this::
745 / \
746 tmp usr
747 / \
748 m1 m2
749 / \ / \
750 tmp usr tmp usr
751 / \ /
752 m1 m2 m1
753 / \ / \
754 tmp usr tmp usr
755 / / \
756 m1 m1 m2
757 / \
758 tmp usr
759 / \
760 m1 m2
761 740
762 it has 6 vfsmounts741 root
742 / \
743 tmp usr
744 / \
745 m1 m2
746 / \ / \
747 tmp usr tmp usr
748 / \ /
749 m1 m2 m1
750 / \ / \
751 tmp usr tmp usr
752 / / \
753 m1 m1 m2
754 / \
755 tmp usr
756 / \
757 m1 m2
763 758
764 step 4:759 it has 6 vfsmounts
765 ::
766 mkdir -p /tmp/m3
767 mount --rbind /root /tmp/m3
768 760
769 I won't draw the tree..but it has 24 vfsmounts761 step 4:
762 ::
770 763
764 mkdir -p /tmp/m3
765 mount --rbind /root /tmp/m3
771 766
772 at step i the number of vfsmounts is V[i] = i*V[i-1].767 I won't draw the tree..but it has 24 vfsmounts
773 This is an exponential function. And this tree has way more
774 mounts than what we really needed in the first place.
775 768
776 One could use a series of umount at each step to prune
777 out the unneeded mounts. But there is a better solution.
778 Unclonable mounts come in handy here.
779 769
780 step 1:770 at step i the number of vfsmounts is V[i] = i*V[i-1].
781 let's say the root tree has just two directories with771 This is an exponential function. And this tree has way more
782 one vfsmount::772 mounts than what we really needed in the first place.
783 773
784 root774 One could use a series of umount at each step to prune
785 / \775 out the unneeded mounts. But there is a better solution.
786 tmp usr776 Unclonable mounts come in handy here.
787 777
788 How do we set up the same tree at multiple locations under778 step 1:
789 /root/tmp779 let's say the root tree has just two directories with
780 one vfsmount::
790 781
791 step 2:782 root
792 ::783 / \
784 tmp usr
793 785
786 How do we set up the same tree at multiple locations under
787 /root/tmp
794 788
795 mount --bind /root/tmp /root/tmp789 step 2:
790 ::
796 791
797 mount --make-rshared /root
798 mount --make-unbindable /root/tmp
799 792
800 mkdir -p /tmp/m1793 mount --bind /root/tmp /root/tmp
801 794
802 mount --rbind /root /tmp/m1795 mount --make-rshared /root
796 mount --make-unbindable /root/tmp
803 797
804 the new tree now looks like this::798 mkdir -p /tmp/m1
805 799
806 root800 mount --rbind /root /tmp/m1
807 / \
808 tmp usr
809 /
810 m1
811 / \
812 tmp usr
813 801
814 step 3:802 the new tree now looks like this::
815 ::
816 803
817 mkdir -p /tmp/m2804 root
818 mount --rbind /root /tmp/m2805 / \
806 tmp usr
807 /
808 m1
809 / \
810 tmp usr
819 811
820 the new tree now looks like this::812 step 3:
813 ::
821 814
822 root815 mkdir -p /tmp/m2
823 / \816 mount --rbind /root /tmp/m2
824 tmp usr
825 / \
826 m1 m2
827 / \ / \
828 tmp usr tmp usr
829 817
830 step 4:818 the new tree now looks like this::
831 ::
832 819
833 mkdir -p /tmp/m3820 root
834 mount --rbind /root /tmp/m3821 / \
822 tmp usr
823 / \
824 m1 m2
825 / \ / \
826 tmp usr tmp usr
835 827
836 the new tree now looks like this::828 step 4:
829 ::
837 830
838 root831 mkdir -p /tmp/m3
839 / \832 mount --rbind /root /tmp/m3
840 tmp usr833
841 / \ \834 the new tree now looks like this::
842 m1 m2 m3835
843 / \ / \ / \836 root
844 tmp usr tmp usr tmp usr837 / \
838 tmp usr
839 / \ \
840 m1 m2 m3
841 / \ / \ / \
842 tmp usr tmp usr tmp usr
845 843
8468) Implementation8448) Implementation
847-----------------845-----------------
848 846
8498A) Datastructure847A) Datastructure
848
849 Several new fields are introduced to struct vfsmount:
850
851 ->mnt_share
852 Links together all the mount to/from which this vfsmount
853 send/receives propagation events.
850 854
851 4 new fields are introduced to struct vfsmount:855 ->mnt_slave_list
856 Links all the mounts to which this vfsmount propagates
857 to.
852 858
853 * ->mnt_share859 ->mnt_slave
854 * ->mnt_slave_list860 Links together all the slaves that its master vfsmount
855 * ->mnt_slave861 propagates to.
856 * ->mnt_master
857 862
858 ->mnt_share863 ->mnt_master
859 links together all the mount to/from which this vfsmount864 Points to the master vfsmount from which this vfsmount
860 send/receives propagation events.865 receives propagation.
861 866
862 ->mnt_slave_list867 ->mnt_flags
863 links all the mounts to which this vfsmount propagates868 Takes two more flags to indicate the propagation status of
864 to.869 the vfsmount. MNT_SHARE indicates that the vfsmount is a shared
870 vfsmount. MNT_UNCLONABLE indicates that the vfsmount cannot be
871 replicated.
865 872
866 ->mnt_slave873 All the shared vfsmounts in a peer group form a cyclic list through
867 links together all the slaves that its master vfsmount874 ->mnt_share.
868 propagates to.
869 875
870 ->mnt_master876 All vfsmounts with the same ->mnt_master form on a cyclic list anchored
871 points to the master vfsmount from which this vfsmount877 in ->mnt_master->mnt_slave_list and going through ->mnt_slave.
872 receives propagation.
873 878
874 ->mnt_flags879 ->mnt_master can point to arbitrary (and possibly different) members
875 takes two more flags to indicate the propagation status of880 of master peer group. To find all immediate slaves of a peer group
876 the vfsmount. MNT_SHARE indicates that the vfsmount is a shared881 you need to go through _all_ ->mnt_slave_list of its members.
877 vfsmount. MNT_UNCLONABLE indicates that the vfsmount cannot be882 Conceptually it's just a single set - distribution among the
878 replicated.883 individual lists does not affect propagation or the way propagation
884 tree is modified by operations.
879 885
880 All the shared vfsmounts in a peer group form a cyclic list through886 All vfsmounts in a peer group have the same ->mnt_master. If it is
881 ->mnt_share.887 non-NULL, they form a contiguous (ordered) segment of slave list.
882 888
883 All vfsmounts with the same ->mnt_master form on a cyclic list anchored889 A example propagation tree looks as shown in the figure below.
884 in ->mnt_master->mnt_slave_list and going through ->mnt_slave.
885 890
886 ->mnt_master can point to arbitrary (and possibly different) members891 .. note::
887 of master peer group. To find all immediate slaves of a peer group892 Though it looks like a forest, if we consider all the shared
888 you need to go through _all_ ->mnt_slave_list of its members.893 mounts as a conceptual entity called 'pnode', it becomes a tree.
889 Conceptually it's just a single set - distribution among the
890 individual lists does not affect propagation or the way propagation
891 tree is modified by operations.
892 894
893 All vfsmounts in a peer group have the same ->mnt_master. If it is895 ::
894 non-NULL, they form a contiguous (ordered) segment of slave list.
895 896
896 A example propagation tree looks as shown in the figure below.
897 [ NOTE: Though it looks like a forest, if we consider all the shared
898 mounts as a conceptual entity called 'pnode', it becomes a tree]::
899 897
898 A <--> B <--> C <---> D
899 /|\ /| |\
900 / F G J K H I
901 /
902 E<-->K
903 /|\
904 M L N
900 905
901 A <--> B <--> C <---> D906 In the above figure A,B,C and D all are shared and propagate to each
902 /|\ /| |\907 other. 'A' has got 3 slave mounts 'E' 'F' and 'G' 'C' has got 2 slave
903 / F G J K H I908 mounts 'J' and 'K' and 'D' has got two slave mounts 'H' and 'I'.
904 /909 'E' is also shared with 'K' and they propagate to each other. And
905 E<-->K910 'K' has 3 slaves 'M', 'L' and 'N'
906 /|\
907 M L N
908 911
909 In the above figure A,B,C and D all are shared and propagate to each912 A's ->mnt_share links with the ->mnt_share of 'B' 'C' and 'D'
910 other. 'A' has got 3 slave mounts 'E' 'F' and 'G' 'C' has got 2 slave
911 mounts 'J' and 'K' and 'D' has got two slave mounts 'H' and 'I'.
912 'E' is also shared with 'K' and they propagate to each other. And
913 'K' has 3 slaves 'M', 'L' and 'N'
914 913
915 A's ->mnt_share links with the ->mnt_share of 'B' 'C' and 'D'914 A's ->mnt_slave_list links with ->mnt_slave of 'E', 'K', 'F' and 'G'
916 915
917 A's ->mnt_slave_list links with ->mnt_slave of 'E', 'K', 'F' and 'G'916 E's ->mnt_share links with ->mnt_share of K
918 917
919 E's ->mnt_share links with ->mnt_share of K918 'E', 'K', 'F', 'G' have their ->mnt_master point to struct vfsmount of 'A'
920 919
921 'E', 'K', 'F', 'G' have their ->mnt_master point to struct vfsmount of 'A'920 'M', 'L', 'N' have their ->mnt_master point to struct vfsmount of 'K'
922 921
923 'M', 'L', 'N' have their ->mnt_master point to struct vfsmount of 'K'922 K's ->mnt_slave_list links with ->mnt_slave of 'M', 'L' and 'N'
924 923
925 K's ->mnt_slave_list links with ->mnt_slave of 'M', 'L' and 'N'924 C's ->mnt_slave_list links with ->mnt_slave of 'J' and 'K'
926 925
927 C's ->mnt_slave_list links with ->mnt_slave of 'J' and 'K'926 J and K's ->mnt_master points to struct vfsmount of C
928 927
929 J and K's ->mnt_master points to struct vfsmount of C928 and finally D's ->mnt_slave_list links with ->mnt_slave of 'H' and 'I'
930 929
931 and finally D's ->mnt_slave_list links with ->mnt_slave of 'H' and 'I'930 'H' and 'I' have their ->mnt_master pointing to struct vfsmount of 'D'.
932 931
933 'H' and 'I' have their ->mnt_master pointing to struct vfsmount of 'D'.
934 932
933 NOTE: The propagation tree is orthogonal to the mount tree.
935 934
936 NOTE: The propagation tree is orthogonal to the mount tree.935B) Locking:
937 936
9388B Locking:937 ->mnt_share, ->mnt_slave, ->mnt_slave_list, ->mnt_master are protected
938 by namespace_sem (exclusive for modifications, shared for reading).
939 939
940 ->mnt_share, ->mnt_slave, ->mnt_slave_list, ->mnt_master are protected940 Normally we have ->mnt_flags modifications serialized by vfsmount_lock.
941 by namespace_sem (exclusive for modifications, shared for reading).941 There are two exceptions: do_add_mount() and clone_mnt().
942 The former modifies a vfsmount that has not been visible in any shared
943 data structures yet.
944 The latter holds namespace_sem and the only references to vfsmount
945 are in lists that can't be traversed without namespace_sem.
942 946
943 Normally we have ->mnt_flags modifications serialized by vfsmount_lock.947C) Algorithm:
944 There are two exceptions: do_add_mount() and clone_mnt().
945 The former modifies a vfsmount that has not been visible in any shared
946 data structures yet.
947 The latter holds namespace_sem and the only references to vfsmount
948 are in lists that can't be traversed without namespace_sem.
949 948
9508C Algorithm:949 The crux of the implementation resides in rbind/move operation.
951 950
952 The crux of the implementation resides in rbind/move operation.951 The overall algorithm breaks the operation into 3 phases: (look at
952 attach_recursive_mnt() and propagate_mnt())
953 953
954 The overall algorithm breaks the operation into 3 phases: (look at954 1. Prepare phase.
955 attach_recursive_mnt() and propagate_mnt())
956 955
957 1. prepare phase.956 For each mount in the source tree:
958 2. commit phases.
959 3. abort phases.
960 957
961 Prepare phase:958 a) Create the necessary number of mount trees to
959 be attached to each of the mounts that receive
960 propagation from the destination mount.
961 b) Do not attach any of the trees to its destination.
962 However note down its ->mnt_parent and ->mnt_mountpoint
963 c) Link all the new mounts to form a propagation tree that
964 is identical to the propagation tree of the destination
965 mount.
962 966
963 for each mount in the source tree:967 If this phase is successful, there should be 'n' new
968 propagation trees; where 'n' is the number of mounts in the
969 source tree. Go to the commit phase
964 970
965 a) Create the necessary number of mount trees to971 Also there should be 'm' new mount trees, where 'm' is
966 be attached to each of the mounts that receive972 the number of mounts to which the destination mount
967 propagation from the destination mount.973 propagates to.
968 b) Do not attach any of the trees to its destination.
969 However note down its ->mnt_parent and ->mnt_mountpoint
970 c) Link all the new mounts to form a propagation tree that
971 is identical to the propagation tree of the destination
972 mount.
973 974
974 If this phase is successful, there should be 'n' new975 If any memory allocations fail, go to the abort phase.
975 propagation trees; where 'n' is the number of mounts in the
976 source tree. Go to the commit phase
977 976
978 Also there should be 'm' new mount trees, where 'm' is977 2. Commit phase.
979 the number of mounts to which the destination mount
980 propagates to.
981 978
982 if any memory allocations fail, go to the abort phase.979 Attach each of the mount trees to their corresponding
980 destination mounts.
983 981
984 Commit phase982 3. Abort phase.
985 attach each of the mount trees to their corresponding
986 destination mounts.
987 983
988 Abort phase984 Delete all the newly created trees.
989 delete all the newly created trees.
990 985
991 .. Note::986 .. Note::
992 all the propagation related functionality resides in the file pnode.c987 all the propagation related functionality resides in the file pnode.c
993 988
994 989
995------------------------------------------------------------------------990------------------------------------------------------------------------
Documentation/filesystems/sysfs.rst+19−6
@@ -243,8 +243,8 @@ Other notes: · 242 unmodified lines
243- show() methods should return the number of bytes printed into the243- show() methods should return the number of bytes printed into the
244 buffer.244 buffer.
245 245
246- show() should only use sysfs_emit() or sysfs_emit_at() when formatting246- New implementations of show() methods should only use sysfs_emit() or
247 the value to be returned to user space.247 sysfs_emit_at() when formatting the value to be returned to user space.
248 248
249- store() should return the number of bytes used from the buffer. If the249- store() should return the number of bytes used from the buffer. If the
250 entire buffer has been used, just return the count argument.250 entire buffer has been used, just return the count argument.
@@ -299,7 +299,6 @@ The top level sysfs directory looks like:: · 48 unmodified lines
299 hypervisor/299 hypervisor/
300 kernel/300 kernel/
301 module/301 module/
302 net/
303 power/302 power/
304 303
305devices/ contains a filesystem representation of the device tree. It maps304devices/ contains a filesystem representation of the device tree. It maps
@@ -313,7 +312,7 @@ kernel. Each bus's directory contains two subdirectories:: · 7 unmodified lines
313 drivers/312 drivers/
314 313
315devices/ contains symlinks for each device discovered in the system314devices/ contains symlinks for each device discovered in the system
316that point to the device's directory under root/.315that point to the device's directory under /sys/devices.
317 316
318drivers/ contains a directory for each device driver that is loaded317drivers/ contains a directory for each device driver that is loaded
319for devices on that particular bus (this assumes that drivers do not318for devices on that particular bus (this assumes that drivers do not
@@ -328,15 +327,29 @@ loaded system modules, for both builtin and loadable modules. · 8 unmodified lines
328 327
329dev/ contains two directories: char/ and block/. Inside these two328dev/ contains two directories: char/ and block/. Inside these two
330directories there are symlinks named <major>:<minor>. These symlinks329directories there are symlinks named <major>:<minor>. These symlinks
331point to the sysfs directory for the given device. /sys/dev provides a330point to the directories under /sys/devices for each device. /sys/dev provides a
332quick way to lookup the sysfs interface for a device from the result of331quick way to lookup the sysfs interface for a device from the result of
333a stat(2) operation.332a stat(2) operation.
334 333
335More information on driver-model specific features can be found in334More information on driver-model specific features can be found in
336Documentation/driver-api/driver-model/.335Documentation/driver-api/driver-model/.
337 336
337block/ contains symlinks to all the block devices discovered on the system.
338These symlinks point to directories under /sys/devices.
338 339
339TODO: Finish this section.340class/ contains a directory for each device class, grouped by functional type.
341Each directory in class/ contains symlinks to devices in the /sys/devices directory.
342
343firmware/ contains system firmware data and configuration such as firmware tables,
344ACPI information, and device tree data.
345
346hypervisor/ contains virtualization platform information and provides an interface to
347the underlying hypervisor. It is only present when running on a virtual machine.
348
349kernel/ contains runtime kernel parameters, configuration settings, and status.
350
351power/ contains power management subsystem information including
352sleep states, suspend/resume capabilities, and policies.
340 353
341 354
342Current Interfaces355Current Interfaces
Documentation/filesystems/xfs/xfs-online-fsck-design.rst+4−4
@@ -454,7 +454,7 @@ filesystem so that it can apply pending filesystem updates to the staging · 453 unmodified lines
454information.454information.
455Once the scan is done, the owning object is re-locked, the live data is used to455Once the scan is done, the owning object is re-locked, the live data is used to
456write a new ondisk structure, and the repairs are committed atomically.456write a new ondisk structure, and the repairs are committed atomically.
457The hooks are disabled and the staging staging area is freed.457The hooks are disabled and the staging area is freed.
458Finally, the storage from the old data structure are carefully reaped.458Finally, the storage from the old data structure are carefully reaped.
459 459
460Introducing concurrency helps online repair avoid various locking problems, but460Introducing concurrency helps online repair avoid various locking problems, but
@@ -475,7 +475,7 @@ operation, which may cause application failure or an unplanned filesystem · 14 unmodified lines
475shutdown.475shutdown.
476 476
477Inspiration for the secondary metadata repair strategy was drawn from section477Inspiration for the secondary metadata repair strategy was drawn from section
4782.4 of Srinivasan above, and sections 2 ("NSF: Inded Build Without Side-File")4782.4 of Srinivasan above, and sections 2 ("NSF: Index Build Without Side-File")
479and 3.1.1 ("Duplicate Key Insert Problem") in C. Mohan, `"Algorithms for479and 3.1.1 ("Duplicate Key Insert Problem") in C. Mohan, `"Algorithms for
480Creating Indexes for Very Large Tables Without Quiescing Updates"480Creating Indexes for Very Large Tables Without Quiescing Updates"
481<https://dl.acm.org/doi/10.1145/130283.130337>`_, 1992.481<https://dl.acm.org/doi/10.1145/130283.130337>`_, 1992.
@@ -2185,7 +2185,7 @@ The chapter about :ref:`secondary metadata<secondary_metadata>` mentioned that · 1703 unmodified lines
2185checking and repairing of secondary metadata commonly requires coordination2185checking and repairing of secondary metadata commonly requires coordination
2186between a live metadata scan of the filesystem and writer threads that are2186between a live metadata scan of the filesystem and writer threads that are
2187updating that metadata.2187updating that metadata.
2188Keeping the scan data up to date requires requires the ability to propagate2188Keeping the scan data up to date requires the ability to propagate
2189metadata updates from the filesystem into the data being collected by the scan.2189metadata updates from the filesystem into the data being collected by the scan.
2190This *can* be done by appending concurrent updates into a separate log file and2190This *can* be done by appending concurrent updates into a separate log file and
2191applying them before writing the new metadata to disk, but this leads to2191applying them before writing the new metadata to disk, but this leads to
@@ -4179,7 +4179,7 @@ When the exchange is initiated, the sequence of operations is as follows: · 1987 unmodified lines
4179 This will be discussed in more detail in subsequent sections.4179 This will be discussed in more detail in subsequent sections.
4180 4180
4181If the filesystem goes down in the middle of an operation, log recovery will4181If the filesystem goes down in the middle of an operation, log recovery will
4182find the most recent unfinished maping exchange log intent item and restart4182find the most recent unfinished mapping exchange log intent item and restart
4183from there.4183from there.
4184This is how atomic file mapping exchanges guarantees that an outside observer4184This is how atomic file mapping exchanges guarantees that an outside observer
4185will either see the old broken structure or the new one, and never a mismash of4185will either see the old broken structure or the new one, and never a mismash of
Documentation/locking/locktypes.rst+21−0
@@ -204,6 +204,27 @@ per-CPU data structures on a non PREEMPT_RT kernel. · 203 unmodified lines
204local_lock is not suitable to protect against preemption or interrupts on a204local_lock is not suitable to protect against preemption or interrupts on a
205PREEMPT_RT kernel due to the PREEMPT_RT specific spinlock_t semantics.205PREEMPT_RT kernel due to the PREEMPT_RT specific spinlock_t semantics.
206 206
207CPU local scope and bottom-half
208-------------------------------
209
210Per-CPU variables that are accessed only in softirq context should not rely on
211the assumption that this context is implicitly protected due to being
212non-preemptible. In a PREEMPT_RT kernel, softirq context is preemptible, and
213synchronizing every bottom-half-disabled section via implicit context results
214in an implicit per-CPU "big kernel lock."
215
216A local_lock_t together with local_lock_nested_bh() and
217local_unlock_nested_bh() for locking operations help to identify the locking
218scope.
219
220When lockdep is enabled, these functions verify that data structure access
221occurs within softirq context.
222Unlike local_lock(), local_unlock_nested_bh() does not disable preemption and
223does not add overhead when used without lockdep.
224
225On a PREEMPT_RT kernel, local_lock_t behaves as a real lock and
226local_unlock_nested_bh() serializes access to the data structure, which allows
227removal of serialization via local_bh_disable().
207 228
208raw_spinlock_t and spinlock_t229raw_spinlock_t and spinlock_t
209=============================230=============================
Documentation/locking/seqlock.rst+2−0
@@ -1,3 +1,5 @@
1.. SPDX-License-Identifier: GPL-2.0
2
1======================================3======================================
2Sequence counters and sequential locks4Sequence counters and sequential locks
3======================================5======================================
Documentation/maintainer/configure-git.rst+0−28
@@ -28,31 +28,3 @@ You may also like to tell ``gpg`` which ``tty`` to use (add to your shell · 27 unmodified lines
28rc file)::28rc file)::
29 29
30 export GPG_TTY=$(tty)30 export GPG_TTY=$(tty)
31
32
33Creating commit links to lore.kernel.org
34----------------------------------------
35
36The web site https://lore.kernel.org is meant as a grand archive of all mail
37list traffic concerning or influencing the kernel development. Storing archives
38of patches here is a recommended practice, and when a maintainer applies a
39patch to a subsystem tree, it is a good idea to provide a Link: tag with a
40reference back to the lore archive so that people that browse the commit
41history can find related discussions and rationale behind a certain change.
42The link tag will look like this::
43
44 Link: https://lore.kernel.org/r/<message-id>
45
46This can be configured to happen automatically any time you issue ``git am``
47by adding the following hook into your git::
48
49 $ git config am.messageid true
50 $ cat >.git/hooks/applypatch-msg <<'EOF'
51 #!/bin/sh
52 . git-sh-setup
53 perl -pi -e 's|^Message-I[dD]:\s*<?([^>]+)>?$|Link: https://lore.kernel.org/r/$1|g;' "$1"
54 test -x "$GIT_DIR/hooks/commit-msg" &&
55 exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"}
56 :
57 EOF
58 $ chmod a+x .git/hooks/applypatch-msg
Documentation/maintainer/maintainer-entry-profile.rst+2−0
@@ -59,6 +59,7 @@ week) that patches might be considered for merging and when patches need to · 58 unmodified lines
59wait for the next -rc. At a minimum:59wait for the next -rc. At a minimum:
60 60
61- Last -rc for new feature submissions:61- Last -rc for new feature submissions:
62
62 New feature submissions targeting the next merge window should have63 New feature submissions targeting the next merge window should have
63 their first posting for consideration before this point. Patches that64 their first posting for consideration before this point. Patches that
64 are submitted after this point should be clear that they are targeting65 are submitted after this point should be clear that they are targeting
@@ -68,6 +69,7 @@ wait for the next -rc. At a minimum: · 3 unmodified lines
68 submissions should appear before -rc5.69 submissions should appear before -rc5.
69 70
70- Last -rc to merge features: Deadline for merge decisions71- Last -rc to merge features: Deadline for merge decisions
72
71 Indicate to contributors the point at which an as yet un-applied patch73 Indicate to contributors the point at which an as yet un-applied patch
72 set will need to wait for the NEXT+1 merge window. Of course there is no74 set will need to wait for the NEXT+1 merge window. Of course there is no
73 obligation to ever accept any given patchset, but if the review has not75 obligation to ever accept any given patchset, but if the review has not
Documentation/mm/physical_memory.rst+2−0
@@ -171,6 +171,8 @@ nodes with particular properties as defined by ``enum node_states``: · 170 unmodified lines
171 The node has memory(regular, high, movable)171 The node has memory(regular, high, movable)
172``N_CPU``172``N_CPU``
173 The node has one or more CPUs173 The node has one or more CPUs
174``N_GENERIC_INITIATOR``
175 The node has one or more Generic Initiators
174 176
175For each node that has a property described above, the bit corresponding to the177For each node that has a property described above, the bit corresponding to the
176node ID in the ``node_states[<property>]`` bitmask is set.178node ID in the ``node_states[<property>]`` bitmask is set.
Documentation/networking/can.rst+1−1
@@ -539,7 +539,7 @@ CAN Filter Usage Optimisation · 538 unmodified lines
539The CAN filters are processed in per-device filter lists at CAN frame539The CAN filters are processed in per-device filter lists at CAN frame
540reception time. To reduce the number of checks that need to be performed540reception time. To reduce the number of checks that need to be performed
541while walking through the filter lists the CAN core provides an optimized541while walking through the filter lists the CAN core provides an optimized
542filter handling when the filter subscription focusses on a single CAN ID.542filter handling when the filter subscription focuses on a single CAN ID.
543 543
544For the possible 2048 SFF CAN identifiers the identifier is used as an index544For the possible 2048 SFF CAN identifiers the identifier is used as an index
545to access the corresponding subscription list without any further checks.545to access the corresponding subscription list without any further checks.
Documentation/networking/device_drivers/ethernet/ti/am65_nuss_cpsw_switchdev.rst+1−1
@@ -42,7 +42,7 @@ Port's netdev devices have to be in UP before joining to the bridge to avoid · 41 unmodified lines
42overwriting of bridge configuration as CPSW switch driver completely reloads its42overwriting of bridge configuration as CPSW switch driver completely reloads its
43configuration when first port changes its state to UP.43configuration when first port changes its state to UP.
44 44
45When the both interfaces joined the bridge - CPSW switch driver will enable45When both interfaces have joined the bridge - CPSW switch driver will enable
46marking packets with offload_fwd_mark flag.46marking packets with offload_fwd_mark flag.
47 47
48All configuration is implemented via switchdev API.48All configuration is implemented via switchdev API.
Documentation/networking/device_drivers/ethernet/ti/cpsw_switchdev.rst+1−1
@@ -92,7 +92,7 @@ Port's netdev devices have to be in UP before joining to the bridge to avoid · 91 unmodified lines
92overwriting of bridge configuration as CPSW switch driver copletly reloads its92overwriting of bridge configuration as CPSW switch driver copletly reloads its
93configuration when first Port changes its state to UP.93configuration when first Port changes its state to UP.
94 94
95When the both interfaces joined the bridge - CPSW switch driver will enable95When both interfaces have joined the bridge - CPSW switch driver will enable
96marking packets with offload_fwd_mark flag unless "ale_bypass=0"96marking packets with offload_fwd_mark flag unless "ale_bypass=0"
97 97
98All configuration is implemented via switchdev API.98All configuration is implemented via switchdev API.
Documentation/networking/rds.rst+1−1
@@ -339,7 +339,7 @@ The send path · 338 unmodified lines
339 rds_sendmsg()339 rds_sendmsg()
340 - struct rds_message built from incoming data340 - struct rds_message built from incoming data
341 - CMSGs parsed (e.g. RDMA ops)341 - CMSGs parsed (e.g. RDMA ops)
342 - transport connection alloced and connected if not already342 - transport connection allocated and connected if not already
343 - rds_message placed on send queue343 - rds_message placed on send queue
344 - send worker awoken344 - send worker awoken
345 345
Documentation/power/pci.rst+2−2
@@ -472,7 +472,7 @@ in the device tree from the root bridge to a leaf device contains both of them). · 471 unmodified lines
472The pci_pm_suspend_noirq() routine is executed after suspend_device_irqs() has472The pci_pm_suspend_noirq() routine is executed after suspend_device_irqs() has
473been called, which means that the device driver's interrupt handler won't be473been called, which means that the device driver's interrupt handler won't be
474invoked while this routine is running. It first checks if the device's driver474invoked while this routine is running. It first checks if the device's driver
475implements legacy PCI suspends routines (Section 3), in which case the legacy475implements legacy PCI suspend routines (Section 3), in which case the legacy
476late suspend routine is called and its result is returned (the standard476late suspend routine is called and its result is returned (the standard
477configuration registers of the device are saved if the driver's callback hasn't477configuration registers of the device are saved if the driver's callback hasn't
478done that). Second, if the device driver's struct dev_pm_ops object is not478done that). Second, if the device driver's struct dev_pm_ops object is not
@@ -544,7 +544,7 @@ result is then returned). · 65 unmodified lines
544The resume phase is carried out asynchronously for PCI devices, like the544The resume phase is carried out asynchronously for PCI devices, like the
545suspend phase described above, which means that if two PCI devices don't depend545suspend phase described above, which means that if two PCI devices don't depend
546on each other in a known way, the pci_pm_resume() routine may be executed for546on each other in a known way, the pci_pm_resume() routine may be executed for
547the both of them in parallel.547both of them in parallel.
548 548
549The pci_pm_complete() routine only executes the device driver's pm->complete()549The pci_pm_complete() routine only executes the device driver's pm->complete()
550callback, if defined.550callback, if defined.
Documentation/power/suspend-and-cpuhotplug.rst+1−1
@@ -13,7 +13,7 @@ infrastructure uses it internally? And where do they share common code? · 12 unmodified lines
13 13
14Well, a picture is worth a thousand words... So ASCII art follows :-)14Well, a picture is worth a thousand words... So ASCII art follows :-)
15 15
16[This depicts the current design in the kernel, and focusses only on the16[This depicts the current design in the kernel, and focuses only on the
17interactions involving the freezer and CPU hotplug and also tries to explain17interactions involving the freezer and CPU hotplug and also tries to explain
18the locking involved. It outlines the notifications involved as well.18the locking involved. It outlines the notifications involved as well.
19But please note that here, only the call paths are illustrated, with the aim19But please note that here, only the call paths are illustrated, with the aim
Documentation/process/5.Posting.rst+3−4
@@ -207,10 +207,9 @@ document with a specification implemented by the patch:: · 206 unmodified lines
207 207
208 Link: https://example.com/somewhere.html optional-other-stuff208 Link: https://example.com/somewhere.html optional-other-stuff
209 209
210Many maintainers when applying a patch also add this tag to link to the210As per guidance from the Chief Penguin, a Link: tag should only be added to
211latest public review posting of the patch; often this is automatically done211a commit if it leads to useful information that is not found in the commit
212by tools like b4 or a git hook like the one described in212itself.
213'Documentation/maintainer/configure-git.rst'.
214 213
215If the URL points to a public bug report being fixed by the patch, use the214If the URL points to a public bug report being fixed by the patch, use the
216"Closes:" tag instead::215"Closes:" tag instead::
Documentation/process/changes.rst+8−1
@@ -61,7 +61,7 @@ Sphinx\ [#f1]_ 3.4.3 sphinx-build --version · 60 unmodified lines
61GNU tar 1.28 tar --version61GNU tar 1.28 tar --version
62gtags (optional) 6.6.5 gtags --version62gtags (optional) 6.6.5 gtags --version
63mkimage (optional) 2017.01 mkimage --version63mkimage (optional) 2017.01 mkimage --version
64Python (optional) 3.9.x python3 --version64Python 3.9.x python3 --version
65GNU AWK (optional) 5.1.0 gawk --version65GNU AWK (optional) 5.1.0 gawk --version
66====================== =============== ========================================66====================== =============== ========================================
67 67
@@ -154,6 +154,13 @@ Perl · 86 unmodified lines
154You will need perl 5 and the following modules: ``Getopt::Long``,154You will need perl 5 and the following modules: ``Getopt::Long``,
155``Getopt::Std``, ``File::Basename``, and ``File::Find`` to build the kernel.155``Getopt::Std``, ``File::Basename``, and ``File::Find`` to build the kernel.
156 156
157Python
158------
159
160Several config options require it: it is required for arm/arm64
161default configs, CONFIG_LTO_CLANG, some DRM optional configs,
162the kernel-doc tool, and docs build (Sphinx), among others.
163
157BC164BC
158--165--
159 166
Documentation/process/maintainer-pgp-guide.rst+75−83
@@ -49,7 +49,7 @@ hosting infrastructure, regardless of how good the security practices · 48 unmodified lines
49for the latter may be.49for the latter may be.
50 50
51The above guiding principle is the reason why this guide is needed. We51The above guiding principle is the reason why this guide is needed. We
52want to make sure that by placing trust into developers we do not simply52want to make sure that by placing trust into developers we do not merely
53shift the blame for potential future security incidents to someone else.53shift the blame for potential future security incidents to someone else.
54The goal is to provide a set of guidelines developers can use to create54The goal is to provide a set of guidelines developers can use to create
55a secure working environment and safeguard the PGP keys used to55a secure working environment and safeguard the PGP keys used to
@@ -60,7 +60,7 @@ establish the integrity of the Linux kernel itself. · 4 unmodified lines
60PGP tools60PGP tools
61=========61=========
62 62
63Use GnuPG 2.2 or later63Use GnuPG 2.4 or later
64----------------------64----------------------
65 65
66Your distro should already have GnuPG installed by default, you just66Your distro should already have GnuPG installed by default, you just
@@ -69,9 +69,9 @@ To check, run:: · 2 unmodified lines
69 69
70 $ gpg --version | head -n170 $ gpg --version | head -n1
71 71
72If you have version 2.2 or above, then you are good to go. If you have a72If you have version 2.4 or above, then you are good to go. If you have
73version that is prior than 2.2, then some commands from this guide may73an earlier version, then you are using a release of GnuPG that is no
74not work.74longer maintained and some commands from this guide may not work.
75 75
76Configure gpg-agent options76Configure gpg-agent options
77~~~~~~~~~~~~~~~~~~~~~~~~~~~77~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -199,13 +199,6 @@ separate signing subkey:: · 121 unmodified lines
199 199
200 $ gpg --quick-addkey [fpr] ed25519 sign200 $ gpg --quick-addkey [fpr] ed25519 sign
201 201
202.. note:: ECC support in GnuPG
203
204 Note, that if you intend to use a hardware token that does not
205 support ED25519 ECC keys, you should choose "nistp256" instead or
206 "ed25519." See the section below on recommended hardware devices.
207
208
209Back up your Certify key for disaster recovery202Back up your Certify key for disaster recovery
210----------------------------------------------203----------------------------------------------
211 204
@@ -213,7 +206,7 @@ The more signatures you have on your PGP key from other developers, the · 1 unmodified line
213more reasons you have to create a backup version that lives on something206more reasons you have to create a backup version that lives on something
214other than digital media, for disaster recovery reasons.207other than digital media, for disaster recovery reasons.
215 208
216The best way to create a printable hardcopy of your private key is by209A good way to create a printable hardcopy of your private key is by
217using the ``paperkey`` software written for this very purpose. See ``man210using the ``paperkey`` software written for this very purpose. See ``man
218paperkey`` for more details on the output format and its benefits over211paperkey`` for more details on the output format and its benefits over
219other solutions. Paperkey should already be packaged for most212other solutions. Paperkey should already be packaged for most
@@ -224,11 +217,11 @@ key:: · 4 unmodified lines
224 217
225 $ gpg --export-secret-key [fpr] | paperkey -o /tmp/key-backup.txt218 $ gpg --export-secret-key [fpr] | paperkey -o /tmp/key-backup.txt
226 219
227Print out that file (or pipe the output straight to lpr), then take a220Print out that file, then take a pen and write your passphrase on the
228pen and write your passphrase on the margin of the paper. **This is221margin of the paper. **This is strongly recommended** because the key
229strongly recommended** because the key printout is still encrypted with222printout is still encrypted with that passphrase, and if you ever change
230that passphrase, and if you ever change it you will not remember what it223it you will not remember what it used to be when you had created the
231used to be when you had created the backup -- *guaranteed*.224backup -- *guaranteed*.
232 225
233Put the resulting printout and the hand-written passphrase into an envelope226Put the resulting printout and the hand-written passphrase into an envelope
234and store in a secure and well-protected place, preferably away from your227and store in a secure and well-protected place, preferably away from your
@@ -236,10 +229,9 @@ home, such as your bank vault. · 1 unmodified line
236 229
237.. note::230.. note::
238 231
239 Your printer is probably no longer a simple dumb device connected to232 The key is still encrypted with your passphrase, so printing out
240 your parallel port, but since the output is still encrypted with233 even to "cloud-integrated" modern printers should remain a
241 your passphrase, printing out even to "cloud-integrated" modern234 relatively safe operation.
242 printers should remain a relatively safe operation.
243 235
244Back up your whole GnuPG directory236Back up your whole GnuPG directory
245----------------------------------237----------------------------------
@@ -255,16 +247,17 @@ on these external copies whenever you need to use your Certify key -- · 9 unmodified lines
255such as when making changes to your own key or signing other people's247such as when making changes to your own key or signing other people's
256keys after conferences and summits.248keys after conferences and summits.
257 249
258Start by getting a small USB "thumb" drive (preferably two!) that you250Start by getting an external media card (preferably two!) that you will
259will use for backup purposes. You will need to encrypt them using LUKS251use for backup purposes. You will need to create an encrypted partition
260-- refer to your distro's documentation on how to accomplish this.252on this device using LUKS -- refer to your distro's documentation on how
253to accomplish this.
261 254
262For the encryption passphrase, you can use the same one as on your255For the encryption passphrase, you can use the same one as on your
263PGP key.256PGP key.
264 257
265Once the encryption process is over, re-insert the USB drive and make258Once the encryption process is over, re-insert your device and make sure
266sure it gets properly mounted. Copy your entire ``.gnupg`` directory259it gets properly mounted. Copy your entire ``.gnupg`` directory over to
267over to the encrypted storage::260the encrypted storage::
268 261
269 $ cp -a ~/.gnupg /media/disk/foo/gnupg-backup262 $ cp -a ~/.gnupg /media/disk/foo/gnupg-backup
270 263
@@ -273,11 +266,10 @@ You should now test to make sure everything still works:: · 2 unmodified lines
273 $ gpg --homedir=/media/disk/foo/gnupg-backup --list-key [fpr]266 $ gpg --homedir=/media/disk/foo/gnupg-backup --list-key [fpr]
274 267
275If you don't get any errors, then you should be good to go. Unmount the268If you don't get any errors, then you should be good to go. Unmount the
276USB drive, distinctly label it so you don't blow it away next time you269device, distinctly label it so you don't overwrite it by accident, and
277need to use a random USB drive, and put in a safe place -- but not too270put in a safe place -- but not too far away, because you'll need to use
278far away, because you'll need to use it every now and again for things271it every now and again for things like editing identities, adding or
279like editing identities, adding or revoking subkeys, or signing other272revoking subkeys, or signing other people's keys.
280people's keys.
281 273
282Remove the Certify key from your homedir274Remove the Certify key from your homedir
283----------------------------------------275----------------------------------------
@@ -303,7 +295,7 @@ and store it on offline storage. · 19 unmodified lines
303 your GnuPG directory in its entirety. What we are about to do will295 your GnuPG directory in its entirety. What we are about to do will
304 render your key useless if you do not have a usable backup!296 render your key useless if you do not have a usable backup!
305 297
306First, identify the keygrip of your Certify key::298First, identify the "keygrip" of your Certify key::
307 299
308 $ gpg --with-keygrip --list-key [fpr]300 $ gpg --with-keygrip --list-key [fpr]
309 301
@@ -328,8 +320,8 @@ Certify key fingerprint). This will correspond directly to a file in your · 18 unmodified lines
328 2222000000000000000000000000000000000000.key320 2222000000000000000000000000000000000000.key
329 3333000000000000000000000000000000000000.key321 3333000000000000000000000000000000000000.key
330 322
331All you have to do is simply remove the .key file that corresponds to323It is sufficient to remove the .key file that corresponds to the Certify
332the Certify key keygrip::324key keygrip::
333 325
334 $ cd ~/.gnupg/private-keys-v1.d326 $ cd ~/.gnupg/private-keys-v1.d
335 $ rm 1111000000000000000000000000000000000000.key327 $ rm 1111000000000000000000000000000000000000.key
@@ -372,7 +364,7 @@ GnuPG operation is performed, the keys are loaded into system memory and · 36 unmodified lines
372can be stolen from there by sufficiently advanced malware (think364can be stolen from there by sufficiently advanced malware (think
373Meltdown and Spectre).365Meltdown and Spectre).
374 366
375The best way to completely protect your keys is to move them to a367A good way to completely protect your keys is to move them to a
376specialized hardware device that is capable of smartcard operations.368specialized hardware device that is capable of smartcard operations.
377 369
378The benefits of smartcards370The benefits of smartcards
@@ -383,11 +375,11 @@ private keys and performing crypto operations directly on the card · 4 unmodified lines
383itself. Because the key contents never leave the smartcard, the375itself. Because the key contents never leave the smartcard, the
384operating system of the computer into which you plug in the hardware376operating system of the computer into which you plug in the hardware
385device is not able to retrieve the private keys themselves. This is very377device is not able to retrieve the private keys themselves. This is very
386different from the encrypted USB storage device we used earlier for378different from the encrypted media storage device we used earlier for
387backup purposes -- while that USB device is plugged in and mounted, the379backup purposes -- while that device is plugged in and mounted, the
388operating system is able to access the private key contents.380operating system is able to access the private key contents.
389 381
390Using external encrypted USB media is not a substitute to having a382Using external encrypted media is not a substitute to having a
391smartcard-capable device.383smartcard-capable device.
392 384
393Available smartcard devices385Available smartcard devices
@@ -398,17 +390,15 @@ easiest is to get a specialized USB device that implements smartcard · 4 unmodified lines
398functionality. There are several options available:390functionality. There are several options available:
399 391
400- `Nitrokey Start`_: Open hardware and Free Software, based on FSI392- `Nitrokey Start`_: Open hardware and Free Software, based on FSI
401 Japan's `Gnuk`_. One of the few available commercial devices that393 Japan's `Gnuk`_. One of the cheapest options, but offers fewest
402 support ED25519 ECC keys, but offer fewest security features (such as394 security features (such as resistance to tampering or some
403 resistance to tampering or some side-channel attacks).395 side-channel attacks).
404- `Nitrokey Pro 2`_: Similar to the Nitrokey Start, but more396- `Nitrokey 3`_: Similar to the Nitrokey Start, but more
405 tamper-resistant and offers more security features. Pro 2 supports ECC397 tamper-resistant and offers more security features and USB
406 cryptography (NISTP).398 form-factors. Supports ECC cryptography (ED25519 and NISTP).
407- `Yubikey 5`_: proprietary hardware and software, but cheaper than399- `Yubikey 5`_: proprietary hardware and software, but cheaper than
408 Nitrokey Pro and comes available in the USB-C form that is more useful400 Nitrokey with a similar set of features. Supports ECC cryptography
409 with newer laptops. Offers additional security features such as FIDO401 (ED25519 and NISTP).
410 U2F, among others, and now finally supports NISTP and ED25519 ECC
411 keys.
412 402
413Your choice will depend on cost, shipping availability in your403Your choice will depend on cost, shipping availability in your
414geographical region, and open/proprietary hardware considerations.404geographical region, and open/proprietary hardware considerations.
@@ -419,8 +409,8 @@ geographical region, and open/proprietary hardware considerations. · 4 unmodified lines
419 you `qualify for a free Nitrokey Start`_ courtesy of The Linux409 you `qualify for a free Nitrokey Start`_ courtesy of The Linux
420 Foundation.410 Foundation.
421 411
422.. _`Nitrokey Start`: https://shop.nitrokey.com/shop/product/nitrokey-start-6412.. _`Nitrokey Start`: https://www.nitrokey.com/products/nitrokeys
423.. _`Nitrokey Pro 2`: https://shop.nitrokey.com/shop/product/nkpr2-nitrokey-pro-2-3413.. _`Nitrokey 3`: https://www.nitrokey.com/products/nitrokeys
424.. _`Yubikey 5`: https://www.yubico.com/products/yubikey-5-overview/414.. _`Yubikey 5`: https://www.yubico.com/products/yubikey-5-overview/
425.. _Gnuk: https://www.fsij.org/doc-gnuk/415.. _Gnuk: https://www.fsij.org/doc-gnuk/
426.. _`qualify for a free Nitrokey Start`: https://www.kernel.org/nitrokey-digital-tokens-for-kernel-developers.html416.. _`qualify for a free Nitrokey Start`: https://www.kernel.org/nitrokey-digital-tokens-for-kernel-developers.html
@@ -455,7 +445,7 @@ the smartcard). You so rarely need to use the Admin PIN, that you will · 28 unmodified lines
455inevitably forget what it is if you do not record it.445inevitably forget what it is if you do not record it.
456 446
457Getting back to the main card menu, you can also set other values (such447Getting back to the main card menu, you can also set other values (such
458as name, sex, login data, etc), but it's not necessary and will448as name, gender, login data, etc), but it's not necessary and will
459additionally leak information about your smartcard should you lose it.449additionally leak information about your smartcard should you lose it.
460 450
461.. note::451.. note::
@@ -615,7 +605,7 @@ run:: · 153 unmodified lines
615You can also use a specific date if that is easier to remember (e.g.605You can also use a specific date if that is easier to remember (e.g.
616your birthday, January 1st, or Canada Day)::606your birthday, January 1st, or Canada Day)::
617 607
618 $ gpg --quick-set-expire [fpr] 2025-07-01608 $ gpg --quick-set-expire [fpr] 2038-07-01
619 609
620Remember to send the updated key back to keyservers::610Remember to send the updated key back to keyservers::
621 611
@@ -656,9 +646,9 @@ hundreds of cloned repositories floating around, how does anyone verify · 34 unmodified lines
656that their copy of linux.git has not been tampered with by a malicious646that their copy of linux.git has not been tampered with by a malicious
657third party?647third party?
658 648
659Or what happens if a backdoor is discovered in the code and the "Author"649Or what happens if malicious code is discovered in the kernel and the
660line in the commit says it was done by you, while you're pretty sure you650"Author" line in the commit says it was done by you, while you're pretty
661had `nothing to do with it`_?651sure you had `nothing to do with it`_?
662 652
663To address both of these issues, Git introduced PGP integration. Signed653To address both of these issues, Git introduced PGP integration. Signed
664tags prove the repository integrity by assuring that its contents are654tags prove the repository integrity by assuring that its contents are
@@ -681,8 +671,7 @@ should be used (``[fpr]`` is the fingerprint of your key):: · 16 unmodified lines
681How to work with signed tags671How to work with signed tags
682----------------------------672----------------------------
683 673
684To create a signed tag, simply pass the ``-s`` switch to the tag674To create a signed tag, pass the ``-s`` switch to the tag command::
685command::
686 675
687 $ git tag -s [tagname]676 $ git tag -s [tagname]
688 677
@@ -693,7 +682,7 @@ not been maliciously altered. · 4 unmodified lines
693How to verify signed tags682How to verify signed tags
694~~~~~~~~~~~~~~~~~~~~~~~~~683~~~~~~~~~~~~~~~~~~~~~~~~~
695 684
696To verify a signed tag, simply use the ``verify-tag`` command::685To verify a signed tag, use the ``verify-tag`` command::
697 686
698 $ git verify-tag [tagname]687 $ git verify-tag [tagname]
699 688
@@ -712,9 +701,9 @@ The merge message will contain something like this:: · 12 unmodified lines
712 # gpg: Signature made [...]701 # gpg: Signature made [...]
713 # gpg: Good signature from [...]702 # gpg: Good signature from [...]
714 703
715If you are verifying someone else's git tag, then you will need to704If you are verifying someone else's git tag, you will first need to
716import their PGP key. Please refer to the705import their PGP key. Please refer to the ":ref:`verify_identities`"
717":ref:`verify_identities`" section below.706section below.
718 707
719Configure git to always sign annotated tags708Configure git to always sign annotated tags
720~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~709~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -728,16 +717,16 @@ configuration option:: · 7 unmodified lines
728How to work with signed commits717How to work with signed commits
729-------------------------------718-------------------------------
730 719
731It is easy to create signed commits, but it is much more difficult to720It is also possible to create signed commits, but they have limited
732use them in Linux kernel development, since it relies on patches sent to721usefulness in Linux kernel development. The kernel contribution workflow
733the mailing list, and this workflow does not preserve PGP commit722relies on sending in patches, and converting commits to patches does not
734signatures. Furthermore, when rebasing your repository to match723preserve git commit signatures. Furthermore, when rebasing your own
735upstream, even your own PGP commit signatures will end up discarded. For724repository on a newer upstream, PGP commit signatures will end up
736this reason, most kernel developers don't bother signing their commits725discarded. For this reason, most kernel developers don't bother signing
737and will ignore signed commits in any external repositories that they726their commits and will ignore signed commits in any external
738rely upon in their work.727repositories that they rely upon in their work.
739 728
740However, if you have your working git tree publicly available at some729That said, if you have your working git tree publicly available at some
741git hosting service (kernel.org, infradead.org, ozlabs.org, or others),730git hosting service (kernel.org, infradead.org, ozlabs.org, or others),
742then the recommendation is that you sign all your git commits even if731then the recommendation is that you sign all your git commits even if
743upstream developers do not directly benefit from this practice.732upstream developers do not directly benefit from this practice.
@@ -748,7 +737,7 @@ We recommend this for the following reasons: · 4 unmodified lines
748 provenance, even externally maintained trees carrying PGP commit737 provenance, even externally maintained trees carrying PGP commit
749 signatures will be valuable for such purposes.738 signatures will be valuable for such purposes.
7502. If you ever need to re-clone your local repository (for example,7392. If you ever need to re-clone your local repository (for example,
751 after a disk failure), this lets you easily verify the repository740 after reinstalling your system), this lets you verify the repository
752 integrity before resuming your work.741 integrity before resuming your work.
7533. If someone needs to cherry-pick your commits, this allows them to7423. If someone needs to cherry-pick your commits, this allows them to
754 quickly verify their integrity before applying them.743 quickly verify their integrity before applying them.
@@ -756,9 +745,8 @@ We recommend this for the following reasons: · 1 unmodified line
756Creating signed commits745Creating signed commits
757~~~~~~~~~~~~~~~~~~~~~~~746~~~~~~~~~~~~~~~~~~~~~~~
758 747
759To create a signed commit, you just need to pass the ``-S`` flag to the748To create a signed commit, pass the ``-S`` flag to the ``git commit``
760``git commit`` command (it's capital ``-S`` due to collision with749command (it's capital ``-S`` due to collision with another flag)::
761another flag)::
762 750
763 $ git commit -S751 $ git commit -S
764 752
@@ -775,7 +763,6 @@ You can tell git to always sign commits:: · 10 unmodified lines
775 763
776.. _verify_identities:764.. _verify_identities:
777 765
778
779How to work with signed patches766How to work with signed patches
780-------------------------------767-------------------------------
781 768
@@ -793,6 +780,11 @@ headers (a-la DKIM): · 11 unmodified lines
793Installing and configuring patatt780Installing and configuring patatt
794~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~781~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
795 782
783.. note::
784
785 If you use B4 to send in your patches, patatt is already installed
786 and integrated into your workflow.
787
796Patatt is packaged for many distributions already, so please check there788Patatt is packaged for many distributions already, so please check there
797first. You can also install it from pypi using "``pip install patatt``".789first. You can also install it from pypi using "``pip install patatt``".
798 790
@@ -835,9 +827,9 @@ encounters, for example:: · 36 unmodified lines
835How to verify kernel developer identities827How to verify kernel developer identities
836=========================================828=========================================
837 829
838Signing tags and commits is easy, but how does one go about verifying830Signing tags and commits is straightforward, but how does one go about
839that the key used to sign something belongs to the actual kernel831verifying that the key used to sign something belongs to the actual
840developer and not to a malicious imposter?832kernel developer and not to a malicious imposter?
841 833
842Configure auto-key-retrieval using WKD and DANE834Configure auto-key-retrieval using WKD and DANE
843-----------------------------------------------835-----------------------------------------------
@@ -884,7 +876,7 @@ various software makers dictating who should be your trusted certifying · 40 unmodified lines
884entity, PGP leaves this responsibility to each user.876entity, PGP leaves this responsibility to each user.
885 877
886Unfortunately, very few people understand how the Web of Trust works.878Unfortunately, very few people understand how the Web of Trust works.
887While it remains an important aspect of the OpenPGP specification,879While it is still an important part of the OpenPGP specification,
888recent versions of GnuPG (2.2 and above) have implemented an alternative880recent versions of GnuPG (2.2 and above) have implemented an alternative
889mechanism called "Trust on First Use" (TOFU). You can think of TOFU as881mechanism called "Trust on First Use" (TOFU). You can think of TOFU as
890"the SSH-like approach to trust." With SSH, the first time you connect882"the SSH-like approach to trust." With SSH, the first time you connect
@@ -894,8 +886,8 @@ to connect, forcing you to make a decision on whether you choose to · 3 unmodified lines
894trust the changed key or not. Similarly, the first time you import886trust the changed key or not. Similarly, the first time you import
895someone's PGP key, it is assumed to be valid. If at any point in the887someone's PGP key, it is assumed to be valid. If at any point in the
896future GnuPG comes across another key with the same identity, both the888future GnuPG comes across another key with the same identity, both the
897previously imported key and the new key will be marked as invalid and889previously imported key and the new key will be marked for verification
898you will need to manually figure out which one to keep.890and you will need to manually figure out which one to keep.
899 891
900We recommend that you use the combined TOFU+PGP trust model (which is892We recommend that you use the combined TOFU+PGP trust model (which is
901the new default in GnuPG v2). To set it, add (or modify) the893the new default in GnuPG v2). To set it, add (or modify) the
Documentation/process/submitting-patches.rst+3−3
@@ -343,7 +343,7 @@ https://en.wikipedia.org/wiki/Posting_style#Interleaved_style · 342 unmodified lines
343As is frequently quoted on the mailing list::343As is frequently quoted on the mailing list::
344 344
345 A: http://en.wikipedia.org/wiki/Top_post345 A: http://en.wikipedia.org/wiki/Top_post
346 Q: Were do I find info about this thing called top-posting?346 Q: Where do I find info about this thing called top-posting?
347 A: Because it messes up the order in which people normally read text.347 A: Because it messes up the order in which people normally read text.
348 Q: Why is top-posting such a bad thing?348 Q: Why is top-posting such a bad thing?
349 A: Top-posting.349 A: Top-posting.
@@ -602,8 +602,8 @@ future. Note, this is one of only three tags you might be able to use without · 252 unmodified lines
602explicit permission of the person named (see 'Tagging people requires602explicit permission of the person named (see 'Tagging people requires
603permission' below for details).603permission' below for details).
604 604
605A Fixes: tag indicates that the patch fixes an issue in a previous commit. It605A Fixes: tag indicates that the patch fixes a bug in a previous commit. It
606is used to make it easy to determine where a bug originated, which can help606is used to make it easy to determine where an issue originated, which can help
607review a bug fix. This tag also assists the stable kernel team in determining607review a bug fix. This tag also assists the stable kernel team in determining
608which stable kernel versions should receive your fix. This is the preferred608which stable kernel versions should receive your fix. This is the preferred
609method for indicating a bug fixed by the patch. See :ref:`describe_changes`609method for indicating a bug fixed by the patch. See :ref:`describe_changes`
Documentation/sphinx/automarkup.py+1−1
@@ -244,7 +244,7 @@ def add_and_resolve_xref(app, docname, domain, reftype, target, contnode=None): · 243 unmodified lines
244 return contnode244 return contnode
245 245
246#246#
247# Variant of markup_abi_ref() that warns whan a reference is not found247# Variant of markup_abi_ref() that warns when a reference is not found
248#248#
249def markup_abi_file_ref(docname, app, match):249def markup_abi_file_ref(docname, app, match):
250 return markup_abi_ref(docname, app, match, warning=True)250 return markup_abi_ref(docname, app, match, warning=True)
Documentation/sphinx/cdomain.py+0−247
@@ -1,247 +0,0 @@
1# -*- coding: utf-8; mode: python -*-
2# SPDX-License-Identifier: GPL-2.0
3# pylint: disable=W0141,C0113,C0103,C0325
4"""
5 cdomain
6 ~~~~~~~
7
8 Replacement for the sphinx c-domain.
9
10 :copyright: Copyright (C) 2016 Markus Heiser
11 :license: GPL Version 2, June 1991 see Linux/COPYING for details.
12
13 List of customizations:
14
15 * Moved the *duplicate C object description* warnings for function
16 declarations in the nitpicky mode. See Sphinx documentation for
17 the config values for ``nitpick`` and ``nitpick_ignore``.
18
19 * Add option 'name' to the "c:function:" directive. With option 'name' the
20 ref-name of a function can be modified. E.g.::
21
22 .. c:function:: int ioctl( int fd, int request )
23 :name: VIDIOC_LOG_STATUS
24
25 The func-name (e.g. ioctl) remains in the output but the ref-name changed
26 from 'ioctl' to 'VIDIOC_LOG_STATUS'. The function is referenced by::
27
28 * :c:func:`VIDIOC_LOG_STATUS` or
29 * :any:`VIDIOC_LOG_STATUS` (``:any:`` needs sphinx 1.3)
30
31 * Handle signatures of function-like macros well. Don't try to deduce
32 arguments types of function-like macros.
33
34"""
35
36from docutils import nodes
37from docutils.parsers.rst import directives
38
39import sphinx
40from sphinx import addnodes
41from sphinx.domains.c import c_funcptr_sig_re, c_sig_re
42from sphinx.domains.c import CObject as Base_CObject
43from sphinx.domains.c import CDomain as Base_CDomain
44from itertools import chain
45import re
46
47__version__ = '1.1'
48
49# Namespace to be prepended to the full name
50namespace = None
51
52#
53# Handle trivial newer c domain tags that are part of Sphinx 3.1 c domain tags
54# - Store the namespace if ".. c:namespace::" tag is found
55#
56RE_namespace = re.compile(r'^\s*..\s*c:namespace::\s*(\S+)\s*$')
57
58def markup_namespace(match):
59 global namespace
60
61 namespace = match.group(1)
62
63 return ""
64
65#
66# Handle c:macro for function-style declaration
67#
68RE_macro = re.compile(r'^\s*..\s*c:macro::\s*(\S+)\s+(\S.*)\s*$')
69def markup_macro(match):
70 return ".. c:function:: " + match.group(1) + ' ' + match.group(2)
71
72#
73# Handle newer c domain tags that are evaluated as .. c:type: for
74# backward-compatibility with Sphinx < 3.0
75#
76RE_ctype = re.compile(r'^\s*..\s*c:(struct|union|enum|enumerator|alias)::\s*(.*)$')
77
78def markup_ctype(match):
79 return ".. c:type:: " + match.group(2)
80
81#
82# Handle newer c domain tags that are evaluated as :c:type: for
83# backward-compatibility with Sphinx < 3.0
84#
85RE_ctype_refs = re.compile(r':c:(var|struct|union|enum|enumerator)::`([^\`]+)`')
86def markup_ctype_refs(match):
87 return ":c:type:`" + match.group(2) + '`'
88
89#
90# Simply convert :c:expr: and :c:texpr: into a literal block.
91#
92RE_expr = re.compile(r':c:(expr|texpr):`([^\`]+)`')
93def markup_c_expr(match):
94 return '\\ ``' + match.group(2) + '``\\ '
95
96#
97# Parse Sphinx 3.x C markups, replacing them by backward-compatible ones
98#
99def c_markups(app, docname, source):
100 result = ""
101 markup_func = {
102 RE_namespace: markup_namespace,
103 RE_expr: markup_c_expr,
104 RE_macro: markup_macro,
105 RE_ctype: markup_ctype,
106 RE_ctype_refs: markup_ctype_refs,
107 }
108
109 lines = iter(source[0].splitlines(True))
110 for n in lines:
111 match_iterators = [regex.finditer(n) for regex in markup_func]
112 matches = sorted(chain(*match_iterators), key=lambda m: m.start())
113 for m in matches:
114 n = n[:m.start()] + markup_func[m.re](m) + n[m.end():]
115
116 result = result + n
117
118 source[0] = result
119
120#
121# Now implements support for the cdomain namespacing logic
122#
123
124def setup(app):
125
126 # Handle easy Sphinx 3.1+ simple new tags: :c:expr and .. c:namespace::
127 app.connect('source-read', c_markups)
128 app.add_domain(CDomain, override=True)
129
130 return dict(
131 version = __version__,
132 parallel_read_safe = True,
133 parallel_write_safe = True
134 )
135
136class CObject(Base_CObject):
137
138 """
139 Description of a C language object.
140 """
141 option_spec = {
142 "name" : directives.unchanged
143 }
144
145 def handle_func_like_macro(self, sig, signode):
146 """Handles signatures of function-like macros.
147
148 If the objtype is 'function' and the signature ``sig`` is a
149 function-like macro, the name of the macro is returned. Otherwise
150 ``False`` is returned. """
151
152 global namespace
153
154 if not self.objtype == 'function':
155 return False
156
157 m = c_funcptr_sig_re.match(sig)
158 if m is None:
159 m = c_sig_re.match(sig)
160 if m is None:
161 raise ValueError('no match')
162
163 rettype, fullname, arglist, _const = m.groups()
164 arglist = arglist.strip()
165 if rettype or not arglist:
166 return False
167
168 arglist = arglist.replace('`', '').replace('\\ ', '') # remove markup
169 arglist = [a.strip() for a in arglist.split(",")]
170
171 # has the first argument a type?
172 if len(arglist[0].split(" ")) > 1:
173 return False
174
175 # This is a function-like macro, its arguments are typeless!
176 signode += addnodes.desc_name(fullname, fullname)
177 paramlist = addnodes.desc_parameterlist()
178 signode += paramlist
179
180 for argname in arglist:
181 param = addnodes.desc_parameter('', '', noemph=True)
182 # separate by non-breaking space in the output
183 param += nodes.emphasis(argname, argname)
184 paramlist += param
185
186 if namespace:
187 fullname = namespace + "." + fullname
188
189 return fullname
190
191 def handle_signature(self, sig, signode):
192 """Transform a C signature into RST nodes."""
193
194 global namespace
195
196 fullname = self.handle_func_like_macro(sig, signode)
197 if not fullname:
198 fullname = super(CObject, self).handle_signature(sig, signode)
199
200 if "name" in self.options:
201 if self.objtype == 'function':
202 fullname = self.options["name"]
203 else:
204 # FIXME: handle :name: value of other declaration types?
205 pass
206 else:
207 if namespace:
208 fullname = namespace + "." + fullname
209
210 return fullname
211
212 def add_target_and_index(self, name, sig, signode):
213 # for C API items we add a prefix since names are usually not qualified
214 # by a module name and so easily clash with e.g. section titles
215 targetname = 'c.' + name
216 if targetname not in self.state.document.ids:
217 signode['names'].append(targetname)
218 signode['ids'].append(targetname)
219 signode['first'] = (not self.names)
220 self.state.document.note_explicit_target(signode)
221 inv = self.env.domaindata['c']['objects']
222 if (name in inv and self.env.config.nitpicky):
223 if self.objtype == 'function':
224 if ('c:func', name) not in self.env.config.nitpick_ignore:
225 self.state_machine.reporter.warning(
226 'duplicate C object description of %s, ' % name +
227 'other instance in ' + self.env.doc2path(inv[name][0]),
228 line=self.lineno)
229 inv[name] = (self.env.docname, self.objtype)
230
231 indextext = self.get_index_text(name)
232 if indextext:
233 self.indexnode['entries'].append(
234 ('single', indextext, targetname, '', None))
235
236class CDomain(Base_CDomain):
237
238 """C language domain."""
239 name = 'c'
240 label = 'C'
241 directives = {
242 'function': CObject,
243 'member': CObject,
244 'macro': CObject,
245 'type': CObject,
246 'var': CObject,
247 }
Documentation/sphinx/kernel_feat.py+3−1
@@ -40,9 +40,11 @@ import sys · 39 unmodified lines
40from docutils import nodes, statemachine40from docutils import nodes, statemachine
41from docutils.statemachine import ViewList41from docutils.statemachine import ViewList
42from docutils.parsers.rst import directives, Directive42from docutils.parsers.rst import directives, Directive
43from docutils.utils.error_reporting import ErrorString
44from sphinx.util.docutils import switch_source_input43from sphinx.util.docutils import switch_source_input
45 44
45def ErrorString(exc): # Shamelessly stolen from docutils
46 return f'{exc.__class__.__name}: {exc}'
47
46__version__ = '1.0'48__version__ = '1.0'
47 49
48def setup(app):50def setup(app):
Documentation/sphinx/kernel_include.py+392−136
@@ -1,31 +1,82 @@
1#!/usr/bin/env python31#!/usr/bin/env python3
2# -*- coding: utf-8; mode: python -*-
3# SPDX-License-Identifier: GPL-2.02# SPDX-License-Identifier: GPL-2.0
4# pylint: disable=R0903, C0330, R0914, R0912, E04013# pylint: disable=R0903, R0912, R0914, R0915, C0209,W0707
4
5 5
6"""6"""
7 kernel-include7Implementation of the ``kernel-include`` reST-directive.
8 ~~~~~~~~~~~~~~8
9:copyright: Copyright (C) 2016 Markus Heiser
10:license: GPL Version 2, June 1991 see linux/COPYING for details.
11
12The ``kernel-include`` reST-directive is a replacement for the ``include``
13directive. The ``kernel-include`` directive expand environment variables in
14the path name and allows to include files from arbitrary locations.
15
16.. hint::
17
18 Including files from arbitrary locations (e.g. from ``/etc``) is a
19 security risk for builders. This is why the ``include`` directive from
20 docutils *prohibit* pathnames pointing to locations *above* the filesystem
21 tree where the reST document with the include directive is placed.
22
23Substrings of the form $name or ${name} are replaced by the value of
24environment variable name. Malformed variable names and references to
25non-existing variables are left unchanged.
26
27**Supported Sphinx Include Options**:
28
29:param literal:
30 If present, the included file is inserted as a literal block.
31
32:param code:
33 Specify the language for syntax highlighting (e.g., 'c', 'python').
34
35:param encoding:
36 Specify the encoding of the included file (default: 'utf-8').
37
38:param tab-width:
39 Specify the number of spaces that a tab represents.
40
41:param start-line:
42 Line number at which to start including the file (1-based).
43
44:param end-line:
45 Line number at which to stop including the file (inclusive).
46
47:param start-after:
48 Include lines after the first line matching this text.
49
50:param end-before:
51 Include lines before the first line matching this text.
9 52
10 Implementation of the ``kernel-include`` reST-directive.53:param number-lines:
54 Number the included lines (integer specifies start number).
55 Only effective with 'literal' or 'code' options.
11 56
12 :copyright: Copyright (C) 2016 Markus Heiser57:param class:
13 :license: GPL Version 2, June 1991 see linux/COPYING for details.58 Specify HTML class attribute for the included content.
14 59
15 The ``kernel-include`` reST-directive is a replacement for the ``include``60**Kernel-specific Extensions**:
16 directive. The ``kernel-include`` directive expand environment variables in
17 the path name and allows to include files from arbitrary locations.
18 61
19 .. hint::62:param generate-cross-refs:
63 If present, instead of directly including the file, it calls
64 ParseDataStructs() to convert C data structures into cross-references
65 that link to comprehensive documentation in other ReST files.
20 66
21 Including files from arbitrary locations (e.g. from ``/etc``) is a67:param exception-file:
22 security risk for builders. This is why the ``include`` directive from68 (Used with generate-cross-refs)
23 docutils *prohibit* pathnames pointing to locations *above* the filesystem
24 tree where the reST document with the include directive is placed.
25 69
26 Substrings of the form $name or ${name} are replaced by the value of70 Path to a file containing rules for handling special cases:
27 environment variable name. Malformed variable names and references to71 - Ignore specific C data structures
28 non-existing variables are left unchanged.72 - Use alternative reference names
73 - Specify different reference types
74
75:param warn-broken:
76 (Used with generate-cross-refs)
77
78 Enables warnings when auto-generated cross-references don't point to
79 existing documentation targets.
29"""80"""
30 81
31# ==============================================================================82# ==============================================================================
@@ -33,161 +84,366 @@ · 1 unmodified line
33# ==============================================================================84# ==============================================================================
34 85
35import os.path86import os.path
87import re
88import sys
36 89
37from docutils import io, nodes, statemachine90from docutils import io, nodes, statemachine
38from docutils.utils.error_reporting import SafeString, ErrorString91from docutils.statemachine import ViewList
39from docutils.parsers.rst import directives92from docutils.parsers.rst import Directive, directives
40from docutils.parsers.rst.directives.body import CodeBlock, NumberLines93from docutils.parsers.rst.directives.body import CodeBlock, NumberLines
41from docutils.parsers.rst.directives.misc import Include
42 94
43__version__ = '1.0'95from sphinx.util import logging
44 96
45# ==============================================================================97srctree = os.path.abspath(os.environ["srctree"])
46def setup(app):98sys.path.insert(0, os.path.join(srctree, "tools/docs/lib"))
47# ==============================================================================
48 99
49 app.add_directive("kernel-include", KernelInclude)100from parse_data_structs import ParseDataStructs
50 return dict(
51 version = __version__,
52 parallel_read_safe = True,
53 parallel_write_safe = True
54 )
55 101
56# ==============================================================================102__version__ = "1.0"
57class KernelInclude(Include):103logger = logging.getLogger(__name__)
58# ==============================================================================
59 104
60 """KernelInclude (``kernel-include``) directive"""105RE_DOMAIN_REF = re.compile(r'\\ :(ref|c:type|c:func):`([^<`]+)(?:<([^>]+)>)?`\\')
106RE_SIMPLE_REF = re.compile(r'`([^`]+)`')
61 107
62 def run(self):108def ErrorString(exc): # Shamelessly stolen from docutils
63 env = self.state.document.settings.env109 return f'{exc.__class__.__name}: {exc}'
64 path = os.path.realpath(
65 os.path.expandvars(self.arguments[0]))
66 110
67 # to get a bit security back, prohibit /etc:
68 if path.startswith(os.sep + "etc"):
69 raise self.severe(
70 'Problems with "%s" directive, prohibited path: %s'
71 % (self.name, path))
72 111
73 self.arguments[0] = path112# ==============================================================================
113class KernelInclude(Directive):
114 """
115 KernelInclude (``kernel-include``) directive
74 116
75 env.note_dependency(os.path.abspath(path))117 Most of the stuff here came from Include directive defined at:
118 docutils/parsers/rst/directives/misc.py
76 119
77 #return super(KernelInclude, self).run() # won't work, see HINTs in _run()120 Yet, overriding the class don't has any benefits: the original class
78 return self._run()121 only have run() and argument list. Not all of them are implemented,
122 when checked against latest Sphinx version, as with time more arguments
123 were added.
79 124
80 def _run(self):125 So, keep its own list of supported arguments
81 """Include a file as part of the content of this reST file."""126 """
82 127
83 # HINT: I had to copy&paste the whole Include.run method. I'am not happy128 required_arguments = 1
84 # with this, but due to security reasons, the Include.run method does129 optional_arguments = 0
85 # not allow absolute or relative pathnames pointing to locations *above*130 final_argument_whitespace = True
86 # the filesystem tree where the reST document is placed.131 option_spec = {
132 'literal': directives.flag,
133 'code': directives.unchanged,
134 'encoding': directives.encoding,
135 'tab-width': int,
136 'start-line': int,
137 'end-line': int,
138 'start-after': directives.unchanged_required,
139 'end-before': directives.unchanged_required,
140 # ignored except for 'literal' or 'code':
141 'number-lines': directives.unchanged, # integer or None
142 'class': directives.class_option,
87 143
88 if not self.state.document.settings.file_insertion_enabled:144 # Arguments that aren't from Sphinx Include directive
89 raise self.warning('"%s" directive disabled.' % self.name)145 'generate-cross-refs': directives.flag,
90 source = self.state_machine.input_lines.source(146 'warn-broken': directives.flag,
91 self.lineno - self.state_machine.input_offset - 1)147 'toc': directives.flag,
92 source_dir = os.path.dirname(os.path.abspath(source))148 'exception-file': directives.unchanged,
93 path = directives.path(self.arguments[0])149 }
94 if path.startswith('<') and path.endswith('>'):
95 path = os.path.join(self.standard_include_path, path[1:-1])
96 path = os.path.normpath(os.path.join(source_dir, path))
97 150
98 # HINT: this is the only line I had to change / commented out:151 def read_rawtext(self, path, encoding):
99 #path = utils.relative_path(None, path)152 """Read and process file content with error handling"""
153 try:
154 self.state.document.settings.record_dependencies.add(path)
155 include_file = io.FileInput(source_path=path,
156 encoding=encoding,
157 error_handler=self.state.document.settings.input_encoding_error_handler)
158 except UnicodeEncodeError:
159 raise self.severe('Problems with directive path:\n'
160 'Cannot encode input file path "%s" '
161 '(wrong locale?).' % path)
162 except IOError as error:
163 raise self.severe('Problems with directive path:\n%s.' % ErrorString(error))
100 164
101 encoding = self.options.get(165 try:
102 'encoding', self.state.document.settings.input_encoding)166 return include_file.read()
103 e_handler=self.state.document.settings.input_encoding_error_handler167 except UnicodeError as error:
104 tab_width = self.options.get(168 raise self.severe('Problem with directive:\n%s' % ErrorString(error))
105 'tab-width', self.state.document.settings.tab_width)169
106 try:170 def apply_range(self, rawtext):
107 self.state.document.settings.record_dependencies.add(path)171 """
108 include_file = io.FileInput(source_path=path,172 Handles start-line, end-line, start-after and end-before parameters
109 encoding=encoding,173 """
110 error_handler=e_handler)174
111 except UnicodeEncodeError as error:175 # Get to-be-included content
112 raise self.severe('Problems with "%s" directive path:\n'
113 'Cannot encode input file path "%s" '
114 '(wrong locale?).' %
115 (self.name, SafeString(path)))
116 except IOError as error:
117 raise self.severe('Problems with "%s" directive path:\n%s.' %
118 (self.name, ErrorString(error)))
119 startline = self.options.get('start-line', None)176 startline = self.options.get('start-line', None)
120 endline = self.options.get('end-line', None)177 endline = self.options.get('end-line', None)
121 try:178 try:
122 if startline or (endline is not None):179 if startline or (endline is not None):
123 lines = include_file.readlines()180 lines = rawtext.splitlines()
124 rawtext = ''.join(lines[startline:endline])181 rawtext = '\n'.join(lines[startline:endline])
125 else:
126 rawtext = include_file.read()
127 except UnicodeError as error:182 except UnicodeError as error:
128 raise self.severe('Problem with "%s" directive:\n%s' %183 raise self.severe(f'Problem with "{self.name}" directive:\n'
129 (self.name, ErrorString(error)))184 + io.error_string(error))
130 # start-after/end-before: no restrictions on newlines in match-text,185 # start-after/end-before: no restrictions on newlines in match-text,
131 # and no restrictions on matching inside lines vs. line boundaries186 # and no restrictions on matching inside lines vs. line boundaries
132 after_text = self.options.get('start-after', None)187 after_text = self.options.get("start-after", None)
133 if after_text:188 if after_text:
134 # skip content in rawtext before *and incl.* a matching text189 # skip content in rawtext before *and incl.* a matching text
135 after_index = rawtext.find(after_text)190 after_index = rawtext.find(after_text)
136 if after_index < 0:191 if after_index < 0:
137 raise self.severe('Problem with "start-after" option of "%s" '192 raise self.severe('Problem with "start-after" option of "%s" '
138 'directive:\nText not found.' % self.name)193 "directive:\nText not found." % self.name)
139 rawtext = rawtext[after_index + len(after_text):]194 rawtext = rawtext[after_index + len(after_text) :]
140 before_text = self.options.get('end-before', None)195 before_text = self.options.get("end-before", None)
141 if before_text:196 if before_text:
142 # skip content in rawtext after *and incl.* a matching text197 # skip content in rawtext after *and incl.* a matching text
143 before_index = rawtext.find(before_text)198 before_index = rawtext.find(before_text)
144 if before_index < 0:199 if before_index < 0:
145 raise self.severe('Problem with "end-before" option of "%s" '200 raise self.severe('Problem with "end-before" option of "%s" '
146 'directive:\nText not found.' % self.name)201 "directive:\nText not found." % self.name)
147 rawtext = rawtext[:before_index]202 rawtext = rawtext[:before_index]
148 203
204 return rawtext
205
206 def xref_text(self, env, path, tab_width):
207 """
208 Read and add contents from a C file parsed to have cross references.
209
210 There are two types of supported output here:
211 - A C source code with cross-references;
212 - a TOC table containing cross references.
213 """
214 parser = ParseDataStructs()
215 parser.parse_file(path)
216
217 if 'exception-file' in self.options:
218 source_dir = os.path.dirname(os.path.abspath(
219 self.state_machine.input_lines.source(
220 self.lineno - self.state_machine.input_offset - 1)))
221 exceptions_file = os.path.join(source_dir, self.options['exception-file'])
222 parser.process_exceptions(exceptions_file)
223
224 # Store references on a symbol dict to be used at check time
225 if 'warn-broken' in self.options:
226 env._xref_files.add(path)
227
228 if "toc" not in self.options:
229
230 rawtext = ".. parsed-literal::\n\n" + parser.gen_output()
231 self.apply_range(rawtext)
232
233 include_lines = statemachine.string2lines(rawtext, tab_width,
234 convert_whitespace=True)
235
236 # Sphinx always blame the ".. <directive>", so placing
237 # line numbers here won't make any difference
238
239 self.state_machine.insert_input(include_lines, path)
240 return []
241
242 # TOC output is a ReST file, not a literal. So, we can add line
243 # numbers
244
245 rawtext = parser.gen_toc()
246
149 include_lines = statemachine.string2lines(rawtext, tab_width,247 include_lines = statemachine.string2lines(rawtext, tab_width,
150 convert_whitespace=True)248 convert_whitespace=True)
151 if 'literal' in self.options:249
152 # Convert tabs to spaces, if `tab_width` is positive.250 # Append line numbers data
153 if tab_width >= 0:251
154 text = rawtext.expandtabs(tab_width)252 startline = self.options.get('start-line', None)
155 else:253
156 text = rawtext254 result = ViewList()
157 literal_block = nodes.literal_block(rawtext, source=path,255 if startline and startline > 0:
158 classes=self.options.get('class', []))256 offset = startline - 1
159 literal_block.line = 1257 else:
160 self.add_name(literal_block)258 offset = 0
161 if 'number-lines' in self.options:259
162 try:260 for ln, line in enumerate(include_lines, start=offset):
163 startline = int(self.options['number-lines'] or 1)261 result.append(line, path, ln)
164 except ValueError:262
165 raise self.error(':number-lines: with non-integer '263 self.state_machine.insert_input(result, path)
166 'start value')264
167 endline = startline + len(include_lines)
168 if text.endswith('\n'):
169 text = text[:-1]
170 tokens = NumberLines([([], text)], startline, endline)
171 for classes, value in tokens:
172 if classes:
173 literal_block += nodes.inline(value, value,
174 classes=classes)
175 else:
176 literal_block += nodes.Text(value, value)
177 else:
178 literal_block += nodes.Text(text, text)
179 return [literal_block]
180 if 'code' in self.options:
181 self.options['source'] = path
182 codeblock = CodeBlock(self.name,
183 [self.options.pop('code')], # arguments
184 self.options,
185 include_lines, # content
186 self.lineno,
187 self.content_offset,
188 self.block_text,
189 self.state,
190 self.state_machine)
191 return codeblock.run()
192 self.state_machine.insert_input(include_lines, path)
193 return []265 return []
266
267 def literal(self, path, tab_width, rawtext):
268 """Output a literal block"""
269
270 # Convert tabs to spaces, if `tab_width` is positive.
271 if tab_width >= 0:
272 text = rawtext.expandtabs(tab_width)
273 else:
274 text = rawtext
275 literal_block = nodes.literal_block(rawtext, source=path,
276 classes=self.options.get("class", []))
277 literal_block.line = 1
278 self.add_name(literal_block)
279 if "number-lines" in self.options:
280 try:
281 startline = int(self.options["number-lines"] or 1)
282 except ValueError:
283 raise self.error(":number-lines: with non-integer start value")
284 endline = startline + len(include_lines)
285 if text.endswith("\n"):
286 text = text[:-1]
287 tokens = NumberLines([([], text)], startline, endline)
288 for classes, value in tokens:
289 if classes:
290 literal_block += nodes.inline(value, value,
291 classes=classes)
292 else:
293 literal_block += nodes.Text(value, value)
294 else:
295 literal_block += nodes.Text(text, text)
296 return [literal_block]
297
298 def code(self, path, tab_width):
299 """Output a code block"""
300
301 include_lines = statemachine.string2lines(rawtext, tab_width,
302 convert_whitespace=True)
303
304 self.options["source"] = path
305 codeblock = CodeBlock(self.name,
306 [self.options.pop("code")], # arguments
307 self.options,
308 include_lines,
309 self.lineno,
310 self.content_offset,
311 self.block_text,
312 self.state,
313 self.state_machine)
314 return codeblock.run()
315
316 def run(self):
317 """Include a file as part of the content of this reST file."""
318 env = self.state.document.settings.env
319
320 #
321 # The include logic accepts only patches relative to the
322 # Kernel source tree. The logic does check it to prevent
323 # directory traverse issues.
324 #
325
326 srctree = os.path.abspath(os.environ["srctree"])
327
328 path = os.path.expandvars(self.arguments[0])
329 src_path = os.path.join(srctree, path)
330
331 if os.path.isfile(src_path):
332 base = srctree
333 path = src_path
334 else:
335 raise self.warning(f'File "%s" doesn\'t exist', path)
336
337 abs_base = os.path.abspath(base)
338 abs_full_path = os.path.abspath(os.path.join(base, path))
339
340 try:
341 if os.path.commonpath([abs_full_path, abs_base]) != abs_base:
342 raise self.severe('Problems with "%s" directive, prohibited path: %s' %
343 (self.name, path))
344 except ValueError:
345 # Paths don't have the same drive (Windows) or other incompatibility
346 raise self.severe('Problems with "%s" directive, invalid path: %s' %
347 (self.name, path))
348
349 self.arguments[0] = path
350
351 #
352 # Add path location to Sphinx dependencies to ensure proper cache
353 # invalidation check.
354 #
355
356 env.note_dependency(os.path.abspath(path))
357
358 if not self.state.document.settings.file_insertion_enabled:
359 raise self.warning('"%s" directive disabled.' % self.name)
360 source = self.state_machine.input_lines.source(self.lineno -
361 self.state_machine.input_offset - 1)
362 source_dir = os.path.dirname(os.path.abspath(source))
363 path = directives.path(self.arguments[0])
364 if path.startswith("<") and path.endswith(">"):
365 path = os.path.join(self.standard_include_path, path[1:-1])
366 path = os.path.normpath(os.path.join(source_dir, path))
367
368 # HINT: this is the only line I had to change / commented out:
369 # path = utils.relative_path(None, path)
370
371 encoding = self.options.get("encoding",
372 self.state.document.settings.input_encoding)
373 tab_width = self.options.get("tab-width",
374 self.state.document.settings.tab_width)
375
376 # Get optional arguments to related to cross-references generation
377 if "generate-cross-refs" in self.options:
378 return self.xref_text(env, path, tab_width)
379
380 rawtext = self.read_rawtext(path, encoding)
381 rawtext = self.apply_range(rawtext)
382
383 if "code" in self.options:
384 return self.code(path, tab_width, rawtext)
385
386 return self.literal(path, tab_width, rawtext)
387
388# ==============================================================================
389
390reported = set()
391
392def check_missing_refs(app, env, node, contnode):
393 """Check broken refs for the files it creates xrefs"""
394 if not node.source:
395 return None
396
397 try:
398 xref_files = env._xref_files
399 except AttributeError:
400 logger.critical("FATAL: _xref_files not initialized!")
401 raise
402
403 # Only show missing references for kernel-include reference-parsed files
404 if node.source not in xref_files:
405 return None
406
407 target = node.get('reftarget', '')
408 domain = node.get('refdomain', 'std')
409 reftype = node.get('reftype', '')
410
411 msg = f"can't link to: {domain}:{reftype}:: {target}"
412
413 # Don't duplicate warnings
414 data = (node.source, msg)
415 if data in reported:
416 return None
417 reported.add(data)
418
419 logger.warning(msg, location=node, type='ref', subtype='missing')
420
421 return None
422
423def merge_xref_info(app, env, docnames, other):
424 """
425 As each process modify env._xref_files, we need to merge them back.
426 """
427 if not hasattr(other, "_xref_files"):
428 return
429 env._xref_files.update(getattr(other, "_xref_files", set()))
430
431def init_xref_docs(app, env, docnames):
432 """Initialize a list of files that we're generating cross references¨"""
433 app.env._xref_files = set()
434
435# ==============================================================================
436
437def setup(app):
438 """Setup Sphinx exension"""
439
440 app.connect("env-before-read-docs", init_xref_docs)
441 app.connect("env-merge-info", merge_xref_info)
442 app.add_directive("kernel-include", KernelInclude)
443 app.connect("missing-reference", check_missing_refs)
444
445 return {
446 "version": __version__,
447 "parallel_read_safe": True,
448 "parallel_write_safe": True,
449 }
Documentation/sphinx/maintainers_include.py+3−1
@@ -22,10 +22,12 @@ import re · 21 unmodified lines
22import os.path22import os.path
23 23
24from docutils import statemachine24from docutils import statemachine
25from docutils.utils.error_reporting import ErrorString
26from docutils.parsers.rst import Directive25from docutils.parsers.rst import Directive
27from docutils.parsers.rst.directives.misc import Include26from docutils.parsers.rst.directives.misc import Include
28 27
28def ErrorString(exc): # Shamelessly stolen from docutils
29 return f'{exc.__class__.__name}: {exc}'
30
29__version__ = '1.0'31__version__ = '1.0'
30 32
31def setup(app):33def setup(app):
Documentation/sphinx/parse-headers.pl+0−404
@@ -1,404 +0,0 @@
1#!/usr/bin/env perl
2# SPDX-License-Identifier: GPL-2.0
3# Copyright (c) 2016 by Mauro Carvalho Chehab <mchehab@kernel.org>.
4
5use strict;
6use Text::Tabs;
7use Getopt::Long;
8use Pod::Usage;
9
10my $debug;
11my $help;
12my $man;
13
14GetOptions(
15 "debug" => \$debug,
16 'usage|?' => \$help,
17 'help' => \$man
18) or pod2usage(2);
19
20pod2usage(1) if $help;
21pod2usage(-exitstatus => 0, -verbose => 2) if $man;
22pod2usage(2) if (scalar @ARGV < 2 || scalar @ARGV > 3);
23
24my ($file_in, $file_out, $file_exceptions) = @ARGV;
25
26my $data;
27my %ioctls;
28my %defines;
29my %typedefs;
30my %enums;
31my %enum_symbols;
32my %structs;
33
34require Data::Dumper if ($debug);
35
36#
37# read the file and get identifiers
38#
39
40my $is_enum = 0;
41my $is_comment = 0;
42open IN, $file_in or die "Can't open $file_in";
43while (<IN>) {
44 $data .= $_;
45
46 my $ln = $_;
47 if (!$is_comment) {
48 $ln =~ s,/\*.*(\*/),,g;
49
50 $is_comment = 1 if ($ln =~ s,/\*.*,,);
51 } else {
52 if ($ln =~ s,^(.*\*/),,) {
53 $is_comment = 0;
54 } else {
55 next;
56 }
57 }
58
59 if ($is_enum && $ln =~ m/^\s*([_\w][\w\d_]+)\s*[\,=]?/) {
60 my $s = $1;
61 my $n = $1;
62 $n =~ tr/A-Z/a-z/;
63 $n =~ tr/_/-/;
64
65 $enum_symbols{$s} = "\\ :ref:`$s <$n>`\\ ";
66
67 $is_enum = 0 if ($is_enum && m/\}/);
68 next;
69 }
70 $is_enum = 0 if ($is_enum && m/\}/);
71
72 if ($ln =~ m/^\s*#\s*define\s+([_\w][\w\d_]+)\s+_IO/) {
73 my $s = $1;
74 my $n = $1;
75 $n =~ tr/A-Z/a-z/;
76
77 $ioctls{$s} = "\\ :ref:`$s <$n>`\\ ";
78 next;
79 }
80
81 if ($ln =~ m/^\s*#\s*define\s+([_\w][\w\d_]+)\s+/) {
82 my $s = $1;
83 my $n = $1;
84 $n =~ tr/A-Z/a-z/;
85 $n =~ tr/_/-/;
86
87 $defines{$s} = "\\ :ref:`$s <$n>`\\ ";
88 next;
89 }
90
91 if ($ln =~ m/^\s*typedef\s+([_\w][\w\d_]+)\s+(.*)\s+([_\w][\w\d_]+);/) {
92 my $s = $2;
93 my $n = $3;
94
95 $typedefs{$n} = "\\ :c:type:`$n <$s>`\\ ";
96 next;
97 }
98 if ($ln =~ m/^\s*enum\s+([_\w][\w\d_]+)\s+\{/
99 || $ln =~ m/^\s*enum\s+([_\w][\w\d_]+)$/
100 || $ln =~ m/^\s*typedef\s*enum\s+([_\w][\w\d_]+)\s+\{/
101 || $ln =~ m/^\s*typedef\s*enum\s+([_\w][\w\d_]+)$/) {
102 my $s = $1;
103
104 $enums{$s} = "enum :c:type:`$s`\\ ";
105
106 $is_enum = $1;
107 next;
108 }
109 if ($ln =~ m/^\s*struct\s+([_\w][\w\d_]+)\s+\{/
110 || $ln =~ m/^\s*struct\s+([[_\w][\w\d_]+)$/
111 || $ln =~ m/^\s*typedef\s*struct\s+([_\w][\w\d_]+)\s+\{/
112 || $ln =~ m/^\s*typedef\s*struct\s+([[_\w][\w\d_]+)$/
113 ) {
114 my $s = $1;
115
116 $structs{$s} = "struct $s\\ ";
117 next;
118 }
119}
120close IN;
121
122#
123# Handle multi-line typedefs
124#
125
126my @matches = ($data =~ m/typedef\s+struct\s+\S+?\s*\{[^\}]+\}\s*(\S+)\s*\;/g,
127 $data =~ m/typedef\s+enum\s+\S+?\s*\{[^\}]+\}\s*(\S+)\s*\;/g,);
128foreach my $m (@matches) {
129 my $s = $m;
130
131 $typedefs{$s} = "\\ :c:type:`$s`\\ ";
132 next;
133}
134
135#
136# Handle exceptions, if any
137#
138
139my %def_reftype = (
140 "ioctl" => ":ref",
141 "define" => ":ref",
142 "symbol" => ":ref",
143 "typedef" => ":c:type",
144 "enum" => ":c:type",
145 "struct" => ":c:type",
146);
147
148if ($file_exceptions) {
149 open IN, $file_exceptions or die "Can't read $file_exceptions";
150 while (<IN>) {
151 next if (m/^\s*$/ || m/^\s*#/);
152
153 # Parsers to ignore a symbol
154
155 if (m/^ignore\s+ioctl\s+(\S+)/) {
156 delete $ioctls{$1} if (exists($ioctls{$1}));
157 next;
158 }
159 if (m/^ignore\s+define\s+(\S+)/) {
160 delete $defines{$1} if (exists($defines{$1}));
161 next;
162 }
163 if (m/^ignore\s+typedef\s+(\S+)/) {
164 delete $typedefs{$1} if (exists($typedefs{$1}));
165 next;
166 }
167 if (m/^ignore\s+enum\s+(\S+)/) {
168 delete $enums{$1} if (exists($enums{$1}));
169 next;
170 }
171 if (m/^ignore\s+struct\s+(\S+)/) {
172 delete $structs{$1} if (exists($structs{$1}));
173 next;
174 }
175 if (m/^ignore\s+symbol\s+(\S+)/) {
176 delete $enum_symbols{$1} if (exists($enum_symbols{$1}));
177 next;
178 }
179
180 # Parsers to replace a symbol
181 my ($type, $old, $new, $reftype);
182
183 if (m/^replace\s+(\S+)\s+(\S+)\s+(\S+)/) {
184 $type = $1;
185 $old = $2;
186 $new = $3;
187 } else {
188 die "Can't parse $file_exceptions: $_";
189 }
190
191 if ($new =~ m/^\:c\:(data|func|macro|type)\:\`(.+)\`/) {
192 $reftype = ":c:$1";
193 $new = $2;
194 } elsif ($new =~ m/\:ref\:\`(.+)\`/) {
195 $reftype = ":ref";
196 $new = $1;
197 } else {
198 $reftype = $def_reftype{$type};
199 }
200 $new = "$reftype:`$old <$new>`";
201
202 if ($type eq "ioctl") {
203 $ioctls{$old} = $new if (exists($ioctls{$old}));
204 next;
205 }
206 if ($type eq "define") {
207 $defines{$old} = $new if (exists($defines{$old}));
208 next;
209 }
210 if ($type eq "symbol") {
211 $enum_symbols{$old} = $new if (exists($enum_symbols{$old}));
212 next;
213 }
214 if ($type eq "typedef") {
215 $typedefs{$old} = $new if (exists($typedefs{$old}));
216 next;
217 }
218 if ($type eq "enum") {
219 $enums{$old} = $new if (exists($enums{$old}));
220 next;
221 }
222 if ($type eq "struct") {
223 $structs{$old} = $new if (exists($structs{$old}));
224 next;
225 }
226
227 die "Can't parse $file_exceptions: $_";
228 }
229}
230
231if ($debug) {
232 print Data::Dumper->Dump([\%ioctls], [qw(*ioctls)]) if (%ioctls);
233 print Data::Dumper->Dump([\%typedefs], [qw(*typedefs)]) if (%typedefs);
234 print Data::Dumper->Dump([\%enums], [qw(*enums)]) if (%enums);
235 print Data::Dumper->Dump([\%structs], [qw(*structs)]) if (%structs);
236 print Data::Dumper->Dump([\%defines], [qw(*defines)]) if (%defines);
237 print Data::Dumper->Dump([\%enum_symbols], [qw(*enum_symbols)]) if (%enum_symbols);
238}
239
240#
241# Align block
242#
243$data = expand($data);
244$data = " " . $data;
245$data =~ s/\n/\n /g;
246$data =~ s/\n\s+$/\n/g;
247$data =~ s/\n\s+\n/\n\n/g;
248
249#
250# Add escape codes for special characters
251#
252$data =~ s,([\_\`\*\<\>\&\\\\:\/\|\%\$\#\{\}\~\^]),\\$1,g;
253
254$data =~ s,DEPRECATED,**DEPRECATED**,g;
255
256#
257# Add references
258#
259
260my $start_delim = "[ \n\t\(\=\*\@]";
261my $end_delim = "(\\s|,|\\\\=|\\\\:|\\;|\\\)|\\}|\\{)";
262
263foreach my $r (keys %ioctls) {
264 my $s = $ioctls{$r};
265
266 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
267
268 print "$r -> $s\n" if ($debug);
269
270 $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
271}
272
273foreach my $r (keys %defines) {
274 my $s = $defines{$r};
275
276 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
277
278 print "$r -> $s\n" if ($debug);
279
280 $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
281}
282
283foreach my $r (keys %enum_symbols) {
284 my $s = $enum_symbols{$r};
285
286 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
287
288 print "$r -> $s\n" if ($debug);
289
290 $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
291}
292
293foreach my $r (keys %enums) {
294 my $s = $enums{$r};
295
296 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
297
298 print "$r -> $s\n" if ($debug);
299
300 $data =~ s/enum\s+($r)$end_delim/$s$2/g;
301}
302
303foreach my $r (keys %structs) {
304 my $s = $structs{$r};
305
306 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
307
308 print "$r -> $s\n" if ($debug);
309
310 $data =~ s/struct\s+($r)$end_delim/$s$2/g;
311}
312
313foreach my $r (keys %typedefs) {
314 my $s = $typedefs{$r};
315
316 $r =~ s,([\_\`\*\<\>\&\\\\:\/]),\\\\$1,g;
317
318 print "$r -> $s\n" if ($debug);
319 $data =~ s/($start_delim)($r)$end_delim/$1$s$3/g;
320}
321
322$data =~ s/\\ ([\n\s])/\1/g;
323
324#
325# Generate output file
326#
327
328my $title = $file_in;
329$title =~ s,.*/,,;
330
331open OUT, "> $file_out" or die "Can't open $file_out";
332print OUT ".. -*- coding: utf-8; mode: rst -*-\n\n";
333print OUT "$title\n";
334print OUT "=" x length($title);
335print OUT "\n\n.. parsed-literal::\n\n";
336print OUT $data;
337close OUT;
338
339__END__
340
341=head1 NAME
342
343parse_headers.pl - parse a C file, in order to identify functions, structs,
344enums and defines and create cross-references to a Sphinx book.
345
346=head1 SYNOPSIS
347
348B<parse_headers.pl> [<options>] <C_FILE> <OUT_FILE> [<EXCEPTIONS_FILE>]
349
350Where <options> can be: --debug, --help or --usage.
351
352=head1 OPTIONS
353
354=over 8
355
356=item B<--debug>
357
358Put the script in verbose mode, useful for debugging.
359
360=item B<--usage>
361
362Prints a brief help message and exits.
363
364=item B<--help>
365
366Prints a more detailed help message and exits.
367
368=back
369
370=head1 DESCRIPTION
371
372Convert a C header or source file (C_FILE), into a ReStructured Text
373included via ..parsed-literal block with cross-references for the
374documentation files that describe the API. It accepts an optional
375EXCEPTIONS_FILE with describes what elements will be either ignored or
376be pointed to a non-default reference.
377
378The output is written at the (OUT_FILE).
379
380It is capable of identifying defines, functions, structs, typedefs,
381enums and enum symbols and create cross-references for all of them.
382It is also capable of distinguish #define used for specifying a Linux
383ioctl.
384
385The EXCEPTIONS_FILE contain two rules to allow ignoring a symbol or
386to replace the default references by a custom one.
387
388Please read Documentation/doc-guide/parse-headers.rst at the Kernel's
389tree for more details.
390
391=head1 BUGS
392
393Report bugs to Mauro Carvalho Chehab <mchehab@kernel.org>
394
395=head1 COPYRIGHT
396
397Copyright (c) 2016 by Mauro Carvalho Chehab <mchehab@kernel.org>.
398
399License GPLv2: GNU GPL version 2 <https://gnu.org/licenses/gpl.html>.
400
401This is free software: you are free to change and redistribute it.
402There is NO WARRANTY, to the extent permitted by law.
403
404=cut
Documentation/sphinx/templates/kernel-toc.html+2−1
@@ -1,4 +1,5 @@
1<!-- SPDX-License-Identifier: GPL-2.0 -->1{# SPDX-License-Identifier: GPL-2.0 #}
2
2{# Create a local TOC the kernel way #}3{# Create a local TOC the kernel way #}
3<p>4<p>
4<h3 class="kernel-toc-contents">Contents</h3>5<h3 class="kernel-toc-contents">Contents</h3>
Documentation/sphinx/templates/translations.html+2−2
@@ -1,5 +1,5 @@
1<!-- SPDX-License-Identifier: GPL-2.0 -->1{# SPDX-License-Identifier: GPL-2.0 #}
2<!-- Copyright © 2023, Oracle and/or its affiliates. -->2{# Copyright © 2023, Oracle and/or its affiliates. #}
3 3
4{# Create a language menu for translations #}4{# Create a language menu for translations #}
5{% if languages|length > 0: %}5{% if languages|length > 0: %}
Documentation/staging/remoteproc.rst+1−1
@@ -104,7 +104,7 @@ Typical usage · 103 unmodified lines
104 rproc_shutdown(my_rproc);104 rproc_shutdown(my_rproc);
105 }105 }
106 106
107API for implementors107API for implementers
108====================108====================
109 109
110::110::
Documentation/trace/boottime-trace.rst+1−1
@@ -19,7 +19,7 @@ this uses bootconfig file to describe tracing feature programming. · 18 unmodified lines
19Options in the Boot Config19Options in the Boot Config
20==========================20==========================
21 21
22Here is the list of available options list for boot time tracing in22Here is the list of available options for boot time tracing in
23boot config file [1]_. All options are under "ftrace." or "kernel."23boot config file [1]_. All options are under "ftrace." or "kernel."
24prefix. See kernel parameters for the options which starts24prefix. See kernel parameters for the options which starts
25with "kernel." prefix [2]_.25with "kernel." prefix [2]_.
Documentation/trace/debugging.rst+1−1
@@ -59,7 +59,7 @@ There is various methods of acquiring the state of the system when a kernel · 58 unmodified lines
59crash occurs. This could be from the oops message in printk, or one could59crash occurs. This could be from the oops message in printk, or one could
60use kexec/kdump. But these just show what happened at the time of the crash.60use kexec/kdump. But these just show what happened at the time of the crash.
61It can be very useful in knowing what happened up to the point of the crash.61It can be very useful in knowing what happened up to the point of the crash.
62The tracing ring buffer, by default, is a circular buffer than will62The tracing ring buffer, by default, is a circular buffer that will
63overwrite older events with newer ones. When a crash happens, the content of63overwrite older events with newer ones. When a crash happens, the content of
64the ring buffer will be all the events that lead up to the crash.64the ring buffer will be all the events that lead up to the crash.
65 65
Documentation/trace/events.rst+4−4
@@ -629,8 +629,8 @@ following: · 628 unmodified lines
629 - tracing synthetic events from in-kernel code629 - tracing synthetic events from in-kernel code
630 - the low-level "dynevent_cmd" API630 - the low-level "dynevent_cmd" API
631 631
6327.1 Dyamically creating synthetic event definitions6327.1 Dynamically creating synthetic event definitions
633---------------------------------------------------633----------------------------------------------------
634 634
635There are a couple ways to create a new synthetic event from a kernel635There are a couple ways to create a new synthetic event from a kernel
636module or other kernel code.636module or other kernel code.
@@ -944,8 +944,8 @@ Note that synth_event_trace_end() must be called at the end regardless · 307 unmodified lines
944of whether any of the add calls failed (say due to a bad field name944of whether any of the add calls failed (say due to a bad field name
945being passed in).945being passed in).
946 946
9477.3 Dyamically creating kprobe and kretprobe event definitions9477.3 Dynamically creating kprobe and kretprobe event definitions
948--------------------------------------------------------------948---------------------------------------------------------------
949 949
950To create a kprobe or kretprobe trace event from kernel code, the950To create a kprobe or kretprobe trace event from kernel code, the
951kprobe_event_gen_cmd_start() or kretprobe_event_gen_cmd_start()951kprobe_event_gen_cmd_start() or kretprobe_event_gen_cmd_start()
Documentation/trace/fprobe.rst+1−1
@@ -81,7 +81,7 @@ Same as ftrace, the registered callbacks will start being called some time · 80 unmodified lines
81after the register_fprobe() is called and before it returns. See81after the register_fprobe() is called and before it returns. See
82:file:`Documentation/trace/ftrace.rst`.82:file:`Documentation/trace/ftrace.rst`.
83 83
84Also, the unregister_fprobe() will guarantee that the both enter and exit84Also, the unregister_fprobe() will guarantee that both enter and exit
85handlers are no longer being called by functions after unregister_fprobe()85handlers are no longer being called by functions after unregister_fprobe()
86returns as same as unregister_ftrace_function().86returns as same as unregister_ftrace_function().
87 87
Documentation/trace/ftrace-uses.rst+1−1
@@ -193,7 +193,7 @@ FTRACE_OPS_FL_RECURSION · 192 unmodified lines
193 Note, if this flag is set, then the callback will always be called193 Note, if this flag is set, then the callback will always be called
194 with preemption disabled. If it is not set, then it is possible194 with preemption disabled. If it is not set, then it is possible
195 (but not guaranteed) that the callback will be called in195 (but not guaranteed) that the callback will be called in
196 preemptable context.196 preemptible context.
197 197
198FTRACE_OPS_FL_IPMODIFY198FTRACE_OPS_FL_IPMODIFY
199 Requires FTRACE_OPS_FL_SAVE_REGS set. If the callback is to "hijack"199 Requires FTRACE_OPS_FL_SAVE_REGS set. If the callback is to "hijack"
Documentation/trace/ftrace.rst+7−7
@@ -30,7 +30,7 @@ disabled and enabled, as well as for preemption and from a time · 29 unmodified lines
30a task is woken to the task is actually scheduled in.30a task is woken to the task is actually scheduled in.
31 31
32One of the most common uses of ftrace is the event tracing.32One of the most common uses of ftrace is the event tracing.
33Throughout the kernel is hundreds of static event points that33Throughout the kernel are hundreds of static event points that
34can be enabled via the tracefs file system to see what is34can be enabled via the tracefs file system to see what is
35going on in certain parts of the kernel.35going on in certain parts of the kernel.
36 36
@@ -383,7 +383,7 @@ of ftrace. Here is a list of some of the key files: · 346 unmodified lines
383 not be listed in this count.383 not be listed in this count.
384 384
385 If the callback registered to be traced by a function with385 If the callback registered to be traced by a function with
386 the "save regs" attribute (thus even more overhead), a 'R'386 the "save regs" attribute (thus even more overhead), an 'R'
387 will be displayed on the same line as the function that387 will be displayed on the same line as the function that
388 is returning registers.388 is returning registers.
389 389
@@ -392,7 +392,7 @@ of ftrace. Here is a list of some of the key files: · 2 unmodified lines
392 an 'I' will be displayed on the same line as the function that392 an 'I' will be displayed on the same line as the function that
393 can be overridden.393 can be overridden.
394 394
395 If a non ftrace trampoline is attached (BPF) a 'D' will be displayed.395 If a non-ftrace trampoline is attached (BPF) a 'D' will be displayed.
396 Note, normal ftrace trampolines can also be attached, but only one396 Note, normal ftrace trampolines can also be attached, but only one
397 "direct" trampoline can be attached to a given function at a time.397 "direct" trampoline can be attached to a given function at a time.
398 398
@@ -402,7 +402,7 @@ of ftrace. Here is a list of some of the key files: · 3 unmodified lines
402 402
403 If a function had either the "ip modify" or a "direct" call attached to403 If a function had either the "ip modify" or a "direct" call attached to
404 it in the past, a 'M' will be shown. This flag is never cleared. It is404 it in the past, a 'M' will be shown. This flag is never cleared. It is
405 used to know if a function was every modified by the ftrace infrastructure,405 used to know if a function was ever modified by the ftrace infrastructure,
406 and can be used for debugging.406 and can be used for debugging.
407 407
408 If the architecture supports it, it will also show what callback408 If the architecture supports it, it will also show what callback
@@ -418,7 +418,7 @@ of ftrace. Here is a list of some of the key files: · 9 unmodified lines
418 418
419 This file contains all the functions that ever had a function callback419 This file contains all the functions that ever had a function callback
420 to it via the ftrace infrastructure. It has the same format as420 to it via the ftrace infrastructure. It has the same format as
421 enabled_functions but shows all functions that have every been421 enabled_functions but shows all functions that have ever been
422 traced.422 traced.
423 423
424 To see any function that has every been modified by "ip modify" or a424 To see any function that has every been modified by "ip modify" or a
@@ -517,7 +517,7 @@ of ftrace. Here is a list of some of the key files: · 92 unmodified lines
517 Whenever an event is recorded into the ring buffer, a517 Whenever an event is recorded into the ring buffer, a
518 "timestamp" is added. This stamp comes from a specified518 "timestamp" is added. This stamp comes from a specified
519 clock. By default, ftrace uses the "local" clock. This519 clock. By default, ftrace uses the "local" clock. This
520 clock is very fast and strictly per cpu, but on some520 clock is very fast and strictly per CPU, but on some
521 systems it may not be monotonic with respect to other521 systems it may not be monotonic with respect to other
522 CPUs. In other words, the local clocks may not be in sync522 CPUs. In other words, the local clocks may not be in sync
523 with local clocks on other CPUs.523 with local clocks on other CPUs.
@@ -868,7 +868,7 @@ Here is the list of current tracers that may be configured. · 344 unmodified lines
868 868
869 "mmiotrace"869 "mmiotrace"
870 870
871 A special tracer that is used to trace binary module.871 A special tracer that is used to trace binary modules.
872 It will trace all the calls that a module makes to the872 It will trace all the calls that a module makes to the
873 hardware. Everything it writes and reads from the I/O873 hardware. Everything it writes and reads from the I/O
874 as well.874 as well.
Documentation/trace/histogram-design.rst+89−86
@@ -11,13 +11,14 @@ histograms work and how the individual pieces map to the data · 10 unmodified lines
11structures used to implement them in trace_events_hist.c and11structures used to implement them in trace_events_hist.c and
12tracing_map.c.12tracing_map.c.
13 13
14Note: All the ftrace histogram command examples assume the working14.. note::
15 directory is the ftrace /tracing directory. For example::15 All the ftrace histogram command examples assume the working
16 directory is the ftrace /tracing directory. For example::
16 17
17 # cd /sys/kernel/tracing18 # cd /sys/kernel/tracing
18 19
19Also, the histogram output displayed for those commands will be20 Also, the histogram output displayed for those commands will be
20generally be truncated - only enough to make the point is displayed.21 generally be truncated - only enough to make the point is displayed.
21 22
22'hist_debug' trace event files23'hist_debug' trace event files
23==============================24==============================
@@ -142,30 +143,30 @@ elements for a couple hypothetical keys and values.:: · 118 unmodified lines
142 +--------------+ | |143 +--------------+ | |
143 n_keys = n_fields - n_vals | |144 n_keys = n_fields - n_vals | |
144 145
145The hist_data n_vals and n_fields delineate the extent of the fields[] | |146The hist_data n_vals and n_fields delineate the extent of the fields[]
146array and separate keys from values for the rest of the code. | |147array and separate keys from values for the rest of the code.
147 148
148Below is a run-time representation of the tracing_map part of the | |149Below is a run-time representation of the tracing_map part of the
149histogram, with pointers from various parts of the fields[] array | |150histogram, with pointers from various parts of the fields[] array
150to corresponding parts of the tracing_map. | |151to corresponding parts of the tracing_map.
151 152
152The tracing_map consists of an array of tracing_map_entrys and a set | |153The tracing_map consists of an array of tracing_map_entrys and a set
153of preallocated tracing_map_elts (abbreviated below as map_entry and | |154of preallocated tracing_map_elts (abbreviated below as map_entry and
154map_elt). The total number of map_entrys in the hist_data.map array = | |155map_elt). The total number of map_entrys in the hist_data.map array =
155map->max_elts (actually map->map_size but only max_elts of those are | |156map->max_elts (actually map->map_size but only max_elts of those are
156used. This is a property required by the map_insert() algorithm). | |157used. This is a property required by the map_insert() algorithm).
157 158
158If a map_entry is unused, meaning no key has yet hashed into it, its | |159If a map_entry is unused, meaning no key has yet hashed into it, its
159.key value is 0 and its .val pointer is NULL. Once a map_entry has | |160.key value is 0 and its .val pointer is NULL. Once a map_entry has
160been claimed, the .key value contains the key's hash value and the | |161been claimed, the .key value contains the key's hash value and the
161.val member points to a map_elt containing the full key and an entry | |162.val member points to a map_elt containing the full key and an entry
162for each key or value in the map_elt.fields[] array. There is an | |163for each key or value in the map_elt.fields[] array. There is an
163entry in the map_elt.fields[] array corresponding to each hist_field | |164entry in the map_elt.fields[] array corresponding to each hist_field
164in the histogram, and this is where the continually aggregated sums | |165in the histogram, and this is where the continually aggregated sums
165corresponding to each histogram value are kept. | |166corresponding to each histogram value are kept.
166 167
167The diagram attempts to show the relationship between the | |168The diagram attempts to show the relationship between the
168hist_data.fields[] and the map_elt.fields[] with the links drawn | |169hist_data.fields[] and the map_elt.fields[] with the links drawn
169between diagrams::170between diagrams::
170 171
171 +-----------+ | |172 +-----------+ | |
@@ -380,7 +381,9 @@ entry, ts0, corresponding to the ts0 variable in the sched_waking · 208 unmodified lines
380trigger above.381trigger above.
381 382
382sched_waking histogram383sched_waking histogram
383----------------------::384----------------------
385
386.. code-block::
384 387
385 +------------------+388 +------------------+
386 | hist_data |<-------------------------------------------------------+389 | hist_data |<-------------------------------------------------------+
@@ -440,31 +443,31 @@ sched_waking histogram · 53 unmodified lines
440 n_keys = n_fields - n_vals | | |443 n_keys = n_fields - n_vals | | |
441 | | |444 | | |
442 445
443This is very similar to the basic case. In the above diagram, we can | | |446This is very similar to the basic case. In the above diagram, we can
444see a new .flags member has been added to the struct hist_field | | |447see a new .flags member has been added to the struct hist_field
445struct, and a new entry added to hist_data.fields representing the ts0 | | |448struct, and a new entry added to hist_data.fields representing the ts0
446variable. For a normal val hist_field, .flags is just 0 (modulo | | |449variable. For a normal val hist_field, .flags is just 0 (modulo
447modifier flags), but if the value is defined as a variable, the .flags | | |450modifier flags), but if the value is defined as a variable, the .flags
448contains a set FL_VAR bit. | | |451contains a set FL_VAR bit.
449 452
450As you can see, the ts0 entry's .var.idx member contains the index | | |453As you can see, the ts0 entry's .var.idx member contains the index
451into the tracing_map_elts' .vars[] array containing variable values. | | |454into the tracing_map_elts' .vars[] array containing variable values.
452This idx is used whenever the value of the variable is set or read. | | |455This idx is used whenever the value of the variable is set or read.
453The map_elt.vars idx assigned to the given variable is assigned and | | |456The map_elt.vars idx assigned to the given variable is assigned and
454saved in .var.idx by create_tracing_map_fields() after it calls | | |457saved in .var.idx by create_tracing_map_fields() after it calls
455tracing_map_add_var(). | | |458tracing_map_add_var().
456 459
457Below is a representation of the histogram at run-time, which | | |460Below is a representation of the histogram at run-time, which
458populates the map, along with correspondence to the above hist_data and | | |461populates the map, along with correspondence to the above hist_data and
459hist_field data structures. | | |462hist_field data structures.
460 463
461The diagram attempts to show the relationship between the | | |464The diagram attempts to show the relationship between the
462hist_data.fields[] and the map_elt.fields[] and map_elt.vars[] with | | |465hist_data.fields[] and the map_elt.fields[] and map_elt.vars[] with
463the links drawn between diagrams. For each of the map_elts, you can | | |466the links drawn between diagrams. For each of the map_elts, you can
464see that the .fields[] members point to the .sum or .offset of a key | | |467see that the .fields[] members point to the .sum or .offset of a key
465or val and the .vars[] members point to the value of a variable. The | | |468or val and the .vars[] members point to the value of a variable. The
466arrows between the two diagrams show the linkages between those | | |469arrows between the two diagrams show the linkages between those
467tracing_map members and the field definitions in the corresponding | | |470tracing_map members and the field definitions in the corresponding
468hist_data fields[] members.::471hist_data fields[] members.::
469 472
470 +-----------+ | | |473 +-----------+ | | |
@@ -565,40 +568,40 @@ hist_data fields[] members.:: · 94 unmodified lines
565 | | | |568 | | | |
566 +---------------+ | |569 +---------------+ | |
567 570
568For each used map entry, there's a map_elt pointing to an array of | |571For each used map entry, there's a map_elt pointing to an array of
569.vars containing the current value of the variables associated with | |572.vars containing the current value of the variables associated with
570that histogram entry. So in the above, the timestamp associated with | |573that histogram entry. So in the above, the timestamp associated with
571pid 999 is 113345679876, and the timestamp variable in the same | |574pid 999 is 113345679876, and the timestamp variable in the same
572.var.idx for pid 4444 is 213499240729. | |575.var.idx for pid 4444 is 213499240729.
573 576
574sched_switch histogram | |577sched_switch histogram
575---------------------- | |578----------------------
576 579
577The sched_switch histogram paired with the above sched_waking | |580The sched_switch histogram paired with the above sched_waking
578histogram is shown below. The most important aspect of the | |581histogram is shown below. The most important aspect of the
579sched_switch histogram is that it references a variable on the | |582sched_switch histogram is that it references a variable on the
580sched_waking histogram above. | |583sched_waking histogram above.
581 584
582The histogram diagram is very similar to the others so far displayed, | |585The histogram diagram is very similar to the others so far displayed,
583but it adds variable references. You can see the normal hitcount and | |586but it adds variable references. You can see the normal hitcount and
584key fields along with a new wakeup_lat variable implemented in the | |587key fields along with a new wakeup_lat variable implemented in the
585same way as the sched_waking ts0 variable, but in addition there's an | |588same way as the sched_waking ts0 variable, but in addition there's an
586entry with the new FL_VAR_REF (short for HIST_FIELD_FL_VAR_REF) flag. | |589entry with the new FL_VAR_REF (short for HIST_FIELD_FL_VAR_REF) flag.
587 590
588Associated with the new var ref field are a couple of new hist_field | |591Associated with the new var ref field are a couple of new hist_field
589members, var.hist_data and var_ref_idx. For a variable reference, the | |592members, var.hist_data and var_ref_idx. For a variable reference, the
590var.hist_data goes with the var.idx, which together uniquely identify | |593var.hist_data goes with the var.idx, which together uniquely identify
591a particular variable on a particular histogram. The var_ref_idx is | |594a particular variable on a particular histogram. The var_ref_idx is
592just the index into the var_ref_vals[] array that caches the values of | |595just the index into the var_ref_vals[] array that caches the values of
593each variable whenever a hist trigger is updated. Those resulting | |596each variable whenever a hist trigger is updated. Those resulting
594values are then finally accessed by other code such as trace action | |597values are then finally accessed by other code such as trace action
595code that uses the var_ref_idx values to assign param values. | |598code that uses the var_ref_idx values to assign param values.
596 599
597The diagram below describes the situation for the sched_switch | |600The diagram below describes the situation for the sched_switch
598histogram referred to before::601histogram referred to before::
599 602
600 # echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0' >> | |603 # echo 'hist:keys=next_pid:wakeup_lat=common_timestamp.usecs-$ts0' >>
601 events/sched/sched_switch/trigger | |604 events/sched/sched_switch/trigger
602 | |605 | |
603 +------------------+ | |606 +------------------+ | |
604 | hist_data | | |607 | hist_data | | |
Documentation/trace/histogram.rst+20−20
@@ -186,8 +186,8 @@ Documentation written by Tom Zanussi · 185 unmodified lines
186 The examples below provide a more concrete illustration of the186 The examples below provide a more concrete illustration of the
187 concepts and typical usage patterns discussed above.187 concepts and typical usage patterns discussed above.
188 188
189'special' event fields1892.1. 'special' event fields
190------------------------190---------------------------
191 191
192 There are a number of 'special event fields' available for use as192 There are a number of 'special event fields' available for use as
193 keys or values in a hist trigger. These look like and behave as if193 keys or values in a hist trigger. These look like and behave as if
@@ -204,16 +204,16 @@ Documentation written by Tom Zanussi · 10 unmodified lines
204 common_cpu int the cpu on which the event occurred.204 common_cpu int the cpu on which the event occurred.
205 ====================== ==== =======================================205 ====================== ==== =======================================
206 206
207Extended error information2072.2. Extended error information
208--------------------------208-------------------------------
209 209
210 For some error conditions encountered when invoking a hist trigger210 For some error conditions encountered when invoking a hist trigger
211 command, extended error information is available via the211 command, extended error information is available via the
212 tracing/error_log file. See Error Conditions in212 tracing/error_log file. See "Error conditions" section in
213 :file:`Documentation/trace/ftrace.rst` for details.213 Documentation/trace/ftrace.rst for details.
214 214
2156.2 'hist' trigger examples2152.3. 'hist' trigger examples
216---------------------------216----------------------------
217 217
218 The first set of examples creates aggregations using the kmalloc218 The first set of examples creates aggregations using the kmalloc
219 event. The fields that can be used for the hist trigger are listed219 event. The fields that can be used for the hist trigger are listed
@@ -840,7 +840,7 @@ Extended error information · 620 unmodified lines
840 840
841 The compound key examples used a key and a sum value (hitcount) to841 The compound key examples used a key and a sum value (hitcount) to
842 sort the output, but we can just as easily use two keys instead.842 sort the output, but we can just as easily use two keys instead.
843 Here's an example where we use a compound key composed of the the843 Here's an example where we use a compound key composed of the
844 common_pid and size event fields. Sorting with pid as the primary844 common_pid and size event fields. Sorting with pid as the primary
845 key and 'size' as the secondary key allows us to display an845 key and 'size' as the secondary key allows us to display an
846 ordered summary of the recvfrom sizes, with counts, received by846 ordered summary of the recvfrom sizes, with counts, received by
@@ -1608,8 +1608,8 @@ Extended error information · 761 unmodified lines
1608 Entries: 71608 Entries: 7
1609 Dropped: 01609 Dropped: 0
1610 1610
16112.2 Inter-event hist triggers16112.4. Inter-event hist triggers
1612-----------------------------1612------------------------------
1613 1613
1614Inter-event hist triggers are hist triggers that combine values from1614Inter-event hist triggers are hist triggers that combine values from
1615one or more other events and create a histogram using that data. Data1615one or more other events and create a histogram using that data. Data
@@ -1685,8 +1685,8 @@ pseudo-file. · 69 unmodified lines
1685 1685
1686These features are described in more detail in the following sections.1686These features are described in more detail in the following sections.
1687 1687
16882.2.1 Histogram Variables16882.5. Histogram Variables
1689-------------------------1689------------------------
1690 1690
1691Variables are simply named locations used for saving and retrieving1691Variables are simply named locations used for saving and retrieving
1692values between matching events. A 'matching' event is defined as an1692values between matching events. A 'matching' event is defined as an
@@ -1789,8 +1789,8 @@ or assigned to a variable and referenced in a subsequent expression:: · 96 unmodified lines
1789 1789
1790Variables can even hold stacktraces, which are useful with synthetic events.1790Variables can even hold stacktraces, which are useful with synthetic events.
1791 1791
17922.2.2 Synthetic Events17922.6. Synthetic Events
1793----------------------1793---------------------
1794 1794
1795Synthetic events are user-defined events generated from hist trigger1795Synthetic events are user-defined events generated from hist trigger
1796variables or fields associated with one or more other events. Their1796variables or fields associated with one or more other events. Their
@@ -1846,7 +1846,7 @@ the command that defined it with a '!':: · 49 unmodified lines
1846At this point, there isn't yet an actual 'wakeup_latency' event1846At this point, there isn't yet an actual 'wakeup_latency' event
1847instantiated in the event subsystem - for this to happen, a 'hist1847instantiated in the event subsystem - for this to happen, a 'hist
1848trigger action' needs to be instantiated and bound to actual fields1848trigger action' needs to be instantiated and bound to actual fields
1849and variables defined on other events (see Section 2.2.3 below on1849and variables defined on other events (see Section 2.7. below on
1850how that is done using hist trigger 'onmatch' action). Once that is1850how that is done using hist trigger 'onmatch' action). Once that is
1851done, the 'wakeup_latency' synthetic event instance is created.1851done, the 'wakeup_latency' synthetic event instance is created.
1852 1852
@@ -2094,8 +2094,8 @@ histogram:: · 241 unmodified lines
2094 Entries: 72094 Entries: 7
2095 Dropped: 02095 Dropped: 0
2096 2096
20972.2.3 Hist trigger 'handlers' and 'actions'20972.7. Hist trigger 'handlers' and 'actions'
2098-------------------------------------------2098------------------------------------------
2099 2099
2100A hist trigger 'action' is a function that's executed (in most cases2100A hist trigger 'action' is a function that's executed (in most cases
2101conditionally) whenever a histogram entry is added or updated.2101conditionally) whenever a histogram entry is added or updated.
@@ -2526,8 +2526,8 @@ The following commonly-used handler.action pairs are available: · 424 unmodified lines
2526 kworker/3:2-135 [003] d..3 49.823123: sched_switch: prev_comm=kworker/3:2 prev_pid=135 prev_prio=120 prev_state=T ==> next_comm=swapper/3 next_pid=0 next_prio=1202526 kworker/3:2-135 [003] d..3 49.823123: sched_switch: prev_comm=kworker/3:2 prev_pid=135 prev_prio=120 prev_state=T ==> next_comm=swapper/3 next_pid=0 next_prio=120
2527 <idle>-0 [004] ..s7 49.823798: tcp_probe: src=10.0.0.10:54326 dest=23.215.104.193:80 mark=0x0 length=32 snd_nxt=0xe3ae2ff5 snd_una=0xe3ae2ecd snd_cwnd=10 ssthresh=2147483647 snd_wnd=28960 srtt=19604 rcv_wnd=293122527 <idle>-0 [004] ..s7 49.823798: tcp_probe: src=10.0.0.10:54326 dest=23.215.104.193:80 mark=0x0 length=32 snd_nxt=0xe3ae2ff5 snd_una=0xe3ae2ecd snd_cwnd=10 ssthresh=2147483647 snd_wnd=28960 srtt=19604 rcv_wnd=29312
2528 2528
25293. User space creating a trigger25292.8. User space creating a trigger
2530--------------------------------2530----------------------------------
2531 2531
2532Writing into /sys/kernel/tracing/trace_marker writes into the ftrace2532Writing into /sys/kernel/tracing/trace_marker writes into the ftrace
2533ring buffer. This can also act like an event, by writing into the trigger2533ring buffer. This can also act like an event, by writing into the trigger
Documentation/trace/rv/monitor_synthesis.rst+1−1
@@ -181,7 +181,7 @@ which is the list of atomic propositions present in the LTL specification · 180 unmodified lines
181functions interacting with the Buchi automaton.181functions interacting with the Buchi automaton.
182 182
183While generating code, `rvgen` cannot understand the meaning of the atomic183While generating code, `rvgen` cannot understand the meaning of the atomic
184propositions. Thus, that task is left for manual work. The recommended pratice184propositions. Thus, that task is left for manual work. The recommended practice
185is adding tracepoints to places where the atomic propositions change; and in the185is adding tracepoints to places where the atomic propositions change; and in the
186tracepoints' handlers: the Buchi automaton is executed using::186tracepoints' handlers: the Buchi automaton is executed using::
187 187
Documentation/translations/it_IT/process/changes.rst+0−14
@@ -46,7 +46,6 @@ util-linux 2.10o mount --version · 45 unmodified lines
46kmod 13 depmod -V46kmod 13 depmod -V
47e2fsprogs 1.41.4 e2fsck -V47e2fsprogs 1.41.4 e2fsck -V
48jfsutils 1.1.3 fsck.jfs -V48jfsutils 1.1.3 fsck.jfs -V
49reiserfsprogs 3.6.3 reiserfsck -V
50xfsprogs 2.6.0 xfs_db -V49xfsprogs 2.6.0 xfs_db -V
51squashfs-tools 4.0 mksquashfs -version50squashfs-tools 4.0 mksquashfs -version
52btrfs-progs 0.18 btrfsck51btrfs-progs 0.18 btrfsck
@@ -260,14 +259,6 @@ Sono disponibili i seguenti strumenti: · 207 unmodified lines
260 259
261- sono disponibili altri strumenti per il file-system.260- sono disponibili altri strumenti per il file-system.
262 261
263Reiserfsprogs
264-------------
265
266Il pacchetto reiserfsprogs dovrebbe essere usato con reiserfs-3.6.x (Linux
267kernel 2.4.x). Questo è un pacchetto combinato che contiene versioni
268funzionanti di ``mkreiserfs``, ``resize_reiserfs``, ``debugreiserfs`` e
269``reiserfsck``. Questi programmi funzionano sulle piattaforme i386 e alpha.
270
271Xfsprogs262Xfsprogs
272--------263--------
273 264
@@ -479,11 +470,6 @@ JFSutils · 205 unmodified lines
479 470
480- <https://jfs.sourceforge.net/>471- <https://jfs.sourceforge.net/>
481 472
482Reiserfsprogs
483-------------
484
485- <https://git.kernel.org/pub/scm/linux/kernel/git/jeffm/reiserfsprogs.git/>
486
487Xfsprogs473Xfsprogs
488--------474--------
489 475
Documentation/userspace-api/media/Makefile+0−64
@@ -1,64 +0,0 @@
1# SPDX-License-Identifier: GPL-2.0
2
3# Rules to convert a .h file to inline RST documentation
4
5SRC_DIR=$(srctree)/Documentation/userspace-api/media
6PARSER = $(srctree)/Documentation/sphinx/parse-headers.pl
7UAPI = $(srctree)/include/uapi/linux
8KAPI = $(srctree)/include/linux
9
10FILES = ca.h.rst dmx.h.rst frontend.h.rst net.h.rst \
11 videodev2.h.rst media.h.rst cec.h.rst lirc.h.rst
12
13TARGETS := $(addprefix $(BUILDDIR)/, $(FILES))
14
15gen_rst = \
16 echo ${PARSER} $< $@ $(SRC_DIR)/$(notdir $@).exceptions; \
17 ${PARSER} $< $@ $(SRC_DIR)/$(notdir $@).exceptions
18
19quiet_gen_rst = echo ' PARSE $(patsubst $(srctree)/%,%,$<)'; \
20 ${PARSER} $< $@ $(SRC_DIR)/$(notdir $@).exceptions
21
22silent_gen_rst = ${gen_rst}
23
24$(BUILDDIR)/ca.h.rst: ${UAPI}/dvb/ca.h ${PARSER} $(SRC_DIR)/ca.h.rst.exceptions
25 @$($(quiet)gen_rst)
26
27$(BUILDDIR)/dmx.h.rst: ${UAPI}/dvb/dmx.h ${PARSER} $(SRC_DIR)/dmx.h.rst.exceptions
28 @$($(quiet)gen_rst)
29
30$(BUILDDIR)/frontend.h.rst: ${UAPI}/dvb/frontend.h ${PARSER} $(SRC_DIR)/frontend.h.rst.exceptions
31 @$($(quiet)gen_rst)
32
33$(BUILDDIR)/net.h.rst: ${UAPI}/dvb/net.h ${PARSER} $(SRC_DIR)/net.h.rst.exceptions
34 @$($(quiet)gen_rst)
35
36$(BUILDDIR)/videodev2.h.rst: ${UAPI}/videodev2.h ${PARSER} $(SRC_DIR)/videodev2.h.rst.exceptions
37 @$($(quiet)gen_rst)
38
39$(BUILDDIR)/media.h.rst: ${UAPI}/media.h ${PARSER} $(SRC_DIR)/media.h.rst.exceptions
40 @$($(quiet)gen_rst)
41
42$(BUILDDIR)/cec.h.rst: ${UAPI}/cec.h ${PARSER} $(SRC_DIR)/cec.h.rst.exceptions
43 @$($(quiet)gen_rst)
44
45$(BUILDDIR)/lirc.h.rst: ${UAPI}/lirc.h ${PARSER} $(SRC_DIR)/lirc.h.rst.exceptions
46 @$($(quiet)gen_rst)
47
48# Media build rules
49
50.PHONY: all html texinfo epub xml latex
51
52all: $(IMGDOT) $(BUILDDIR) ${TARGETS}
53html: all
54texinfo: all
55epub: all
56xml: all
57latex: $(IMGPDF) all
58linkcheck:
59
60clean:
61 -rm -f $(DOTTGT) $(IMGTGT) ${TARGETS} 2>/dev/null
62
63$(BUILDDIR):
64 $(Q)mkdir -p $@
Documentation/userspace-api/media/cec/cec-header.rst+3−2
@@ -6,5 +6,6 @@ · 5 unmodified lines
6CEC Header File6CEC Header File
7***************7***************
8 8
9.. kernel-include:: $BUILDDIR/cec.h.rst9.. kernel-include:: include/uapi/linux/cec.h
10 10 :generate-cross-refs:
11 :exception-file: cec.h.rst.exceptions
Documentation/userspace-api/media/cec/cec.h.rst.exceptionsrenamed from Documentation/userspace-api/media/cec.h.rst.exceptions+0−0

File renamed without changes.

Documentation/userspace-api/media/dvb/ca.h.rst.exceptionsrenamed from Documentation/userspace-api/media/ca.h.rst.exceptions+0−0

File renamed without changes.

Documentation/userspace-api/media/dvb/dmx.h.rst.exceptionsrenamed from Documentation/userspace-api/media/dmx.h.rst.exceptions+0−0

File renamed without changes.

Documentation/userspace-api/media/dvb/frontend.h.rst.exceptionsrenamed from Documentation/userspace-api/media/frontend.h.rst.exceptions+0−0

File renamed without changes.

Documentation/userspace-api/media/dvb/headers.rst+13−4
@@ -7,10 +7,19 @@ Digital TV uAPI header files · 6 unmodified lines
7Digital TV uAPI headers7Digital TV uAPI headers
8***********************8***********************
9 9
10.. kernel-include:: $BUILDDIR/frontend.h.rst10.. kernel-include:: include/uapi/linux/dvb/frontend.h
11 :generate-cross-refs:
12 :exception-file: frontend.h.rst.exceptions
11 13
12.. kernel-include:: $BUILDDIR/dmx.h.rst14.. kernel-include:: include/uapi/linux/dvb/dmx.h
15 :generate-cross-refs:
16 :exception-file: dmx.h.rst.exceptions
13 17
14.. kernel-include:: $BUILDDIR/ca.h.rst18.. kernel-include:: include/uapi/linux/dvb/ca.h
19 :generate-cross-refs:
20 :exception-file: ca.h.rst.exceptions
21
22.. kernel-include:: include/uapi/linux/dvb/net.h
23 :generate-cross-refs:
24 :exception-file: net.h.rst.exceptions
15 25
16.. kernel-include:: $BUILDDIR/net.h.rst
Documentation/userspace-api/media/dvb/net.h.rst.exceptionsrenamed from Documentation/userspace-api/media/net.h.rst.exceptions+0−0

File renamed without changes.

Documentation/userspace-api/media/mediactl/media-header.rst+3−2
@@ -6,5 +6,6 @@ · 5 unmodified lines
6Media Controller Header File6Media Controller Header File
7****************************7****************************
8 8
9.. kernel-include:: $BUILDDIR/media.h.rst9.. kernel-include:: include/uapi/linux/media.h
10 10 :generate-cross-refs:
11 :exception-file: media.h.rst.exceptions
Documentation/userspace-api/media/mediactl/media.h.rst.exceptionsrenamed from Documentation/userspace-api/media/media.h.rst.exceptions+0−0

File renamed without changes.

Documentation/userspace-api/media/rc/lirc-header.rst+3−1
@@ -6,5 +6,7 @@ · 5 unmodified lines
6LIRC Header File6LIRC Header File
7****************7****************
8 8
9.. kernel-include:: $BUILDDIR/lirc.h.rst9.. kernel-include:: include/uapi/linux/lirc.h
10 :generate-cross-refs:
11 :exception-file: lirc.h.rst.exceptions
10 12
Documentation/userspace-api/media/rc/lirc.h.rst.exceptionsrenamed from Documentation/userspace-api/media/lirc.h.rst.exceptions+0−0

File renamed without changes.

Documentation/userspace-api/media/v4l/videodev.rst+3−1
@@ -6,4 +6,6 @@ · 5 unmodified lines
6Video For Linux Two Header File6Video For Linux Two Header File
7*******************************7*******************************
8 8
9.. kernel-include:: $BUILDDIR/videodev2.h.rst9.. kernel-include:: include/uapi/linux/videodev2.h
10 :generate-cross-refs:
11 :exception-file: videodev2.h.rst.exceptions
Documentation/userspace-api/media/v4l/videodev2.h.rst.exceptionsrenamed from Documentation/userspace-api/media/videodev2.h.rst.exceptions+0−0

File renamed without changes.

Documentation/virt/kvm/review-checklist.rst+1−1
@@ -98,7 +98,7 @@ New APIs · 97 unmodified lines
98 It is important to demonstrate your use case. This can be as simple as98 It is important to demonstrate your use case. This can be as simple as
99 explaining that the feature is already in use on bare metal, or it can be99 explaining that the feature is already in use on bare metal, or it can be
100 a proof-of-concept implementation in userspace. The latter need not be100 a proof-of-concept implementation in userspace. The latter need not be
101 open source, though that is of course preferrable for easier testing.101 open source, though that is of course preferable for easier testing.
102 Selftests should test corner cases of the APIs, and should also cover102 Selftests should test corner cases of the APIs, and should also cover
103 basic host and guest operation if no open source VMM uses the feature.103 basic host and guest operation if no open source VMM uses the feature.
104 104
Documentation/w1/masters/ds2482.rst+1−1
@@ -22,7 +22,7 @@ Description · 21 unmodified lines
22-----------22-----------
23 23
24The Maxim/Dallas Semiconductor DS2482 is a I2C device that provides24The Maxim/Dallas Semiconductor DS2482 is a I2C device that provides
25one (DS2482-100) or eight (DS2482-800) 1-wire busses.25one (DS2482-100) or eight (DS2482-800) 1-wire buses.
26 26
27 27
28General Remarks28General Remarks
Documentation/w1/masters/index.rst+1−1
@@ -1,4 +1,4 @@
1. SPDX-License-Identifier: GPL-2.01.. SPDX-License-Identifier: GPL-2.0
2 2
3=====================3=====================
41-wire Master Drivers41-wire Master Drivers
Documentation/w1/slaves/index.rst+1−1
@@ -1,4 +1,4 @@
1. SPDX-License-Identifier: GPL-2.01.. SPDX-License-Identifier: GPL-2.0
2 2
3====================3====================
41-wire Slave Drivers41-wire Slave Drivers
MAINTAINERS+3−0
@@ -7384,11 +7384,13 @@ P: Documentation/doc-guide/maintainer-profile.rst · 7383 unmodified lines
7384T: git git://git.lwn.net/linux.git docs-next7384T: git git://git.lwn.net/linux.git docs-next
7385F: Documentation/7385F: Documentation/
7386F: scripts/check-variable-fonts.sh7386F: scripts/check-variable-fonts.sh
7387F: scripts/checktransupdate.py
7387F: scripts/documentation-file-ref-check7388F: scripts/documentation-file-ref-check
7388F: scripts/get_abi.py7389F: scripts/get_abi.py
7389F: scripts/kernel-doc*7390F: scripts/kernel-doc*
7390F: scripts/lib/abi/*7391F: scripts/lib/abi/*
7391F: scripts/lib/kdoc/*7392F: scripts/lib/kdoc/*
7393F: tools/docs/*
7392F: tools/net/ynl/pyynl/lib/doc_generator.py7394F: tools/net/ynl/pyynl/lib/doc_generator.py
7393F: scripts/sphinx-pre-install7395F: scripts/sphinx-pre-install
7394X: Documentation/ABI/7396X: Documentation/ABI/
@@ -14323,6 +14325,7 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/rcu/linux.git rcu/dev · 6928 unmodified lines
14323F: Documentation/atomic_bitops.txt14325F: Documentation/atomic_bitops.txt
14324F: Documentation/atomic_t.txt14326F: Documentation/atomic_t.txt
14325F: Documentation/core-api/refcount-vs-atomic.rst14327F: Documentation/core-api/refcount-vs-atomic.rst
14328F: Documentation/dev-tools/lkmm/
14326F: Documentation/litmus-tests/14329F: Documentation/litmus-tests/
14327F: Documentation/memory-barriers.txt14330F: Documentation/memory-barriers.txt
14328F: tools/memory-model/14331F: tools/memory-model/
Makefile+3−2
@@ -1797,8 +1797,9 @@ $(help-board-dirs): help-%: · 1796 unmodified lines
1797 1797
1798# Documentation targets1798# Documentation targets
1799# ---------------------------------------------------------------------------1799# ---------------------------------------------------------------------------
1800DOC_TARGETS := xmldocs latexdocs pdfdocs htmldocs epubdocs cleandocs \1800DOC_TARGETS := xmldocs latexdocs pdfdocs htmldocs htmldocs-redirects \
1801 linkcheckdocs dochelp refcheckdocs texinfodocs infodocs1801 epubdocs cleandocs linkcheckdocs dochelp refcheckdocs \
1802 texinfodocs infodocs
1802PHONY += $(DOC_TARGETS)1803PHONY += $(DOC_TARGETS)
1803$(DOC_TARGETS):1804$(DOC_TARGETS):
1804 $(Q)$(MAKE) $(build)=Documentation $@1805 $(Q)$(MAKE) $(build)=Documentation $@
fs/btrfs/tree-log.c+1−1
@@ -5829,7 +5829,7 @@ struct btrfs_dir_list { · 5828 unmodified lines
5829 * See process_dir_items_leaf() for details about why it is needed.5829 * See process_dir_items_leaf() for details about why it is needed.
5830 * This is a recursive operation - if an existing dentry corresponds to a5830 * This is a recursive operation - if an existing dentry corresponds to a
5831 * directory, that directory's new entries are logged too (same behaviour as5831 * directory, that directory's new entries are logged too (same behaviour as
5832 * ext3/4, xfs, f2fs, reiserfs, nilfs2). Note that when logging the inodes5832 * ext3/4, xfs, f2fs, nilfs2). Note that when logging the inodes
5833 * the dentries point to we do not acquire their VFS lock, otherwise lockdep5833 * the dentries point to we do not acquire their VFS lock, otherwise lockdep
5834 * complains about the following circular lock dependency / possible deadlock:5834 * complains about the following circular lock dependency / possible deadlock:
5835 *5835 *
scripts/kernel-doc.py+24−10
@@ -2,8 +2,17 @@ · 1 unmodified line
2# SPDX-License-Identifier: GPL-2.02# SPDX-License-Identifier: GPL-2.0
3# Copyright(c) 2025: Mauro Carvalho Chehab <mchehab@kernel.org>.3# Copyright(c) 2025: Mauro Carvalho Chehab <mchehab@kernel.org>.
4#4#
5# pylint: disable=C0103,R09155# pylint: disable=C0103,R0912,R0914,R0915
6#6
7# NOTE: While kernel-doc requires at least version 3.6 to run, the
8# command line should work with Python 3.2+ (tested with 3.4).
9# The rationale is that it shall fail gracefully during Kernel
10# compilation with older Kernel versions. Due to that:
11# - encoding line is needed here;
12# - no f-strings can be used on this file.
13# - the libraries that require newer versions can only be included
14# after Python version is checked.
15
7# Converted from the kernel-doc script originally written in Perl16# Converted from the kernel-doc script originally written in Perl
8# under GPLv2, copyrighted since 1998 by the following authors:17# under GPLv2, copyrighted since 1998 by the following authors:
9#18#
@@ -107,9 +116,6 @@ SRC_DIR = os.path.dirname(os.path.realpath(__file__)) · 97 unmodified lines
107 116
108sys.path.insert(0, os.path.join(SRC_DIR, LIB_DIR))117sys.path.insert(0, os.path.join(SRC_DIR, LIB_DIR))
109 118
110from kdoc_files import KernelFiles # pylint: disable=C0413
111from kdoc_output import RestFormat, ManFormat # pylint: disable=C0413
112
113DESC = """119DESC = """
114Read C language source or header FILEs, extract embedded documentation comments,120Read C language source or header FILEs, extract embedded documentation comments,
115and print formatted documentation to standard output.121and print formatted documentation to standard output.
@@ -273,14 +279,22 @@ def main(): · 157 unmodified lines
273 279
274 python_ver = sys.version_info[:2]280 python_ver = sys.version_info[:2]
275 if python_ver < (3,6):281 if python_ver < (3,6):
276 logger.warning("Python 3.6 or later is required by kernel-doc")282 # Depending on Kernel configuration, kernel-doc --none is called at
283 # build time. As we don't want to break compilation due to the
284 # usage of an old Python version, return 0 here.
285 if args.none:
286 logger.error("Python 3.6 or later is required by kernel-doc. skipping checks")
287 sys.exit(0)
277 288
278 # Return 0 here to avoid breaking compilation289 sys.exit("Python 3.6 or later is required by kernel-doc. Aborting.")
279 sys.exit(0)
280 290
281 if python_ver < (3,7):291 if python_ver < (3,7):
282 logger.warning("Python 3.7 or later is required for correct results")292 logger.warning("Python 3.7 or later is required for correct results")
283 293
294 # Import kernel-doc libraries only after checking Python version
295 from kdoc_files import KernelFiles # pylint: disable=C0415
296 from kdoc_output import RestFormat, ManFormat # pylint: disable=C0415
297
284 if args.man:298 if args.man:
285 out_style = ManFormat(modulename=args.modulename)299 out_style = ManFormat(modulename=args.modulename)
286 elif args.none:300 elif args.none:
@@ -308,11 +322,11 @@ def main(): · 21 unmodified lines
308 sys.exit(0)322 sys.exit(0)
309 323
310 if args.werror:324 if args.werror:
311 print(f"{error_count} warnings as errors")325 print("%s warnings as errors" % error_count) # pylint: disable=C0209
312 sys.exit(error_count)326 sys.exit(error_count)
313 327
314 if args.verbose:328 if args.verbose:
315 print(f"{error_count} errors")329 print("%s errors" % error_count) # pylint: disable=C0209
316 330
317 if args.none:331 if args.none:
318 sys.exit(0)332 sys.exit(0)
scripts/lib/kdoc/kdoc_parser.py+414−434
@@ -46,7 +46,7 @@ doc_decl = doc_com + KernRe(r'(\w+)', cache=False) · 45 unmodified lines
46known_section_names = 'description|context|returns?|notes?|examples?'46known_section_names = 'description|context|returns?|notes?|examples?'
47known_sections = KernRe(known_section_names, flags = re.I)47known_sections = KernRe(known_section_names, flags = re.I)
48doc_sect = doc_com + \48doc_sect = doc_com + \
49 KernRe(r'\s*(\@[.\w]+|\@\.\.\.|' + known_section_names + r')\s*:([^:].*)?$',49 KernRe(r'\s*(@[.\w]+|@\.\.\.|' + known_section_names + r')\s*:([^:].*)?$',
50 flags=re.I, cache=False)50 flags=re.I, cache=False)
51 51
52doc_content = doc_com_body + KernRe(r'(.*)', cache=False)52doc_content = doc_com_body + KernRe(r'(.*)', cache=False)
@@ -54,13 +54,11 @@ doc_inline_start = KernRe(r'^\s*/\*\*\s*$', cache=False) · 1 unmodified line
54doc_inline_sect = KernRe(r'\s*\*\s*(@\s*[\w][\w\.]*\s*):(.*)', cache=False)54doc_inline_sect = KernRe(r'\s*\*\s*(@\s*[\w][\w\.]*\s*):(.*)', cache=False)
55doc_inline_end = KernRe(r'^\s*\*/\s*$', cache=False)55doc_inline_end = KernRe(r'^\s*\*/\s*$', cache=False)
56doc_inline_oneline = KernRe(r'^\s*/\*\*\s*(@[\w\s]+):\s*(.*)\s*\*/\s*$', cache=False)56doc_inline_oneline = KernRe(r'^\s*/\*\*\s*(@[\w\s]+):\s*(.*)\s*\*/\s*$', cache=False)
57attribute = KernRe(r"__attribute__\s*\(\([a-z0-9,_\*\s\(\)]*\)\)",
58 flags=re.I | re.S, cache=False)
59 57
60export_symbol = KernRe(r'^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*', cache=False)58export_symbol = KernRe(r'^\s*EXPORT_SYMBOL(_GPL)?\s*\(\s*(\w+)\s*\)\s*', cache=False)
61export_symbol_ns = KernRe(r'^\s*EXPORT_SYMBOL_NS(_GPL)?\s*\(\s*(\w+)\s*,\s*"\S+"\)\s*', cache=False)59export_symbol_ns = KernRe(r'^\s*EXPORT_SYMBOL_NS(_GPL)?\s*\(\s*(\w+)\s*,\s*"\S+"\)\s*', cache=False)
62 60
63type_param = KernRe(r"\@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)", cache=False)61type_param = KernRe(r"@(\w*((\.\w+)|(->\w+))*(\.\.\.)?)", cache=False)
64 62
65#63#
66# Tests for the beginning of a kerneldoc block in its various forms.64# Tests for the beginning of a kerneldoc block in its various forms.
@@ -74,6 +72,133 @@ doc_begin_func = KernRe(str(doc_com) + # initial " * ' · 7 unmodified lines
74 r'(?:[-:].*)?$', # description (not captured)72 r'(?:[-:].*)?$', # description (not captured)
75 cache = False)73 cache = False)
76 74
75#
76# Here begins a long set of transformations to turn structure member prefixes
77# and macro invocations into something we can parse and generate kdoc for.
78#
79struct_args_pattern = r'([^,)]+)'
80
81struct_xforms = [
82 # Strip attributes
83 (KernRe(r"__attribute__\s*\(\([a-z0-9,_\*\s\(\)]*\)\)", flags=re.I | re.S, cache=False), ' '),
84 (KernRe(r'\s*__aligned\s*\([^;]*\)', re.S), ' '),
85 (KernRe(r'\s*__counted_by\s*\([^;]*\)', re.S), ' '),
86 (KernRe(r'\s*__counted_by_(le|be)\s*\([^;]*\)', re.S), ' '),
87 (KernRe(r'\s*__packed\s*', re.S), ' '),
88 (KernRe(r'\s*CRYPTO_MINALIGN_ATTR', re.S), ' '),
89 (KernRe(r'\s*____cacheline_aligned_in_smp', re.S), ' '),
90 (KernRe(r'\s*____cacheline_aligned', re.S), ' '),
91 (KernRe(r'\s*__cacheline_group_(begin|end)\([^\)]+\);'), ''),
92 #
93 # Unwrap struct_group macros based on this definition:
94 # __struct_group(TAG, NAME, ATTRS, MEMBERS...)
95 # which has variants like: struct_group(NAME, MEMBERS...)
96 # Only MEMBERS arguments require documentation.
97 #
98 # Parsing them happens on two steps:
99 #
100 # 1. drop struct group arguments that aren't at MEMBERS,
101 # storing them as STRUCT_GROUP(MEMBERS)
102 #
103 # 2. remove STRUCT_GROUP() ancillary macro.
104 #
105 # The original logic used to remove STRUCT_GROUP() using an
106 # advanced regex:
107 #
108 # \bSTRUCT_GROUP(\(((?:(?>[^)(]+)|(?1))*)\))[^;]*;
109 #
110 # with two patterns that are incompatible with
111 # Python re module, as it has:
112 #
113 # - a recursive pattern: (?1)
114 # - an atomic grouping: (?>...)
115 #
116 # I tried a simpler version: but it didn't work either:
117 # \bSTRUCT_GROUP\(([^\)]+)\)[^;]*;
118 #
119 # As it doesn't properly match the end parenthesis on some cases.
120 #
121 # So, a better solution was crafted: there's now a NestedMatch
122 # class that ensures that delimiters after a search are properly
123 # matched. So, the implementation to drop STRUCT_GROUP() will be
124 # handled in separate.
125 #
126 (KernRe(r'\bstruct_group\s*\(([^,]*,)', re.S), r'STRUCT_GROUP('),
127 (KernRe(r'\bstruct_group_attr\s*\(([^,]*,){2}', re.S), r'STRUCT_GROUP('),
128 (KernRe(r'\bstruct_group_tagged\s*\(([^,]*),([^,]*),', re.S), r'struct \1 \2; STRUCT_GROUP('),
129 (KernRe(r'\b__struct_group\s*\(([^,]*,){3}', re.S), r'STRUCT_GROUP('),
130 #
131 # Replace macros
132 #
133 # TODO: use NestedMatch for FOO($1, $2, ...) matches
134 #
135 # it is better to also move those to the NestedMatch logic,
136 # to ensure that parenthesis will be properly matched.
137 #
138 (KernRe(r'__ETHTOOL_DECLARE_LINK_MODE_MASK\s*\(([^\)]+)\)', re.S),
139 r'DECLARE_BITMAP(\1, __ETHTOOL_LINK_MODE_MASK_NBITS)'),
140 (KernRe(r'DECLARE_PHY_INTERFACE_MASK\s*\(([^\)]+)\)', re.S),
141 r'DECLARE_BITMAP(\1, PHY_INTERFACE_MODE_MAX)'),
142 (KernRe(r'DECLARE_BITMAP\s*\(' + struct_args_pattern + r',\s*' + struct_args_pattern + r'\)',
143 re.S), r'unsigned long \1[BITS_TO_LONGS(\2)]'),
144 (KernRe(r'DECLARE_HASHTABLE\s*\(' + struct_args_pattern + r',\s*' + struct_args_pattern + r'\)',
145 re.S), r'unsigned long \1[1 << ((\2) - 1)]'),
146 (KernRe(r'DECLARE_KFIFO\s*\(' + struct_args_pattern + r',\s*' + struct_args_pattern +
147 r',\s*' + struct_args_pattern + r'\)', re.S), r'\2 *\1'),
148 (KernRe(r'DECLARE_KFIFO_PTR\s*\(' + struct_args_pattern + r',\s*' +
149 struct_args_pattern + r'\)', re.S), r'\2 *\1'),
150 (KernRe(r'(?:__)?DECLARE_FLEX_ARRAY\s*\(' + struct_args_pattern + r',\s*' +
151 struct_args_pattern + r'\)', re.S), r'\1 \2[]'),
152 (KernRe(r'DEFINE_DMA_UNMAP_ADDR\s*\(' + struct_args_pattern + r'\)', re.S), r'dma_addr_t \1'),
153 (KernRe(r'DEFINE_DMA_UNMAP_LEN\s*\(' + struct_args_pattern + r'\)', re.S), r'__u32 \1'),
154]
155#
156# Regexes here are guaranteed to have the end limiter matching
157# the start delimiter. Yet, right now, only one replace group
158# is allowed.
159#
160struct_nested_prefixes = [
161 (re.compile(r'\bSTRUCT_GROUP\('), r'\1'),
162]
163
164#
165# Transforms for function prototypes
166#
167function_xforms = [
168 (KernRe(r"^static +"), ""),
169 (KernRe(r"^extern +"), ""),
170 (KernRe(r"^asmlinkage +"), ""),
171 (KernRe(r"^inline +"), ""),
172 (KernRe(r"^__inline__ +"), ""),
173 (KernRe(r"^__inline +"), ""),
174 (KernRe(r"^__always_inline +"), ""),
175 (KernRe(r"^noinline +"), ""),
176 (KernRe(r"^__FORTIFY_INLINE +"), ""),
177 (KernRe(r"__init +"), ""),
178 (KernRe(r"__init_or_module +"), ""),
179 (KernRe(r"__deprecated +"), ""),
180 (KernRe(r"__flatten +"), ""),
181 (KernRe(r"__meminit +"), ""),
182 (KernRe(r"__must_check +"), ""),
183 (KernRe(r"__weak +"), ""),
184 (KernRe(r"__sched +"), ""),
185 (KernRe(r"_noprof"), ""),
186 (KernRe(r"__printf\s*\(\s*\d*\s*,\s*\d*\s*\) +"), ""),
187 (KernRe(r"__(?:re)?alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\) +"), ""),
188 (KernRe(r"__diagnose_as\s*\(\s*\S+\s*(?:,\s*\d+\s*)*\) +"), ""),
189 (KernRe(r"DECL_BUCKET_PARAMS\s*\(\s*(\S+)\s*,\s*(\S+)\s*\)"), r"\1, \2"),
190 (KernRe(r"__attribute_const__ +"), ""),
191 (KernRe(r"__attribute__\s*\(\((?:[\w\s]+(?:\([^)]*\))?\s*,?)+\)\)\s+"), ""),
192]
193
194#
195# Apply a set of transforms to a block of text.
196#
197def apply_transforms(xforms, text):
198 for search, subst in xforms:
199 text = search.sub(subst, text)
200 return text
201
77#202#
78# A little helper to get rid of excess white space203# A little helper to get rid of excess white space
79#204#
@@ -81,6 +206,21 @@ multi_space = KernRe(r'\s\s+') · 1 unmodified line
81def trim_whitespace(s):206def trim_whitespace(s):
82 return multi_space.sub(' ', s.strip())207 return multi_space.sub(' ', s.strip())
83 208
209#
210# Remove struct/enum members that have been marked "private".
211#
212def trim_private_members(text):
213 #
214 # First look for a "public:" block that ends a private region, then
215 # handle the "private until the end" case.
216 #
217 text = KernRe(r'/\*\s*private:.*?/\*\s*public:.*?\*/', flags=re.S).sub('', text)
218 text = KernRe(r'/\*\s*private:.*', flags=re.S).sub('', text)
219 #
220 # We needed the comments to do the above, but now we can take them out.
221 #
222 return KernRe(r'\s*/\*.*?\*/\s*', flags=re.S).sub('', text).strip()
223
84class state:224class state:
85 """225 """
86 State machine enums226 State machine enums
@@ -318,36 +458,26 @@ class KernelDoc: · 231 unmodified lines
318 458
319 param = KernRe(r'[\[\)].*').sub('', param, count=1)459 param = KernRe(r'[\[\)].*').sub('', param, count=1)
320 460
321 if dtype == "" and param.endswith("..."):461 #
322 if KernRe(r'\w\.\.\.$').search(param):462 # Look at various "anonymous type" cases.
323 # For named variable parameters of the form `x...`,463 #
324 # remove the dots464 if dtype == '':
325 param = param[:-3]465 if param.endswith("..."):
326 else:466 if len(param) > 3: # there is a name provided, use that
327 # Handles unnamed variable parameters467 param = param[:-3]
328 param = "..."468 if not self.entry.parameterdescs.get(param):
329 469 self.entry.parameterdescs[param] = "variable arguments"
330 if param not in self.entry.parameterdescs or \470
331 not self.entry.parameterdescs[param]:471 elif (not param) or param == "void":
332 472 param = "void"
333 self.entry.parameterdescs[param] = "variable arguments"473 self.entry.parameterdescs[param] = "no arguments"
334 474
335 elif dtype == "" and (not param or param == "void"):475 elif param in ["struct", "union"]:
336 param = "void"476 # Handle unnamed (anonymous) union or struct
337 self.entry.parameterdescs[param] = "no arguments"477 dtype = param
338 478 param = "{unnamed_" + param + "}"
339 elif dtype == "" and param in ["struct", "union"]:479 self.entry.parameterdescs[param] = "anonymous\n"
340 # Handle unnamed (anonymous) union or struct480 self.entry.anon_struct_union = True
341 dtype = param
342 param = "{unnamed_" + param + "}"
343 self.entry.parameterdescs[param] = "anonymous\n"
344 self.entry.anon_struct_union = True
345
346 # Handle cache group enforcing variables: they do not need
347 # to be described in header files
348 elif "__cacheline_group" in param:
349 # Ignore __cacheline_group_begin and __cacheline_group_end
350 return
351 481
352 # Warn if parameter has no description482 # Warn if parameter has no description
353 # (but ignore ones starting with # as these are not parameters483 # (but ignore ones starting with # as these are not parameters
@@ -389,9 +519,6 @@ class KernelDoc: · 35 unmodified lines
389 args = arg_expr.sub(r"\1#", args)519 args = arg_expr.sub(r"\1#", args)
390 520
391 for arg in args.split(splitter):521 for arg in args.split(splitter):
392 # Strip comments
393 arg = KernRe(r'\/\*.*\*\/').sub('', arg)
394
395 # Ignore argument attributes522 # Ignore argument attributes
396 arg = KernRe(r'\sPOS0?\s').sub(' ', arg)523 arg = KernRe(r'\sPOS0?\s').sub(' ', arg)
397 524
@@ -407,81 +534,76 @@ class KernelDoc: · 9 unmodified lines
407 # Treat preprocessor directive as a typeless variable534 # Treat preprocessor directive as a typeless variable
408 self.push_parameter(ln, decl_type, arg, "",535 self.push_parameter(ln, decl_type, arg, "",
409 "", declaration_name)536 "", declaration_name)
410 537 #
538 # The pointer-to-function case.
539 #
411 elif KernRe(r'\(.+\)\s*\(').search(arg):540 elif KernRe(r'\(.+\)\s*\(').search(arg):
412 # Pointer-to-function
413
414 arg = arg.replace('#', ',')541 arg = arg.replace('#', ',')
415 542 r = KernRe(r'[^\(]+\(\*?\s*' # Everything up to "(*"
416 r = KernRe(r'[^\(]+\(\*?\s*([\w\[\]\.]*)\s*\)')543 r'([\w\[\].]*)' # Capture the name and possible [array]
544 r'\s*\)') # Make sure the trailing ")" is there
417 if r.match(arg):545 if r.match(arg):
418 param = r.group(1)546 param = r.group(1)
419 else:547 else:
420 self.emit_msg(ln, f"Invalid param: {arg}")548 self.emit_msg(ln, f"Invalid param: {arg}")
421 param = arg549 param = arg
422 550 dtype = arg.replace(param, '')
423 dtype = KernRe(r'([^\(]+\(\*?)\s*' + re.escape(param)).sub(r'\1', arg)551 self.push_parameter(ln, decl_type, param, dtype, arg, declaration_name)
424 self.push_parameter(ln, decl_type, param, dtype,552 #
425 arg, declaration_name)553 # The array-of-pointers case. Dig the parameter name out from the middle
426 554 # of the declaration.
555 #
427 elif KernRe(r'\(.+\)\s*\[').search(arg):556 elif KernRe(r'\(.+\)\s*\[').search(arg):
428 # Array-of-pointers557 r = KernRe(r'[^\(]+\(\s*\*\s*' # Up to "(" and maybe "*"
429 558 r'([\w.]*?)' # The actual pointer name
430 arg = arg.replace('#', ',')559 r'\s*(\[\s*\w+\s*\]\s*)*\)') # The [array portion]
431 r = KernRe(r'[^\(]+\(\s*\*\s*([\w\[\]\.]*?)\s*(\s*\[\s*[\w]+\s*\]\s*)*\)')
432 if r.match(arg):560 if r.match(arg):
433 param = r.group(1)561 param = r.group(1)
434 else:562 else:
435 self.emit_msg(ln, f"Invalid param: {arg}")563 self.emit_msg(ln, f"Invalid param: {arg}")
436 param = arg564 param = arg
437 565 dtype = arg.replace(param, '')
438 dtype = KernRe(r'([^\(]+\(\*?)\s*' + re.escape(param)).sub(r'\1', arg)566 self.push_parameter(ln, decl_type, param, dtype, arg, declaration_name)
439
440 self.push_parameter(ln, decl_type, param, dtype,
441 arg, declaration_name)
442
443 elif arg:567 elif arg:
568 #
569 # Clean up extraneous spaces and split the string at commas; the first
570 # element of the resulting list will also include the type information.
571 #
444 arg = KernRe(r'\s*:\s*').sub(":", arg)572 arg = KernRe(r'\s*:\s*').sub(":", arg)
445 arg = KernRe(r'\s*\[').sub('[', arg)573 arg = KernRe(r'\s*\[').sub('[', arg)
446
447 args = KernRe(r'\s*,\s*').split(arg)574 args = KernRe(r'\s*,\s*').split(arg)
448 if args[0] and '*' in args[0]:575 args[0] = re.sub(r'(\*+)\s*', r' \1', args[0])
449 args[0] = re.sub(r'(\*+)\s*', r' \1', args[0])576 #
450 577 # args[0] has a string of "type a". If "a" includes an [array]
451 first_arg = []578 # declaration, we want to not be fooled by any white space inside
452 r = KernRe(r'^(.*\s+)(.*?\[.*\].*)$')579 # the brackets, so detect and handle that case specially.
453 if args[0] and r.match(args[0]):580 #
454 args.pop(0)581 r = KernRe(r'^([^[\]]*\s+)(.*)$')
455 first_arg.extend(r.group(1))582 if r.match(args[0]):
456 first_arg.append(r.group(2))583 args[0] = r.group(2)
584 dtype = r.group(1)
457 else:585 else:
458 first_arg = KernRe(r'\s+').split(args.pop(0))586 # No space in args[0]; this seems wrong but preserves previous behavior
459 587 dtype = ''
460 args.insert(0, first_arg.pop())
461 dtype = ' '.join(first_arg)
462 588
589 bitfield_re = KernRe(r'(.*?):(\w+)')
463 for param in args:590 for param in args:
464 if KernRe(r'^(\*+)\s*(.*)').match(param):591 #
465 r = KernRe(r'^(\*+)\s*(.*)')592 # For pointers, shift the star(s) from the variable name to the
466 if not r.match(param):593 # type declaration.
467 self.emit_msg(ln, f"Invalid param: {param}")594 #
468 continue595 r = KernRe(r'^(\*+)\s*(.*)')
469 596 if r.match(param):
470 param = r.group(1)
471
472 self.push_parameter(ln, decl_type, r.group(2),597 self.push_parameter(ln, decl_type, r.group(2),
473 f"{dtype} {r.group(1)}",598 f"{dtype} {r.group(1)}",
474 arg, declaration_name)599 arg, declaration_name)
475 600 #
476 elif KernRe(r'(.*?):(\w+)').search(param):601 # Perform a similar shift for bitfields.
477 r = KernRe(r'(.*?):(\w+)')602 #
478 if not r.match(param):603 elif bitfield_re.search(param):
479 self.emit_msg(ln, f"Invalid param: {param}")
480 continue
481
482 if dtype != "": # Skip unnamed bit-fields604 if dtype != "": # Skip unnamed bit-fields
483 self.push_parameter(ln, decl_type, r.group(1),605 self.push_parameter(ln, decl_type, bitfield_re.group(1),
484 f"{dtype}:{r.group(2)}",606 f"{dtype}:{bitfield_re.group(2)}",
485 arg, declaration_name)607 arg, declaration_name)
486 else:608 else:
487 self.push_parameter(ln, decl_type, param, dtype,609 self.push_parameter(ln, decl_type, param, dtype,
@@ -520,13 +642,11 @@ class KernelDoc: · 32 unmodified lines
520 self.emit_msg(ln,642 self.emit_msg(ln,
521 f"No description found for return value of '{declaration_name}'")643 f"No description found for return value of '{declaration_name}'")
522 644
523 def dump_struct(self, ln, proto):645 #
524 """646 # Split apart a structure prototype; returns (struct|union, name, members) or None
525 Store an entry for an struct or union647 #
526 """648 def split_struct_proto(self, proto):
527
528 type_pattern = r'(struct|union)'649 type_pattern = r'(struct|union)'
529
530 qualifiers = [650 qualifiers = [
531 "__attribute__",651 "__attribute__",
532 "__packed",652 "__packed",
@@ -534,288 +654,202 @@ class KernelDoc: · 1 unmodified line
534 "____cacheline_aligned_in_smp",654 "____cacheline_aligned_in_smp",
535 "____cacheline_aligned",655 "____cacheline_aligned",
536 ]656 ]
537
538 definition_body = r'\{(.*)\}\s*' + "(?:" + '|'.join(qualifiers) + ")?"657 definition_body = r'\{(.*)\}\s*' + "(?:" + '|'.join(qualifiers) + ")?"
539 struct_members = KernRe(type_pattern + r'([^\{\};]+)(\{)([^\{\}]*)(\})([^\{\}\;]*)(\;)')
540
541 # Extract struct/union definition
542 members = None
543 declaration_name = None
544 decl_type = None
545 658
546 r = KernRe(type_pattern + r'\s+(\w+)\s*' + definition_body)659 r = KernRe(type_pattern + r'\s+(\w+)\s*' + definition_body)
547 if r.search(proto):660 if r.search(proto):
548 decl_type = r.group(1)661 return (r.group(1), r.group(2), r.group(3))
549 declaration_name = r.group(2)
550 members = r.group(3)
551 else:662 else:
552 r = KernRe(r'typedef\s+' + type_pattern + r'\s*' + definition_body + r'\s*(\w+)\s*;')663 r = KernRe(r'typedef\s+' + type_pattern + r'\s*' + definition_body + r'\s*(\w+)\s*;')
553
554 if r.search(proto):664 if r.search(proto):
555 decl_type = r.group(1)665 return (r.group(1), r.group(3), r.group(2))
556 declaration_name = r.group(3)666 return None
557 members = r.group(2)667 #
558 668 # Rewrite the members of a structure or union for easier formatting later on.
559 if not members:669 # Among other things, this function will turn a member like:
560 self.emit_msg(ln, f"{proto} error: Cannot parse struct or union!")670 #
561 return671 # struct { inner_members; } foo;
562 672 #
563 if self.entry.identifier != declaration_name:673 # into:
564 self.emit_msg(ln,674 #
565 f"expecting prototype for {decl_type} {self.entry.identifier}. Prototype was for {decl_type} {declaration_name} instead\n")675 # struct foo; inner_members;
566 return676 #
567 677 def rewrite_struct_members(self, members):
568 args_pattern = r'([^,)]+)'
569
570 sub_prefixes = [
571 (KernRe(r'\/\*\s*private:.*?\/\*\s*public:.*?\*\/', re.S | re.I), ''),
572 (KernRe(r'\/\*\s*private:.*', re.S | re.I), ''),
573
574 # Strip comments
575 (KernRe(r'\/\*.*?\*\/', re.S), ''),
576
577 # Strip attributes
578 (attribute, ' '),
579 (KernRe(r'\s*__aligned\s*\([^;]*\)', re.S), ' '),
580 (KernRe(r'\s*__counted_by\s*\([^;]*\)', re.S), ' '),
581 (KernRe(r'\s*__counted_by_(le|be)\s*\([^;]*\)', re.S), ' '),
582 (KernRe(r'\s*__packed\s*', re.S), ' '),
583 (KernRe(r'\s*CRYPTO_MINALIGN_ATTR', re.S), ' '),
584 (KernRe(r'\s*____cacheline_aligned_in_smp', re.S), ' '),
585 (KernRe(r'\s*____cacheline_aligned', re.S), ' '),
586
587 # Unwrap struct_group macros based on this definition:
588 # __struct_group(TAG, NAME, ATTRS, MEMBERS...)
589 # which has variants like: struct_group(NAME, MEMBERS...)
590 # Only MEMBERS arguments require documentation.
591 #
592 # Parsing them happens on two steps:
593 #
594 # 1. drop struct group arguments that aren't at MEMBERS,
595 # storing them as STRUCT_GROUP(MEMBERS)
596 #
597 # 2. remove STRUCT_GROUP() ancillary macro.
598 #
599 # The original logic used to remove STRUCT_GROUP() using an
600 # advanced regex:
601 #
602 # \bSTRUCT_GROUP(\(((?:(?>[^)(]+)|(?1))*)\))[^;]*;
603 #
604 # with two patterns that are incompatible with
605 # Python re module, as it has:
606 #
607 # - a recursive pattern: (?1)
608 # - an atomic grouping: (?>...)
609 #
610 # I tried a simpler version: but it didn't work either:
611 # \bSTRUCT_GROUP\(([^\)]+)\)[^;]*;
612 #
613 # As it doesn't properly match the end parenthesis on some cases.
614 #
615 # So, a better solution was crafted: there's now a NestedMatch
616 # class that ensures that delimiters after a search are properly
617 # matched. So, the implementation to drop STRUCT_GROUP() will be
618 # handled in separate.
619
620 (KernRe(r'\bstruct_group\s*\(([^,]*,)', re.S), r'STRUCT_GROUP('),
621 (KernRe(r'\bstruct_group_attr\s*\(([^,]*,){2}', re.S), r'STRUCT_GROUP('),
622 (KernRe(r'\bstruct_group_tagged\s*\(([^,]*),([^,]*),', re.S), r'struct \1 \2; STRUCT_GROUP('),
623 (KernRe(r'\b__struct_group\s*\(([^,]*,){3}', re.S), r'STRUCT_GROUP('),
624
625 # Replace macros
626 #
627 # TODO: use NestedMatch for FOO($1, $2, ...) matches
628 #
629 # it is better to also move those to the NestedMatch logic,
630 # to ensure that parenthesis will be properly matched.
631
632 (KernRe(r'__ETHTOOL_DECLARE_LINK_MODE_MASK\s*\(([^\)]+)\)', re.S), r'DECLARE_BITMAP(\1, __ETHTOOL_LINK_MODE_MASK_NBITS)'),
633 (KernRe(r'DECLARE_PHY_INTERFACE_MASK\s*\(([^\)]+)\)', re.S), r'DECLARE_BITMAP(\1, PHY_INTERFACE_MODE_MAX)'),
634 (KernRe(r'DECLARE_BITMAP\s*\(' + args_pattern + r',\s*' + args_pattern + r'\)', re.S), r'unsigned long \1[BITS_TO_LONGS(\2)]'),
635 (KernRe(r'DECLARE_HASHTABLE\s*\(' + args_pattern + r',\s*' + args_pattern + r'\)', re.S), r'unsigned long \1[1 << ((\2) - 1)]'),
636 (KernRe(r'DECLARE_KFIFO\s*\(' + args_pattern + r',\s*' + args_pattern + r',\s*' + args_pattern + r'\)', re.S), r'\2 *\1'),
637 (KernRe(r'DECLARE_KFIFO_PTR\s*\(' + args_pattern + r',\s*' + args_pattern + r'\)', re.S), r'\2 *\1'),
638 (KernRe(r'(?:__)?DECLARE_FLEX_ARRAY\s*\(' + args_pattern + r',\s*' + args_pattern + r'\)', re.S), r'\1 \2[]'),
639 (KernRe(r'DEFINE_DMA_UNMAP_ADDR\s*\(' + args_pattern + r'\)', re.S), r'dma_addr_t \1'),
640 (KernRe(r'DEFINE_DMA_UNMAP_LEN\s*\(' + args_pattern + r'\)', re.S), r'__u32 \1'),
641 (KernRe(r'VIRTIO_DECLARE_FEATURES\s*\(' + args_pattern + r'\)', re.S), r'u64 \1; u64 \1_array[VIRTIO_FEATURES_DWORDS]'),
642 ]
643
644 # Regexes here are guaranteed to have the end limiter matching
645 # the start delimiter. Yet, right now, only one replace group
646 # is allowed.
647
648 sub_nested_prefixes = [
649 (re.compile(r'\bSTRUCT_GROUP\('), r'\1'),
650 ]
651
652 for search, sub in sub_prefixes:
653 members = search.sub(sub, members)
654
655 nested = NestedMatch()
656
657 for search, sub in sub_nested_prefixes:
658 members = nested.sub(search, sub, members)
659
660 # Keeps the original declaration as-is
661 declaration = members
662
663 # Split nested struct/union elements
664 #
665 # This loop was simpler at the original kernel-doc perl version, as
666 # while ($members =~ m/$struct_members/) { ... }
667 # reads 'members' string on each interaction.
668 #
669 # Python behavior is different: it parses 'members' only once,
670 # creating a list of tuples from the first interaction.
671 #678 #
672 # On other words, this won't get nested structs.679 # Process struct/union members from the most deeply nested outward. The
680 # trick is in the ^{ below - it prevents a match of an outer struct/union
681 # until the inner one has been munged (removing the "{" in the process).
673 #682 #
674 # So, we need to have an extra loop on Python to override such683 struct_members = KernRe(r'(struct|union)' # 0: declaration type
675 # re limitation.684 r'([^\{\};]+)' # 1: possible name
676 685 r'(\{)'
677 while True:686 r'([^\{\}]*)' # 3: Contents of declaration
678 tuples = struct_members.findall(members)687 r'(\})'
679 if not tuples:688 r'([^\{\};]*)(;)') # 5: Remaining stuff after declaration
680 break689 tuples = struct_members.findall(members)
681 690 while tuples:
682 for t in tuples:691 for t in tuples:
683 newmember = ""692 newmember = ""
684 maintype = t[0]693 oldmember = "".join(t) # Reconstruct the original formatting
685 s_ids = t[5]694 dtype, name, lbr, content, rbr, rest, semi = t
686 content = t[3]695 #
687 696 # Pass through each field name, normalizing the form and formatting.
688 oldmember = "".join(t)697 #
689 698 for s_id in rest.split(','):
690 for s_id in s_ids.split(','):
691 s_id = s_id.strip()699 s_id = s_id.strip()
692 700 newmember += f"{dtype} {s_id}; "
693 newmember += f"{maintype} {s_id}; "701 #
702 # Remove bitfield/array/pointer info, getting the bare name.
703 #
694 s_id = KernRe(r'[:\[].*').sub('', s_id)704 s_id = KernRe(r'[:\[].*').sub('', s_id)
695 s_id = KernRe(r'^\s*\**(\S+)\s*').sub(r'\1', s_id)705 s_id = KernRe(r'^\s*\**(\S+)\s*').sub(r'\1', s_id)
696 706 #
707 # Pass through the members of this inner structure/union.
708 #
697 for arg in content.split(';'):709 for arg in content.split(';'):
698 arg = arg.strip()710 arg = arg.strip()
699 711 #
700 if not arg:712 # Look for (type)(*name)(args) - pointer to function
701 continue713 #
702 714 r = KernRe(r'^([^\(]+\(\*?\s*)([\w.]*)(\s*\).*)')
703 r = KernRe(r'^([^\(]+\(\*?\s*)([\w\.]*)(\s*\).*)')
704 if r.match(arg):715 if r.match(arg):
716 dtype, name, extra = r.group(1), r.group(2), r.group(3)
705 # Pointer-to-function717 # Pointer-to-function
706 dtype = r.group(1)
707 name = r.group(2)
708 extra = r.group(3)
709
710 if not name:
711 continue
712
713 if not s_id:718 if not s_id:
714 # Anonymous struct/union719 # Anonymous struct/union
715 newmember += f"{dtype}{name}{extra}; "720 newmember += f"{dtype}{name}{extra}; "
716 else:721 else:
717 newmember += f"{dtype}{s_id}.{name}{extra}; "722 newmember += f"{dtype}{s_id}.{name}{extra}; "
718 723 #
724 # Otherwise a non-function member.
725 #
719 else:726 else:
720 arg = arg.strip()727 #
721 # Handle bitmaps728 # Remove bitmap and array portions and spaces around commas
729 #
722 arg = KernRe(r':\s*\d+\s*').sub('', arg)730 arg = KernRe(r':\s*\d+\s*').sub('', arg)
723
724 # Handle arrays
725 arg = KernRe(r'\[.*\]').sub('', arg)731 arg = KernRe(r'\[.*\]').sub('', arg)
726
727 # Handle multiple IDs
728 arg = KernRe(r'\s*,\s*').sub(',', arg)732 arg = KernRe(r'\s*,\s*').sub(',', arg)
729 733 #
734 # Look for a normal decl - "type name[,name...]"
735 #
730 r = KernRe(r'(.*)\s+([\S+,]+)')736 r = KernRe(r'(.*)\s+([\S+,]+)')
731
732 if r.search(arg):737 if r.search(arg):
733 dtype = r.group(1)738 for name in r.group(2).split(','):
734 names = r.group(2)739 name = KernRe(r'^\s*\**(\S+)\s*').sub(r'\1', name)
740 if not s_id:
741 # Anonymous struct/union
742 newmember += f"{r.group(1)} {name}; "
743 else:
744 newmember += f"{r.group(1)} {s_id}.{name}; "
735 else:745 else:
736 newmember += f"{arg}; "746 newmember += f"{arg}; "
737 continue747 #
738 748 # At the end of the s_id loop, replace the original declaration with
739 for name in names.split(','):749 # the munged version.
740 name = KernRe(r'^\s*\**(\S+)\s*').sub(r'\1', name).strip()750 #
741
742 if not name:
743 continue
744
745 if not s_id:
746 # Anonymous struct/union
747 newmember += f"{dtype} {name}; "
748 else:
749 newmember += f"{dtype} {s_id}.{name}; "
750
751 members = members.replace(oldmember, newmember)751 members = members.replace(oldmember, newmember)
752 #
753 # End of the tuple loop - search again and see if there are outer members
754 # that now turn up.
755 #
756 tuples = struct_members.findall(members)
757 return members
752 758
753 # Ignore other nested elements, like enums759 #
754 members = re.sub(r'(\{[^\{\}]*\})', '', members)760 # Format the struct declaration into a standard form for inclusion in the
755 761 # resulting docs.
756 self.create_parameter_list(ln, decl_type, members, ';',762 #
757 declaration_name)763 def format_struct_decl(self, declaration):
758 self.check_sections(ln, declaration_name, decl_type)764 #
759 765 # Insert newlines, get rid of extra spaces.
760 # Adjust declaration for better display766 #
761 declaration = KernRe(r'([\{;])').sub(r'\1\n', declaration)767 declaration = KernRe(r'([\{;])').sub(r'\1\n', declaration)
762 declaration = KernRe(r'\}\s+;').sub('};', declaration)768 declaration = KernRe(r'\}\s+;').sub('};', declaration)
763 769 #
764 # Better handle inlined enums770 # Format inline enums with each member on its own line.
765 while True:771 #
766 r = KernRe(r'(enum\s+\{[^\}]+),([^\n])')772 r = KernRe(r'(enum\s+\{[^\}]+),([^\n])')
767 if not r.search(declaration):773 while r.search(declaration):
768 break
769
770 declaration = r.sub(r'\1,\n\2', declaration)774 declaration = r.sub(r'\1,\n\2', declaration)
771 775 #
776 # Now go through and supply the right number of tabs
777 # for each line.
778 #
772 def_args = declaration.split('\n')779 def_args = declaration.split('\n')
773 level = 1780 level = 1
774 declaration = ""781 declaration = ""
775 for clause in def_args:782 for clause in def_args:
783 clause = KernRe(r'\s+').sub(' ', clause.strip(), count=1)
784 if clause:
785 if '}' in clause and level > 1:
786 level -= 1
787 if not clause.startswith('#'):
788 declaration += "\t" * level
789 declaration += "\t" + clause + "\n"
790 if "{" in clause and "}" not in clause:
791 level += 1
792 return declaration
776 793
777 clause = clause.strip()
778 clause = KernRe(r'\s+').sub(' ', clause, count=1)
779
780 if not clause:
781 continue
782
783 if '}' in clause and level > 1:
784 level -= 1
785 794
786 if not KernRe(r'^\s*#').match(clause):795 def dump_struct(self, ln, proto):
787 declaration += "\t" * level796 """
797 Store an entry for an struct or union
798 """
799 #
800 # Do the basic parse to get the pieces of the declaration.
801 #
802 struct_parts = self.split_struct_proto(proto)
803 if not struct_parts:
804 self.emit_msg(ln, f"{proto} error: Cannot parse struct or union!")
805 return
806 decl_type, declaration_name, members = struct_parts
788 807
789 declaration += "\t" + clause + "\n"808 if self.entry.identifier != declaration_name:
790 if "{" in clause and "}" not in clause:809 self.emit_msg(ln, f"expecting prototype for {decl_type} {self.entry.identifier}. "
791 level += 1810 f"Prototype was for {decl_type} {declaration_name} instead\n")
811 return
812 #
813 # Go through the list of members applying all of our transformations.
814 #
815 members = trim_private_members(members)
816 members = apply_transforms(struct_xforms, members)
792 817
818 nested = NestedMatch()
819 for search, sub in struct_nested_prefixes:
820 members = nested.sub(search, sub, members)
821 #
822 # Deal with embedded struct and union members, and drop enums entirely.
823 #
824 declaration = members
825 members = self.rewrite_struct_members(members)
826 members = re.sub(r'(\{[^\{\}]*\})', '', members)
827 #
828 # Output the result and we are done.
829 #
830 self.create_parameter_list(ln, decl_type, members, ';',
831 declaration_name)
832 self.check_sections(ln, declaration_name, decl_type)
793 self.output_declaration(decl_type, declaration_name,833 self.output_declaration(decl_type, declaration_name,
794 definition=declaration,834 definition=self.format_struct_decl(declaration),
795 purpose=self.entry.declaration_purpose)835 purpose=self.entry.declaration_purpose)
796 836
797 def dump_enum(self, ln, proto):837 def dump_enum(self, ln, proto):
798 """838 """
799 Stores an enum inside self.entries array.839 Stores an enum inside self.entries array.
800 """840 """
801 841 #
802 # Ignore members marked private842 # Strip preprocessor directives. Note that this depends on the
803 proto = KernRe(r'\/\*\s*private:.*?\/\*\s*public:.*?\*\/', flags=re.S).sub('', proto)843 # trailing semicolon we added in process_proto_type().
804 proto = KernRe(r'\/\*\s*private:.*}', flags=re.S).sub('}', proto)844 #
805
806 # Strip comments
807 proto = KernRe(r'\/\*.*?\*\/', flags=re.S).sub('', proto)
808
809 # Strip #define macros inside enums
810 proto = KernRe(r'#\s*((define|ifdef|if)\s+|endif)[^;]*;', flags=re.S).sub('', proto)845 proto = KernRe(r'#\s*((define|ifdef|if)\s+|endif)[^;]*;', flags=re.S).sub('', proto)
811
812 #846 #
813 # Parse out the name and members of the enum. Typedef form first.847 # Parse out the name and members of the enum. Typedef form first.
814 #848 #
815 r = KernRe(r'typedef\s+enum\s*\{(.*)\}\s*(\w*)\s*;')849 r = KernRe(r'typedef\s+enum\s*\{(.*)\}\s*(\w*)\s*;')
816 if r.search(proto):850 if r.search(proto):
817 declaration_name = r.group(2)851 declaration_name = r.group(2)
818 members = r.group(1).rstrip()852 members = trim_private_members(r.group(1))
819 #853 #
820 # Failing that, look for a straight enum854 # Failing that, look for a straight enum
821 #855 #
@@ -823,7 +857,7 @@ class KernelDoc: · 1 unmodified line
823 r = KernRe(r'enum\s+(\w*)\s*\{(.*)\}')857 r = KernRe(r'enum\s+(\w*)\s*\{(.*)\}')
824 if r.match(proto):858 if r.match(proto):
825 declaration_name = r.group(1)859 declaration_name = r.group(1)
826 members = r.group(2).rstrip()860 members = trim_private_members(r.group(2))
827 #861 #
828 # OK, this isn't going to work.862 # OK, this isn't going to work.
829 #863 #
@@ -892,62 +926,31 @@ class KernelDoc: · 62 unmodified lines
892 Stores a function of function macro inside self.entries array.926 Stores a function of function macro inside self.entries array.
893 """927 """
894 928
895 func_macro = False929 found = func_macro = False
896 return_type = ''930 return_type = ''
897 decl_type = 'function'931 decl_type = 'function'
898 932 #
899 # Prefixes that would be removed933 # Apply the initial transformations.
900 sub_prefixes = [934 #
901 (r"^static +", "", 0),935 prototype = apply_transforms(function_xforms, prototype)
902 (r"^extern +", "", 0),936 #
903 (r"^asmlinkage +", "", 0),937 # If we have a macro, remove the "#define" at the front.
904 (r"^inline +", "", 0),938 #
905 (r"^__inline__ +", "", 0),
906 (r"^__inline +", "", 0),
907 (r"^__always_inline +", "", 0),
908 (r"^noinline +", "", 0),
909 (r"^__FORTIFY_INLINE +", "", 0),
910 (r"__init +", "", 0),
911 (r"__init_or_module +", "", 0),
912 (r"__deprecated +", "", 0),
913 (r"__flatten +", "", 0),
914 (r"__meminit +", "", 0),
915 (r"__must_check +", "", 0),
916 (r"__weak +", "", 0),
917 (r"__sched +", "", 0),
918 (r"_noprof", "", 0),
919 (r"__printf\s*\(\s*\d*\s*,\s*\d*\s*\) +", "", 0),
920 (r"__(?:re)?alloc_size\s*\(\s*\d+\s*(?:,\s*\d+\s*)?\) +", "", 0),
921 (r"__diagnose_as\s*\(\s*\S+\s*(?:,\s*\d+\s*)*\) +", "", 0),
922 (r"DECL_BUCKET_PARAMS\s*\(\s*(\S+)\s*,\s*(\S+)\s*\)", r"\1, \2", 0),
923 (r"__attribute_const__ +", "", 0),
924
925 # It seems that Python support for re.X is broken:
926 # At least for me (Python 3.13), this didn't work
927# (r"""
928# __attribute__\s*\(\(
929# (?:
930# [\w\s]+ # attribute name
931# (?:\([^)]*\))? # attribute arguments
932# \s*,? # optional comma at the end
933# )+
934# \)\)\s+
935# """, "", re.X),
936
937 # So, remove whitespaces and comments from it
938 (r"__attribute__\s*\(\((?:[\w\s]+(?:\([^)]*\))?\s*,?)+\)\)\s+", "", 0),
939 ]
940
941 for search, sub, flags in sub_prefixes:
942 prototype = KernRe(search, flags).sub(sub, prototype)
943
944 # Macros are a special case, as they change the prototype format
945 new_proto = KernRe(r"^#\s*define\s+").sub("", prototype)939 new_proto = KernRe(r"^#\s*define\s+").sub("", prototype)
946 if new_proto != prototype:940 if new_proto != prototype:
947 is_define_proto = True
948 prototype = new_proto941 prototype = new_proto
949 else:942 #
950 is_define_proto = False943 # Dispense with the simple "#define A B" case here; the key
944 # is the space after the name of the symbol being defined.
945 # NOTE that the seemingly misnamed "func_macro" indicates a
946 # macro *without* arguments.
947 #
948 r = KernRe(r'^(\w+)\s+')
949 if r.search(prototype):
950 return_type = ''
951 declaration_name = r.group(1)
952 func_macro = True
953 found = True
951 954
952 # Yes, this truly is vile. We are looking for:955 # Yes, this truly is vile. We are looking for:
953 # 1. Return type (may be nothing if we're looking at a macro)956 # 1. Return type (may be nothing if we're looking at a macro)
@@ -965,91 +968,73 @@ class KernelDoc: · 11 unmodified lines
965 # - atomic_set (macro)968 # - atomic_set (macro)
966 # - pci_match_device, __copy_to_user (long return type)969 # - pci_match_device, __copy_to_user (long return type)
967 970
968 name = r'[a-zA-Z0-9_~:]+'971 name = r'\w+'
969 prototype_end1 = r'[^\(]*'
970 prototype_end2 = r'[^\{]*'
971 prototype_end = fr'\(({prototype_end1}|{prototype_end2})\)'
972
973 # Besides compiling, Perl qr{[\w\s]+} works as a non-capturing group.
974 # So, this needs to be mapped in Python with (?:...)? or (?:...)+
975
976 type1 = r'(?:[\w\s]+)?'972 type1 = r'(?:[\w\s]+)?'
977 type2 = r'(?:[\w\s]+\*+)+'973 type2 = r'(?:[\w\s]+\*+)+'
978 974 #
979 found = False975 # Attempt to match first on (args) with no internal parentheses; this
980 976 # lets us easily filter out __acquires() and other post-args stuff. If
981 if is_define_proto:977 # that fails, just grab the rest of the line to the last closing
982 r = KernRe(r'^()(' + name + r')\s+')978 # parenthesis.
983 979 #
984 if r.search(prototype):980 proto_args = r'\(([^\(]*|.*)\)'
985 return_type = ''981 #
986 declaration_name = r.group(2)982 # (Except for the simple macro case) attempt to split up the prototype
987 func_macro = True983 # in the various ways we understand.
988 984 #
989 found = True
990
991 if not found:985 if not found:
992 patterns = [986 patterns = [
993 rf'^()({name})\s*{prototype_end}',987 rf'^()({name})\s*{proto_args}',
994 rf'^({type1})\s+({name})\s*{prototype_end}',988 rf'^({type1})\s+({name})\s*{proto_args}',
995 rf'^({type2})\s*({name})\s*{prototype_end}',989 rf'^({type2})\s*({name})\s*{proto_args}',
996 ]990 ]
997 991
998 for p in patterns:992 for p in patterns:
999 r = KernRe(p)993 r = KernRe(p)
1000
1001 if r.match(prototype):994 if r.match(prototype):
1002
1003 return_type = r.group(1)995 return_type = r.group(1)
1004 declaration_name = r.group(2)996 declaration_name = r.group(2)
1005 args = r.group(3)997 args = r.group(3)
1006
1007 self.create_parameter_list(ln, decl_type, args, ',',998 self.create_parameter_list(ln, decl_type, args, ',',
1008 declaration_name)999 declaration_name)
1009
1010 found = True1000 found = True
1011 break1001 break
1002 #
1003 # Parsing done; make sure that things are as we expect.
1004 #
1012 if not found:1005 if not found:
1013 self.emit_msg(ln,1006 self.emit_msg(ln,
1014 f"cannot understand function prototype: '{prototype}'")1007 f"cannot understand function prototype: '{prototype}'")
1015 return1008 return
1016
1017 if self.entry.identifier != declaration_name:1009 if self.entry.identifier != declaration_name:
1018 self.emit_msg(ln,1010 self.emit_msg(ln, f"expecting prototype for {self.entry.identifier}(). "
1019 f"expecting prototype for {self.entry.identifier}(). Prototype was for {declaration_name}() instead")1011 f"Prototype was for {declaration_name}() instead")
1020 return1012 return
1021
1022 self.check_sections(ln, declaration_name, "function")1013 self.check_sections(ln, declaration_name, "function")
1023
1024 self.check_return_section(ln, declaration_name, return_type)1014 self.check_return_section(ln, declaration_name, return_type)
1015 #
1016 # Store the result.
1017 #
1018 self.output_declaration(decl_type, declaration_name,
1019 typedef=('typedef' in return_type),
1020 functiontype=return_type,
1021 purpose=self.entry.declaration_purpose,
1022 func_macro=func_macro)
1025 1023
1026 if 'typedef' in return_type:
1027 self.output_declaration(decl_type, declaration_name,
1028 typedef=True,
1029 functiontype=return_type,
1030 purpose=self.entry.declaration_purpose,
1031 func_macro=func_macro)
1032 else:
1033 self.output_declaration(decl_type, declaration_name,
1034 typedef=False,
1035 functiontype=return_type,
1036 purpose=self.entry.declaration_purpose,
1037 func_macro=func_macro)
1038 1024
1039 def dump_typedef(self, ln, proto):1025 def dump_typedef(self, ln, proto):
1040 """1026 """
1041 Stores a typedef inside self.entries array.1027 Stores a typedef inside self.entries array.
1042 """1028 """
1043 1029 #
1044 typedef_type = r'((?:\s+[\w\*]+\b){0,7}\s+(?:\w+\b|\*+))\s*'1030 # We start by looking for function typedefs.
1031 #
1032 typedef_type = r'typedef((?:\s+[\w*]+\b){0,7}\s+(?:\w+\b|\*+))\s*'
1045 typedef_ident = r'\*?\s*(\w\S+)\s*'1033 typedef_ident = r'\*?\s*(\w\S+)\s*'
1046 typedef_args = r'\s*\((.*)\);'1034 typedef_args = r'\s*\((.*)\);'
1047 1035
1048 typedef1 = KernRe(r'typedef' + typedef_type + r'\(' + typedef_ident + r'\)' + typedef_args)1036 typedef1 = KernRe(typedef_type + r'\(' + typedef_ident + r'\)' + typedef_args)
1049 typedef2 = KernRe(r'typedef' + typedef_type + typedef_ident + typedef_args)1037 typedef2 = KernRe(typedef_type + typedef_ident + typedef_args)
1050
1051 # Strip comments
1052 proto = KernRe(r'/\*.*?\*/', flags=re.S).sub('', proto)
1053 1038
1054 # Parse function typedef prototypes1039 # Parse function typedef prototypes
1055 for r in [typedef1, typedef2]:1040 for r in [typedef1, typedef2]:
@@ -1065,21 +1050,16 @@ class KernelDoc: · 9 unmodified lines
1065 f"expecting prototype for typedef {self.entry.identifier}. Prototype was for typedef {declaration_name} instead\n")1050 f"expecting prototype for typedef {self.entry.identifier}. Prototype was for typedef {declaration_name} instead\n")
1066 return1051 return
1067 1052
1068 decl_type = 'function'1053 self.create_parameter_list(ln, 'function', args, ',', declaration_name)
1069 self.create_parameter_list(ln, decl_type, args, ',', declaration_name)
1070 1054
1071 self.output_declaration(decl_type, declaration_name,1055 self.output_declaration('function', declaration_name,
1072 typedef=True,1056 typedef=True,
1073 functiontype=return_type,1057 functiontype=return_type,
1074 purpose=self.entry.declaration_purpose)1058 purpose=self.entry.declaration_purpose)
1075 return1059 return
1076 1060 #
1077 # Handle nested parentheses or brackets1061 # Not a function, try to parse a simple typedef.
1078 r = KernRe(r'(\(*.\)\s*|\[*.\]\s*);$')1062 #
1079 while r.search(proto):
1080 proto = r.sub('', proto)
1081
1082 # Parse simple typedefs
1083 r = KernRe(r'typedef.*\s+(\w+)\s*;')1063 r = KernRe(r'typedef.*\s+(\w+)\s*;')
1084 if r.match(proto):1064 if r.match(proto):
1085 declaration_name = r.group(1)1065 declaration_name = r.group(1)
@@ -1262,7 +1242,7 @@ class KernelDoc: · 176 unmodified lines
1262 self.dump_section()1242 self.dump_section()
1263 1243
1264 # Look for doc_com + <text> + doc_end:1244 # Look for doc_com + <text> + doc_end:
1265 r = KernRe(r'\s*\*\s*[a-zA-Z_0-9:\.]+\*/')1245 r = KernRe(r'\s*\*\s*[a-zA-Z_0-9:.]+\*/')
1266 if r.match(line):1246 if r.match(line):
1267 self.emit_msg(ln, f"suspicious ending line: {line}")1247 self.emit_msg(ln, f"suspicious ending line: {line}")
1268 1248
@@ -1473,7 +1453,7 @@ class KernelDoc: · 204 unmodified lines
1473 """Ancillary routine to process a function prototype"""1453 """Ancillary routine to process a function prototype"""
1474 1454
1475 # strip C99-style comments to end of line1455 # strip C99-style comments to end of line
1476 line = KernRe(r"\/\/.*$", re.S).sub('', line)1456 line = KernRe(r"//.*$", re.S).sub('', line)
1477 #1457 #
1478 # Soak up the line's worth of prototype text, stopping at { or ; if present.1458 # Soak up the line's worth of prototype text, stopping at { or ; if present.
1479 #1459 #
scripts/selinux/install_policy.sh+1−1
@@ -74,7 +74,7 @@ cd /etc/selinux/dummy/contexts/files · 73 unmodified lines
74$SF -F file_contexts /74$SF -F file_contexts /
75 75
76mounts=`cat /proc/$$/mounts | \76mounts=`cat /proc/$$/mounts | \
77 grep -E "ext[234]|jfs|xfs|reiserfs|jffs2|gfs2|btrfs|f2fs|ocfs2" | \77 grep -E "ext[234]|jfs|xfs|jffs2|gfs2|btrfs|f2fs|ocfs2" | \
78 awk '{ print $2 '}`78 awk '{ print $2 '}`
79$SF -F file_contexts $mounts79$SF -F file_contexts $mounts
80 80
scripts/sphinx-build-wrapper+719−0
@@ -0,0 +1,719 @@
1#!/usr/bin/env python3
2# SPDX-License-Identifier: GPL-2.0
3# Copyright (C) 2025 Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
4#
5# pylint: disable=R0902, R0912, R0913, R0914, R0915, R0917, C0103
6#
7# Converted from docs Makefile and parallel-wrapper.sh, both under
8# GPLv2, copyrighted since 2008 by the following authors:
9#
10# Akira Yokosawa <akiyks@gmail.com>
11# Arnd Bergmann <arnd@arndb.de>
12# Breno Leitao <leitao@debian.org>
13# Carlos Bilbao <carlos.bilbao@amd.com>
14# Dave Young <dyoung@redhat.com>
15# Donald Hunter <donald.hunter@gmail.com>
16# Geert Uytterhoeven <geert+renesas@glider.be>
17# Jani Nikula <jani.nikula@intel.com>
18# Jan Stancek <jstancek@redhat.com>
19# Jonathan Corbet <corbet@lwn.net>
20# Joshua Clayton <stillcompiling@gmail.com>
21# Kees Cook <keescook@chromium.org>
22# Linus Torvalds <torvalds@linux-foundation.org>
23# Magnus Damm <damm+renesas@opensource.se>
24# Masahiro Yamada <masahiroy@kernel.org>
25# Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
26# Maxim Cournoyer <maxim.cournoyer@gmail.com>
27# Peter Foley <pefoley2@pefoley.com>
28# Randy Dunlap <rdunlap@infradead.org>
29# Rob Herring <robh@kernel.org>
30# Shuah Khan <shuahkh@osg.samsung.com>
31# Thorsten Blum <thorsten.blum@toblux.com>
32# Tomas Winkler <tomas.winkler@intel.com>
33
34
35"""
36Sphinx build wrapper that handles Kernel-specific business rules:
37
38- it gets the Kernel build environment vars;
39- it determines what's the best parallelism;
40- it handles SPHINXDIRS
41
42This tool ensures that MIN_PYTHON_VERSION is satisfied. If version is
43below that, it seeks for a new Python version. If found, it re-runs using
44the newer version.
45"""
46
47import argparse
48import locale
49import os
50import re
51import shlex
52import shutil
53import subprocess
54import sys
55
56from concurrent import futures
57from glob import glob
58
59LIB_DIR = "lib"
60SRC_DIR = os.path.dirname(os.path.realpath(__file__))
61
62sys.path.insert(0, os.path.join(SRC_DIR, LIB_DIR))
63
64from jobserver import JobserverExec # pylint: disable=C0413
65
66
67def parse_version(version):
68 """Convert a major.minor.patch version into a tuple"""
69 return tuple(int(x) for x in version.split("."))
70
71def ver_str(version):
72 """Returns a version tuple as major.minor.patch"""
73
74 return ".".join([str(x) for x in version])
75
76# Minimal supported Python version needed by Sphinx and its extensions
77MIN_PYTHON_VERSION = parse_version("3.7")
78
79# Default value for --venv parameter
80VENV_DEFAULT = "sphinx_latest"
81
82# List of make targets and its corresponding builder and output directory
83TARGETS = {
84 "cleandocs": {
85 "builder": "clean",
86 },
87 "htmldocs": {
88 "builder": "html",
89 },
90 "epubdocs": {
91 "builder": "epub",
92 "out_dir": "epub",
93 },
94 "texinfodocs": {
95 "builder": "texinfo",
96 "out_dir": "texinfo",
97 },
98 "infodocs": {
99 "builder": "texinfo",
100 "out_dir": "texinfo",
101 },
102 "latexdocs": {
103 "builder": "latex",
104 "out_dir": "latex",
105 },
106 "pdfdocs": {
107 "builder": "latex",
108 "out_dir": "latex",
109 },
110 "xmldocs": {
111 "builder": "xml",
112 "out_dir": "xml",
113 },
114 "linkcheckdocs": {
115 "builder": "linkcheck"
116 },
117}
118
119# Paper sizes. An empty value will pick the default
120PAPER = ["", "a4", "letter"]
121
122class SphinxBuilder:
123 """
124 Handles a sphinx-build target, adding needed arguments to build
125 with the Kernel.
126 """
127
128 def is_rust_enabled(self):
129 """Check if rust is enabled at .config"""
130 config_path = os.path.join(self.srctree, ".config")
131 if os.path.isfile(config_path):
132 with open(config_path, "r", encoding="utf-8") as f:
133 return "CONFIG_RUST=y" in f.read()
134 return False
135
136 def get_path(self, path, abs_path=False):
137 """
138 Ancillary routine to handle patches the right way, as shell does.
139
140 It first expands "~" and "~user". Then, if patch is not absolute,
141 join self.srctree. Finally, if requested, convert to abspath.
142 """
143
144 path = os.path.expanduser(path)
145 if not path.startswith("/"):
146 path = os.path.join(self.srctree, path)
147
148 if abs_path:
149 return os.path.abspath(path)
150
151 return path
152
153 def __init__(self, venv=None, verbose=False, n_jobs=None, interactive=None):
154 """Initialize internal variables"""
155 self.venv = venv
156 self.verbose = None
157
158 # Normal variables passed from Kernel's makefile
159 self.kernelversion = os.environ.get("KERNELVERSION", "unknown")
160 self.kernelrelease = os.environ.get("KERNELRELEASE", "unknown")
161 self.pdflatex = os.environ.get("PDFLATEX", "xelatex")
162
163 if not interactive:
164 self.latexopts = os.environ.get("LATEXOPTS", "-interaction=batchmode -no-shell-escape")
165 else:
166 self.latexopts = os.environ.get("LATEXOPTS", "")
167
168 if not verbose:
169 verbose = bool(os.environ.get("KBUILD_VERBOSE", "") != "")
170
171 # Handle SPHINXOPTS evironment
172 sphinxopts = shlex.split(os.environ.get("SPHINXOPTS", ""))
173
174 # As we handle number of jobs and quiet in separate, we need to pick
175 # it the same way as sphinx-build would pick, so let's use argparse
176 # do to the right argument expansion
177 parser = argparse.ArgumentParser()
178 parser.add_argument('-j', '--jobs', type=int)
179 parser.add_argument('-q', '--quiet', type=int)
180
181 # Other sphinx-build arguments go as-is, so place them
182 # at self.sphinxopts
183 sphinx_args, self.sphinxopts = parser.parse_known_args(sphinxopts)
184 if sphinx_args.quiet == True:
185 self.verbose = False
186
187 if sphinx_args.jobs:
188 self.n_jobs = sphinx_args.jobs
189
190 # Command line arguments was passed, override SPHINXOPTS
191 if verbose is not None:
192 self.verbose = verbose
193
194 self.n_jobs = n_jobs
195
196 # Source tree directory. This needs to be at os.environ, as
197 # Sphinx extensions and media uAPI makefile needs it
198 self.srctree = os.environ.get("srctree")
199 if not self.srctree:
200 self.srctree = "."
201 os.environ["srctree"] = self.srctree
202
203 # Now that we can expand srctree, get other directories as well
204 self.sphinxbuild = os.environ.get("SPHINXBUILD", "sphinx-build")
205 self.kerneldoc = self.get_path(os.environ.get("KERNELDOC",
206 "scripts/kernel-doc.py"))
207 self.obj = os.environ.get("obj", "Documentation")
208 self.builddir = self.get_path(os.path.join(self.obj, "output"),
209 abs_path=True)
210
211 # Media uAPI needs it
212 os.environ["BUILDDIR"] = self.builddir
213
214 # Detect if rust is enabled
215 self.config_rust = self.is_rust_enabled()
216
217 # Get directory locations for LaTeX build toolchain
218 self.pdflatex_cmd = shutil.which(self.pdflatex)
219 self.latexmk_cmd = shutil.which("latexmk")
220
221 self.env = os.environ.copy()
222
223 # If venv parameter is specified, run Sphinx from venv
224 if venv:
225 bin_dir = os.path.join(venv, "bin")
226 if os.path.isfile(os.path.join(bin_dir, "activate")):
227 # "activate" virtual env
228 self.env["PATH"] = bin_dir + ":" + self.env["PATH"]
229 self.env["VIRTUAL_ENV"] = venv
230 if "PYTHONHOME" in self.env:
231 del self.env["PYTHONHOME"]
232 print(f"Setting venv to {venv}")
233 else:
234 sys.exit(f"Venv {venv} not found.")
235
236 def run_sphinx(self, sphinx_build, build_args, *args, **pwargs):
237 """
238 Executes sphinx-build using current python3 command and setting
239 -j parameter if possible to run the build in parallel.
240 """
241
242 with JobserverExec() as jobserver:
243 if jobserver.claim:
244 n_jobs = str(jobserver.claim)
245 else:
246 n_jobs = "auto" # Supported since Sphinx 1.7
247
248 cmd = []
249
250 if self.venv:
251 cmd.append("python")
252 else:
253 cmd.append(sys.executable)
254
255 cmd.append(sphinx_build)
256
257 # if present, SPHINXOPTS or command line --jobs overrides default
258 if self.n_jobs:
259 n_jobs = str(self.n_jobs)
260
261 if n_jobs:
262 cmd += [f"-j{n_jobs}"]
263
264 if not self.verbose:
265 cmd.append("-q")
266
267 cmd += self.sphinxopts
268
269 cmd += build_args
270
271 if self.verbose:
272 print(" ".join(cmd))
273
274 rc = subprocess.call(cmd, *args, **pwargs)
275
276 def handle_html(self, css, output_dir):
277 """
278 Extra steps for HTML and epub output.
279
280 For such targets, we need to ensure that CSS will be properly
281 copied to the output _static directory
282 """
283
284 if not css:
285 return
286
287 css = os.path.expanduser(css)
288 if not css.startswith("/"):
289 css = os.path.join(self.srctree, css)
290
291 static_dir = os.path.join(output_dir, "_static")
292 os.makedirs(static_dir, exist_ok=True)
293
294 try:
295 shutil.copy2(css, static_dir)
296 except (OSError, IOError) as e:
297 print(f"Warning: Failed to copy CSS: {e}", file=sys.stderr)
298
299 def build_pdf_file(self, latex_cmd, from_dir, path):
300 """Builds a single pdf file using latex_cmd"""
301 try:
302 subprocess.run(latex_cmd + [path],
303 cwd=from_dir, check=True)
304
305 return True
306 except subprocess.CalledProcessError:
307 # LaTeX PDF error code is almost useless: it returns
308 # error codes even when build succeeds but has warnings.
309 # So, we'll ignore the results
310 return False
311
312 def pdf_parallel_build(self, tex_suffix, latex_cmd, tex_files, n_jobs):
313 """Build PDF files in parallel if possible"""
314 builds = {}
315 build_failed = False
316 max_len = 0
317 has_tex = False
318
319 # Process files in parallel
320 with futures.ThreadPoolExecutor(max_workers=n_jobs) as executor:
321 jobs = {}
322
323 for from_dir, pdf_dir, entry in tex_files:
324 name = entry.name
325
326 if not name.endswith(tex_suffix):
327 continue
328
329 name = name[:-len(tex_suffix)]
330
331 max_len = max(max_len, len(name))
332
333 has_tex = True
334
335 future = executor.submit(self.build_pdf_file, latex_cmd,
336 from_dir, entry.path)
337 jobs[future] = (from_dir, name, entry.path)
338
339 for future in futures.as_completed(jobs):
340 from_dir, name, path = jobs[future]
341
342 pdf_name = name + ".pdf"
343 pdf_from = os.path.join(from_dir, pdf_name)
344
345 try:
346 success = future.result()
347
348 if success and os.path.exists(pdf_from):
349 pdf_to = os.path.join(pdf_dir, pdf_name)
350
351 os.rename(pdf_from, pdf_to)
352 builds[name] = os.path.relpath(pdf_to, self.builddir)
353 else:
354 builds[name] = "FAILED"
355 build_failed = True
356 except Exception as e:
357 builds[name] = f"FAILED ({str(e)})"
358 build_failed = True
359
360 # Handle case where no .tex files were found
361 if not has_tex:
362 name = "Sphinx LaTeX builder"
363 max_len = max(max_len, len(name))
364 builds[name] = "FAILED (no .tex file was generated)"
365 build_failed = True
366
367 return builds, build_failed, max_len
368
369 def handle_pdf(self, output_dirs):
370 """
371 Extra steps for PDF output.
372
373 As PDF is handled via a LaTeX output, after building the .tex file,
374 a new build is needed to create the PDF output from the latex
375 directory.
376 """
377 builds = {}
378 max_len = 0
379 tex_suffix = ".tex"
380
381 # Get all tex files that will be used for PDF build
382 tex_files = []
383 for from_dir in output_dirs:
384 pdf_dir = os.path.join(from_dir, "../pdf")
385 os.makedirs(pdf_dir, exist_ok=True)
386
387 if self.latexmk_cmd:
388 latex_cmd = [self.latexmk_cmd, f"-{self.pdflatex}"]
389 else:
390 latex_cmd = [self.pdflatex]
391
392 latex_cmd.extend(shlex.split(self.latexopts))
393
394 # Get a list of tex files to process
395 with os.scandir(from_dir) as it:
396 for entry in it:
397 if entry.name.endswith(tex_suffix):
398 tex_files.append((from_dir, pdf_dir, entry))
399
400 # When using make, this won't be used, as the number of jobs comes
401 # from POSIX jobserver. So, this covers the case where build comes
402 # from command line. On such case, serialize by default, except if
403 # the user explicitly sets the number of jobs.
404 n_jobs = 1
405
406 # n_jobs is either an integer or "auto". Only use it if it is a number
407 if self.n_jobs:
408 try:
409 n_jobs = int(self.n_jobs)
410 except ValueError:
411 pass
412
413 # When using make, jobserver.claim is the number of jobs that were
414 # used with "-j" and that aren't used by other make targets
415 with JobserverExec() as jobserver:
416 n_jobs = 1
417
418 # Handle the case when a parameter is passed via command line,
419 # using it as default, if jobserver doesn't claim anything
420 if self.n_jobs:
421 try:
422 n_jobs = int(self.n_jobs)
423 except ValueError:
424 pass
425
426 if jobserver.claim:
427 n_jobs = jobserver.claim
428
429 # Build files in parallel
430 builds, build_failed, max_len = self.pdf_parallel_build(tex_suffix,
431 latex_cmd,
432 tex_files,
433 n_jobs)
434
435 msg = "Summary"
436 msg += "\n" + "=" * len(msg)
437 print()
438 print(msg)
439
440 for pdf_name, pdf_file in builds.items():
441 print(f"{pdf_name:<{max_len}}: {pdf_file}")
442
443 print()
444
445 # return an error if a PDF file is missing
446
447 if build_failed:
448 sys.exit(f"PDF build failed: not all PDF files were created.")
449 else:
450 print("All PDF files were built.")
451
452 def handle_info(self, output_dirs):
453 """
454 Extra steps for Info output.
455
456 For texinfo generation, an additional make is needed from the
457 texinfo directory.
458 """
459
460 for output_dir in output_dirs:
461 try:
462 subprocess.run(["make", "info"], cwd=output_dir, check=True)
463 except subprocess.CalledProcessError as e:
464 sys.exit(f"Error generating info docs: {e}")
465
466 def cleandocs(self, builder):
467
468 shutil.rmtree(self.builddir, ignore_errors=True)
469
470 def build(self, target, sphinxdirs=None, conf="conf.py",
471 theme=None, css=None, paper=None):
472 """
473 Build documentation using Sphinx. This is the core function of this
474 module. It prepares all arguments required by sphinx-build.
475 """
476
477 builder = TARGETS[target]["builder"]
478 out_dir = TARGETS[target].get("out_dir", "")
479
480 # Cleandocs doesn't require sphinx-build
481 if target == "cleandocs":
482 self.cleandocs(builder)
483 return
484
485 # Other targets require sphinx-build
486 sphinxbuild = shutil.which(self.sphinxbuild, path=self.env["PATH"])
487 if not sphinxbuild:
488 sys.exit(f"Error: {self.sphinxbuild} not found in PATH.\n")
489
490 if builder == "latex":
491 if not self.pdflatex_cmd and not self.latexmk_cmd:
492 sys.exit("Error: pdflatex or latexmk required for PDF generation")
493
494 docs_dir = os.path.abspath(os.path.join(self.srctree, "Documentation"))
495
496 # Prepare base arguments for Sphinx build
497 kerneldoc = self.kerneldoc
498 if kerneldoc.startswith(self.srctree):
499 kerneldoc = os.path.relpath(kerneldoc, self.srctree)
500
501 # Prepare common Sphinx options
502 args = [
503 "-b", builder,
504 "-c", docs_dir,
505 ]
506
507 if builder == "latex":
508 if not paper:
509 paper = PAPER[1]
510
511 args.extend(["-D", f"latex_elements.papersize={paper}paper"])
512
513 if self.config_rust:
514 args.extend(["-t", "rustdoc"])
515
516 if conf:
517 self.env["SPHINX_CONF"] = self.get_path(conf, abs_path=True)
518
519 if not sphinxdirs:
520 sphinxdirs = os.environ.get("SPHINXDIRS", ".")
521
522 # The sphinx-build tool has a bug: internally, it tries to set
523 # locale with locale.setlocale(locale.LC_ALL, ''). This causes a
524 # crash if language is not set. Detect and fix it.
525 try:
526 locale.setlocale(locale.LC_ALL, '')
527 except Exception:
528 self.env["LC_ALL"] = "C"
529 self.env["LANG"] = "C"
530
531 # sphinxdirs can be a list or a whitespace-separated string
532 sphinxdirs_list = []
533 for sphinxdir in sphinxdirs:
534 if isinstance(sphinxdir, list):
535 sphinxdirs_list += sphinxdir
536 else:
537 for name in sphinxdir.split(" "):
538 sphinxdirs_list.append(name)
539
540 # Build each directory
541 output_dirs = []
542 for sphinxdir in sphinxdirs_list:
543 src_dir = os.path.join(docs_dir, sphinxdir)
544 doctree_dir = os.path.join(self.builddir, ".doctrees")
545 output_dir = os.path.join(self.builddir, sphinxdir, out_dir)
546
547 # Make directory names canonical
548 src_dir = os.path.normpath(src_dir)
549 doctree_dir = os.path.normpath(doctree_dir)
550 output_dir = os.path.normpath(output_dir)
551
552 os.makedirs(doctree_dir, exist_ok=True)
553 os.makedirs(output_dir, exist_ok=True)
554
555 output_dirs.append(output_dir)
556
557 build_args = args + [
558 "-d", doctree_dir,
559 "-D", f"kerneldoc_bin={kerneldoc}",
560 "-D", f"version={self.kernelversion}",
561 "-D", f"release={self.kernelrelease}",
562 "-D", f"kerneldoc_srctree={self.srctree}",
563 src_dir,
564 output_dir,
565 ]
566
567 # Execute sphinx-build
568 try:
569 self.run_sphinx(sphinxbuild, build_args, env=self.env)
570 except Exception as e:
571 sys.exit(f"Build failed: {e}")
572
573 # Ensure that html/epub will have needed static files
574 if target in ["htmldocs", "epubdocs"]:
575 self.handle_html(css, output_dir)
576
577 # PDF and Info require a second build step
578 if target == "pdfdocs":
579 self.handle_pdf(output_dirs)
580 elif target == "infodocs":
581 self.handle_info(output_dirs)
582
583 @staticmethod
584 def get_python_version(cmd):
585 """
586 Get python version from a Python binary. As we need to detect if
587 are out there newer python binaries, we can't rely on sys.release here.
588 """
589
590 result = subprocess.run([cmd, "--version"], check=True,
591 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
592 universal_newlines=True)
593 version = result.stdout.strip()
594
595 match = re.search(r"(\d+\.\d+\.\d+)", version)
596 if match:
597 return parse_version(match.group(1))
598
599 print(f"Can't parse version {version}")
600 return (0, 0, 0)
601
602 @staticmethod
603 def find_python():
604 """
605 Detect if are out there any python 3.xy version newer than the
606 current one.
607
608 Note: this routine is limited to up to 2 digits for python3. We
609 may need to update it one day, hopefully on a distant future.
610 """
611 patterns = [
612 "python3.[0-9]",
613 "python3.[0-9][0-9]",
614 ]
615
616 # Seek for a python binary newer than MIN_PYTHON_VERSION
617 for path in os.getenv("PATH", "").split(":"):
618 for pattern in patterns:
619 for cmd in glob(os.path.join(path, pattern)):
620 if os.path.isfile(cmd) and os.access(cmd, os.X_OK):
621 version = SphinxBuilder.get_python_version(cmd)
622 if version >= MIN_PYTHON_VERSION:
623 return cmd
624
625 return None
626
627 @staticmethod
628 def check_python():
629 """
630 Check if the current python binary satisfies our minimal requirement
631 for Sphinx build. If not, re-run with a newer version if found.
632 """
633 cur_ver = sys.version_info[:3]
634 if cur_ver >= MIN_PYTHON_VERSION:
635 return
636
637 python_ver = ver_str(cur_ver)
638
639 new_python_cmd = SphinxBuilder.find_python()
640 if not new_python_cmd:
641 sys.exit(f"Python version {python_ver} is not supported anymore.")
642
643 # Restart script using the newer version
644 script_path = os.path.abspath(sys.argv[0])
645 args = [new_python_cmd, script_path] + sys.argv[1:]
646
647 print(f"Python {python_ver} not supported. Changing to {new_python_cmd}")
648
649 try:
650 os.execv(new_python_cmd, args)
651 except OSError as e:
652 sys.exit(f"Failed to restart with {new_python_cmd}: {e}")
653
654def jobs_type(value):
655 """
656 Handle valid values for -j. Accepts Sphinx "-jauto", plus a number
657 equal or bigger than one.
658 """
659 if value is None:
660 return None
661
662 if value.lower() == 'auto':
663 return value.lower()
664
665 try:
666 if int(value) >= 1:
667 return value
668
669 raise argparse.ArgumentTypeError(f"Minimum jobs is 1, got {value}")
670 except ValueError:
671 raise argparse.ArgumentTypeError(f"Must be 'auto' or positive integer, got {value}")
672
673def main():
674 """
675 Main function. The only mandatory argument is the target. If not
676 specified, the other arguments will use default values if not
677 specified at os.environ.
678 """
679 parser = argparse.ArgumentParser(description="Kernel documentation builder")
680
681 parser.add_argument("target", choices=list(TARGETS.keys()),
682 help="Documentation target to build")
683 parser.add_argument("--sphinxdirs", nargs="+",
684 help="Specific directories to build")
685 parser.add_argument("--conf", default="conf.py",
686 help="Sphinx configuration file")
687
688 parser.add_argument("--theme", help="Sphinx theme to use")
689
690 parser.add_argument("--css", help="Custom CSS file for HTML/EPUB")
691
692 parser.add_argument("--paper", choices=PAPER, default=PAPER[0],
693 help="Paper size for LaTeX/PDF output")
694
695 parser.add_argument("-v", "--verbose", action='store_true',
696 help="place build in verbose mode")
697
698 parser.add_argument('-j', '--jobs', type=jobs_type,
699 help="Sets number of jobs to use with sphinx-build")
700
701 parser.add_argument('-i', '--interactive', action='store_true',
702 help="Change latex default to run in interactive mode")
703
704 parser.add_argument("-V", "--venv", nargs='?', const=f'{VENV_DEFAULT}',
705 default=None,
706 help=f'If used, run Sphinx from a venv dir (default dir: {VENV_DEFAULT})')
707
708 args = parser.parse_args()
709
710 SphinxBuilder.check_python()
711
712 builder = SphinxBuilder(venv=args.venv, verbose=args.verbose,
713 n_jobs=args.jobs, interactive=args.interactive)
714
715 builder.build(args.target, sphinxdirs=args.sphinxdirs, conf=args.conf,
716 theme=args.theme, css=args.css, paper=args.paper)
717
718if __name__ == "__main__":
719 main()
scripts/sphinx-pre-install+1617−1052
@@ -1,1056 +1,1621 @@
1#!/usr/bin/env perl1#!/usr/bin/env python3
2# SPDX-License-Identifier: GPL-2.0-or-later2# SPDX-License-Identifier: GPL-2.0-or-later
3use strict;3# Copyright (c) 2017-2025 Mauro Carvalho Chehab <mchehab+huawei@kernel.org>
4
5# Copyright (c) 2017-2020 Mauro Carvalho Chehab <mchehab@kernel.org>
6#
7
8my $prefix = "./";
9$prefix = "$ENV{'srctree'}/" if ($ENV{'srctree'});
10
11my $conf = $prefix . "Documentation/conf.py";
12my $requirement_file = $prefix . "Documentation/sphinx/requirements.txt";
13my $virtenv_prefix = "sphinx_";
14
15#
16# Static vars
17#
18
19my %missing;
20my $system_release;
21my $need = 0;
22my $optional = 0;
23my $need_symlink = 0;
24my $need_sphinx = 0;
25my $need_pip = 0;
26my $need_virtualenv = 0;
27my $rec_sphinx_upgrade = 0;
28my $verbose_warn_install = 1;
29my $install = "";
30my $virtenv_dir = "";
31my $python_cmd = "";
32my $activate_cmd;
33my $min_version;
34my $cur_version;
35my $rec_version = "3.4.3";
36my $latest_avail_ver;
37
38#
39# Command line arguments
40#
41
42my $pdf = 1;
43my $virtualenv = 1;
44my $version_check = 0;
45
46#
47# List of required texlive packages on Fedora and OpenSuse
48#
49
50my %texlive = (
51 'amsfonts.sty' => 'texlive-amsfonts',
52 'amsmath.sty' => 'texlive-amsmath',
53 'amssymb.sty' => 'texlive-amsfonts',
54 'amsthm.sty' => 'texlive-amscls',
55 'anyfontsize.sty' => 'texlive-anyfontsize',
56 'atbegshi.sty' => 'texlive-oberdiek',
57 'bm.sty' => 'texlive-tools',
58 'capt-of.sty' => 'texlive-capt-of',
59 'cmap.sty' => 'texlive-cmap',
60 'ecrm1000.tfm' => 'texlive-ec',
61 'eqparbox.sty' => 'texlive-eqparbox',
62 'eu1enc.def' => 'texlive-euenc',
63 'fancybox.sty' => 'texlive-fancybox',
64 'fancyvrb.sty' => 'texlive-fancyvrb',
65 'float.sty' => 'texlive-float',
66 'fncychap.sty' => 'texlive-fncychap',
67 'footnote.sty' => 'texlive-mdwtools',
68 'framed.sty' => 'texlive-framed',
69 'luatex85.sty' => 'texlive-luatex85',
70 'multirow.sty' => 'texlive-multirow',
71 'needspace.sty' => 'texlive-needspace',
72 'palatino.sty' => 'texlive-psnfss',
73 'parskip.sty' => 'texlive-parskip',
74 'polyglossia.sty' => 'texlive-polyglossia',
75 'tabulary.sty' => 'texlive-tabulary',
76 'threeparttable.sty' => 'texlive-threeparttable',
77 'titlesec.sty' => 'texlive-titlesec',
78 'ucs.sty' => 'texlive-ucs',
79 'upquote.sty' => 'texlive-upquote',
80 'wrapfig.sty' => 'texlive-wrapfig',
81 'ctexhook.sty' => 'texlive-ctex',
82);
83
84#
85# Subroutines that checks if a feature exists
86#
87
88sub check_missing(%)
89{
90 my %map = %{$_[0]};
91
92 foreach my $prog (sort keys %missing) {
93 my $is_optional = $missing{$prog};
94
95 # At least on some LTS distros like CentOS 7, texlive doesn't
96 # provide all packages we need. When such distros are
97 # detected, we have to disable PDF output.
98 #
99 # So, we need to ignore the packages that distros would
100 # need for LaTeX to work
101 if ($is_optional == 2 && !$pdf) {
102 $optional--;
103 next;
104 }
105
106 if ($verbose_warn_install) {
107 if ($is_optional) {
108 print "Warning: better to also install \"$prog\".\n";
109 } else {
110 print "ERROR: please install \"$prog\", otherwise, build won't work.\n";
111 }
112 }
113 if (defined($map{$prog})) {
114 $install .= " " . $map{$prog};
115 } else {
116 $install .= " " . $prog;
117 }
118 }
119
120 $install =~ s/^\s//;
121}
122
123sub add_package($$)
124{
125 my $package = shift;
126 my $is_optional = shift;
127
128 $missing{$package} = $is_optional;
129 if ($is_optional) {
130 $optional++;
131 } else {
132 $need++;
133 }
134}
135
136sub check_missing_file($$$)
137{
138 my $files = shift;
139 my $package = shift;
140 my $is_optional = shift;
141
142 for (@$files) {
143 return if(-e $_);
144 }
145
146 add_package($package, $is_optional);
147}
148
149sub findprog($)
150{
151 foreach(split(/:/, $ENV{PATH})) {
152 return "$_/$_[0]" if(-x "$_/$_[0]");
153 }
154}
155
156sub find_python_no_venv()
157{
158 my $prog = shift;
159
160 my $cur_dir = qx(pwd);
161 $cur_dir =~ s/\s+$//;
162
163 foreach my $dir (split(/:/, $ENV{PATH})) {
164 next if ($dir =~ m,($cur_dir)/sphinx,);
165 return "$dir/python3" if(-x "$dir/python3");
166 }
167 foreach my $dir (split(/:/, $ENV{PATH})) {
168 next if ($dir =~ m,($cur_dir)/sphinx,);
169 return "$dir/python" if(-x "$dir/python");
170 }
171 return "python";
172}
173
174sub check_program($$)
175{
176 my $prog = shift;
177 my $is_optional = shift;
178
179 return $prog if findprog($prog);
180
181 add_package($prog, $is_optional);
182}
183
184sub check_perl_module($$)
185{
186 my $prog = shift;
187 my $is_optional = shift;
188
189 my $err = system("perl -M$prog -e 1 2>/dev/null /dev/null");
190 return if ($err == 0);
191
192 add_package($prog, $is_optional);
193}
194
195sub check_python_module($$)
196{
197 my $prog = shift;
198 my $is_optional = shift;
199
200 return if (!$python_cmd);
201
202 my $err = system("$python_cmd -c 'import $prog' 2>/dev/null /dev/null");
203 return if ($err == 0);
204
205 add_package($prog, $is_optional);
206}
207
208sub check_rpm_missing($$)
209{
210 my @pkgs = @{$_[0]};
211 my $is_optional = $_[1];
212
213 foreach my $prog(@pkgs) {
214 my $err = system("rpm -q '$prog' 2>/dev/null >/dev/null");
215 add_package($prog, $is_optional) if ($err);
216 }
217}
218
219sub check_pacman_missing($$)
220{
221 my @pkgs = @{$_[0]};
222 my $is_optional = $_[1];
223
224 foreach my $prog(@pkgs) {
225 my $err = system("pacman -Q '$prog' 2>/dev/null >/dev/null");
226 add_package($prog, $is_optional) if ($err);
227 }
228}
229
230sub check_missing_tex($)
231{
232 my $is_optional = shift;
233 my $kpsewhich = findprog("kpsewhich");
234
235 foreach my $prog(keys %texlive) {
236 my $package = $texlive{$prog};
237 if (!$kpsewhich) {
238 add_package($package, $is_optional);
239 next;
240 }
241 my $file = qx($kpsewhich $prog);
242 add_package($package, $is_optional) if ($file =~ /^\s*$/);
243 }
244}
245
246sub get_sphinx_fname()
247{
248 if ($ENV{'SPHINXBUILD'}) {
249 return $ENV{'SPHINXBUILD'};
250 }
251
252 my $fname = "sphinx-build";
253 return $fname if findprog($fname);
254
255 $fname = "sphinx-build-3";
256 if (findprog($fname)) {
257 $need_symlink = 1;
258 return $fname;
259 }
260
261 return "";
262}
263
264sub get_sphinx_version($)
265{
266 my $cmd = shift;
267 my $ver;
268
269 open IN, "$cmd --version 2>&1 |";
270 while (<IN>) {
271 if (m/^\s*sphinx-build\s+([\d\.]+)((\+\/[\da-f]+)|(b\d+))?$/) {
272 $ver=$1;
273 last;
274 }
275 # Sphinx 1.2.x uses a different format
276 if (m/^\s*Sphinx.*\s+([\d\.]+)$/) {
277 $ver=$1;
278 last;
279 }
280 }
281 close IN;
282 return $ver;
283}
284
285sub check_sphinx()
286{
287 open IN, $conf or die "Can't open $conf";
288 while (<IN>) {
289 if (m/^\s*needs_sphinx\s*=\s*[\'\"]([\d\.]+)[\'\"]/) {
290 $min_version=$1;
291 last;
292 }
293 }
294 close IN;
295
296 die "Can't get needs_sphinx version from $conf" if (!$min_version);
297
298 $virtenv_dir = $virtenv_prefix . "latest";
299
300 my $sphinx = get_sphinx_fname();
301 if ($sphinx eq "") {
302 $need_sphinx = 1;
303 return;
304 }
305
306 $cur_version = get_sphinx_version($sphinx);
307 die "$sphinx didn't return its version" if (!$cur_version);
308
309 if ($cur_version lt $min_version) {
310 printf "ERROR: Sphinx version is %s. It should be >= %s\n",
311 $cur_version, $min_version;
312 $need_sphinx = 1;
313 return;
314 }
315
316 return if ($cur_version lt $rec_version);
317
318 # On version check mode, just assume Sphinx has all mandatory deps
319 exit (0) if ($version_check);
320}
321
322#
323# Ancillary subroutines
324#
325
326sub catcheck($)
327{
328 my $res = "";
329 $res = qx(cat $_[0]) if (-r $_[0]);
330 return $res;
331}
332
333sub which($)
334{
335 my $file = shift;
336 my @path = split ":", $ENV{PATH};
337
338 foreach my $dir(@path) {
339 my $name = $dir.'/'.$file;
340 return $name if (-x $name );
341 }
342 return undef;
343}
344
345#
346# Subroutines that check distro-specific hints
347#
348
349sub give_debian_hints()
350{
351 my %map = (
352 "python-sphinx" => "python3-sphinx",
353 "yaml" => "python3-yaml",
354 "ensurepip" => "python3-venv",
355 "virtualenv" => "virtualenv",
356 "dot" => "graphviz",
357 "convert" => "imagemagick",
358 "Pod::Usage" => "perl-modules",
359 "xelatex" => "texlive-xetex",
360 "rsvg-convert" => "librsvg2-bin",
361 );
362
363 if ($pdf) {
364 check_missing_file(["/usr/share/texlive/texmf-dist/tex/latex/ctex/ctexhook.sty"],
365 "texlive-lang-chinese", 2);
366
367 check_missing_file(["/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"],
368 "fonts-dejavu", 2);
369
370 check_missing_file(["/usr/share/fonts/noto-cjk/NotoSansCJK-Regular.ttc",
371 "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc",
372 "/usr/share/fonts/opentype/noto/NotoSerifCJK-Regular.ttc"],
373 "fonts-noto-cjk", 2);
374 }
375
376 check_program("dvipng", 2) if ($pdf);
377 check_missing(\%map);
378
379 return if (!$need && !$optional);
380 printf("You should run:\n") if ($verbose_warn_install);
381 printf("\n\tsudo apt-get install $install\n");
382}
383
384sub give_redhat_hints()
385{
386 my %map = (
387 "python-sphinx" => "python3-sphinx",
388 "yaml" => "python3-pyyaml",
389 "virtualenv" => "python3-virtualenv",
390 "dot" => "graphviz",
391 "convert" => "ImageMagick",
392 "Pod::Usage" => "perl-Pod-Usage",
393 "xelatex" => "texlive-xetex-bin",
394 "rsvg-convert" => "librsvg2-tools",
395 );
396
397 my @fedora26_opt_pkgs = (
398 "graphviz-gd", # Fedora 26: needed for PDF support
399 );
400
401 my @fedora_tex_pkgs = (
402 "texlive-collection-fontsrecommended",
403 "texlive-collection-latex",
404 "texlive-xecjk",
405 "dejavu-sans-fonts",
406 "dejavu-serif-fonts",
407 "dejavu-sans-mono-fonts",
408 );
409
410 #
411 # Checks valid for RHEL/CentOS version 7.x.
412 #
413 my $old = 0;
414 my $rel;
415 my $noto_sans_redhat = "google-noto-sans-cjk-ttc-fonts";
416 $rel = $1 if ($system_release =~ /(release|Linux)\s+(\d+)/);
417
418 if (!($system_release =~ /Fedora/)) {
419 $map{"virtualenv"} = "python-virtualenv";
420
421 if ($rel && $rel < 8) {
422 $old = 1;
423 $pdf = 0;
424
425 printf("Note: texlive packages on RHEL/CENTOS <= 7 are incomplete. Can't support PDF output\n");
426 printf("If you want to build PDF, please read:\n");
427 printf("\thttps://www.systutorials.com/241660/how-to-install-tex-live-on-centos-7-linux/\n");
428 }
429 } else {
430 if ($rel && $rel < 26) {
431 $old = 1;
432 }
433 if ($rel && $rel >= 38) {
434 $noto_sans_redhat = "google-noto-sans-cjk-fonts";
435 }
436 }
437 if (!$rel) {
438 printf("Couldn't identify release number\n");
439 $old = 1;
440 $pdf = 0;
441 }
442
443 if ($pdf) {
444 check_missing_file(["/usr/share/fonts/google-noto-cjk/NotoSansCJK-Regular.ttc",
445 "/usr/share/fonts/google-noto-sans-cjk-fonts/NotoSansCJK-Regular.ttc"],
446 $noto_sans_redhat, 2);
447 }
448
449 check_rpm_missing(\@fedora26_opt_pkgs, 2) if ($pdf && !$old);
450 check_rpm_missing(\@fedora_tex_pkgs, 2) if ($pdf);
451 check_missing_tex(2) if ($pdf);
452 check_missing(\%map);
453
454 return if (!$need && !$optional);
455
456 if (!$old) {
457 # dnf, for Fedora 18+
458 printf("You should run:\n") if ($verbose_warn_install);
459 printf("\n\tsudo dnf install -y $install\n");
460 } else {
461 # yum, for RHEL (and clones) or Fedora version < 18
462 printf("You should run:\n") if ($verbose_warn_install);
463 printf("\n\tsudo yum install -y $install\n");
464 }
465}
466
467sub give_opensuse_hints()
468{
469 my %map = (
470 "python-sphinx" => "python3-sphinx",
471 "yaml" => "python3-pyyaml",
472 "virtualenv" => "python3-virtualenv",
473 "dot" => "graphviz",
474 "convert" => "ImageMagick",
475 "Pod::Usage" => "perl-Pod-Usage",
476 "xelatex" => "texlive-xetex-bin",
477 );
478
479 # On Tumbleweed, this package is also named rsvg-convert
480 $map{"rsvg-convert"} = "rsvg-view" if (!($system_release =~ /Tumbleweed/));
481
482 my @suse_tex_pkgs = (
483 "texlive-babel-english",
484 "texlive-caption",
485 "texlive-colortbl",
486 "texlive-courier",
487 "texlive-dvips",
488 "texlive-helvetic",
489 "texlive-makeindex",
490 "texlive-metafont",
491 "texlive-metapost",
492 "texlive-palatino",
493 "texlive-preview",
494 "texlive-times",
495 "texlive-zapfchan",
496 "texlive-zapfding",
497 );
498
499 $map{"latexmk"} = "texlive-latexmk-bin";
500
501 # FIXME: add support for installing CJK fonts
502 #
503 # I tried hard, but was unable to find a way to install
504 # "Noto Sans CJK SC" on openSUSE
505
506 check_rpm_missing(\@suse_tex_pkgs, 2) if ($pdf);
507 check_missing_tex(2) if ($pdf);
508 check_missing(\%map);
509
510 return if (!$need && !$optional);
511 printf("You should run:\n") if ($verbose_warn_install);
512 printf("\n\tsudo zypper install --no-recommends $install\n");
513}
514
515sub give_mageia_hints()
516{
517 my %map = (
518 "python-sphinx" => "python3-sphinx",
519 "yaml" => "python3-yaml",
520 "virtualenv" => "python3-virtualenv",
521 "dot" => "graphviz",
522 "convert" => "ImageMagick",
523 "Pod::Usage" => "perl-Pod-Usage",
524 "xelatex" => "texlive",
525 "rsvg-convert" => "librsvg2",
526 );
527
528 my @tex_pkgs = (
529 "texlive-fontsextra",
530 );
531
532 $map{"latexmk"} = "texlive-collection-basic";
533
534 my $packager_cmd;
535 my $noto_sans;
536 if ($system_release =~ /OpenMandriva/) {
537 $packager_cmd = "dnf install";
538 $noto_sans = "noto-sans-cjk-fonts";
539 @tex_pkgs = ( "texlive-collection-fontsextra" );
540 } else {
541 $packager_cmd = "urpmi";
542 $noto_sans = "google-noto-sans-cjk-ttc-fonts";
543 }
544
545
546 if ($pdf) {
547 check_missing_file(["/usr/share/fonts/google-noto-cjk/NotoSansCJK-Regular.ttc",
548 "/usr/share/fonts/TTF/NotoSans-Regular.ttf"],
549 $noto_sans, 2);
550 }
551
552 check_rpm_missing(\@tex_pkgs, 2) if ($pdf);
553 check_missing(\%map);
554
555 return if (!$need && !$optional);
556 printf("You should run:\n") if ($verbose_warn_install);
557 printf("\n\tsudo $packager_cmd $install\n");
558}
559
560sub give_arch_linux_hints()
561{
562 my %map = (
563 "yaml" => "python-yaml",
564 "virtualenv" => "python-virtualenv",
565 "dot" => "graphviz",
566 "convert" => "imagemagick",
567 "xelatex" => "texlive-xetex",
568 "latexmk" => "texlive-core",
569 "rsvg-convert" => "extra/librsvg",
570 );
571
572 my @archlinux_tex_pkgs = (
573 "texlive-core",
574 "texlive-latexextra",
575 "ttf-dejavu",
576 );
577 check_pacman_missing(\@archlinux_tex_pkgs, 2) if ($pdf);
578
579 if ($pdf) {
580 check_missing_file(["/usr/share/fonts/noto-cjk/NotoSansCJK-Regular.ttc"],
581 "noto-fonts-cjk", 2);
582 }
583
584 check_missing(\%map);
585
586 return if (!$need && !$optional);
587 printf("You should run:\n") if ($verbose_warn_install);
588 printf("\n\tsudo pacman -S $install\n");
589}
590
591sub give_gentoo_hints()
592{
593 my %map = (
594 "yaml" => "dev-python/pyyaml",
595 "virtualenv" => "dev-python/virtualenv",
596 "dot" => "media-gfx/graphviz",
597 "convert" => "media-gfx/imagemagick",
598 "xelatex" => "dev-texlive/texlive-xetex media-fonts/dejavu",
599 "rsvg-convert" => "gnome-base/librsvg",
600 );
601
602 check_missing_file(["/usr/share/fonts/dejavu/DejaVuSans.ttf"],
603 "media-fonts/dejavu", 2) if ($pdf);
604
605 if ($pdf) {
606 check_missing_file(["/usr/share/fonts/noto-cjk/NotoSansCJKsc-Regular.otf",
607 "/usr/share/fonts/noto-cjk/NotoSerifCJK-Regular.ttc"],
608 "media-fonts/noto-cjk", 2);
609 }
610
611 check_missing(\%map);
612
613 return if (!$need && !$optional);
614
615 printf("You should run:\n") if ($verbose_warn_install);
616 printf("\n");
617
618 my $imagemagick = "media-gfx/imagemagick svg png";
619 my $cairo = "media-gfx/graphviz cairo pdf";
620 my $portage_imagemagick = "/etc/portage/package.use/imagemagick";
621 my $portage_cairo = "/etc/portage/package.use/graphviz";
622
623 if (qx(grep imagemagick $portage_imagemagick 2>/dev/null) eq "") {
624 printf("\tsudo su -c 'echo \"$imagemagick\" > $portage_imagemagick'\n")
625 }
626 if (qx(grep graphviz $portage_cairo 2>/dev/null) eq "") {
627 printf("\tsudo su -c 'echo \"$cairo\" > $portage_cairo'\n");
628 }
629
630 printf("\tsudo emerge --ask $install\n");
631
632}
633
634sub check_distros()
635{
636 # Distro-specific hints
637 if ($system_release =~ /Red Hat Enterprise Linux/) {
638 give_redhat_hints;
639 return;
640 }
641 if ($system_release =~ /CentOS/) {
642 give_redhat_hints;
643 return;
644 }
645 if ($system_release =~ /Scientific Linux/) {
646 give_redhat_hints;
647 return;
648 }
649 if ($system_release =~ /Oracle Linux Server/) {
650 give_redhat_hints;
651 return;
652 }
653 if ($system_release =~ /Fedora/) {
654 give_redhat_hints;
655 return;
656 }
657 if ($system_release =~ /Ubuntu/) {
658 give_debian_hints;
659 return;
660 }
661 if ($system_release =~ /Debian/) {
662 give_debian_hints;
663 return;
664 }
665 if ($system_release =~ /openSUSE/) {
666 give_opensuse_hints;
667 return;
668 }
669 if ($system_release =~ /Mageia/) {
670 give_mageia_hints;
671 return;
672 }
673 if ($system_release =~ /OpenMandriva/) {
674 give_mageia_hints;
675 return;
676 }
677 if ($system_release =~ /Arch Linux/) {
678 give_arch_linux_hints;
679 return;
680 }
681 if ($system_release =~ /Gentoo/) {
682 give_gentoo_hints;
683 return;
684 }
685
686 #
687 # Fall-back to generic hint code for other distros
688 # That's far from ideal, specially for LaTeX dependencies.
689 #
690 my %map = (
691 "sphinx-build" => "sphinx"
692 );
693 check_missing_tex(2) if ($pdf);
694 check_missing(\%map);
695 print "I don't know distro $system_release.\n";
696 print "So, I can't provide you a hint with the install procedure.\n";
697 print "There are likely missing dependencies.\n";
698}
699
700#
701# Common dependencies
702#4#
5# pylint: disable=C0103,C0114,C0115,C0116,C0301,C0302
6# pylint: disable=R0902,R0904,R0911,R0912,R0914,R0915,R1705,R1710,E1121
7
8# Note: this script requires at least Python 3.6 to run.
9# Don't add changes not compatible with it, it is meant to report
10# incompatible python versions.
11
12"""
13Dependency checker for Sphinx documentation Kernel build.
14
15This module provides tools to check for all required dependencies needed to
16build documentation using Sphinx, including system packages, Python modules
17and LaTeX packages for PDF generation.
18
19It detect packages for a subset of Linux distributions used by Kernel
20maintainers, showing hints and missing dependencies.
21
22The main class SphinxDependencyChecker handles the dependency checking logic
23and provides recommendations for installing missing packages. It supports both
24system package installations and Python virtual environments. By default,
25system pacage install is recommended.
26"""
27
28import argparse
29import os
30import re
31import subprocess
32import sys
33from glob import glob
34
35
36def parse_version(version):
37 """Convert a major.minor.patch version into a tuple"""
38 return tuple(int(x) for x in version.split("."))
39
40
41def ver_str(version):
42 """Returns a version tuple as major.minor.patch"""
43
44 return ".".join([str(x) for x in version])
45
46
47RECOMMENDED_VERSION = parse_version("3.4.3")
48MIN_PYTHON_VERSION = parse_version("3.7")
49
50
51class DepManager:
52 """
53 Manage package dependencies. There are three types of dependencies:
54
55 - System: dependencies required for docs build;
56 - Python: python dependencies for a native distro Sphinx install;
57 - PDF: dependencies needed by PDF builds.
58
59 Each dependency can be mandatory or optional. Not installing an optional
60 dependency won't break the build, but will cause degradation at the
61 docs output.
62 """
63
64 # Internal types of dependencies. Don't use them outside DepManager class.
65 _SYS_TYPE = 0
66 _PHY_TYPE = 1
67 _PDF_TYPE = 2
68
69 # Dependencies visible outside the class.
70 # The keys are tuple with: (type, is_mandatory flag).
71 #
72 # Currently we're not using all optional dep types. Yet, we'll keep all
73 # possible combinations here. They're not many, and that makes easier
74 # if later needed and for the name() method below
75
76 SYSTEM_MANDATORY = (_SYS_TYPE, True)
77 PYTHON_MANDATORY = (_PHY_TYPE, True)
78 PDF_MANDATORY = (_PDF_TYPE, True)
79
80 SYSTEM_OPTIONAL = (_SYS_TYPE, False)
81 PYTHON_OPTIONAL = (_PHY_TYPE, False)
82 PDF_OPTIONAL = (_PDF_TYPE, True)
83
84 def __init__(self, pdf):
85 """
86 Initialize internal vars:
87
88 - missing: missing dependencies list, containing a distro-independent
89 name for a missing dependency and its type.
90 - missing_pkg: ancillary dict containing missing dependencies in
91 distro namespace, organized by type.
92 - need: total number of needed dependencies. Never cleaned.
93 - optional: total number of optional dependencies. Never cleaned.
94 - pdf: Is PDF support enabled?
95 """
96 self.missing = {}
97 self.missing_pkg = {}
98 self.need = 0
99 self.optional = 0
100 self.pdf = pdf
101
102 @staticmethod
103 def name(dtype):
104 """
105 Ancillary routine to output a warn/error message reporting
106 missing dependencies.
107 """
108 if dtype[0] == DepManager._SYS_TYPE:
109 msg = "build"
110 elif dtype[0] == DepManager._PHY_TYPE:
111 msg = "Python"
112 else:
113 msg = "PDF"
114
115 if dtype[1]:
116 return f"ERROR: {msg} mandatory deps missing"
117 else:
118 return f"Warning: {msg} optional deps missing"
119
120 @staticmethod
121 def is_optional(dtype):
122 """Ancillary routine to report if a dependency is optional"""
123 return not dtype[1]
124
125 @staticmethod
126 def is_pdf(dtype):
127 """Ancillary routine to report if a dependency is for PDF generation"""
128 if dtype[0] == DepManager._PDF_TYPE:
129 return True
130
131 return False
132
133 def add_package(self, package, dtype):
134 """
135 Add a package at the self.missing() dictionary.
136 Doesn't update missing_pkg.
137 """
138 is_optional = DepManager.is_optional(dtype)
139 self.missing[package] = dtype
140 if is_optional:
141 self.optional += 1
142 else:
143 self.need += 1
144
145 def del_package(self, package):
146 """
147 Remove a package at the self.missing() dictionary.
148 Doesn't update missing_pkg.
149 """
150 if package in self.missing:
151 del self.missing[package]
152
153 def clear_deps(self):
154 """
155 Clear dependencies without changing needed/optional.
156
157 This is an ackward way to have a separate section to recommend
158 a package after system main dependencies.
159
160 TODO: rework the logic to prevent needing it.
161 """
162
163 self.missing = {}
164 self.missing_pkg = {}
165
166 def check_missing(self, progs):
167 """
168 Update self.missing_pkg, using progs dict to convert from the
169 agnostic package name to distro-specific one.
170
171 Returns an string with the packages to be installed, sorted and
172 with eventual duplicates removed.
173 """
174
175 self.missing_pkg = {}
176
177 for prog, dtype in sorted(self.missing.items()):
178 # At least on some LTS distros like CentOS 7, texlive doesn't
179 # provide all packages we need. When such distros are
180 # detected, we have to disable PDF output.
181 #
182 # So, we need to ignore the packages that distros would
183 # need for LaTeX to work
184 if DepManager.is_pdf(dtype) and not self.pdf:
185 self.optional -= 1
186 continue
187
188 if not dtype in self.missing_pkg:
189 self.missing_pkg[dtype] = []
190
191 self.missing_pkg[dtype].append(progs.get(prog, prog))
192
193 install = []
194 for dtype, pkgs in self.missing_pkg.items():
195 install += pkgs
196
197 return " ".join(sorted(set(install)))
198
199 def warn_install(self):
200 """
201 Emit warnings/errors related to missing packages.
202 """
203
204 output_msg = ""
205
206 for dtype in sorted(self.missing_pkg.keys()):
207 progs = " ".join(sorted(set(self.missing_pkg[dtype])))
208
209 try:
210 name = DepManager.name(dtype)
211 output_msg += f'{name}:\t{progs}\n'
212 except KeyError:
213 raise KeyError(f"ERROR!!!: invalid dtype for {progs}: {dtype}")
214
215 if output_msg:
216 print(f"\n{output_msg}")
217
218class AncillaryMethods:
219 """
220 Ancillary methods that checks for missing dependencies for different
221 types of types, like binaries, python modules, rpm deps, etc.
222 """
223
224 @staticmethod
225 def which(prog):
226 """
227 Our own implementation of which(). We could instead use
228 shutil.which(), but this function is simple enough.
229 Probably faster to use this implementation than to import shutil.
230 """
231 for path in os.environ.get("PATH", "").split(":"):
232 full_path = os.path.join(path, prog)
233 if os.access(full_path, os.X_OK):
234 return full_path
235
236 return None
237
238 @staticmethod
239 def get_python_version(cmd):
240 """
241 Get python version from a Python binary. As we need to detect if
242 are out there newer python binaries, we can't rely on sys.release here.
243 """
244
245 result = SphinxDependencyChecker.run([cmd, "--version"],
246 capture_output=True, text=True)
247 version = result.stdout.strip()
248
249 match = re.search(r"(\d+\.\d+\.\d+)", version)
250 if match:
251 return parse_version(match.group(1))
252
253 print(f"Can't parse version {version}")
254 return (0, 0, 0)
255
256 @staticmethod
257 def find_python():
258 """
259 Detect if are out there any python 3.xy version newer than the
260 current one.
261
262 Note: this routine is limited to up to 2 digits for python3. We
263 may need to update it one day, hopefully on a distant future.
264 """
265 patterns = [
266 "python3.[0-9]",
267 "python3.[0-9][0-9]",
268 ]
269
270 # Seek for a python binary newer than MIN_PYTHON_VERSION
271 for path in os.getenv("PATH", "").split(":"):
272 for pattern in patterns:
273 for cmd in glob(os.path.join(path, pattern)):
274 if os.path.isfile(cmd) and os.access(cmd, os.X_OK):
275 version = SphinxDependencyChecker.get_python_version(cmd)
276 if version >= MIN_PYTHON_VERSION:
277 return cmd
278
279 @staticmethod
280 def check_python():
281 """
282 Check if the current python binary satisfies our minimal requirement
283 for Sphinx build. If not, re-run with a newer version if found.
284 """
285 cur_ver = sys.version_info[:3]
286 if cur_ver >= MIN_PYTHON_VERSION:
287 ver = ver_str(cur_ver)
288 print(f"Python version: {ver}")
289
290 # This could be useful for debugging purposes
291 if SphinxDependencyChecker.which("docutils"):
292 result = SphinxDependencyChecker.run(["docutils", "--version"],
293 capture_output=True, text=True)
294 ver = result.stdout.strip()
295 match = re.search(r"(\d+\.\d+\.\d+)", ver)
296 if match:
297 ver = match.group(1)
298
299 print(f"Docutils version: {ver}")
300
301 return
302
303 python_ver = ver_str(cur_ver)
304
305 new_python_cmd = SphinxDependencyChecker.find_python()
306 if not new_python_cmd:
307 print(f"ERROR: Python version {python_ver} is not spported anymore\n")
308 print(" Can't find a new version. This script may fail")
309 return
310
311 # Restart script using the newer version
312 script_path = os.path.abspath(sys.argv[0])
313 args = [new_python_cmd, script_path] + sys.argv[1:]
314
315 print(f"Python {python_ver} not supported. Changing to {new_python_cmd}")
316
317 try:
318 os.execv(new_python_cmd, args)
319 except OSError as e:
320 sys.exit(f"Failed to restart with {new_python_cmd}: {e}")
321
322 @staticmethod
323 def run(*args, **kwargs):
324 """
325 Excecute a command, hiding its output by default.
326 Preserve comatibility with older Python versions.
327 """
328
329 capture_output = kwargs.pop('capture_output', False)
330
331 if capture_output:
332 if 'stdout' not in kwargs:
333 kwargs['stdout'] = subprocess.PIPE
334 if 'stderr' not in kwargs:
335 kwargs['stderr'] = subprocess.PIPE
336 else:
337 if 'stdout' not in kwargs:
338 kwargs['stdout'] = subprocess.DEVNULL
339 if 'stderr' not in kwargs:
340 kwargs['stderr'] = subprocess.DEVNULL
341
342 # Don't break with older Python versions
343 if 'text' in kwargs and sys.version_info < (3, 7):
344 kwargs['universal_newlines'] = kwargs.pop('text')
345
346 return subprocess.run(*args, **kwargs)
347
348class MissingCheckers(AncillaryMethods):
349 """
350 Contains some ancillary checkers for different types of binaries and
351 package managers.
352 """
353
354 def __init__(self, args, texlive):
355 """
356 Initialize its internal variables
357 """
358 self.pdf = args.pdf
359 self.virtualenv = args.virtualenv
360 self.version_check = args.version_check
361 self.texlive = texlive
362
363 self.min_version = (0, 0, 0)
364 self.cur_version = (0, 0, 0)
365
366 self.deps = DepManager(self.pdf)
367
368 self.need_symlink = 0
369 self.need_sphinx = 0
370
371 self.verbose_warn_install = 1
372
373 self.virtenv_dir = ""
374 self.install = ""
375 self.python_cmd = ""
376
377 self.virtenv_prefix = ["sphinx_", "Sphinx_" ]
378
379 def check_missing_file(self, files, package, dtype):
380 """
381 Does the file exists? If not, add it to missing dependencies.
382 """
383 for f in files:
384 if os.path.exists(f):
385 return
386 self.deps.add_package(package, dtype)
387
388 def check_program(self, prog, dtype):
389 """
390 Does the program exists and it is at the PATH?
391 If not, add it to missing dependencies.
392 """
393 found = self.which(prog)
394 if found:
395 return found
396
397 self.deps.add_package(prog, dtype)
398
399 return None
400
401 def check_perl_module(self, prog, dtype):
402 """
403 Does perl have a dependency? Is it available?
404 If not, add it to missing dependencies.
405
406 Right now, we still need Perl for doc build, as it is required
407 by some tools called at docs or kernel build time, like:
408
409 scripts/documentation-file-ref-check
410
411 Also, checkpatch is on Perl.
412 """
413
414 # While testing with lxc download template, one of the
415 # distros (Oracle) didn't have perl - nor even an option to install
416 # before installing oraclelinux-release-el9 package.
417 #
418 # Check it before running an error. If perl is not there,
419 # add it as a mandatory package, as some parts of the doc builder
420 # needs it.
421 if not self.which("perl"):
422 self.deps.add_package("perl", DepManager.SYSTEM_MANDATORY)
423 self.deps.add_package(prog, dtype)
424 return
425
426 try:
427 self.run(["perl", f"-M{prog}", "-e", "1"], check=True)
428 except subprocess.CalledProcessError:
429 self.deps.add_package(prog, dtype)
430
431 def check_python_module(self, module, is_optional=False):
432 """
433 Does a python module exists outside venv? If not, add it to missing
434 dependencies.
435 """
436 if is_optional:
437 dtype = DepManager.PYTHON_OPTIONAL
438 else:
439 dtype = DepManager.PYTHON_MANDATORY
440
441 try:
442 self.run([self.python_cmd, "-c", f"import {module}"], check=True)
443 except subprocess.CalledProcessError:
444 self.deps.add_package(module, dtype)
445
446 def check_rpm_missing(self, pkgs, dtype):
447 """
448 Does a rpm package exists? If not, add it to missing dependencies.
449 """
450 for prog in pkgs:
451 try:
452 self.run(["rpm", "-q", prog], check=True)
453 except subprocess.CalledProcessError:
454 self.deps.add_package(prog, dtype)
455
456 def check_pacman_missing(self, pkgs, dtype):
457 """
458 Does a pacman package exists? If not, add it to missing dependencies.
459 """
460 for prog in pkgs:
461 try:
462 self.run(["pacman", "-Q", prog], check=True)
463 except subprocess.CalledProcessError:
464 self.deps.add_package(prog, dtype)
465
466 def check_missing_tex(self, is_optional=False):
467 """
468 Does a LaTeX package exists? If not, add it to missing dependencies.
469 """
470 if is_optional:
471 dtype = DepManager.PDF_OPTIONAL
472 else:
473 dtype = DepManager.PDF_MANDATORY
474
475 kpsewhich = self.which("kpsewhich")
476 for prog, package in self.texlive.items():
477
478 # If kpsewhich is not there, just add it to deps
479 if not kpsewhich:
480 self.deps.add_package(package, dtype)
481 continue
482
483 # Check if the package is needed
484 try:
485 result = self.run(
486 [kpsewhich, prog], stdout=subprocess.PIPE, text=True, check=True
487 )
488
489 # Didn't find. Add it
490 if not result.stdout.strip():
491 self.deps.add_package(package, dtype)
492
493 except subprocess.CalledProcessError:
494 # kpsewhich returned an error. Add it, just in case
495 self.deps.add_package(package, dtype)
496
497 def get_sphinx_fname(self):
498 """
499 Gets the binary filename for sphinx-build.
500 """
501 if "SPHINXBUILD" in os.environ:
502 return os.environ["SPHINXBUILD"]
503
504 fname = "sphinx-build"
505 if self.which(fname):
506 return fname
507
508 fname = "sphinx-build-3"
509 if self.which(fname):
510 self.need_symlink = 1
511 return fname
512
513 return ""
514
515 def get_sphinx_version(self, cmd):
516 """
517 Gets sphinx-build version.
518 """
519 try:
520 result = self.run([cmd, "--version"],
521 stdout=subprocess.PIPE,
522 stderr=subprocess.STDOUT,
523 text=True, check=True)
524 except (subprocess.CalledProcessError, FileNotFoundError):
525 return None
526
527 for line in result.stdout.split("\n"):
528 match = re.match(r"^sphinx-build\s+([\d\.]+)(?:\+(?:/[\da-f]+)|b\d+)?\s*$", line)
529 if match:
530 return parse_version(match.group(1))
531
532 match = re.match(r"^Sphinx.*\s+([\d\.]+)\s*$", line)
533 if match:
534 return parse_version(match.group(1))
535
536 def check_sphinx(self, conf):
537 """
538 Checks Sphinx minimal requirements
539 """
540 try:
541 with open(conf, "r", encoding="utf-8") as f:
542 for line in f:
543 match = re.match(r"^\s*needs_sphinx\s*=\s*[\'\"]([\d\.]+)[\'\"]", line)
544 if match:
545 self.min_version = parse_version(match.group(1))
546 break
547 except IOError:
548 sys.exit(f"Can't open {conf}")
549
550 if not self.min_version:
551 sys.exit(f"Can't get needs_sphinx version from {conf}")
552
553 self.virtenv_dir = self.virtenv_prefix[0] + "latest"
554
555 sphinx = self.get_sphinx_fname()
556 if not sphinx:
557 self.need_sphinx = 1
558 return
559
560 self.cur_version = self.get_sphinx_version(sphinx)
561 if not self.cur_version:
562 sys.exit(f"{sphinx} didn't return its version")
563
564 if self.cur_version < self.min_version:
565 curver = ver_str(self.cur_version)
566 minver = ver_str(self.min_version)
567
568 print(f"ERROR: Sphinx version is {curver}. It should be >= {minver}")
569 self.need_sphinx = 1
570 return
571
572 # On version check mode, just assume Sphinx has all mandatory deps
573 if self.version_check and self.cur_version >= RECOMMENDED_VERSION:
574 sys.exit(0)
575
576 def catcheck(self, filename):
577 """
578 Reads a file if it exists, returning as string.
579 If not found, returns an empty string.
580 """
581 if os.path.exists(filename):
582 with open(filename, "r", encoding="utf-8") as f:
583 return f.read().strip()
584 return ""
585
586 def get_system_release(self):
587 """
588 Determine the system type. There's no unique way that would work
589 with all distros with a minimal package install. So, several
590 methods are used here.
591
592 By default, it will use lsb_release function. If not available, it will
593 fail back to reading the known different places where the distro name
594 is stored.
595
596 Several modern distros now have /etc/os-release, which usually have
597 a decent coverage.
598 """
599
600 system_release = ""
601
602 if self.which("lsb_release"):
603 result = self.run(["lsb_release", "-d"], capture_output=True, text=True)
604 system_release = result.stdout.replace("Description:", "").strip()
605
606 release_files = [
607 "/etc/system-release",
608 "/etc/redhat-release",
609 "/etc/lsb-release",
610 "/etc/gentoo-release",
611 ]
612
613 if not system_release:
614 for f in release_files:
615 system_release = self.catcheck(f)
616 if system_release:
617 break
618
619 # This seems more common than LSB these days
620 if not system_release:
621 os_var = {}
622 try:
623 with open("/etc/os-release", "r", encoding="utf-8") as f:
624 for line in f:
625 match = re.match(r"^([\w\d\_]+)=\"?([^\"]*)\"?\n", line)
626 if match:
627 os_var[match.group(1)] = match.group(2)
628
629 system_release = os_var.get("NAME", "")
630 if "VERSION_ID" in os_var:
631 system_release += " " + os_var["VERSION_ID"]
632 elif "VERSION" in os_var:
633 system_release += " " + os_var["VERSION"]
634 except IOError:
635 pass
636
637 if not system_release:
638 system_release = self.catcheck("/etc/issue")
639
640 system_release = system_release.strip()
641
642 return system_release
643
644class SphinxDependencyChecker(MissingCheckers):
645 """
646 Main class for checking Sphinx documentation build dependencies.
647
648 - Check for missing system packages;
649 - Check for missing Python modules;
650 - Check for missing LaTeX packages needed by PDF generation;
651 - Propose Sphinx install via Python Virtual environment;
652 - Propose Sphinx install via distro-specific package install.
653 """
654 def __init__(self, args):
655 """Initialize checker variables"""
656
657 # List of required texlive packages on Fedora and OpenSuse
658 texlive = {
659 "amsfonts.sty": "texlive-amsfonts",
660 "amsmath.sty": "texlive-amsmath",
661 "amssymb.sty": "texlive-amsfonts",
662 "amsthm.sty": "texlive-amscls",
663 "anyfontsize.sty": "texlive-anyfontsize",
664 "atbegshi.sty": "texlive-oberdiek",
665 "bm.sty": "texlive-tools",
666 "capt-of.sty": "texlive-capt-of",
667 "cmap.sty": "texlive-cmap",
668 "ctexhook.sty": "texlive-ctex",
669 "ecrm1000.tfm": "texlive-ec",
670 "eqparbox.sty": "texlive-eqparbox",
671 "eu1enc.def": "texlive-euenc",
672 "fancybox.sty": "texlive-fancybox",
673 "fancyvrb.sty": "texlive-fancyvrb",
674 "float.sty": "texlive-float",
675 "fncychap.sty": "texlive-fncychap",
676 "footnote.sty": "texlive-mdwtools",
677 "framed.sty": "texlive-framed",
678 "luatex85.sty": "texlive-luatex85",
679 "multirow.sty": "texlive-multirow",
680 "needspace.sty": "texlive-needspace",
681 "palatino.sty": "texlive-psnfss",
682 "parskip.sty": "texlive-parskip",
683 "polyglossia.sty": "texlive-polyglossia",
684 "tabulary.sty": "texlive-tabulary",
685 "threeparttable.sty": "texlive-threeparttable",
686 "titlesec.sty": "texlive-titlesec",
687 "ucs.sty": "texlive-ucs",
688 "upquote.sty": "texlive-upquote",
689 "wrapfig.sty": "texlive-wrapfig",
690 }
691
692 super().__init__(args, texlive)
693
694 self.need_pip = False
695 self.rec_sphinx_upgrade = 0
696
697 self.system_release = self.get_system_release()
698 self.activate_cmd = ""
699
700 # Some distros may not have a Sphinx shipped package compatible with
701 # our minimal requirements
702 self.package_supported = True
703
704 # Recommend a new python version
705 self.recommend_python = None
706
707 # Certain hints are meant to be shown only once
708 self.distro_msg = None
709
710 self.latest_avail_ver = (0, 0, 0)
711 self.venv_ver = (0, 0, 0)
712
713 prefix = os.environ.get("srctree", ".") + "/"
714
715 self.conf = prefix + "Documentation/conf.py"
716 self.requirement_file = prefix + "Documentation/sphinx/requirements.txt"
717
718 def get_install_progs(self, progs, cmd, extra=None):
719 """
720 Check for missing dependencies using the provided program mapping.
721
722 The actual distro-specific programs are mapped via progs argument.
723 """
724 install = self.deps.check_missing(progs)
725
726 if self.verbose_warn_install:
727 self.deps.warn_install()
728
729 if not install:
730 return
731
732 if cmd:
733 if self.verbose_warn_install:
734 msg = "You should run:"
735 else:
736 msg = ""
737
738 if extra:
739 msg += "\n\t" + extra.replace("\n", "\n\t")
740
741 return(msg + "\n\tsudo " + cmd + " " + install)
742
743 return None
744
745 #
746 # Distro-specific hints methods
747 #
748
749 def give_debian_hints(self):
750 """
751 Provide package installation hints for Debian-based distros.
752 """
753 progs = {
754 "Pod::Usage": "perl-modules",
755 "convert": "imagemagick",
756 "dot": "graphviz",
757 "ensurepip": "python3-venv",
758 "python-sphinx": "python3-sphinx",
759 "rsvg-convert": "librsvg2-bin",
760 "virtualenv": "virtualenv",
761 "xelatex": "texlive-xetex",
762 "yaml": "python3-yaml",
763 }
764
765 if self.pdf:
766 pdf_pkgs = {
767 "fonts-dejavu": [
768 "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
769 ],
770 "fonts-noto-cjk": [
771 "/usr/share/fonts/noto-cjk/NotoSansCJK-Regular.ttc",
772 "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc",
773 "/usr/share/fonts/opentype/noto/NotoSerifCJK-Regular.ttc",
774 ],
775 "tex-gyre": [
776 "/usr/share/texmf/tex/latex/tex-gyre/tgtermes.sty"
777 ],
778 "texlive-fonts-recommended": [
779 "/usr/share/texlive/texmf-dist/fonts/tfm/adobe/zapfding/pzdr.tfm",
780 ],
781 "texlive-lang-chinese": [
782 "/usr/share/texlive/texmf-dist/tex/latex/ctex/ctexhook.sty",
783 ],
784 }
785
786 for package, files in pdf_pkgs.items():
787 self.check_missing_file(files, package, DepManager.PDF_MANDATORY)
788
789 self.check_program("dvipng", DepManager.PDF_MANDATORY)
790
791 if not self.distro_msg:
792 self.distro_msg = \
793 "Note: ImageMagick is broken on some distros, affecting PDF output. For more details:\n" \
794 "\thttps://askubuntu.com/questions/1158894/imagemagick-still-broken-using-with-usr-bin-convert"
795
796 return self.get_install_progs(progs, "apt-get install")
797
798 def give_redhat_hints(self):
799 """
800 Provide package installation hints for RedHat-based distros
801 (Fedora, RHEL and RHEL-based variants).
802 """
803 progs = {
804 "Pod::Usage": "perl-Pod-Usage",
805 "convert": "ImageMagick",
806 "dot": "graphviz",
807 "python-sphinx": "python3-sphinx",
808 "rsvg-convert": "librsvg2-tools",
809 "virtualenv": "python3-virtualenv",
810 "xelatex": "texlive-xetex-bin",
811 "yaml": "python3-pyyaml",
812 }
813
814 fedora_tex_pkgs = [
815 "dejavu-sans-fonts",
816 "dejavu-sans-mono-fonts",
817 "dejavu-serif-fonts",
818 "texlive-collection-fontsrecommended",
819 "texlive-collection-latex",
820 "texlive-xecjk",
821 ]
822
823 fedora = False
824 rel = None
825
826 match = re.search(r"(release|Linux)\s+(\d+)", self.system_release)
827 if match:
828 rel = int(match.group(2))
829
830 if not rel:
831 print("Couldn't identify release number")
832 noto_sans_redhat = None
833 self.pdf = False
834 elif re.search("Fedora", self.system_release):
835 # Fedora 38 and upper use this CJK font
836
837 noto_sans_redhat = "google-noto-sans-cjk-fonts"
838 fedora = True
839 else:
840 # Almalinux, CentOS, RHEL, ...
841
842 # at least up to version 9 (and Fedora < 38), that's the CJK font
843 noto_sans_redhat = "google-noto-sans-cjk-ttc-fonts"
844
845 progs["virtualenv"] = "python-virtualenv"
846
847 if not rel or rel < 8:
848 print("ERROR: Distro not supported. Too old?")
849 return
850
851 # RHEL 8 uses Python 3.6, which is not compatible with
852 # the build system anymore. Suggest Python 3.11
853 if rel == 8:
854 self.check_program("python3.9", DepManager.SYSTEM_MANDATORY)
855 progs["python3.9"] = "python39"
856 progs["yaml"] = "python39-pyyaml"
857
858 self.recommend_python = True
859
860 # There's no python39-sphinx package. Only pip is supported
861 self.package_supported = False
862
863 if not self.distro_msg:
864 self.distro_msg = \
865 "Note: RHEL-based distros typically require extra repositories.\n" \
866 "For most, enabling epel and crb are enough:\n" \
867 "\tsudo dnf install -y epel-release\n" \
868 "\tsudo dnf config-manager --set-enabled crb\n" \
869 "Yet, some may have other required repositories. Those commands could be useful:\n" \
870 "\tsudo dnf repolist all\n" \
871 "\tsudo dnf repoquery --available --info <pkgs>\n" \
872 "\tsudo dnf config-manager --set-enabled '*' # enable all - probably not what you want"
873
874 if self.pdf:
875 pdf_pkgs = [
876 "/usr/share/fonts/google-noto-cjk/NotoSansCJK-Regular.ttc",
877 "/usr/share/fonts/google-noto-sans-cjk-fonts/NotoSansCJK-Regular.ttc",
878 ]
879
880 self.check_missing_file(pdf_pkgs, noto_sans_redhat, DepManager.PDF_MANDATORY)
881
882 self.check_rpm_missing(fedora_tex_pkgs, DepManager.PDF_MANDATORY)
883
884 self.check_missing_tex(DepManager.PDF_MANDATORY)
885
886 # There's no texlive-ctex on RHEL 8 repositories. This will
887 # likely affect CJK pdf build only.
888 if not fedora and rel == 8:
889 self.deps.del_package("texlive-ctex")
890
891 return self.get_install_progs(progs, "dnf install")
892
893 def give_opensuse_hints(self):
894 """
895 Provide package installation hints for openSUSE-based distros
896 (Leap and Tumbleweed).
897 """
898 progs = {
899 "Pod::Usage": "perl-Pod-Usage",
900 "convert": "ImageMagick",
901 "dot": "graphviz",
902 "python-sphinx": "python3-sphinx",
903 "virtualenv": "python3-virtualenv",
904 "xelatex": "texlive-xetex-bin texlive-dejavu",
905 "yaml": "python3-pyyaml",
906 }
907
908 suse_tex_pkgs = [
909 "texlive-babel-english",
910 "texlive-caption",
911 "texlive-colortbl",
912 "texlive-courier",
913 "texlive-dvips",
914 "texlive-helvetic",
915 "texlive-makeindex",
916 "texlive-metafont",
917 "texlive-metapost",
918 "texlive-palatino",
919 "texlive-preview",
920 "texlive-times",
921 "texlive-zapfchan",
922 "texlive-zapfding",
923 ]
924
925 progs["latexmk"] = "texlive-latexmk-bin"
926
927 match = re.search(r"(Leap)\s+(\d+).(\d)", self.system_release)
928 if match:
929 rel = int(match.group(2))
930
931 # Leap 15.x uses Python 3.6, which is not compatible with
932 # the build system anymore. Suggest Python 3.11
933 if rel == 15:
934 if not self.which(self.python_cmd):
935 self.check_program("python3.11", DepManager.SYSTEM_MANDATORY)
936 progs["python3.11"] = "python311"
937 self.recommend_python = True
938
939 progs.update({
940 "python-sphinx": "python311-Sphinx python311-Sphinx-latex",
941 "virtualenv": "python311-virtualenv",
942 "yaml": "python311-PyYAML",
943 })
944 else:
945 # Tumbleweed defaults to Python 3.11
946
947 progs.update({
948 "python-sphinx": "python313-Sphinx python313-Sphinx-latex",
949 "virtualenv": "python313-virtualenv",
950 "yaml": "python313-PyYAML",
951 })
952
953 # FIXME: add support for installing CJK fonts
954 #
955 # I tried hard, but was unable to find a way to install
956 # "Noto Sans CJK SC" on openSUSE
957
958 if self.pdf:
959 self.check_rpm_missing(suse_tex_pkgs, DepManager.PDF_MANDATORY)
960 if self.pdf:
961 self.check_missing_tex()
962
963 return self.get_install_progs(progs, "zypper install --no-recommends")
964
965 def give_mageia_hints(self):
966 """
967 Provide package installation hints for Mageia and OpenMandriva.
968 """
969 progs = {
970 "Pod::Usage": "perl-Pod-Usage",
971 "convert": "ImageMagick",
972 "dot": "graphviz",
973 "python-sphinx": "python3-sphinx",
974 "rsvg-convert": "librsvg2",
975 "virtualenv": "python3-virtualenv",
976 "xelatex": "texlive",
977 "yaml": "python3-yaml",
978 }
979
980 tex_pkgs = [
981 "texlive-fontsextra",
982 "texlive-fonts-asian",
983 "fonts-ttf-dejavu",
984 ]
985
986 if re.search(r"OpenMandriva", self.system_release):
987 packager_cmd = "dnf install"
988 noto_sans = "noto-sans-cjk-fonts"
989 tex_pkgs = [
990 "texlive-collection-basic",
991 "texlive-collection-langcjk",
992 "texlive-collection-fontsextra",
993 "texlive-collection-fontsrecommended"
994 ]
995
996 # Tested on OpenMandriva Lx 4.3
997 progs["convert"] = "imagemagick"
998 progs["yaml"] = "python-pyyaml"
999 progs["python-virtualenv"] = "python-virtualenv"
1000 progs["python-sphinx"] = "python-sphinx"
1001 progs["xelatex"] = "texlive"
1002
1003 self.check_program("python-virtualenv", DepManager.PYTHON_MANDATORY)
1004
1005 # On my tests with openMandriva LX 4.0 docker image, upgraded
1006 # to 4.3, python-virtualenv package is broken: it is missing
1007 # ensurepip. Without it, the alternative would be to run:
1008 # python3 -m venv --without-pip ~/sphinx_latest, but running
1009 # pip there won't install sphinx at venv.
1010 #
1011 # Add a note about that.
1012
1013 if not self.distro_msg:
1014 self.distro_msg = \
1015 "Notes:\n"\
1016 "1. for venv, ensurepip could be broken, preventing its install method.\n" \
1017 "2. at least on OpenMandriva LX 4.3, texlive packages seem broken"
1018
1019 else:
1020 packager_cmd = "urpmi"
1021 noto_sans = "google-noto-sans-cjk-ttc-fonts"
1022
1023 progs["latexmk"] = "texlive-collection-basic"
1024
1025 if self.pdf:
1026 pdf_pkgs = [
1027 "/usr/share/fonts/google-noto-cjk/NotoSansCJK-Regular.ttc",
1028 "/usr/share/fonts/TTF/NotoSans-Regular.ttf",
1029 ]
1030
1031 self.check_missing_file(pdf_pkgs, noto_sans, DepManager.PDF_MANDATORY)
1032 self.check_rpm_missing(tex_pkgs, DepManager.PDF_MANDATORY)
1033
1034 return self.get_install_progs(progs, packager_cmd)
1035
1036 def give_arch_linux_hints(self):
1037 """
1038 Provide package installation hints for ArchLinux.
1039 """
1040 progs = {
1041 "convert": "imagemagick",
1042 "dot": "graphviz",
1043 "latexmk": "texlive-core",
1044 "rsvg-convert": "extra/librsvg",
1045 "virtualenv": "python-virtualenv",
1046 "xelatex": "texlive-xetex",
1047 "yaml": "python-yaml",
1048 }
1049
1050 archlinux_tex_pkgs = [
1051 "texlive-basic",
1052 "texlive-binextra",
1053 "texlive-core",
1054 "texlive-fontsrecommended",
1055 "texlive-langchinese",
1056 "texlive-langcjk",
1057 "texlive-latexextra",
1058 "ttf-dejavu",
1059 ]
1060
1061 if self.pdf:
1062 self.check_pacman_missing(archlinux_tex_pkgs,
1063 DepManager.PDF_MANDATORY)
1064
1065 self.check_missing_file(["/usr/share/fonts/noto-cjk/NotoSansCJK-Regular.ttc"],
1066 "noto-fonts-cjk",
1067 DepManager.PDF_MANDATORY)
1068
1069
1070 return self.get_install_progs(progs, "pacman -S")
1071
1072 def give_gentoo_hints(self):
1073 """
1074 Provide package installation hints for Gentoo.
1075 """
1076 texlive_deps = [
1077 "dev-texlive/texlive-fontsrecommended",
1078 "dev-texlive/texlive-latexextra",
1079 "dev-texlive/texlive-xetex",
1080 "media-fonts/dejavu",
1081 ]
1082
1083 progs = {
1084 "convert": "media-gfx/imagemagick",
1085 "dot": "media-gfx/graphviz",
1086 "rsvg-convert": "gnome-base/librsvg",
1087 "virtualenv": "dev-python/virtualenv",
1088 "xelatex": " ".join(texlive_deps),
1089 "yaml": "dev-python/pyyaml",
1090 "python-sphinx": "dev-python/sphinx",
1091 }
1092
1093 if self.pdf:
1094 pdf_pkgs = {
1095 "media-fonts/dejavu": [
1096 "/usr/share/fonts/dejavu/DejaVuSans.ttf",
1097 ],
1098 "media-fonts/noto-cjk": [
1099 "/usr/share/fonts/noto-cjk/NotoSansCJKsc-Regular.otf",
1100 "/usr/share/fonts/noto-cjk/NotoSerifCJK-Regular.ttc",
1101 ],
1102 }
1103 for package, files in pdf_pkgs.items():
1104 self.check_missing_file(files, package, DepManager.PDF_MANDATORY)
1105
1106 # Handling dependencies is a nightmare, as Gentoo refuses to emerge
1107 # some packages if there's no package.use file describing them.
1108 # To make it worse, compilation flags shall also be present there
1109 # for some packages. If USE is not perfect, error/warning messages
1110 # like those are shown:
1111 #
1112 # !!! The following binary packages have been ignored due to non matching USE:
1113 #
1114 # =media-gfx/graphviz-12.2.1-r1 X pdf -python_single_target_python3_13 qt6 svg
1115 # =media-gfx/graphviz-12.2.1-r1 X pdf python_single_target_python3_12 -python_single_target_python3_13 qt6 svg
1116 # =media-gfx/graphviz-12.2.1-r1 X pdf qt6 svg
1117 # =media-gfx/graphviz-12.2.1-r1 X pdf -python_single_target_python3_10 qt6 svg
1118 # =media-gfx/graphviz-12.2.1-r1 X pdf -python_single_target_python3_10 python_single_target_python3_12 -python_single_target_python3_13 qt6 svg
1119 # =media-fonts/noto-cjk-20190416 X
1120 # =app-text/texlive-core-2024-r1 X cjk -xetex
1121 # =app-text/texlive-core-2024-r1 X -xetex
1122 # =app-text/texlive-core-2024-r1 -xetex
1123 # =dev-libs/zziplib-0.13.79-r1 sdl
1124 #
1125 # And will ignore such packages, installing the remaining ones. That
1126 # affects mostly the image extension and PDF generation.
1127
1128 # Package dependencies and the minimal needed args:
1129 portages = {
1130 "graphviz": "media-gfx/graphviz",
1131 "imagemagick": "media-gfx/imagemagick",
1132 "media-libs": "media-libs/harfbuzz icu",
1133 "media-fonts": "media-fonts/noto-cjk",
1134 "texlive": "app-text/texlive-core xetex",
1135 "zziblib": "dev-libs/zziplib sdl",
1136 }
1137
1138 extra_cmds = ""
1139 if not self.distro_msg:
1140 self.distro_msg = "Note: Gentoo requires package.use to be adjusted before emerging packages"
1141
1142 use_base = "/etc/portage/package.use"
1143 files = glob(f"{use_base}/*")
1144
1145 for fname, portage in portages.items():
1146 install = False
1147
1148 while install is False:
1149 if not files:
1150 # No files under package.usage. Install all
1151 install = True
1152 break
1153
1154 args = portage.split(" ")
1155
1156 name = args.pop(0)
1157
1158 cmd = ["grep", "-l", "-E", rf"^{name}\b" ] + files
1159 result = self.run(cmd, stdout=subprocess.PIPE, text=True)
1160 if result.returncode or not result.stdout.strip():
1161 # File containing portage name not found
1162 install = True
1163 break
1164
1165 # Ensure that needed USE flags are present
1166 if args:
1167 match_fname = result.stdout.strip()
1168 with open(match_fname, 'r', encoding='utf8',
1169 errors='backslashreplace') as fp:
1170 for line in fp:
1171 for arg in args:
1172 if arg.startswith("-"):
1173 continue
1174
1175 if not re.search(rf"\s*{arg}\b", line):
1176 # Needed file argument not found
1177 install = True
1178 break
1179
1180 # Everything looks ok, don't install
1181 break
1182
1183 # emit a code to setup missing USE
1184 if install:
1185 extra_cmds += (f"sudo su -c 'echo \"{portage}\" > {use_base}/{fname}'\n")
1186
1187 # Now, we can use emerge and let it respect USE
1188 return self.get_install_progs(progs,
1189 "emerge --ask --changed-use --binpkg-respect-use=y",
1190 extra_cmds)
1191
1192 def get_install(self):
1193 """
1194 OS-specific hints logic. Seeks for a hinter. If found, use it to
1195 provide package-manager specific install commands.
1196
1197 Otherwise, outputs install instructions for the meta-packages.
1198
1199 Returns a string with the command to be executed to install the
1200 the needed packages, if distro found. Otherwise, return just a
1201 list of packages that require installation.
1202 """
1203 os_hints = {
1204 re.compile("Red Hat Enterprise Linux"): self.give_redhat_hints,
1205 re.compile("Fedora"): self.give_redhat_hints,
1206 re.compile("AlmaLinux"): self.give_redhat_hints,
1207 re.compile("Amazon Linux"): self.give_redhat_hints,
1208 re.compile("CentOS"): self.give_redhat_hints,
1209 re.compile("openEuler"): self.give_redhat_hints,
1210 re.compile("Oracle Linux Server"): self.give_redhat_hints,
1211 re.compile("Rocky Linux"): self.give_redhat_hints,
1212 re.compile("Springdale Open Enterprise"): self.give_redhat_hints,
1213
1214 re.compile("Ubuntu"): self.give_debian_hints,
1215 re.compile("Debian"): self.give_debian_hints,
1216 re.compile("Devuan"): self.give_debian_hints,
1217 re.compile("Kali"): self.give_debian_hints,
1218 re.compile("Mint"): self.give_debian_hints,
1219
1220 re.compile("openSUSE"): self.give_opensuse_hints,
1221
1222 re.compile("Mageia"): self.give_mageia_hints,
1223 re.compile("OpenMandriva"): self.give_mageia_hints,
1224
1225 re.compile("Arch Linux"): self.give_arch_linux_hints,
1226 re.compile("Gentoo"): self.give_gentoo_hints,
1227 }
1228
1229 # If the OS is detected, use per-OS hint logic
1230 for regex, os_hint in os_hints.items():
1231 if regex.search(self.system_release):
1232 return os_hint()
1233
1234 #
1235 # Fall-back to generic hint code for other distros
1236 # That's far from ideal, specially for LaTeX dependencies.
1237 #
1238 progs = {"sphinx-build": "sphinx"}
1239 if self.pdf:
1240 self.check_missing_tex()
1241
1242 self.distro_msg = \
1243 f"I don't know distro {self.system_release}.\n" \
1244 "So, I can't provide you a hint with the install procedure.\n" \
1245 "There are likely missing dependencies."
1246
1247 return self.get_install_progs(progs, None)
1248
1249 #
1250 # Common dependencies
1251 #
1252 def deactivate_help(self):
1253 """
1254 Print a helper message to disable a virtual environment.
1255 """
1256
1257 print("\n If you want to exit the virtualenv, you can use:")
1258 print("\tdeactivate")
1259
1260 def get_virtenv(self):
1261 """
1262 Give a hint about how to activate an already-existing virtual
1263 environment containing sphinx-build.
1264
1265 Returns a tuble with (activate_cmd_path, sphinx_version) with
1266 the newest available virtual env.
1267 """
1268
1269 cwd = os.getcwd()
1270
1271 activates = []
1272
1273 # Add all sphinx prefixes with possible version numbers
1274 for p in self.virtenv_prefix:
1275 activates += glob(f"{cwd}/{p}[0-9]*/bin/activate")
1276
1277 activates.sort(reverse=True, key=str.lower)
1278
1279 # Place sphinx_latest first, if it exists
1280 for p in self.virtenv_prefix:
1281 activates = glob(f"{cwd}/{p}*latest/bin/activate") + activates
1282
1283 ver = (0, 0, 0)
1284 for f in activates:
1285 # Discard too old Sphinx virtual environments
1286 match = re.search(r"(\d+)\.(\d+)\.(\d+)", f)
1287 if match:
1288 ver = (int(match.group(1)), int(match.group(2)), int(match.group(3)))
1289
1290 if ver < self.min_version:
1291 continue
1292
1293 sphinx_cmd = f.replace("activate", "sphinx-build")
1294 if not os.path.isfile(sphinx_cmd):
1295 continue
1296
1297 ver = self.get_sphinx_version(sphinx_cmd)
1298
1299 if not ver:
1300 venv_dir = f.replace("/bin/activate", "")
1301 print(f"Warning: virtual environment {venv_dir} is not working.\n" \
1302 "Python version upgrade? Remove it with:\n\n" \
1303 "\trm -rf {venv_dir}\n\n")
1304 else:
1305 if self.need_sphinx and ver >= self.min_version:
1306 return (f, ver)
1307 elif parse_version(ver) > self.cur_version:
1308 return (f, ver)
1309
1310 return ("", ver)
1311
1312 def recommend_sphinx_upgrade(self):
1313 """
1314 Check if Sphinx needs to be upgraded.
1315
1316 Returns a tuple with the higest available Sphinx version if found.
1317 Otherwise, returns None to indicate either that no upgrade is needed
1318 or no venv was found.
1319 """
1320
1321 # Avoid running sphinx-builds from venv if cur_version is good
1322 if self.cur_version and self.cur_version >= RECOMMENDED_VERSION:
1323 self.latest_avail_ver = self.cur_version
1324 return None
1325
1326 # Get the highest version from sphinx_*/bin/sphinx-build and the
1327 # corresponding command to activate the venv/virtenv
1328 self.activate_cmd, self.venv_ver = self.get_virtenv()
1329
1330 # Store the highest version from Sphinx existing virtualenvs
1331 if self.activate_cmd and self.venv_ver > self.cur_version:
1332 self.latest_avail_ver = self.venv_ver
1333 else:
1334 if self.cur_version:
1335 self.latest_avail_ver = self.cur_version
1336 else:
1337 self.latest_avail_ver = (0, 0, 0)
1338
1339 # As we don't know package version of Sphinx, and there's no
1340 # virtual environments, don't check if upgrades are needed
1341 if not self.virtualenv:
1342 if not self.latest_avail_ver:
1343 return None
1344
1345 return self.latest_avail_ver
1346
1347 # Either there are already a virtual env or a new one should be created
1348 self.need_pip = True
1349
1350 if not self.latest_avail_ver:
1351 return None
1352
1353 # Return if the reason is due to an upgrade or not
1354 if self.latest_avail_ver != (0, 0, 0):
1355 if self.latest_avail_ver < RECOMMENDED_VERSION:
1356 self.rec_sphinx_upgrade = 1
1357
1358 return self.latest_avail_ver
1359
1360 def recommend_package(self):
1361 """
1362 Recommend installing Sphinx as a distro-specific package.
1363 """
1364
1365 print("\n2) As a package with:")
1366
1367 old_need = self.deps.need
1368 old_optional = self.deps.optional
1369
1370 self.pdf = False
1371 self.deps.optional = 0
1372 old_verbose = self.verbose_warn_install
1373 self.verbose_warn_install = 0
1374
1375 self.deps.clear_deps()
1376
1377 self.deps.add_package("python-sphinx", DepManager.PYTHON_MANDATORY)
1378
1379 cmd = self.get_install()
1380 if cmd:
1381 print(cmd)
1382
1383 self.deps.need = old_need
1384 self.deps.optional = old_optional
1385 self.verbose_warn_install = old_verbose
1386
1387 def recommend_sphinx_version(self, virtualenv_cmd):
1388 """
1389 Provide recommendations for installing or upgrading Sphinx based
1390 on current version.
1391
1392 The logic here is complex, as it have to deal with different versions:
1393
1394 - minimal supported version;
1395 - minimal PDF version;
1396 - recommended version.
1397
1398 It also needs to work fine with both distro's package and
1399 venv/virtualenv
1400 """
1401
1402 if self.recommend_python:
1403 cur_ver = sys.version_info[:3]
1404 if cur_ver < MIN_PYTHON_VERSION:
1405 print(f"\nPython version {cur_ver} is incompatible with doc build.\n" \
1406 "Please upgrade it and re-run.\n")
1407 return
1408
1409 # Version is OK. Nothing to do.
1410 if self.cur_version != (0, 0, 0) and self.cur_version >= RECOMMENDED_VERSION:
1411 return
1412
1413 if self.latest_avail_ver:
1414 latest_avail_ver = ver_str(self.latest_avail_ver)
1415
1416 if not self.need_sphinx:
1417 # sphinx-build is present and its version is >= $min_version
1418
1419 # only recommend enabling a newer virtenv version if makes sense.
1420 if self.latest_avail_ver and self.latest_avail_ver > self.cur_version:
1421 print(f"\nYou may also use the newer Sphinx version {latest_avail_ver} with:")
1422 if f"{self.virtenv_prefix}" in os.getcwd():
1423 print("\tdeactivate")
1424 print(f"\t. {self.activate_cmd}")
1425 self.deactivate_help()
1426 return
1427
1428 if self.latest_avail_ver and self.latest_avail_ver >= RECOMMENDED_VERSION:
1429 return
1430
1431 if not self.virtualenv:
1432 # No sphinx either via package or via virtenv. As we can't
1433 # Compare the versions here, just return, recommending the
1434 # user to install it from the package distro.
1435 if not self.latest_avail_ver or self.latest_avail_ver == (0, 0, 0):
1436 return
1437
1438 # User doesn't want a virtenv recommendation, but he already
1439 # installed one via virtenv with a newer version.
1440 # So, print commands to enable it
1441 if self.latest_avail_ver > self.cur_version:
1442 print(f"\nYou may also use the Sphinx virtualenv version {latest_avail_ver} with:")
1443 if f"{self.virtenv_prefix}" in os.getcwd():
1444 print("\tdeactivate")
1445 print(f"\t. {self.activate_cmd}")
1446 self.deactivate_help()
1447 return
1448 print("\n")
1449 else:
1450 if self.need_sphinx:
1451 self.deps.need += 1
1452
1453 # Suggest newer versions if current ones are too old
1454 if self.latest_avail_ver and self.latest_avail_ver >= self.min_version:
1455 if self.latest_avail_ver >= RECOMMENDED_VERSION:
1456 print(f"\nNeed to activate Sphinx (version {latest_avail_ver}) on virtualenv with:")
1457 print(f"\t. {self.activate_cmd}")
1458 self.deactivate_help()
1459 return
1460
1461 # Version is above the minimal required one, but may be
1462 # below the recommended one. So, print warnings/notes
1463 if self.latest_avail_ver < RECOMMENDED_VERSION:
1464 print(f"Warning: It is recommended at least Sphinx version {RECOMMENDED_VERSION}.")
1465
1466 # At this point, either it needs Sphinx or upgrade is recommended,
1467 # both via pip
1468
1469 if self.rec_sphinx_upgrade:
1470 if not self.virtualenv:
1471 print("Instead of install/upgrade Python Sphinx pkg, you could use pip/pypi with:\n\n")
1472 else:
1473 print("To upgrade Sphinx, use:\n\n")
1474 else:
1475 print("\nSphinx needs to be installed either:\n1) via pip/pypi with:\n")
1476
1477 if not virtualenv_cmd:
1478 print(" Currently not possible.\n")
1479 print(" Please upgrade Python to a newer version and run this script again")
1480 else:
1481 print(f"\t{virtualenv_cmd} {self.virtenv_dir}")
1482 print(f"\t. {self.virtenv_dir}/bin/activate")
1483 print(f"\tpip install -r {self.requirement_file}")
1484 self.deactivate_help()
1485
1486 if self.package_supported:
1487 self.recommend_package()
1488
1489 print("\n" \
1490 " Please note that Sphinx currentlys produce false-positive\n" \
1491 " warnings when the same name is used for more than one type (functions,\n" \
1492 " structs, enums,...). This is known Sphinx bug. For more details, see:\n" \
1493 "\thttps://github.com/sphinx-doc/sphinx/pull/8313")
1494
1495 def check_needs(self):
1496 """
1497 Main method that checks needed dependencies and provides
1498 recommendations.
1499 """
1500 self.python_cmd = sys.executable
1501
1502 # Check if Sphinx is already accessible from current environment
1503 self.check_sphinx(self.conf)
1504
1505 if self.system_release:
1506 print(f"Detected OS: {self.system_release}.")
1507 else:
1508 print("Unknown OS")
1509 if self.cur_version != (0, 0, 0):
1510 ver = ver_str(self.cur_version)
1511 print(f"Sphinx version: {ver}\n")
1512
1513 # Check the type of virtual env, depending on Python version
1514 virtualenv_cmd = None
1515
1516 if sys.version_info < MIN_PYTHON_VERSION:
1517 min_ver = ver_str(MIN_PYTHON_VERSION)
1518 print(f"ERROR: at least python {min_ver} is required to build the kernel docs")
1519 self.need_sphinx = 1
1520
1521 self.venv_ver = self.recommend_sphinx_upgrade()
1522
1523 if self.need_pip:
1524 if sys.version_info < MIN_PYTHON_VERSION:
1525 self.need_pip = False
1526 print("Warning: python version is not supported.")
1527 else:
1528 virtualenv_cmd = f"{self.python_cmd} -m venv"
1529 self.check_python_module("ensurepip")
1530
1531 # Check for needed programs/tools
1532 self.check_perl_module("Pod::Usage", DepManager.SYSTEM_MANDATORY)
1533
1534 self.check_program("make", DepManager.SYSTEM_MANDATORY)
1535 self.check_program("which", DepManager.SYSTEM_MANDATORY)
1536
1537 self.check_program("dot", DepManager.SYSTEM_OPTIONAL)
1538 self.check_program("convert", DepManager.SYSTEM_OPTIONAL)
1539
1540 self.check_python_module("yaml")
1541
1542 if self.pdf:
1543 self.check_program("xelatex", DepManager.PDF_MANDATORY)
1544 self.check_program("rsvg-convert", DepManager.PDF_MANDATORY)
1545 self.check_program("latexmk", DepManager.PDF_MANDATORY)
1546
1547 # Do distro-specific checks and output distro-install commands
1548 cmd = self.get_install()
1549 if cmd:
1550 print(cmd)
1551
1552 # If distro requires some special instructions, print here.
1553 # Please notice that get_install() needs to be called first.
1554 if self.distro_msg:
1555 print("\n" + self.distro_msg)
1556
1557 if not self.python_cmd:
1558 if self.need == 1:
1559 sys.exit("Can't build as 1 mandatory dependency is missing")
1560 elif self.need:
1561 sys.exit(f"Can't build as {self.need} mandatory dependencies are missing")
1562
1563 # Check if sphinx-build is called sphinx-build-3
1564 if self.need_symlink:
1565 sphinx_path = self.which("sphinx-build-3")
1566 if sphinx_path:
1567 print(f"\tsudo ln -sf {sphinx_path} /usr/bin/sphinx-build\n")
1568
1569 self.recommend_sphinx_version(virtualenv_cmd)
1570 print("")
1571
1572 if not self.deps.optional:
1573 print("All optional dependencies are met.")
1574
1575 if self.deps.need == 1:
1576 sys.exit("Can't build as 1 mandatory dependency is missing")
1577 elif self.deps.need:
1578 sys.exit(f"Can't build as {self.deps.need} mandatory dependencies are missing")
1579
1580 print("Needed package dependencies are met.")
1581
1582DESCRIPTION = """
1583Process some flags related to Sphinx installation and documentation build.
1584"""
1585
1586
1587def main():
1588 """Main function"""
1589 parser = argparse.ArgumentParser(description=DESCRIPTION)
1590
1591 parser.add_argument(
1592 "--no-virtualenv",
1593 action="store_false",
1594 dest="virtualenv",
1595 help="Recommend installing Sphinx instead of using a virtualenv",
1596 )
1597
1598 parser.add_argument(
1599 "--no-pdf",
1600 action="store_false",
1601 dest="pdf",
1602 help="Don't check for dependencies required to build PDF docs",
1603 )
1604
1605 parser.add_argument(
1606 "--version-check",
1607 action="store_true",
1608 dest="version_check",
1609 help="If version is compatible, don't check for missing dependencies",
1610 )
703 1611
704sub deactivate_help()1612 args = parser.parse_args()
705{1613
706 printf "\n If you want to exit the virtualenv, you can use:\n";1614 checker = SphinxDependencyChecker(args)
707 printf "\tdeactivate\n";
708}
709
710sub get_virtenv()
711{
712 my $ver;
713 my $min_activate = "$ENV{'PWD'}/${virtenv_prefix}${min_version}/bin/activate";
714 my @activates = glob "$ENV{'PWD'}/${virtenv_prefix}*/bin/activate";
715
716 @activates = sort {$b cmp $a} @activates;
717
718 foreach my $f (@activates) {
719 next if ($f lt $min_activate);
720
721 my $sphinx_cmd = $f;
722 $sphinx_cmd =~ s/activate/sphinx-build/;
723 next if (! -f $sphinx_cmd);
724
725 my $ver = get_sphinx_version($sphinx_cmd);
726
727 if (!$ver) {
728 $f =~ s#/bin/activate##;
729 print("Warning: virtual environment $f is not working.\nPython version upgrade? Remove it with:\n\n\trm -rf $f\n\n");
730 }
731
732 if ($need_sphinx && ($ver ge $min_version)) {
733 return ($f, $ver);
734 } elsif ($ver gt $cur_version) {
735 return ($f, $ver);
736 }
737 }
738 return ("", "");
739}
740
741sub recommend_sphinx_upgrade()
742{
743 my $venv_ver;
744
745 # Avoid running sphinx-builds from venv if $cur_version is good
746 if ($cur_version && ($cur_version ge $rec_version)) {
747 $latest_avail_ver = $cur_version;
748 return;
749 }
750
751 # Get the highest version from sphinx_*/bin/sphinx-build and the
752 # corresponding command to activate the venv/virtenv
753 ($activate_cmd, $venv_ver) = get_virtenv();
754
755 # Store the highest version from Sphinx existing virtualenvs
756 if (($activate_cmd ne "") && ($venv_ver gt $cur_version)) {
757 $latest_avail_ver = $venv_ver;
758 } else {
759 $latest_avail_ver = $cur_version if ($cur_version);
760 }
761
762 # As we don't know package version of Sphinx, and there's no
763 # virtual environments, don't check if upgrades are needed
764 if (!$virtualenv) {
765 return if (!$latest_avail_ver);
766 }
767
768 # Either there are already a virtual env or a new one should be created
769 $need_pip = 1;
770
771 return if (!$latest_avail_ver);
772
773 # Return if the reason is due to an upgrade or not
774 if ($latest_avail_ver lt $rec_version) {
775 $rec_sphinx_upgrade = 1;
776 }
777
778 return $latest_avail_ver;
779}
780
781#
782# The logic here is complex, as it have to deal with different versions:
783# - minimal supported version;
784# - minimal PDF version;
785# - recommended version.
786# It also needs to work fine with both distro's package and venv/virtualenv
787sub recommend_sphinx_version($)
788{
789 my $virtualenv_cmd = shift;
790
791 # Version is OK. Nothing to do.
792 if ($cur_version && ($cur_version ge $rec_version)) {
793 return;
794 };
795
796 if (!$need_sphinx) {
797 # sphinx-build is present and its version is >= $min_version
798
799 #only recommend enabling a newer virtenv version if makes sense.
800 if ($latest_avail_ver gt $cur_version) {
801 printf "\nYou may also use the newer Sphinx version $latest_avail_ver with:\n";
802 printf "\tdeactivate\n" if ($ENV{'PWD'} =~ /${virtenv_prefix}/);
803 printf "\t. $activate_cmd\n";
804 deactivate_help();
805
806 return;
807 }
808 return if ($latest_avail_ver ge $rec_version);
809 }
810
811 if (!$virtualenv) {
812 # No sphinx either via package or via virtenv. As we can't
813 # Compare the versions here, just return, recommending the
814 # user to install it from the package distro.
815 return if (!$latest_avail_ver);
816
817 # User doesn't want a virtenv recommendation, but he already
818 # installed one via virtenv with a newer version.
819 # So, print commands to enable it
820 if ($latest_avail_ver gt $cur_version) {
821 printf "\nYou may also use the Sphinx virtualenv version $latest_avail_ver with:\n";
822 printf "\tdeactivate\n" if ($ENV{'PWD'} =~ /${virtenv_prefix}/);
823 printf "\t. $activate_cmd\n";
824 deactivate_help();
825
826 return;
827 }
828 print "\n";
829 } else {
830 $need++ if ($need_sphinx);
831 }
832
833 # Suggest newer versions if current ones are too old
834 if ($latest_avail_ver && $latest_avail_ver ge $min_version) {
835 # If there's a good enough version, ask the user to enable it
836 if ($latest_avail_ver ge $rec_version) {
837 printf "\nNeed to activate Sphinx (version $latest_avail_ver) on virtualenv with:\n";
838 printf "\t. $activate_cmd\n";
839 deactivate_help();
840
841 return;
842 }
843
844 # Version is above the minimal required one, but may be
845 # below the recommended one. So, print warnings/notes
846
847 if ($latest_avail_ver lt $rec_version) {
848 print "Warning: It is recommended at least Sphinx version $rec_version.\n";
849 }
850 }
851
852 # At this point, either it needs Sphinx or upgrade is recommended,
853 # both via pip
854
855 if ($rec_sphinx_upgrade) {
856 if (!$virtualenv) {
857 print "Instead of install/upgrade Python Sphinx pkg, you could use pip/pypi with:\n\n";
858 } else {
859 print "To upgrade Sphinx, use:\n\n";
860 }
861 } else {
862 print "\nSphinx needs to be installed either:\n1) via pip/pypi with:\n\n";
863 }
864
865 $python_cmd = find_python_no_venv();
866
867 printf "\t$virtualenv_cmd $virtenv_dir\n";
868
869 printf "\t. $virtenv_dir/bin/activate\n";
870 printf "\tpip install -r $requirement_file\n";
871 deactivate_help();
872
873 printf "\n2) As a package with:\n";
874
875 my $old_need = $need;
876 my $old_optional = $optional;
877 %missing = ();
878 $pdf = 0;
879 $optional = 0;
880 $install = "";
881 $verbose_warn_install = 0;
882
883 add_package("python-sphinx", 0);
884
885 check_distros();
886
887 $need = $old_need;
888 $optional = $old_optional;
889
890 printf "\n Please note that Sphinx >= 3.0 will currently produce false-positive\n";
891 printf " warning when the same name is used for more than one type (functions,\n";
892 printf " structs, enums,...). This is known Sphinx bug. For more details, see:\n";
893 printf "\thttps://github.com/sphinx-doc/sphinx/pull/8313\n";
894}
895
896sub check_needs()
897{
898 # Check if Sphinx is already accessible from current environment
899 check_sphinx();
900
901 if ($system_release) {
902 print "Detected OS: $system_release.\n";
903 } else {
904 print "Unknown OS\n";
905 }
906 printf "Sphinx version: %s\n\n", $cur_version if ($cur_version);
907
908 # Check python command line, trying first python3
909 $python_cmd = findprog("python3");
910 $python_cmd = check_program("python", 0) if (!$python_cmd);
911
912 # Check the type of virtual env, depending on Python version
913 if ($python_cmd) {
914 if ($virtualenv) {
915 my $tmp = qx($python_cmd --version 2>&1);
916 if ($tmp =~ m/(\d+\.)(\d+\.)/) {
917 if ($1 < 3) {
918 # Fail if it finds python2 (or worse)
919 die "Python 3 is required to build the kernel docs\n";
920 }
921 if ($1 == 3 && $2 < 3) {
922 # Need Python 3.3 or upper for venv
923 $need_virtualenv = 1;
924 }
925 } else {
926 die "Warning: couldn't identify $python_cmd version!";
927 }
928 } else {
929 add_package("python-sphinx", 0);
930 }
931 }
932
933 my $venv_ver = recommend_sphinx_upgrade();
934
935 my $virtualenv_cmd;
936
937 if ($need_pip) {
938 # Set virtualenv command line, if python < 3.3
939 if ($need_virtualenv) {
940 $virtualenv_cmd = findprog("virtualenv-3");
941 $virtualenv_cmd = findprog("virtualenv-3.5") if (!$virtualenv_cmd);
942 if (!$virtualenv_cmd) {
943 check_program("virtualenv", 0);
944 $virtualenv_cmd = "virtualenv";
945 }
946 } else {
947 $virtualenv_cmd = "$python_cmd -m venv";
948 check_python_module("ensurepip", 0);
949 }
950 }
951
952 # Check for needed programs/tools
953 check_perl_module("Pod::Usage", 0);
954 check_python_module("yaml", 0);
955 check_program("make", 0);
956 check_program("gcc", 0);
957 check_program("dot", 1);
958 check_program("convert", 1);
959
960 # Extra PDF files - should use 2 for is_optional
961 check_program("xelatex", 2) if ($pdf);
962 check_program("rsvg-convert", 2) if ($pdf);
963 check_program("latexmk", 2) if ($pdf);
964
965 # Do distro-specific checks and output distro-install commands
966 check_distros();
967
968 if (!$python_cmd) {
969 if ($need == 1) {
970 die "Can't build as $need mandatory dependency is missing";
971 } elsif ($need) {
972 die "Can't build as $need mandatory dependencies are missing";
973 }
974 }
975
976 # Check if sphinx-build is called sphinx-build-3
977 if ($need_symlink) {
978 printf "\tsudo ln -sf %s /usr/bin/sphinx-build\n\n",
979 which("sphinx-build-3");
980 }
981
982 recommend_sphinx_version($virtualenv_cmd);
983 printf "\n";
984
985 print "All optional dependencies are met.\n" if (!$optional);
986
987 if ($need == 1) {
988 die "Can't build as $need mandatory dependency is missing";
989 } elsif ($need) {
990 die "Can't build as $need mandatory dependencies are missing";
991 }
992
993 print "Needed package dependencies are met.\n";
994}
995
996#
997# Main
998#
999
1000while (@ARGV) {
1001 my $arg = shift(@ARGV);
1002
1003 if ($arg eq "--no-virtualenv") {
1004 $virtualenv = 0;
1005 } elsif ($arg eq "--no-pdf"){
1006 $pdf = 0;
1007 } elsif ($arg eq "--version-check"){
1008 $version_check = 1;
1009 } else {
1010 print "Usage:\n\t$0 <--no-virtualenv> <--no-pdf> <--version-check>\n\n";
1011 print "Where:\n";
1012 print "\t--no-virtualenv\t- Recommend installing Sphinx instead of using a virtualenv\n";
1013 print "\t--version-check\t- if version is compatible, don't check for missing dependencies\n";
1014 print "\t--no-pdf\t- don't check for dependencies required to build PDF docs\n\n";
1015 exit -1;
1016 }
1017}
1018
1019#
1020# Determine the system type. There's no standard unique way that would
1021# work with all distros with a minimal package install. So, several
1022# methods are used here.
1023#
1024# By default, it will use lsb_release function. If not available, it will
1025# fail back to reading the known different places where the distro name
1026# is stored
1027#
1028 1615
1029$system_release = qx(lsb_release -d) if which("lsb_release");1616 checker.check_python()
1030$system_release =~ s/Description:\s*// if ($system_release);1617 checker.check_needs()
1031$system_release = catcheck("/etc/system-release") if !$system_release;1618
1032$system_release = catcheck("/etc/redhat-release") if !$system_release;1619# Call main if not used as module
1033$system_release = catcheck("/etc/lsb-release") if !$system_release;1620if __name__ == "__main__":
1034$system_release = catcheck("/etc/gentoo-release") if !$system_release;1621 main()
1035
1036# This seems more common than LSB these days
1037if (!$system_release) {
1038 my %os_var;
1039 if (open IN, "cat /etc/os-release|") {
1040 while (<IN>) {
1041 if (m/^([\w\d\_]+)=\"?([^\"]*)\"?\n/) {
1042 $os_var{$1}=$2;
1043 }
1044 }
1045 $system_release = $os_var{"NAME"};
1046 if (defined($os_var{"VERSION_ID"})) {
1047 $system_release .= " " . $os_var{"VERSION_ID"} if (defined($os_var{"VERSION_ID"}));
1048 } else {
1049 $system_release .= " " . $os_var{"VERSION"};
1050 }
1051 }
1052}
1053$system_release = catcheck("/etc/issue") if !$system_release;
1054$system_release =~ s/\s+$//;
1055
1056check_needs;
tools/docs/gen-redirects.py+54−0
@@ -0,0 +1,54 @@
1#! /usr/bin/env python3
2# SPDX-License-Identifier: GPL-2.0
3#
4# Copyright © 2025, Oracle and/or its affiliates.
5# Author: Vegard Nossum <vegard.nossum@oracle.com>
6
7"""Generate HTML redirects for renamed Documentation/**.rst files using
8the output of tools/docs/gen-renames.py.
9
10Example:
11
12 tools/docs/gen-redirects.py --output Documentation/output/ < Documentation/.renames.txt
13"""
14
15import argparse
16import os
17import sys
18
19parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
20parser.add_argument('-o', '--output', help='output directory')
21
22args = parser.parse_args()
23
24for line in sys.stdin:
25 line = line.rstrip('\n')
26
27 old_name, new_name = line.split(' ', 2)
28
29 old_html_path = os.path.join(args.output, old_name + '.html')
30 new_html_path = os.path.join(args.output, new_name + '.html')
31
32 if not os.path.exists(new_html_path):
33 print(f"warning: target does not exist: {new_html_path} (redirect from {old_html_path})")
34 continue
35
36 old_html_dir = os.path.dirname(old_html_path)
37 if not os.path.exists(old_html_dir):
38 os.makedirs(old_html_dir)
39
40 relpath = os.path.relpath(new_name, os.path.dirname(old_name)) + '.html'
41
42 with open(old_html_path, 'w') as f:
43 print(f"""\
44<!DOCTYPE html>
45
46<html lang="en">
47<head>
48 <title>This page has moved</title>
49 <meta http-equiv="refresh" content="0; url={relpath}">
50</head>
51<body>
52<p>This page has moved to <a href="{relpath}">{new_name}</a>.</p>
53</body>
54</html>""", file=f)
tools/docs/gen-renames.py+130−0
@@ -0,0 +1,130 @@
1#! /usr/bin/env python3
2# SPDX-License-Identifier: GPL-2.0
3#
4# Copyright © 2025, Oracle and/or its affiliates.
5# Author: Vegard Nossum <vegard.nossum@oracle.com>
6
7"""Trawl repository history for renames of Documentation/**.rst files.
8
9Example:
10
11 tools/docs/gen-renames.py --rev HEAD > Documentation/.renames.txt
12"""
13
14import argparse
15import itertools
16import os
17import subprocess
18import sys
19
20parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
21parser.add_argument('--rev', default='HEAD', help='generate renames up to this revision')
22
23args = parser.parse_args()
24
25def normalize(path):
26 prefix = 'Documentation/'
27 suffix = '.rst'
28
29 assert path.startswith(prefix)
30 assert path.endswith(suffix)
31
32 return path[len(prefix):-len(suffix)]
33
34class Name(object):
35 def __init__(self, name):
36 self.names = [name]
37
38 def rename(self, new_name):
39 self.names.append(new_name)
40
41names = {
42}
43
44for line in subprocess.check_output([
45 'git', 'log',
46 '--reverse',
47 '--oneline',
48 '--find-renames',
49 '--diff-filter=RD',
50 '--name-status',
51 '--format=commit %H',
52 # ~v4.8-ish is when Sphinx/.rst was added in the first place
53 f'v4.8..{args.rev}',
54 '--',
55 'Documentation/'
56], text=True).splitlines():
57 # rename
58 if line.startswith('R'):
59 _, old, new = line[1:].split('\t', 2)
60
61 if old.endswith('.rst') and new.endswith('.rst'):
62 old = normalize(old)
63 new = normalize(new)
64
65 name = names.get(old)
66 if name is None:
67 name = Name(old)
68 else:
69 del names[old]
70
71 name.rename(new)
72 names[new] = name
73
74 continue
75
76 # delete
77 if line.startswith('D'):
78 _, old = line.split('\t', 1)
79
80 if old.endswith('.rst'):
81 old = normalize(old)
82
83 # TODO: we could save added/modified files as well and propose
84 # them as alternatives
85 name = names.get(old)
86 if name is None:
87 pass
88 else:
89 del names[old]
90
91 continue
92
93#
94# Get the set of current files so we can sanity check that we aren't
95# redirecting any of those
96#
97
98current_files = set()
99for line in subprocess.check_output([
100 'git', 'ls-tree',
101 '-r',
102 '--name-only',
103 args.rev,
104 'Documentation/',
105], text=True).splitlines():
106 if line.endswith('.rst'):
107 current_files.add(normalize(line))
108
109#
110# Format/group/output result
111#
112
113result = []
114for _, v in names.items():
115 old_names = v.names[:-1]
116 new_name = v.names[-1]
117
118 for old_name in old_names:
119 if old_name == new_name:
120 # A file was renamed to its new name twice; don't redirect that
121 continue
122
123 if old_name in current_files:
124 # A file was recreated with a former name; don't redirect those
125 continue
126
127 result.append((old_name, new_name))
128
129for old_name, new_name in sorted(result):
130 print(f"{old_name} {new_name}")
tools/docs/lib/__init__.py+0−0

Empty file added.

tools/docs/lib/enrich_formatter.py+70−0
@@ -0,0 +1,70 @@
1#!/usr/bin/env python3
2# SPDX-License-Identifier: GPL-2.0
3# Copyright (c) 2025 by Mauro Carvalho Chehab <mchehab@kernel.org>.
4
5"""
6Ancillary argparse HelpFormatter class that works on a similar way as
7argparse.RawDescriptionHelpFormatter, e.g. description maintains line
8breaks, but it also implement transformations to the help text. The
9actual transformations ar given by enrich_text(), if the output is tty.
10
11Currently, the follow transformations are done:
12
13 - Positional arguments are shown in upper cases;
14 - if output is TTY, ``var`` and positional arguments are shown prepended
15 by an ANSI SGR code. This is usually translated to bold. On some
16 terminals, like, konsole, this is translated into a colored bold text.
17"""
18
19import argparse
20import re
21import sys
22
23class EnrichFormatter(argparse.HelpFormatter):
24 """
25 Better format the output, making easier to identify the positional args
26 and how they're used at the __doc__ description.
27 """
28 def __init__(self, *args, **kwargs):
29 """Initialize class and check if is TTY"""
30 super().__init__(*args, **kwargs)
31 self._tty = sys.stdout.isatty()
32
33 def enrich_text(self, text):
34 """Handle ReST markups (currently, only ``foo``)"""
35 if self._tty and text:
36 # Replace ``text`` with ANSI SGR (bold)
37 return re.sub(r'\`\`(.+?)\`\`',
38 lambda m: f'\033[1m{m.group(1)}\033[0m', text)
39 return text
40
41 def _fill_text(self, text, width, indent):
42 """Enrich descriptions with markups on it"""
43 enriched = self.enrich_text(text)
44 return "\n".join(indent + line for line in enriched.splitlines())
45
46 def _format_usage(self, usage, actions, groups, prefix):
47 """Enrich positional arguments at usage: line"""
48
49 prog = self._prog
50 parts = []
51
52 for action in actions:
53 if action.option_strings:
54 opt = action.option_strings[0]
55 if action.nargs != 0:
56 opt += f" {action.dest.upper()}"
57 parts.append(f"[{opt}]")
58 else:
59 # Positional argument
60 parts.append(self.enrich_text(f"``{action.dest.upper()}``"))
61
62 usage_text = f"{prefix or 'usage: '} {prog} {' '.join(parts)}\n"
63 return usage_text
64
65 def _format_action_invocation(self, action):
66 """Enrich argument names"""
67 if not action.option_strings:
68 return self.enrich_text(f"``{action.dest.upper()}``")
69
70 return ", ".join(action.option_strings)
tools/docs/lib/parse_data_structs.py+452−0
@@ -0,0 +1,452 @@
1#!/usr/bin/env python3
2# SPDX-License-Identifier: GPL-2.0
3# Copyright (c) 2016-2025 by Mauro Carvalho Chehab <mchehab@kernel.org>.
4# pylint: disable=R0912,R0915
5
6"""
7Parse a source file or header, creating ReStructured Text cross references.
8
9It accepts an optional file to change the default symbol reference or to
10suppress symbols from the output.
11
12It is capable of identifying defines, functions, structs, typedefs,
13enums and enum symbols and create cross-references for all of them.
14It is also capable of distinguish #define used for specifying a Linux
15ioctl.
16
17The optional rules file contains a set of rules like:
18
19 ignore ioctl VIDIOC_ENUM_FMT
20 replace ioctl VIDIOC_DQBUF vidioc_qbuf
21 replace define V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ :c:type:`v4l2_event_motion_det`
22"""
23
24import os
25import re
26import sys
27
28
29class ParseDataStructs:
30 """
31 Creates an enriched version of a Kernel header file with cross-links
32 to each C data structure type.
33
34 It is meant to allow having a more comprehensive documentation, where
35 uAPI headers will create cross-reference links to the code.
36
37 It is capable of identifying defines, functions, structs, typedefs,
38 enums and enum symbols and create cross-references for all of them.
39 It is also capable of distinguish #define used for specifying a Linux
40 ioctl.
41
42 By default, it create rules for all symbols and defines, but it also
43 allows parsing an exception file. Such file contains a set of rules
44 using the syntax below:
45
46 1. Ignore rules:
47
48 ignore <type> <symbol>`
49
50 Removes the symbol from reference generation.
51
52 2. Replace rules:
53
54 replace <type> <old_symbol> <new_reference>
55
56 Replaces how old_symbol with a new reference. The new_reference can be:
57 - A simple symbol name;
58 - A full Sphinx reference.
59
60 On both cases, <type> can be:
61 - ioctl: for defines that end with _IO*, e.g. ioctl definitions
62 - define: for other defines
63 - symbol: for symbols defined within enums;
64 - typedef: for typedefs;
65 - enum: for the name of a non-anonymous enum;
66 - struct: for structs.
67
68 Examples:
69
70 ignore define __LINUX_MEDIA_H
71 ignore ioctl VIDIOC_ENUM_FMT
72 replace ioctl VIDIOC_DQBUF vidioc_qbuf
73 replace define V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ :c:type:`v4l2_event_motion_det`
74 """
75
76 # Parser regexes with multiple ways to capture enums and structs
77 RE_ENUMS = [
78 re.compile(r"^\s*enum\s+([\w_]+)\s*\{"),
79 re.compile(r"^\s*enum\s+([\w_]+)\s*$"),
80 re.compile(r"^\s*typedef\s*enum\s+([\w_]+)\s*\{"),
81 re.compile(r"^\s*typedef\s*enum\s+([\w_]+)\s*$"),
82 ]
83 RE_STRUCTS = [
84 re.compile(r"^\s*struct\s+([_\w][\w\d_]+)\s*\{"),
85 re.compile(r"^\s*struct\s+([_\w][\w\d_]+)$"),
86 re.compile(r"^\s*typedef\s*struct\s+([_\w][\w\d_]+)\s*\{"),
87 re.compile(r"^\s*typedef\s*struct\s+([_\w][\w\d_]+)$"),
88 ]
89
90 # FIXME: the original code was written a long time before Sphinx C
91 # domain to have multiple namespaces. To avoid to much turn at the
92 # existing hyperlinks, the code kept using "c:type" instead of the
93 # right types. To change that, we need to change the types not only
94 # here, but also at the uAPI media documentation.
95 DEF_SYMBOL_TYPES = {
96 "ioctl": {
97 "prefix": "\\ ",
98 "suffix": "\\ ",
99 "ref_type": ":ref",
100 "description": "IOCTL Commands",
101 },
102 "define": {
103 "prefix": "\\ ",
104 "suffix": "\\ ",
105 "ref_type": ":ref",
106 "description": "Macros and Definitions",
107 },
108 # We're calling each definition inside an enum as "symbol"
109 "symbol": {
110 "prefix": "\\ ",
111 "suffix": "\\ ",
112 "ref_type": ":ref",
113 "description": "Enumeration values",
114 },
115 "typedef": {
116 "prefix": "\\ ",
117 "suffix": "\\ ",
118 "ref_type": ":c:type",
119 "description": "Type Definitions",
120 },
121 # This is the description of the enum itself
122 "enum": {
123 "prefix": "\\ ",
124 "suffix": "\\ ",
125 "ref_type": ":c:type",
126 "description": "Enumerations",
127 },
128 "struct": {
129 "prefix": "\\ ",
130 "suffix": "\\ ",
131 "ref_type": ":c:type",
132 "description": "Structures",
133 },
134 }
135
136 def __init__(self, debug: bool = False):
137 """Initialize internal vars"""
138 self.debug = debug
139 self.data = ""
140
141 self.symbols = {}
142
143 for symbol_type in self.DEF_SYMBOL_TYPES:
144 self.symbols[symbol_type] = {}
145
146 def store_type(self, symbol_type: str, symbol: str,
147 ref_name: str = None, replace_underscores: bool = True):
148 """
149 Stores a new symbol at self.symbols under symbol_type.
150
151 By default, underscores are replaced by "-"
152 """
153 defs = self.DEF_SYMBOL_TYPES[symbol_type]
154
155 prefix = defs.get("prefix", "")
156 suffix = defs.get("suffix", "")
157 ref_type = defs.get("ref_type")
158
159 # Determine ref_link based on symbol type
160 if ref_type:
161 if symbol_type == "enum":
162 ref_link = f"{ref_type}:`{symbol}`"
163 else:
164 if not ref_name:
165 ref_name = symbol.lower()
166
167 # c-type references don't support hash
168 if ref_type == ":ref" and replace_underscores:
169 ref_name = ref_name.replace("_", "-")
170
171 ref_link = f"{ref_type}:`{symbol} <{ref_name}>`"
172 else:
173 ref_link = symbol
174
175 self.symbols[symbol_type][symbol] = f"{prefix}{ref_link}{suffix}"
176
177 def store_line(self, line):
178 """Stores a line at self.data, properly indented"""
179 line = " " + line.expandtabs()
180 self.data += line.rstrip(" ")
181
182 def parse_file(self, file_in: str):
183 """Reads a C source file and get identifiers"""
184 self.data = ""
185 is_enum = False
186 is_comment = False
187 multiline = ""
188
189 with open(file_in, "r",
190 encoding="utf-8", errors="backslashreplace") as f:
191 for line_no, line in enumerate(f):
192 self.store_line(line)
193 line = line.strip("\n")
194
195 # Handle continuation lines
196 if line.endswith(r"\\"):
197 multiline += line[-1]
198 continue
199
200 if multiline:
201 line = multiline + line
202 multiline = ""
203
204 # Handle comments. They can be multilined
205 if not is_comment:
206 if re.search(r"/\*.*", line):
207 is_comment = True
208 else:
209 # Strip C99-style comments
210 line = re.sub(r"(//.*)", "", line)
211
212 if is_comment:
213 if re.search(r".*\*/", line):
214 is_comment = False
215 else:
216 multiline = line
217 continue
218
219 # At this point, line variable may be a multilined statement,
220 # if lines end with \ or if they have multi-line comments
221 # With that, it can safely remove the entire comments,
222 # and there's no need to use re.DOTALL for the logic below
223
224 line = re.sub(r"(/\*.*\*/)", "", line)
225 if not line.strip():
226 continue
227
228 # It can be useful for debug purposes to print the file after
229 # having comments stripped and multi-lines grouped.
230 if self.debug > 1:
231 print(f"line {line_no + 1}: {line}")
232
233 # Now the fun begins: parse each type and store it.
234
235 # We opted for a two parsing logic here due to:
236 # 1. it makes easier to debug issues not-parsed symbols;
237 # 2. we want symbol replacement at the entire content, not
238 # just when the symbol is detected.
239
240 if is_enum:
241 match = re.match(r"^\s*([_\w][\w\d_]+)\s*[\,=]?", line)
242 if match:
243 self.store_type("symbol", match.group(1))
244 if "}" in line:
245 is_enum = False
246 continue
247
248 match = re.match(r"^\s*#\s*define\s+([\w_]+)\s+_IO", line)
249 if match:
250 self.store_type("ioctl", match.group(1),
251 replace_underscores=False)
252 continue
253
254 match = re.match(r"^\s*#\s*define\s+([\w_]+)(\s+|$)", line)
255 if match:
256 self.store_type("define", match.group(1))
257 continue
258
259 match = re.match(r"^\s*typedef\s+([_\w][\w\d_]+)\s+(.*)\s+([_\w][\w\d_]+);",
260 line)
261 if match:
262 name = match.group(2).strip()
263 symbol = match.group(3)
264 self.store_type("typedef", symbol, ref_name=name)
265 continue
266
267 for re_enum in self.RE_ENUMS:
268 match = re_enum.match(line)
269 if match:
270 self.store_type("enum", match.group(1))
271 is_enum = True
272 break
273
274 for re_struct in self.RE_STRUCTS:
275 match = re_struct.match(line)
276 if match:
277 self.store_type("struct", match.group(1))
278 break
279
280 def process_exceptions(self, fname: str):
281 """
282 Process exceptions file with rules to ignore or replace references.
283 """
284 if not fname:
285 return
286
287 name = os.path.basename(fname)
288
289 with open(fname, "r", encoding="utf-8", errors="backslashreplace") as f:
290 for ln, line in enumerate(f):
291 ln += 1
292 line = line.strip()
293 if not line or line.startswith("#"):
294 continue
295
296 # Handle ignore rules
297 match = re.match(r"^ignore\s+(\w+)\s+(\S+)", line)
298 if match:
299 c_type = match.group(1)
300 symbol = match.group(2)
301
302 if c_type not in self.DEF_SYMBOL_TYPES:
303 sys.exit(f"{name}:{ln}: {c_type} is invalid")
304
305 d = self.symbols[c_type]
306 if symbol in d:
307 del d[symbol]
308
309 continue
310
311 # Handle replace rules
312 match = re.match(r"^replace\s+(\S+)\s+(\S+)\s+(\S+)", line)
313 if not match:
314 sys.exit(f"{name}:{ln}: invalid line: {line}")
315
316 c_type, old, new = match.groups()
317
318 if c_type not in self.DEF_SYMBOL_TYPES:
319 sys.exit(f"{name}:{ln}: {c_type} is invalid")
320
321 reftype = None
322
323 # Parse reference type when the type is specified
324
325 match = re.match(r"^\:c\:(data|func|macro|type)\:\`(.+)\`", new)
326 if match:
327 reftype = f":c:{match.group(1)}"
328 new = match.group(2)
329 else:
330 match = re.search(r"(\:ref)\:\`(.+)\`", new)
331 if match:
332 reftype = match.group(1)
333 new = match.group(2)
334
335 # If the replacement rule doesn't have a type, get default
336 if not reftype:
337 reftype = self.DEF_SYMBOL_TYPES[c_type].get("ref_type")
338 if not reftype:
339 reftype = self.DEF_SYMBOL_TYPES[c_type].get("real_type")
340
341 new_ref = f"{reftype}:`{old} <{new}>`"
342
343 # Change self.symbols to use the replacement rule
344 if old in self.symbols[c_type]:
345 self.symbols[c_type][old] = new_ref
346 else:
347 print(f"{name}:{ln}: Warning: can't find {old} {c_type}")
348
349 def debug_print(self):
350 """
351 Print debug information containing the replacement rules per symbol.
352 To make easier to check, group them per type.
353 """
354 if not self.debug:
355 return
356
357 for c_type, refs in self.symbols.items():
358 if not refs: # Skip empty dictionaries
359 continue
360
361 print(f"{c_type}:")
362
363 for symbol, ref in sorted(refs.items()):
364 print(f" {symbol} -> {ref}")
365
366 print()
367
368 def gen_output(self):
369 """Write the formatted output to a file."""
370
371 # Avoid extra blank lines
372 text = re.sub(r"\s+$", "", self.data) + "\n"
373 text = re.sub(r"\n\s+\n", "\n\n", text)
374
375 # Escape Sphinx special characters
376 text = re.sub(r"([\_\`\*\<\>\&\\\\:\/\|\%\$\#\{\}\~\^])", r"\\\1", text)
377
378 # Source uAPI files may have special notes. Use bold font for them
379 text = re.sub(r"DEPRECATED", "**DEPRECATED**", text)
380
381 # Delimiters to catch the entire symbol after escaped
382 start_delim = r"([ \n\t\(=\*\@])"
383 end_delim = r"(\s|,|\\=|\\:|\;|\)|\}|\{)"
384
385 # Process all reference types
386 for ref_dict in self.symbols.values():
387 for symbol, replacement in ref_dict.items():
388 symbol = re.escape(re.sub(r"([\_\`\*\<\>\&\\\\:\/])", r"\\\1", symbol))
389 text = re.sub(fr'{start_delim}{symbol}{end_delim}',
390 fr'\1{replacement}\2', text)
391
392 # Remove "\ " where not needed: before spaces and at the end of lines
393 text = re.sub(r"\\ ([\n ])", r"\1", text)
394 text = re.sub(r" \\ ", " ", text)
395
396 return text
397
398 def gen_toc(self):
399 """
400 Create a TOC table pointing to each symbol from the header
401 """
402 text = []
403
404 # Add header
405 text.append(".. contents:: Table of Contents")
406 text.append(" :depth: 2")
407 text.append(" :local:")
408 text.append("")
409
410 # Sort symbol types per description
411 symbol_descriptions = []
412 for k, v in self.DEF_SYMBOL_TYPES.items():
413 symbol_descriptions.append((v['description'], k))
414
415 symbol_descriptions.sort()
416
417 # Process each category
418 for description, c_type in symbol_descriptions:
419
420 refs = self.symbols[c_type]
421 if not refs: # Skip empty categories
422 continue
423
424 text.append(f"{description}")
425 text.append("-" * len(description))
426 text.append("")
427
428 # Sort symbols alphabetically
429 for symbol, ref in sorted(refs.items()):
430 text.append(f"* :{ref}:")
431
432 text.append("") # Add empty line between categories
433
434 return "\n".join(text)
435
436 def write_output(self, file_in: str, file_out: str, toc: bool):
437 title = os.path.basename(file_in)
438
439 if toc:
440 text = self.gen_toc()
441 else:
442 text = self.gen_output()
443
444 with open(file_out, "w", encoding="utf-8", errors="backslashreplace") as f:
445 f.write(".. -*- coding: utf-8; mode: rst -*-\n\n")
446 f.write(f"{title}\n")
447 f.write("=" * len(title) + "\n\n")
448
449 if not toc:
450 f.write(".. parsed-literal::\n\n")
451
452 f.write(text)
tools/docs/parse-headers.py+60−0
@@ -0,0 +1,60 @@
1#!/usr/bin/env python3
2# SPDX-License-Identifier: GPL-2.0
3# Copyright (c) 2016, 2025 by Mauro Carvalho Chehab <mchehab@kernel.org>.
4# pylint: disable=C0103
5
6"""
7Convert a C header or source file ``FILE_IN``, into a ReStructured Text
8included via ..parsed-literal block with cross-references for the
9documentation files that describe the API. It accepts an optional
10``FILE_RULES`` file to describes what elements will be either ignored or
11be pointed to a non-default reference type/name.
12
13The output is written at ``FILE_OUT``.
14
15It is capable of identifying defines, functions, structs, typedefs,
16enums and enum symbols and create cross-references for all of them.
17It is also capable of distinguish #define used for specifying a Linux
18ioctl.
19
20The optional ``FILE_RULES`` contains a set of rules like:
21
22 ignore ioctl VIDIOC_ENUM_FMT
23 replace ioctl VIDIOC_DQBUF vidioc_qbuf
24 replace define V4L2_EVENT_MD_FL_HAVE_FRAME_SEQ :c:type:`v4l2_event_motion_det`
25"""
26
27import argparse
28
29from lib.parse_data_structs import ParseDataStructs
30from lib.enrich_formatter import EnrichFormatter
31
32def main():
33 """Main function"""
34 parser = argparse.ArgumentParser(description=__doc__,
35 formatter_class=EnrichFormatter)
36
37 parser.add_argument("-d", "--debug", action="count", default=0,
38 help="Increase debug level. Can be used multiple times")
39 parser.add_argument("-t", "--toc", action="store_true",
40 help="instead of a literal block, outputs a TOC table at the RST file")
41
42 parser.add_argument("file_in", help="Input C file")
43 parser.add_argument("file_out", help="Output RST file")
44 parser.add_argument("file_rules", nargs="?",
45 help="Exceptions file (optional)")
46
47 args = parser.parse_args()
48
49 parser = ParseDataStructs(debug=args.debug)
50 parser.parse_file(args.file_in)
51
52 if args.file_rules:
53 parser.process_exceptions(args.file_rules)
54
55 parser.debug_print()
56 parser.write_output(args.file_in, args.file_out, args.toc)
57
58
59if __name__ == "__main__":
60 main()