[LEDE-DEV] Difference between AutoLoad vs. AutoProbe for kernel modules?
zefir.kurtisi at neratec.com
Tue Jan 10 01:53:16 PST 2017
On 01/10/2017 09:20 AM, John Crispin wrote:
> On 10/01/2017 09:17, Baptiste Jonglez wrote:
>> On Tue, Jan 10, 2017 at 07:56:36AM +0100, John Crispin wrote:
>>>>> While investigating an issue with module loading order¹, I discovered
>>>>> some kernel packages use AutoProbe, like this:
>>>>> AUTOLOAD:=$(call AutoProbe,xt_hashlimit)
>>>>> while some kernel packages use the AutoLoad helper I was used to, with a
>>>>> AUTOLOAD:=$(call AutoLoad,28,raid0)
>>>>> Judging from this commit² and `include/kernel.mk`, it seems the only
>>>>> difference is that AutoProbe does not include a priority.
>>>>> Is the loading order determined automatically for AutoProbe? If so,
>>>>> is the magic, and why is AutoLoad still needed in some cases?
>>>> I opened the issue, so using autoload the modules will get a priority
>>>> specified by the number, for wireguard above 90 would issue only one
>>>> warning and using autoprobe the module would be loaded by the order of
>>>> the name ? so setting the xt_hashlimit with a lower number (autoload)
>>>> will start wireguard without complaining
>>> autoload is like insmod while autoproe is more liek modprobe. kmodloader
>>> will first load all numbered modules in the given order and then probe
>>> the remaining ones.
>> So, with AutoProbe, there is dependency resolution, similarly to modprobe?
>> But without using depmod?
> correct. kmodloader will scan the ELF header and work out which other
> modules are required to be loaded. depmod caches this dependency info
> while kmodloader generates it when needed.
Worth to note that only explicit dependencies are resolved, i.e. if one ko uses
another ko (like ath9k -> ath9k_common). It obviously does not (and can't) work if
one subsystem makes use of a component in another subsystem.
Let me share a recent experience for illustration and amusement. I had to debug a
system where a gianfar ETH driver connects to an at803x PHY driver. Approaching
the problem the usual printk based technique, I ended up in a situation where
printing a string of size n in gianfar made the system work, while reducing the
length of the printed string to (n-1) did not. Realizing that prink-ing random
chars might not be the correct fix for the issue, I was wondering wtf!?
Turned out problem was caused by the kernel module autoloader. While the PHY and
ETH driver were loaded and initialized in the background, the additional printk
caused enough delay to allow the PHY to finish registration before the ETH
attaches to it. If otherwise the ETH attaches to an enumerated PHY on the bus
whose driver did not yet finalize its registration, it gets attach to genphy.
Since everything works more or less, you won't notice unless you look for printk
output - which itself changes measures :\
Lesson learned: autoprobe is convenient, but if you need to ensure lower layer
drivers are loaded before upper layer ones, use autoload.
NOTE: Since module initialization / registration still happens in the background,
this might not prevent from the effect described above from happening (e.g. in
case you delay PHY registration long enough with printk), but at least it gives
you some control for spreading the loading of dependent modules.
More information about the Lede-dev