Just want to add a little more for better understanding: When I spoke about .init section of the final kernel image, please note that this section is going to contain all the __init data (and functions) coming from _All_ the drivers and modules that were included as part of the kernel image. Hence, after initialization when we look at the print:
" [1.011596] Freeing unused kernel memory: 664k freed " we see 664k bytes being freed. This is a significant amount of contiguous physical memory that we can see being released by the kernel. The same cannot be held true for a single loadable module which may be releasing just a few, virtually contiguous memory. Regards, -Amar On Thu, Aug 16, 2012 at 11:57 PM, Amarnath Revanna < amarnath.reva...@gmail.com> wrote: > Hi Ezequiel, > > On Thu, Aug 16, 2012 at 10:53 PM, Ezequiel Garcia > <elezegar...@gmail.com>wrote: > >> Hi Amar, >> >> On Thu, Aug 16, 2012 at 1:08 PM, Amarnath Revanna >> <amarnath.reva...@gmail.com> wrote: >> >> > >> > On the other hand, any other kernel module that you load using insmod or >> > modprobe comes after this stage, wherein the kernel was already booted, >> and >> > hence, no memory area of __init will ever be freed. >> > >> >> Modules are loaded with vmalloc, right? >> >> Could you explain why the kernel can't free those __init symbols >> from memory also in this case? >> >> Thanks, >> Ezequiel. >> > > When we look at the definition of __init & __initdata in > http://lxr.free-electrons.com/source/include/linux/init.h#L44, > > 44 <http://lxr.free-electrons.com/source/include/linux/init.h#L44> #define > __init <http://lxr.free-electrons.com/ident?i=__init> __section > <http://lxr.free-electrons.com/ident?i=__section>(.init > <http://lxr.free-electrons.com/ident?i=init>.text > <http://lxr.free-electrons.com/ident?i=text>) __cold > <http://lxr.free-electrons.com/ident?i=__cold> notrace > <http://lxr.free-electrons.com/ident?i=notrace> > 45 <http://lxr.free-electrons.com/source/include/linux/init.h#L45> #define > __initdata <http://lxr.free-electrons.com/ident?i=__initdata> __section > <http://lxr.free-electrons.com/ident?i=__section>(.init > <http://lxr.free-electrons.com/ident?i=init>.data > <http://lxr.free-electrons.com/ident?i=data>) > 46 <http://lxr.free-electrons.com/source/include/linux/init.h#L46> #define > __initconst <http://lxr.free-electrons.com/ident?i=__initconst> __section > <http://lxr.free-electrons.com/ident?i=__section>(.init > <http://lxr.free-electrons.com/ident?i=init>.rodata > <http://lxr.free-electrons.com/ident?i=rodata>) > 47 <http://lxr.free-electrons.com/source/include/linux/init.h#L47> #define > __exitdata <http://lxr.free-electrons.com/ident?i=__exitdata> __section > <http://lxr.free-electrons.com/ident?i=__section>(.exit > <http://lxr.free-electrons.com/ident?i=exit>.data > <http://lxr.free-electrons.com/ident?i=data>) > 48 <http://lxr.free-electrons.com/source/include/linux/init.h#L48> #define > __exit_call <http://lxr.free-electrons.com/ident?i=__exit_call> __used > <http://lxr.free-electrons.com/ident?i=__used> __section > <http://lxr.free-electrons.com/ident?i=__section>(.exitcall.exit > <http://lxr.free-electrons.com/ident?i=exit>) > > we can notice that the functions represented by __init and any data > represented by __initdata are going to be placed > in a separate section of the final kernel binary image > (zImage/uImage/vmlinux) by the linker. > > This section is going to be called the .init section. > > The idea behind forming this separate .init section in the final kernel > image is to hold all those functions and data structures > that are going to be required only once during initialization, together. > > By doing so, the kernel, once it boots up, would have already utilized all > these resources once during bootup sequence and > hence, can now be released from the memory. As a result, the kernel would > simply discard this entire ".init" section from the > RAM in one go, there by freeing the memory. The amount of memory being > freed by removing this section is thus printed in > the line: > > " [1.011596] Freeing unused kernel memory: 664k freed " > > Now, when we think about loadable modules, as you rightly said, are loaded > into the kernel memory by obtaining the memory > area from the heap using vmalloc. The interesting thing about this is > that, since we are going to load only one module > within this vmalloc'd area, we can normally expect the size of __initdata > and __init function to be pretty small, in few bytes. > Now, it becomes too difficult for the kernel to manage (keep track of and > free) these smaller memory areas coming up from > every individual loaded module. > > Another thing to add is that, in case of freeing up an entire .init > section from the RAM, we are recovering the entire .init > section size'd _contiguous_ physical memory area back to the kernel. > However, in case of Loaded Kernel Module (LKM) if we > try to free up the __init memory of an LKM that was allocated using > vmalloc, we may only be freeing up few bytes of memory > that was virtually contiguous. This may not be of much significance for > the kernel operation as compared to its overhead > involved with managing a process to keep track of and freeing up all > these __init memory in vmalloc area. > > In short, its kind of a nice trade off done to leave this __init data > cleanup for LKM while keeping its significance for all built in > drivers/modules. > > Regards, > -Amar > >
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies