Exported-symbol changes in 5.13
The kernel has many thousands of functions and data structures; most of those are private to a given source file, while others are made available to the kernel as a whole. Loadable modules are special, though; they only have access to symbols that have been explicitly exported to them with EXPORT_SYMBOL() (or one of a few variants); many symbols that are available to code built into the kernel image are unavailable to loadable modules. The intent of this limitation is to keep the interface to modules relatively narrow and manageable.
It is far from clear that this objective has been achieved, though. The 5.12 kernel exported 31,695 symbols to modules, which does not create an impression of a narrow interface. That number grew to 31,822 in 5.13-rc1. That is an increase of 127 symbols, but the actual story is a bit more complicated than that; 244 exported symbols were removed over this time, while 371 were added. The curious can see the full sets of added and removed symbols on this page.
Some changes qualify more as a renaming than a removal or an addition. For example, pmbus_do_probe() is no longer exported in 5.13, at least in that form; it is now listed (using a notation your editor made up on the spot) as PMBUS::pmbus_do_probe(). In other words, this symbol has been moved out of the global namespace into a subsystem-specific one. Namespacing for exported kernel symbols was added in 2018, but uptake has been relatively slow. The 5.13 kernel adds one new namespace (PMBUS) and that subsystem's exported symbols are moving into it. There are now 18 namespaces for symbols in the kernel:
CRYPTO_INTERNAL, FIRMWARE_LOADER_PRIVATE, LTC2497, MCB, NVME_TARGET_PASSTHRU, PMBUS, SND_INTEL_SOUNDWIRE_ACPI, SND_SOC_SOF_INTEL_HDA_COMMON, SND_SOC_SOF_MERRIFIELD, SND_SOC_SOF_HDA_AUDIO_CODEC, SND_SOC_SOF_HDA_AUDIO_CODEC_I915, SND_SOC_SOF_INTEL_HIFI_EP_IPC, SND_SOC_SOF_INTEL_HIFI_EP_IPC, SND_SOC_SOF_ACPI_DEV, SND_SOC_SOF_PCI_DEV, SND_SOC_SOF_XTENSA, SOUNDWIRE_INTEL_INIT, and TEST_FIRMWARE.
The sound subsystem has clearly been the most enthusiastic user of symbol namespaces thus far.
Many other changes in exported symbols are the result of code refactoring within the kernel. Some optimizations in the bit-finding library caused functions like find_first_bit() to be turned into inline functions in header files, which need not be exported. But they fall back to functions like _find_first_bit(), which now do need to be exported. The generic-sounding vmem_map symbol was specific to the ia64 architecture; it went away when ia64 dropped support for the VMEMMAP memory model. Various wimax_ symbols disappeared along with the unloved WiMAX drivers that exported them. Functions like rt_mutex_destroy() were deleted because they were unused.
Many of the new symbols correspond to new features; alloc_pages()
came with batch page allocation, for
example. Others are a bit less clear; what, for example, is
dotdot_name? The commit that added this
export explains it as "useful constants: struct qstr for
'..'
", which may be seen by some as less than fully enlightening.
It provides a shortcut for filesystem code wanting to refer
to directories named ".." without going to the trouble of wrapping it in
the "quick
string" structure used to pass strings around in the virtual filesystem
layer. Several filesystems make use of it in 5.13.
As a general rule, kernel symbols should not be exported unless there is a user of them in the mainline kernel. That rule is generally respected, but there are exceptions. As an example, zynqmp_pm_pinctrl_get_function() was exported in 5.13-rc1, but has no in-kernel users. The other zynqmp_ (all related to functionality on Xilinx Zynq systems-on-chip) symbols that have been exported are not widely used and would be good candidates for hiding within their own namespace. Another exported-but-unused symbol is __cfi_slowpath_diag(), which is part of the Clang control-flow integrity implementation that was merged in this cycle. The reason for the exporting of this symbol is not entirely clear. __cpu_dying_mask() was also introduced and exported in 5.13 with no in-kernel users. There are many others as well; "export it just in case" seems to be a fairly common reflex for kernel developers.
The 5.13 kernel saw the addition of eleven devm_ exports, plus two with the internal __devm_ prefix. Not all of these are used either, but they do represent the type of symbol that one would expect to be exported to modules. These "managed device" functions are intended to make device drivers easier to write and safer by taking care of the freeing of allocated resources when a device is shut down. There are over 300 of these functions exported to modules now, and the list looks likely to continue to grow.
The direct rendering manager (DRM) graphics subsystem added 17 drm_ exports this time around. DRM is clearly one of the most complex driver APIs in the kernel, with no less than 850 exported symbols in 5.13. One begins to understand why the developers of this subsystem have prioritized documentation; this API would be unapproachable without it. That, of course, is a reflection of the problem space; graphics processors are complex devices.
Given that it requires nearly 32,000 exported symbols for a "limited"
module interface, the kernel as a whole is also a complex environment.
That complexity is reflected in the increasing size of the interface it
offers to user space, but also in the growing interface it presents to
loadable modules. This interface has increased significantly in size over
the years, often without a lot of review. The good news is that, as an
internal kernel interface, the set of exported symbols can be changed at
any time. So perhaps this list might shrink someday, but that will not
happen in the 5.13 cycle.
Index entries for this article | |
---|---|
Kernel | Modules/Exported symbols |
Kernel | Releases/5.13 |
Posted May 18, 2021 9:36 UTC (Tue)
by ColinIanKing (guest, #57499)
[Link]
[1] 7613f5a66becfd0e43a0f34de8518695888f5458 ("powerpc/64s/kuap: Use mmu_has_feature()")
Exported-symbol changes in 5.13