Bug 275741 - sys/modules: Fix processing of WITHOUT_MODULES
Summary: sys/modules: Fix processing of WITHOUT_MODULES
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Some People
Assignee: freebsd-bugs (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2023-12-13 09:25 UTC by Joshua Kinard
Modified: 2023-12-13 22:21 UTC (History)
0 users

See Also:


Attachments
Fix processing of WITHOUT_MODULES (31.63 KB, patch)
2023-12-13 09:31 UTC, Joshua Kinard
no flags Details | Diff
Fix processing of WITHOUT_MODULES v2 (31.58 KB, patch)
2023-12-13 22:21 UTC, Joshua Kinard
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Joshua Kinard 2023-12-13 09:25:25 UTC
The handling of WITHOUT_MODULES in the FreeBSD kernel build system is currently suboptimal.  At present, it is only possible to exclude kmods at the top-level of /usr/src/sys/modules from being built with this variable.  If a kmod is in a subdirectory, then it is built regardless if it is listed in WITHOUT_MODULES.  I have tried several forms of specifying subdirectory kmods in this variable to avoid building them, but none of them work.

The crux of the issue is because the only processing of this variable is done in /usr/src/sys/modules/Makefile, and it is a simple loop that iterates over WITHOUT_MODULES and removes any entries from the SUBDIR variable *only* in that top-level Makefile.  For kmods in subdirectories that have their own Makefiles that define SUBDIR, no processing of WITHOUT_MODULES takes place, so they will always be built.

A previous attempt to tackle this issue was found in PR#76225, and the last comment says this was all fixed back in Jan 2005, however, this fix may have been undone at some point, as the current Makefile logic is not capable of excluding kmods in lower-level subdirectories from being built.

The issue was again highlighted by PR#210143, but the reporter did not provide a recommended fix or any patches, and the reporter eventually self-closed the PR due to feedback timeout (by developers?).

I have made an effort to fix this in the attached patch by taking several steps:

1. Move the WITHOUT_MODULES for loop to a new mk file in /usr/src/sys/conf and call it "kmod.without.mk".  The loop is expanded to process kmod names as either a top-level name under /usr/src/sys/modules, or as a path relative to that directory.

2. Include this new mk file in every Makefile that defines a SUBDIR variable in /usr/src/sys/modules.

3. Update the make.conf(5) manpage to specify the way kmods can be excluded from building via this variable.

I've made the patch against -CURRENT (git HEAD), but I've only tested against one of my 14.0-RELEASE systems, as I don't actively run -CURRENT on any machine at present.  My systems use a custom kernel config that inherits from GENERIC, and install to /boot/kernel.custom.  After fixing the processing of WITHOUT_MODULES, I've been able to knock the size of /boot/kernel.custom down to ~47MB, and I can probably get it smaller once I deep dive whether that particular system needs any of the i2c or other ancillary bus drivers.
Comment 1 Joshua Kinard 2023-12-13 09:31:17 UTC
Created attachment 247024 [details]
Fix processing of WITHOUT_MODULES
Comment 2 Joshua Kinard 2023-12-13 22:21:07 UTC
Created attachment 247035 [details]
Fix processing of WITHOUT_MODULES v2

This version of the patch fixes an accidental bug in the kmod.without.mk for loop where I was trying to be too clever and compare `basename CURDIR` against `dirname kmod` to try and limit accidental matches from being removed from SUBDIR.  A.k.a., being overly-cautious and while that check works for a single subdirectory level (foo/bar), it fails if the kmod name in WITHOUT_MODULES has several subdirectory levels (foo/bar/baz).  After adding better debugging and looking through the build log, the conditional simply isn't needed, so it is removed in this version.

Also updated the date in the make.conf.5 man page.