Re: How to understand the macro __init?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Ezequiel,

On Thu, Aug 16, 2012 at 10:53 PM, Ezequiel Garcia <elezegarcia@xxxxxxxxx> wrote:
Hi Amar,

On Thu, Aug 16, 2012 at 1:08 PM, Amarnath Revanna
<amarnath.revanna@xxxxxxxxx> 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 #define __init          __section(.init.text) __cold notrace
 45 #define __initdata      __section(.init.data)
 46 #define __initconst     __section(.init.rodata)
 47 #define __exitdata      __section(.exit.data)
 48 #define __exit_call     __used __section(.exitcall.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@xxxxxxxxxxxxxxxxx
http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux