How to understand the macro __init?

Amarnath Revanna amarnath.revanna at gmail.com
Thu Aug 16 14:39:28 EDT 2012


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.revanna at gmail.com> wrote:

> Hi Ezequiel,
>
> On Thu, Aug 16, 2012 at 10:53 PM, Ezequiel Garcia <elezegarcia at gmail.com>wrote:
>
>> Hi Amar,
>>
>> On Thu, Aug 16, 2012 at 1:08 PM, Amarnath Revanna
>> <amarnath.revanna at 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
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20120817/f741723e/attachment.html 


More information about the Kernelnewbies mailing list