diff mbox

[RFC] arm: add __initbss section attribute

Message ID 1444622356-8263-1-git-send-email-yalin.wang2010@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

yalin wang Oct. 12, 2015, 3:59 a.m. UTC
This attribute can make init data to be into .initbss section,
this will make the data to be NO_BITS in vmlinux, can shrink the
Image file size, and speed up the boot up time.

Signed-off-by: yalin wang <yalin.wang2010@gmail.com>
---
 arch/arm/kernel/vmlinux.lds.S     |  2 +-
 arch/arm/mm/init.c                |  1 +
 include/asm-generic/sections.h    |  1 +
 include/asm-generic/vmlinux.lds.h | 11 ++++++++++-
 include/linux/init.h              |  1 +
 include/linux/mm.h                |  4 +++-
 6 files changed, 17 insertions(+), 3 deletions(-)

Comments

Ard Biesheuvel Oct. 12, 2015, 8:22 a.m. UTC | #1
On 12 October 2015 at 05:59, yalin wang <yalin.wang2010@gmail.com> wrote:
> This attribute can make init data to be into .initbss section,
> this will make the data to be NO_BITS in vmlinux, can shrink the
> Image file size, and speed up the boot up time.
>
> Signed-off-by: yalin wang <yalin.wang2010@gmail.com>
> ---
>  arch/arm/kernel/vmlinux.lds.S     |  2 +-
>  arch/arm/mm/init.c                |  1 +
>  include/asm-generic/sections.h    |  1 +
>  include/asm-generic/vmlinux.lds.h | 11 ++++++++++-
>  include/linux/init.h              |  1 +
>  include/linux/mm.h                |  4 +++-
>  6 files changed, 17 insertions(+), 3 deletions(-)
>
> diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
> index 8b60fde..ad6d740 100644
> --- a/arch/arm/kernel/vmlinux.lds.S
> +++ b/arch/arm/kernel/vmlinux.lds.S
> @@ -330,7 +330,7 @@ SECTIONS
>         }
>  #endif
>
> -       BSS_SECTION(0, 0, 0)
> +       BSS_SECTION(0, 0, 0, 0)
>         _end = .;
>
>         STABS_DEBUG
> diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
> index 8a63b4c..50b881e 100644
> --- a/arch/arm/mm/init.c
> +++ b/arch/arm/mm/init.c
> @@ -722,6 +722,7 @@ void free_initmem(void)
>         free_tcmmem();
>
>         poison_init_mem(__init_begin, __init_end - __init_begin);
> +       poison_init_mem(__initbss_start, __initbss_start - __initbss_end);
>         if (!machine_is_integrator() && !machine_is_cintegrator())
>                 free_initmem_default(-1);
>  }
> diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
> index b58fd66..a63ebe9 100644
> --- a/include/asm-generic/sections.h
> +++ b/include/asm-generic/sections.h
> @@ -29,6 +29,7 @@ extern char _text[], _stext[], _etext[];
>  extern char _data[], _sdata[], _edata[];
>  extern char __bss_start[], __bss_stop[];
>  extern char __init_begin[], __init_end[];
> +extern char __initbss_start[], __initbss_end[];
>  extern char _sinittext[], _einittext[];
>  extern char _end[];
>  extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[];
> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
> index c4bd0e2..b3db62d 100644
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
> @@ -574,6 +574,14 @@
>                 *(COMMON)                                               \
>         }
>
> +#define INITBSS(initbss_align)                                         \
> +       . = ALIGN(initbss_align);                                       \
> +       .initbss : AT(ADDR(.initbss) - LOAD_OFFSET) {                   \
> +               VMLINUX_SYMBOL(__initbss_start) = .;                    \
> +               *(.bss.init.data)                                       \
> +               VMLINUX_SYMBOL(__initbss_end) = .;                      \
> +       }
> +
>  /*
>   * DWARF debug sections.
>   * Symbols in the DWARF debugging sections are relative to
> @@ -831,10 +839,11 @@
>                 INIT_RAM_FS                                             \
>         }
>
> -#define BSS_SECTION(sbss_align, bss_align, stop_align)                 \
> +#define BSS_SECTION(sbss_align, bss_align, initbss_align, stop_align)                  \
>         . = ALIGN(sbss_align);                                          \
>         VMLINUX_SYMBOL(__bss_start) = .;                                \
>         SBSS(sbss_align)                                                \
>         BSS(bss_align)                                                  \
> +       INITBSS(initbss_align)                                          \
>         . = ALIGN(stop_align);                                          \
>         VMLINUX_SYMBOL(__bss_stop) = .;
> diff --git a/include/linux/init.h b/include/linux/init.h
> index b449f37..f2960b2 100644
> --- a/include/linux/init.h
> +++ b/include/linux/init.h
> @@ -41,6 +41,7 @@
>     discard it in modules) */
>  #define __init         __section(.init.text) __cold notrace
>  #define __initdata     __section(.init.data)
> +#define __initbss      __section(.bss.init.data)

Shouldn't this be .init.bss ?

>  #define __initconst    __constsection(.init.rodata)
>  #define __exitdata     __section(.exit.data)
>  #define __exit_call    __used __section(.exitcall.exit)
> diff --git a/include/linux/mm.h b/include/linux/mm.h
> index d30eea3..1f266f7 100644
> --- a/include/linux/mm.h
> +++ b/include/linux/mm.h
> @@ -21,6 +21,7 @@
>  #include <linux/resource.h>
>  #include <linux/page_ext.h>
>  #include <linux/err.h>
> +#include <asm/sections.h>
>
>  struct mempolicy;
>  struct anon_vma;
> @@ -1722,10 +1723,11 @@ static inline void mark_page_reserved(struct page *page)
>   */
>  static inline unsigned long free_initmem_default(int poison)
>  {
> -       extern char __init_begin[], __init_end[];
>
>         return free_reserved_area(&__init_begin, &__init_end,
>                                   poison, "unused kernel");
> +       return free_reserved_area(&__initbss_start, &__initbss_end,
> +                                 poison, "unused kernel");

You obviously have not tested this code, since the first return makes
the second unreachable.

So you will need to put __initbss annotations all over the tree to
actually populate and then free this section (after you have fixed
your code). Before we do that, could we have an estimate of how much
memory it actually frees up, especially since the zImage compression
should ensure that zero initialized PROGBITS .data does not take very
much additional space in the first place.
yalin wang Oct. 12, 2015, 8:46 a.m. UTC | #2
> On Oct 12, 2015, at 16:22, Ard Biesheuvel <ard.biesheuvel@linaro.org> wrote:
> 
> On 12 October 2015 at 05:59, yalin wang <yalin.wang2010@gmail.com> wrote:
>> This attribute can make init data to be into .initbss section,
>> this will make the data to be NO_BITS in vmlinux, can shrink the
>> Image file size, and speed up the boot up time.
>> 
>> Signed-off-by: yalin wang <yalin.wang2010@gmail.com>
>> ---
>> arch/arm/kernel/vmlinux.lds.S     |  2 +-
>> arch/arm/mm/init.c                |  1 +
>> include/asm-generic/sections.h    |  1 +
>> include/asm-generic/vmlinux.lds.h | 11 ++++++++++-
>> include/linux/init.h              |  1 +
>> include/linux/mm.h                |  4 +++-
>> 6 files changed, 17 insertions(+), 3 deletions(-)
>> 
>> diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
>> index 8b60fde..ad6d740 100644
>> --- a/arch/arm/kernel/vmlinux.lds.S
>> +++ b/arch/arm/kernel/vmlinux.lds.S
>> @@ -330,7 +330,7 @@ SECTIONS
>>        }
>> #endif
>> 
>> -       BSS_SECTION(0, 0, 0)
>> +       BSS_SECTION(0, 0, 0, 0)
>>        _end = .;
>> 
>>        STABS_DEBUG
>> diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
>> index 8a63b4c..50b881e 100644
>> --- a/arch/arm/mm/init.c
>> +++ b/arch/arm/mm/init.c
>> @@ -722,6 +722,7 @@ void free_initmem(void)
>>        free_tcmmem();
>> 
>>        poison_init_mem(__init_begin, __init_end - __init_begin);
>> +       poison_init_mem(__initbss_start, __initbss_start - __initbss_end);
>>        if (!machine_is_integrator() && !machine_is_cintegrator())
>>                free_initmem_default(-1);
>> }
>> diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
>> index b58fd66..a63ebe9 100644
>> --- a/include/asm-generic/sections.h
>> +++ b/include/asm-generic/sections.h
>> @@ -29,6 +29,7 @@ extern char _text[], _stext[], _etext[];
>> extern char _data[], _sdata[], _edata[];
>> extern char __bss_start[], __bss_stop[];
>> extern char __init_begin[], __init_end[];
>> +extern char __initbss_start[], __initbss_end[];
>> extern char _sinittext[], _einittext[];
>> extern char _end[];
>> extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[];
>> diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
>> index c4bd0e2..b3db62d 100644
>> --- a/include/asm-generic/vmlinux.lds.h
>> +++ b/include/asm-generic/vmlinux.lds.h
>> @@ -574,6 +574,14 @@
>>                *(COMMON)                                               \
>>        }
>> 
>> +#define INITBSS(initbss_align)                                         \
>> +       . = ALIGN(initbss_align);                                       \
>> +       .initbss : AT(ADDR(.initbss) - LOAD_OFFSET) {                   \
>> +               VMLINUX_SYMBOL(__initbss_start) = .;                    \
>> +               *(.bss.init.data)                                       \
>> +               VMLINUX_SYMBOL(__initbss_end) = .;                      \
>> +       }
>> +
>> /*
>>  * DWARF debug sections.
>>  * Symbols in the DWARF debugging sections are relative to
>> @@ -831,10 +839,11 @@
>>                INIT_RAM_FS                                             \
>>        }
>> 
>> -#define BSS_SECTION(sbss_align, bss_align, stop_align)                 \
>> +#define BSS_SECTION(sbss_align, bss_align, initbss_align, stop_align)             \
>>        . = ALIGN(sbss_align);                                          \
>>        VMLINUX_SYMBOL(__bss_start) = .;                                \
>>        SBSS(sbss_align)                                                \
>>        BSS(bss_align)                                                  \
>> +       INITBSS(initbss_align)                                          \
>>        . = ALIGN(stop_align);                                          \
>>        VMLINUX_SYMBOL(__bss_stop) = .;
>> diff --git a/include/linux/init.h b/include/linux/init.h
>> index b449f37..f2960b2 100644
>> --- a/include/linux/init.h
>> +++ b/include/linux/init.h
>> @@ -41,6 +41,7 @@
>>    discard it in modules) */
>> #define __init         __section(.init.text) __cold notrace
>> #define __initdata     __section(.init.data)
>> +#define __initbss      __section(.bss.init.data)
> 
> Shouldn't this be .init.bss ?
> 
>> #define __initconst    __constsection(.init.rodata)
>> #define __exitdata     __section(.exit.data)
>> #define __exit_call    __used __section(.exitcall.exit)
>> diff --git a/include/linux/mm.h b/include/linux/mm.h
>> index d30eea3..1f266f7 100644
>> --- a/include/linux/mm.h
>> +++ b/include/linux/mm.h
>> @@ -21,6 +21,7 @@
>> #include <linux/resource.h>
>> #include <linux/page_ext.h>
>> #include <linux/err.h>
>> +#include <asm/sections.h>
>> 
>> struct mempolicy;
>> struct anon_vma;
>> @@ -1722,10 +1723,11 @@ static inline void mark_page_reserved(struct page *page)
>>  */
>> static inline unsigned long free_initmem_default(int poison)
>> {
>> -       extern char __init_begin[], __init_end[];
>> 
>>        return free_reserved_area(&__init_begin, &__init_end,
>>                                  poison, "unused kernel");
>> +       return free_reserved_area(&__initbss_start, &__initbss_end,
>> +                                 poison, "unused kernel");
> 
> You obviously have not tested this code, since the first return makes
> the second unreachable.
> 
> So you will need to put __initbss annotations all over the tree to
> actually populate and then free this section (after you have fixed
> your code). Before we do that, could we have an estimate of how much
> memory it actually frees up, especially since the zImage compression 
> should ensure that zero initialized PROGBITS .data does not take very
> much additional space in the first place.
> 
> -- 
> Ard.
yeah, I just compile it , not test it . because i need replace lots of __initdata variable to __initbss first .
i don’t think zImage compression can shrink zero data in .data section , 
in current __initdata implementation , the zero initialized data are mixed with non-zero data,
for example:
int a = 20 __initdata;
int b __initdata;   // zero initialized data
int c = 30 __initdata;

so the zero data are not in a contineous memory area, compress will not benefit from this scenario, 
and on some platforms like arm64 , don’t compress compress zImage , 

i will make a test in some time later, and send out the result to see if this method is better .

Thanks
Arnd Bergmann Oct. 12, 2015, 10:21 a.m. UTC | #3
On Monday 12 October 2015 11:59:16 yalin wang wrote:
> This attribute can make init data to be into .initbss section,
> this will make the data to be NO_BITS in vmlinux, can shrink the
> Image file size, and speed up the boot up time.
> 
> Signed-off-by: yalin wang <yalin.wang2010@gmail.com>

Do you have an estimate of how much it gains?

In multi_v7_defconfig, I see a total of 3367 symbols with
406016 bytes init.data, but only 348 bytes of those are
in zero-initialized symbols.

	Arnd
Sam Ravnborg Oct. 12, 2015, 8:04 p.m. UTC | #4
> --- a/include/asm-generic/vmlinux.lds.h
> +++ b/include/asm-generic/vmlinux.lds.h
>  
> -#define BSS_SECTION(sbss_align, bss_align, stop_align)			\
> +#define BSS_SECTION(sbss_align, bss_align, initbss_align, stop_align)			\

A few comments:

1) - please align the backslash at the end of the
     line with the backslash above it.
2) - you need to fix all the remaining users of BSS_SECTION.
3) - do we really need the flexibility to specify an alignment (stop_align)?
        If not - drop the extra argument.

	Sam
Arnd Bergmann Oct. 13, 2015, 9:40 a.m. UTC | #5
On Tuesday 13 October 2015 15:33:10 yalin wang wrote:
> 
> > On Oct 13, 2015, at 04:04, Sam Ravnborg <sam@ravnborg.org> wrote:
> > 
> >> --- a/include/asm-generic/vmlinux.lds.h
> >> +++ b/include/asm-generic/vmlinux.lds.h
> >> 
> >> -#define BSS_SECTION(sbss_align, bss_align, stop_align)			\
> >> +#define BSS_SECTION(sbss_align, bss_align, initbss_align, stop_align)			\
> > 
> > A few comments:
> > 
> > 1) - please align the backslash at the end of the
> >     line with the backslash above it.
> > 2) - you need to fix all the remaining users of BSS_SECTION.
> > 3) - do we really need the flexibility to specify an alignment (stop_align)?
> >        If not - drop the extra argument.
> > 
> > 	Sam
> i change lots of __initdata to __initbss to test it on ARM arch,
> 

Ok, I found my mistake in the script I used to calculate the savings,
here is the correct output showing all uninitialized variables in
multi_v7_defconfig:

4	done.44688
1024	boot_command_line
1024	tmp_cmdline.44689
4	late_time_init
4	root_mount_data
4	root_fs_names
4	rd_doload
4	root_delay
64	saved_root_name
4	root_device_name
4	message
4	byte_count
4	victim
4	collected
8	this_header
4	state
4	collect
4	remains
4	next_state
8	header_buf
8	next_header
4	do_retain_initrd
4	name_len
4	body_len
4	gid
4	uid
4	mtime
4	wfd
4	vcollected
4	ino
4	mode
4	nlink
4	major
4	minor
4	rdev
4	symlink_buf
4	name_buf
64	msg_buf.29770
128	head
4	machine_desc
4	usermem.34390
4	__atags_pointer
1024	cmd_line
1024	default_command_line
1536	atags_copy
4	dma_mmu_remap_num
64	dma_mmu_remap
4	phys_initrd_start
4024	phys_initrd_size
4096	bm_pte
4	ecc_mask
4	initial_pmd_value
4	arm_lowmem_limit
24	s5p_mfc_mem
28	tx_pad_name
4	use_gptimer_clksrc
4	omap_table_init
4	mpurate
4	am35xx_aes_hwmod_ocp_ifs
4	am35xx_sham_hwmod_ocp_ifs
4	dra72x_hwmod_ocp_ifs
4	rx51_vibra_data
4	num_special_pds
128	special_pds
4	main_extable_sort_needed
4	new_log_buf_len
24	opts.36513
512	smap.22469
512	dmap.22470
64	group_map.22521
64	group_cnt.22522
4	pcpu_chosen_fc
4	vmlist
4	vm_init_off.26867
4	reset_managed_pages_done
116	boot_kmem_cache_node.32827
116	boot_kmem_cache.32826
4	dhash_entries
4	ihash_entries
4	mhash_entries
4	mphash_entries
256	nfs_root_parms
1028	nfs_export_path
1028	nfs_root_device
4	gic_cnt
4	threshold_index
4096	ata_force_param_buf
4	mtd_devs
2432	mtd_dev_param
8	m68k_probes
8	isa_probes
4	arch_timers_present
4	dt_root_size_cells
4	dt_root_addr_cells
4	imx_keep_uart_clocks
4	imx_uart_clocks
4	mt8173_top_clk_data
4	mt8173_pll_clk_data
4	cpg_mode
4	cpg_mode_rates
4	cpg_mode_divs
4	cpg_mode
4	cpg_mode
4	thash_entries
4	uhash_entries
4	ic_got_reply
4	ic_first_dev
4	ic_dev
16	user_dev_name
4	ic_dhcp_msgtype
4	ic_host_name_set
4	ic_dev_mtu
4	ic_set_manually
4	ic_enable
256	vendor_class_identifier
4	ic_proto_have_if
4	dma_reserve
4	nr_kernel_pages
4	nr_all_pages
196	__clk_of_table_sentinel
200	__rmem_of_table_sentinel
196	__clksrc_of_table_sentinel
200	__iommu_of_table_sentinel
8	__cpu_method_of_table_sentinel
8	__cpuidle_method_of_table_sentinel
196	irqchip_of_match_end
32	__earlycon_table_sentinel
200	__earlycon_of_table_sentinel
6	__irf_end


26398 total
yalin wang Oct. 13, 2015, 9:51 a.m. UTC | #6
> On Oct 13, 2015, at 17:40, Arnd Bergmann <arnd@arndb.de> wrote:
> 
> On Tuesday 13 October 2015 15:33:10 yalin wang wrote:
>> 
>>> On Oct 13, 2015, at 04:04, Sam Ravnborg <sam@ravnborg.org> wrote:
>>> 
>>>> --- a/include/asm-generic/vmlinux.lds.h
>>>> +++ b/include/asm-generic/vmlinux.lds.h
>>>> 
>>>> -#define BSS_SECTION(sbss_align, bss_align, stop_align)			\
>>>> +#define BSS_SECTION(sbss_align, bss_align, initbss_align, stop_align)			\
>>> 
>>> A few comments:
>>> 
>>> 1) - please align the backslash at the end of the
>>>    line with the backslash above it.
>>> 2) - you need to fix all the remaining users of BSS_SECTION.
>>> 3) - do we really need the flexibility to specify an alignment (stop_align)?
>>>       If not - drop the extra argument.
>>> 
>>> 	Sam
>> i change lots of __initdata to __initbss to test it on ARM arch,
>> 
> 
> Ok, I found my mistake in the script I used to calculate the savings,
> here is the correct output showing all uninitialized variables in
> multi_v7_defconfig:
> 
> 4	done.44688
> 1024	boot_command_line
> 1024	tmp_cmdline.44689
> 4	late_time_init
> 4	root_mount_data
> 4	root_fs_names
> 4	rd_doload
> 4	root_delay
> 64	saved_root_name
> 4	root_device_name
> 4	message
> 4	byte_count
> 4	victim
> 4	collected
> 8	this_header
> 4	state
> 4	collect
> 4	remains
> 4	next_state
> 8	header_buf
> 8	next_header
> 4	do_retain_initrd
> 4	name_len
> 4	body_len
> 4	gid
> 4	uid
> 4	mtime
> 4	wfd
> 4	vcollected
> 4	ino
> 4	mode
> 4	nlink
> 4	major
> 4	minor
> 4	rdev
> 4	symlink_buf
> 4	name_buf
> 64	msg_buf.29770
> 128	head
> 4	machine_desc
> 4	usermem.34390
> 4	__atags_pointer
> 1024	cmd_line
> 1024	default_command_line
> 1536	atags_copy
> 4	dma_mmu_remap_num
> 64	dma_mmu_remap
> 4	phys_initrd_start
> 4024	phys_initrd_size
> 4096	bm_pte
> 4	ecc_mask
> 4	initial_pmd_value
> 4	arm_lowmem_limit
> 24	s5p_mfc_mem
> 28	tx_pad_name
> 4	use_gptimer_clksrc
> 4	omap_table_init
> 4	mpurate
> 4	am35xx_aes_hwmod_ocp_ifs
> 4	am35xx_sham_hwmod_ocp_ifs
> 4	dra72x_hwmod_ocp_ifs
> 4	rx51_vibra_data
> 4	num_special_pds
> 128	special_pds
> 4	main_extable_sort_needed
> 4	new_log_buf_len
> 24	opts.36513
> 512	smap.22469
> 512	dmap.22470
> 64	group_map.22521
> 64	group_cnt.22522
> 4	pcpu_chosen_fc
> 4	vmlist
> 4	vm_init_off.26867
> 4	reset_managed_pages_done
> 116	boot_kmem_cache_node.32827
> 116	boot_kmem_cache.32826
> 4	dhash_entries
> 4	ihash_entries
> 4	mhash_entries
> 4	mphash_entries
> 256	nfs_root_parms
> 1028	nfs_export_path
> 1028	nfs_root_device
> 4	gic_cnt
> 4	threshold_index
> 4096	ata_force_param_buf
> 4	mtd_devs
> 2432	mtd_dev_param
> 8	m68k_probes
> 8	isa_probes
> 4	arch_timers_present
> 4	dt_root_size_cells
> 4	dt_root_addr_cells
> 4	imx_keep_uart_clocks
> 4	imx_uart_clocks
> 4	mt8173_top_clk_data
> 4	mt8173_pll_clk_data
> 4	cpg_mode
> 4	cpg_mode_rates
> 4	cpg_mode_divs
> 4	cpg_mode
> 4	cpg_mode
> 4	thash_entries
> 4	uhash_entries
> 4	ic_got_reply
> 4	ic_first_dev
> 4	ic_dev
> 16	user_dev_name
> 4	ic_dhcp_msgtype
> 4	ic_host_name_set
> 4	ic_dev_mtu
> 4	ic_set_manually
> 4	ic_enable
> 256	vendor_class_identifier
> 4	ic_proto_have_if
> 4	dma_reserve
> 4	nr_kernel_pages
> 4	nr_all_pages
> 196	__clk_of_table_sentinel
> 200	__rmem_of_table_sentinel
> 196	__clksrc_of_table_sentinel
> 200	__iommu_of_table_sentinel
> 8	__cpu_method_of_table_sentinel
> 8	__cpuidle_method_of_table_sentinel
> 196	irqchip_of_match_end
> 32	__earlycon_table_sentinel
> 200	__earlycon_of_table_sentinel
> 6	__irf_end
> 
> 
> 26398 total
i am curious about your scripts ,
could you show me ?
Thank you !
Arnd Bergmann Oct. 13, 2015, 11:28 a.m. UTC | #7
On Tuesday 13 October 2015 17:51:32 yalin wang wrote:

> > 32	__earlycon_table_sentinel
> > 200	__earlycon_of_table_sentinel
> > 6	__irf_end
> > 
> > 
> > 26398 total
> i am curious about your scripts ,
> could you show me ?

I was using some ad-hoc command line tricks, including

objcopy  -j .init.data  build/multi_v7_defconfig/vmlinux   /tmp/initdata
nm initdata  | sort -n | { read start b sym ; while read a b c ; do objdump -Dr --start-address=0x$start --stop-address=0x$a initdata > initdata.d/$sym  ; start=$a ; sym=$c  ; done }
(some manual sorting to delete the files that have pre-initialized symbols)
sum=0 ; nm /tmp/initdata  | sort -n | { read start b sym ; while read a b c ; do test -e ../$sym  && { echo $[0x$a - 0x$start]\      $sym  ; sum=$[$sum + $[0x$a - 0x$start]] ; } ; start=$a ; sym=$c ; done ; echo $sum;}

I'm sure there are better ways to do this, and the manual step I used at
first was faulty.

	Arnd
diff mbox

Patch

diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 8b60fde..ad6d740 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -330,7 +330,7 @@  SECTIONS
 	}
 #endif
 
-	BSS_SECTION(0, 0, 0)
+	BSS_SECTION(0, 0, 0, 0)
 	_end = .;
 
 	STABS_DEBUG
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 8a63b4c..50b881e 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -722,6 +722,7 @@  void free_initmem(void)
 	free_tcmmem();
 
 	poison_init_mem(__init_begin, __init_end - __init_begin);
+	poison_init_mem(__initbss_start, __initbss_start - __initbss_end);
 	if (!machine_is_integrator() && !machine_is_cintegrator())
 		free_initmem_default(-1);
 }
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index b58fd66..a63ebe9 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -29,6 +29,7 @@  extern char _text[], _stext[], _etext[];
 extern char _data[], _sdata[], _edata[];
 extern char __bss_start[], __bss_stop[];
 extern char __init_begin[], __init_end[];
+extern char __initbss_start[], __initbss_end[];
 extern char _sinittext[], _einittext[];
 extern char _end[];
 extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[];
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index c4bd0e2..b3db62d 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -574,6 +574,14 @@ 
 		*(COMMON)						\
 	}
 
+#define INITBSS(initbss_align)						\
+	. = ALIGN(initbss_align);					\
+	.initbss : AT(ADDR(.initbss) - LOAD_OFFSET) {			\
+		VMLINUX_SYMBOL(__initbss_start) = .;			\
+		*(.bss.init.data)					\
+		VMLINUX_SYMBOL(__initbss_end) = .;			\
+	}
+
 /*
  * DWARF debug sections.
  * Symbols in the DWARF debugging sections are relative to
@@ -831,10 +839,11 @@ 
 		INIT_RAM_FS						\
 	}
 
-#define BSS_SECTION(sbss_align, bss_align, stop_align)			\
+#define BSS_SECTION(sbss_align, bss_align, initbss_align, stop_align)			\
 	. = ALIGN(sbss_align);						\
 	VMLINUX_SYMBOL(__bss_start) = .;				\
 	SBSS(sbss_align)						\
 	BSS(bss_align)							\
+	INITBSS(initbss_align)						\
 	. = ALIGN(stop_align);						\
 	VMLINUX_SYMBOL(__bss_stop) = .;
diff --git a/include/linux/init.h b/include/linux/init.h
index b449f37..f2960b2 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -41,6 +41,7 @@ 
    discard it in modules) */
 #define __init		__section(.init.text) __cold notrace
 #define __initdata	__section(.init.data)
+#define __initbss	__section(.bss.init.data)
 #define __initconst	__constsection(.init.rodata)
 #define __exitdata	__section(.exit.data)
 #define __exit_call	__used __section(.exitcall.exit)
diff --git a/include/linux/mm.h b/include/linux/mm.h
index d30eea3..1f266f7 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -21,6 +21,7 @@ 
 #include <linux/resource.h>
 #include <linux/page_ext.h>
 #include <linux/err.h>
+#include <asm/sections.h>
 
 struct mempolicy;
 struct anon_vma;
@@ -1722,10 +1723,11 @@  static inline void mark_page_reserved(struct page *page)
  */
 static inline unsigned long free_initmem_default(int poison)
 {
-	extern char __init_begin[], __init_end[];
 
 	return free_reserved_area(&__init_begin, &__init_end,
 				  poison, "unused kernel");
+	return free_reserved_area(&__initbss_start, &__initbss_end,
+				  poison, "unused kernel");
 }
 
 static inline unsigned long get_num_physpages(void)