A Bug in linker_reference_module() ?
John Baldwin
jhb at freebsd.org
Fri Sep 22 11:58:45 PDT 2006
On Thursday 21 September 2006 21:57, Intron is my alias on the Internet wrote:
> John Baldwin wrote:
>
> > On Thursday 21 September 2006 14:12, Intron is my alias on the Internet
wrote:
> >> Please have a look at the function linker_reference_module() in
> >> /sys/kern/kern_linker.c of 7.0-CURRENT. If the module is loaded on
demand,
> >> why not increase its reference counter after loading? In my opinion,
> >> linker_reference_module() behaves differently from linker_load_file().
> >
> > This is because a new kld loaded via linker_load_module() starts off
> > with a refcount of 1. Thus, if you do:
> >
> > linker_reference_module(...);
> > ...
> > linker_release_module(...);
> >
> > Then with the current code the release_module() call drops the reference
> > count to 0 and the module is unloaded. This is the desired operation for
> > reference_module/release_module. This model is commonly used in the
kernel.
> > For example, when creating a credential, one just does 'crget()' and later
> > a 'crfree()' to free it instead of doing 'crget(); crhold()' to create
one.
>
> This model is a little confusing. If a module is loaded on demand as
> dependency, its reference counter is set to 1. And if the module is loaded
> by kldload(2), its reference counter is also set to 1, though in fact
> no other loaded module depends on it.
kldload(2) is a way for to specify a user reference on the module, and
kldunload(2) is how you drop that user reference.
> Although this "shift" model can work correctly, I want to know whether
> there's a more reasonable way, such as setting up an auto-unloadable flag.
There is this effectively done with the userref flag. When you kldload a
module, it sets userref to 1, and you can only kldunload a module when
userref == 1. This lets the following work:
thread 1 thread 2
kldload(foo) ...
... linker_reference_module(foo)
(now foo has userref == 1 and refs == 2)
kldunload(foo) ...
(now foo has userref == 0 and refs == 1, kldunload reports success, but module
isn't unloaded due to in-kernel reference)
... linker_release_module(foo)
(now refs drops to 0 and module is actually unloaded)
The simpler cases also work fine if you try them out.
--
John Baldwin
More information about the freebsd-hackers
mailing list