Re: A problem with percpu variable cpu_number

From: Brian Gerst
Date: Tue Feb 21 2012 - 12:58:45 EST


On Tue, Feb 21, 2012 at 9:29 AM, Cong Wang <xiyou.wangcong@xxxxxxxxx> wrote:
> On 02/21/2012 08:41 PM, Tao Jiang wrote:
>>
>> Hi Cong Wang:
>>
>> I read the file vmlinux.lds.S in arch/x86/kernel
>> section .data..percpu is between .init.data and .init.end
>> Is that means these percpu variables will be freed after init?
>
>
> % grep -e __init_begin -e __init_end -e __per_cpu_start -e __per_cpu_end
> /boot/System.map
> 0000000000000000 D __per_cpu_start
> 0000000000014bc0 D __per_cpu_end
> ffffffff81cf3000 D __init_begin
> ffffffff81dfc000 R __init_end
> % objdump -d -j .data..percpu vmlinux | grep cpu_number
> 000000000000dc38 <cpu_number>:

The .data..percpu section is placed in the init section, but x86-64 is
a special case as noted below. The boot cpu is pointed to the init
percpu section until setup_per_cpu_areas() is called, when it switches
to the regular percpu area. The init percpu data is then freed with
all other init data.

The reason the percpu symbols start at virtual address 0 on x86-64 is
because of the requirement that gs_base must be a canonical address
(it cannot be a simple offset like x86-32). But, the data is still
loaded in the init section in memory. See
arch/x86/kernel/vmlinux.lds.S for the explanation of how the linker
changes the program headers to set the virtual address to zero but
keeps the load address in the init section.

To answer the original question. in the case of cpu_number, it is set
to zero in the init section because it doesn't have an explicit
initializer. Therefore the boot cpu will always read zero for the
cpu_number, even before setup_per_cpu_areas() is called.


--
Brian Gerst
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/