Just want to add a little more for better understanding:<div><br></div><div>When I spoke about .init section of the final kernel image, please note that this section is going to </div><div>contain all the __init data (and functions) coming from _All_ the drivers and modules that were included </div>
<div>as part of the kernel image. Hence, after initialization when we look at the print:</div><div><br></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">" [1.011596] Freeing unused kernel memory: 664k freed "</span> </div>
<div><br></div><div>we see 664k bytes being freed. </div><div><br></div><div>This is a significant amount of contiguous physical memory that we can see being released by the kernel. </div><div><br></div><div>The same cannot be held true for a single loadable module which may be releasing just a few, virtually </div>
<div>contiguous memory.</div><div><br></div><div>Regards,</div><div>-Amar</div><div><br></div><div><br><div class="gmail_quote">On Thu, Aug 16, 2012 at 11:57 PM, Amarnath Revanna <span dir="ltr"><<a href="mailto:amarnath.revanna@gmail.com" target="_blank">amarnath.revanna@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Ezequiel,<div><div class="h5"><div><br></div><div>On Thu, Aug 16, 2012 at 10:53 PM, Ezequiel Garcia <span dir="ltr"><<a href="mailto:elezegarcia@gmail.com" target="_blank">elezegarcia@gmail.com</a>></span> wrote:</div>
</div></div><div><div class="gmail_quote"><div><div class="h5">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Amar,<br>
<div><br>
On Thu, Aug 16, 2012 at 1:08 PM, Amarnath Revanna<br>
<<a href="mailto:amarnath.revanna@gmail.com" target="_blank">amarnath.revanna@gmail.com</a>> wrote:<br>
<br>
><br>
> On the other hand, any other kernel module that you load using insmod or<br>
> modprobe comes after this stage, wherein the kernel was already booted, and<br>
> hence, no memory area of __init will ever be freed.<br>
><br>
<br>
</div>Modules are loaded with vmalloc, right?<br>
<br>
Could you explain why the kernel can't free those __init symbols<br>
from memory also in this case?<br>
<br>
Thanks,<br>
Ezequiel.<br></blockquote><div><br></div></div></div><div>When we look at the definition of __init & __initdata in <a href="http://lxr.free-electrons.com/source/include/linux/init.h#L44" target="_blank">http://lxr.free-electrons.com/source/include/linux/init.h#L44</a>,</div>
<div><br></div><div><pre style="color:rgb(120,120,120);overflow:auto;font-size:14px;font-family:Monaco,'Courier New',Courier,monospace;font-weight:bold;padding:1em"> <a name="13930b0b92ff9a80_L44" href="http://lxr.free-electrons.com/source/include/linux/init.h#L44" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">44</a> #define <a href="http://lxr.free-electrons.com/ident?i=__init" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">__init</a> <a href="http://lxr.free-electrons.com/ident?i=__section" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">__section</a>(.<a href="http://lxr.free-electrons.com/ident?i=init" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">init</a>.<a href="http://lxr.free-electrons.com/ident?i=text" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">text</a>) <a href="http://lxr.free-electrons.com/ident?i=__cold" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">__cold</a> <a href="http://lxr.free-electrons.com/ident?i=notrace" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">notrace</a>
<a name="13930b0b92ff9a80_L45" href="http://lxr.free-electrons.com/source/include/linux/init.h#L45" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">45</a> #define <a href="http://lxr.free-electrons.com/ident?i=__initdata" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">__initdata</a> <a href="http://lxr.free-electrons.com/ident?i=__section" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">__section</a>(.<a href="http://lxr.free-electrons.com/ident?i=init" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">init</a>.<a href="http://lxr.free-electrons.com/ident?i=data" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">data</a>)
<a name="13930b0b92ff9a80_L46" href="http://lxr.free-electrons.com/source/include/linux/init.h#L46" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">46</a> #define <a href="http://lxr.free-electrons.com/ident?i=__initconst" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">__initconst</a> <a href="http://lxr.free-electrons.com/ident?i=__section" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">__section</a>(.<a href="http://lxr.free-electrons.com/ident?i=init" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">init</a>.<a href="http://lxr.free-electrons.com/ident?i=rodata" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">rodata</a>)
<a name="13930b0b92ff9a80_L47" href="http://lxr.free-electrons.com/source/include/linux/init.h#L47" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">47</a> #define <a href="http://lxr.free-electrons.com/ident?i=__exitdata" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">__exitdata</a> <a href="http://lxr.free-electrons.com/ident?i=__section" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">__section</a>(.<a href="http://lxr.free-electrons.com/ident?i=exit" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">exit</a>.<a href="http://lxr.free-electrons.com/ident?i=data" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">data</a>)
<a name="13930b0b92ff9a80_L48" href="http://lxr.free-electrons.com/source/include/linux/init.h#L48" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">48</a> #define <a href="http://lxr.free-electrons.com/ident?i=__exit_call" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">__exit_call</a> <a href="http://lxr.free-electrons.com/ident?i=__used" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">__used</a> <a href="http://lxr.free-electrons.com/ident?i=__section" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">__section</a>(.exitcall.<a href="http://lxr.free-electrons.com/ident?i=exit" style="border-bottom-style:dotted;border-bottom-width:1px;color:black;text-decoration:none;border-bottom-color:rgb(153,153,153)" target="_blank">exit</a>)</pre>
</div><div>we can notice that the functions represented by __init and any data represented by __initdata are going to be placed </div><div>in a separate section of the final kernel binary image (zImage/uImage/vmlinux) by the linker.</div>
<div><br></div><div>This section is going to be called the .init section.</div><div><br></div><div>The idea behind forming this separate .init section in the final kernel image is to hold all those functions and data structures </div>
<div>that are going to be required only once during initialization, together.</div><div> </div><div>By doing so, the kernel, once it boots up, would have already utilized all these resources once during bootup sequence and </div>
<div>hence, can now be released from the memory. As a result, the kernel would simply discard this entire ".init" section from the </div><div>RAM in one go, there by freeing the memory. The amount of memory being freed by removing this section is thus printed in </div>
<div>the line:</div></div><div class="im"><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"><div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"><br>
</span></div>" [1.011596] Freeing unused kernel memory: 664k freed "</span>
</div></div><div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"><br></span></div><div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">Now, when we think about loadable modules, as you rightly said, are loaded into the kernel memory by obtaining the memory </span></div>
<div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">area from the heap using vmalloc. The interesting thing about this is that, </span><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">since we are going to load </span><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">only one module </span></div>
<div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">within this vmalloc'd area, we can normally expect the size of </span><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">__initdata and __init function to be pretty small, in few bytes</span><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">. </span></div>
<div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">Now, it becomes too difficult for the kernel to manage (keep track of and free) these smaller memory areas coming up from </span></div>
<div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">every </span><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">individual loaded module.</span></div>
<div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"><br></span></div><div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">Another thing to add is that, in case of freeing up an entire .init section from the RAM, we are recovering the entire .init </span></div>
<div><font color="#222222" face="arial, sans-serif">section size'd _contiguous_ physical memory area </font><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">back</span><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"> to the kernel. However, in case of Loaded Kernel Module (LKM) if we </span></div>
<div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">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 </span></div>
<div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">that was </span><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">virtually contiguous. This may not be of much significance for the kernel operation as compared to its overhead </span></div>
<div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">involved with </span><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">managing a process to keep track of and freeing up all these __init memory in vmalloc area.</span></div>
<div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"><br></span></div><div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">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 </span></div>
<div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">drivers/modules.</span></div><div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif"><br>
</span></div><div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">Regards,</span></div><div><span style="color:rgb(34,34,34);font-size:13px;font-family:arial,sans-serif">-Amar</span></div>
<div><br></div>
</blockquote></div><br></div>