Hi Ezequiel,<div><br></div><div>On Thu, Aug 16, 2012 at 10:53 PM, Ezequiel Garcia <span dir="ltr">&lt;<a href="mailto:elezegarcia@gmail.com" target="_blank">elezegarcia@gmail.com</a>&gt;</span> wrote:</div><div><div class="gmail_quote">

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Amar,<br>
<div class="im"><br>
On Thu, Aug 16, 2012 at 1:08 PM, Amarnath Revanna<br>
&lt;<a href="mailto:amarnath.revanna@gmail.com">amarnath.revanna@gmail.com</a>&gt; wrote:<br>
<br>
&gt;<br>
&gt; On the other hand, any other kernel module that you load using insmod or<br>
&gt; modprobe comes after this stage, wherein the kernel was already booted, and<br>
&gt; hence, no memory area of __init will ever be freed.<br>
&gt;<br>
<br>
</div>Modules are loaded with vmalloc, right?<br>
<br>
Could you explain why the kernel can&#39;t free those __init symbols<br>
from memory also in this case?<br>
<br>
Thanks,<br>
Ezequiel.<br></blockquote><div><br></div><div>When we look at the definition of __init &amp; __initdata in  <a href="http://lxr.free-electrons.com/source/include/linux/init.h#L44">http://lxr.free-electrons.com/source/include/linux/init.h#L44</a>,</div>

<div><br></div><div><pre style="font-family:Monaco,&#39;Courier New&#39;,Courier,monospace;font-size:14px;padding:1em;color:rgb(120,120,120);background-color:rgb(255,255,255);overflow:auto;font-weight:bold"> <a name="L44" href="http://lxr.free-electrons.com/source/include/linux/init.h#L44" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">44</a> #define <a href="http://lxr.free-electrons.com/ident?i=__init" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">__init</a>          <a href="http://lxr.free-electrons.com/ident?i=__section" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">__section</a>(.<a href="http://lxr.free-electrons.com/ident?i=init" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">init</a>.<a href="http://lxr.free-electrons.com/ident?i=text" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">text</a>) <a href="http://lxr.free-electrons.com/ident?i=__cold" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">__cold</a> <a href="http://lxr.free-electrons.com/ident?i=notrace" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">notrace</a>
 <a name="L45" href="http://lxr.free-electrons.com/source/include/linux/init.h#L45" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">45</a> #define <a href="http://lxr.free-electrons.com/ident?i=__initdata" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">__initdata</a>      <a href="http://lxr.free-electrons.com/ident?i=__section" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">__section</a>(.<a href="http://lxr.free-electrons.com/ident?i=init" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">init</a>.<a href="http://lxr.free-electrons.com/ident?i=data" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">data</a>)
 <a name="L46" href="http://lxr.free-electrons.com/source/include/linux/init.h#L46" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">46</a> #define <a href="http://lxr.free-electrons.com/ident?i=__initconst" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">__initconst</a>     <a href="http://lxr.free-electrons.com/ident?i=__section" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">__section</a>(.<a href="http://lxr.free-electrons.com/ident?i=init" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">init</a>.<a href="http://lxr.free-electrons.com/ident?i=rodata" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">rodata</a>)
 <a name="L47" href="http://lxr.free-electrons.com/source/include/linux/init.h#L47" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">47</a> #define <a href="http://lxr.free-electrons.com/ident?i=__exitdata" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">__exitdata</a>      <a href="http://lxr.free-electrons.com/ident?i=__section" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">__section</a>(.<a href="http://lxr.free-electrons.com/ident?i=exit" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">exit</a>.<a href="http://lxr.free-electrons.com/ident?i=data" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">data</a>)
 <a name="L48" href="http://lxr.free-electrons.com/source/include/linux/init.h#L48" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">48</a> #define <a href="http://lxr.free-electrons.com/ident?i=__exit_call" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">__exit_call</a>     <a href="http://lxr.free-electrons.com/ident?i=__used" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">__used</a> <a href="http://lxr.free-electrons.com/ident?i=__section" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">__section</a>(.exitcall.<a href="http://lxr.free-electrons.com/ident?i=exit" style="text-decoration:none;border-bottom-width:1px;border-bottom-style:dotted;border-bottom-color:rgb(153,153,153);color:black;background-color:white">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 &quot;.init&quot; 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><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"><br>

</span></div>&quot; [1.011596] Freeing unused kernel memory: 664k freed &quot;</span>
</div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)"><br></span></div><div><span style="color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">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-family:arial,sans-serif;font-size:13px;background-color:rgb(255,255,255)">area from the heap using vmalloc. The interesting thing about this is that, </span><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">since we are going to load </span><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">only one module </span></div>

<div><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">within this vmalloc&#39;d area, we can normally expect the size of </span><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">__initdata and __init function to be pretty small, in few bytes</span><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">. </span></div>

<div><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">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="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">every </span><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">individual loaded module.</span></div>

<div><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px"><br></span></div><div><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">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&#39;d _contiguous_ physical memory area </font><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">back</span><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px"> to the kernel. However, in case of Loaded Kernel Module (LKM) if we </span></div>

<div><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">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="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">that was </span><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">virtually contiguous. This may not be of much significance for the kernel operation as compared to its overhead </span></div>

<div><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">involved with </span><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">managing a process to keep track of and freeing up all these __init memory in vmalloc area.</span></div>

<div><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px"><br></span></div><div><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">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="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">drivers/modules.</span></div><div><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px"><br>

</span></div><div><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">Regards,</span></div><div><span style="background-color:rgb(255,255,255);color:rgb(34,34,34);font-family:arial,sans-serif;font-size:13px">-Amar</span></div>

<div><br></div>