linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* A problem with percpu variable cpu_number
       [not found] <CAOe6JY2fQ7UcnVprer9tXPxz0FDEv5h1j6txP576-EKXc9v5PA@mail.gmail.com>
@ 2012-02-19 12:20 ` Tao Jiang
  2012-02-19 15:21   ` Cong Wang
  0 siblings, 1 reply; 10+ messages in thread
From: Tao Jiang @ 2012-02-19 12:20 UTC (permalink / raw)
  To: linux-kernel

Hi:

I've asked the question on kernelnewbies, no replies.
So forward it here.
Thank you.


---------- Forwarded message ----------
From: tao jiang <jiangtao.jit@gmail.com>
Date: 2012/2/16
Subject: A problem with percpu variable cpu_number
To: kernelnewbies <kernelnewbies@kernelnewbies.org>


Hi :

At the beginning of start_kernel() -- init/main.c
boot_cpu_init() is called

and in boot_cpu_init() will call smp_processor_id()
it's a macro
and it will be expanded as (percpu_read(cpu_number)) and so on

but i noticed that it's before setup_per_cpu_areas() in start_kernel()
is that mean the percpu areas hadn't be initialized yet
but why smp_processor_id() could be called before setup_per_cpu_areas()


Thank you.

---------------
jiangtao

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: A problem with percpu variable cpu_number
  2012-02-19 12:20 ` A problem with percpu variable cpu_number Tao Jiang
@ 2012-02-19 15:21   ` Cong Wang
  2012-02-20 11:04     ` Tao Jiang
  0 siblings, 1 reply; 10+ messages in thread
From: Cong Wang @ 2012-02-19 15:21 UTC (permalink / raw)
  To: Tao Jiang; +Cc: linux-kernel

On 02/19/2012 08:20 PM, Tao Jiang wrote:
> Hi :
>
> At the beginning of start_kernel() -- init/main.c
> boot_cpu_init() is called
>
> and in boot_cpu_init() will call smp_processor_id()
> it's a macro
> and it will be expanded as (percpu_read(cpu_number)) and so on
>
> but i noticed that it's before setup_per_cpu_areas() in start_kernel()
> is that mean the percpu areas hadn't be initialized yet
> but why smp_processor_id() could be called before setup_per_cpu_areas()

It doesn't matter, as the percpu var 'cpu_number' is defined statically: 
DECLARE_PER_CPU(int, cpu_number);.

Thanks.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: A problem with percpu variable cpu_number
  2012-02-19 15:21   ` Cong Wang
@ 2012-02-20 11:04     ` Tao Jiang
  2012-02-20 15:11       ` Cong Wang
  0 siblings, 1 reply; 10+ messages in thread
From: Tao Jiang @ 2012-02-20 11:04 UTC (permalink / raw)
  To: Cong Wang; +Cc: linux-kernel

Cong Wang:

Thanks for you reply.
But I think it's not the truth.

The percpu variable cpu_number is defined in arch/x86/kernel/setup_percpu.c
use DEFINE_PER_CPU(int, cpu_number);
and declared in head file arch/x86/include/asm/smp.h
use DECLARE_PER_CPU(int, cpu_number);

I read the macor DEFINE_PER_CPU
it's decorated by some percpu attributes
it will be put in section .data..percpu in init section
and init section will be free after the kernel had been initialized
so at the beginning of start_kernel()
what smp_processor_id() read is not initialized yet
am I right ?
Let me know if i made some misunderstanding of the code.
Thank you.




2012/2/19 Cong Wang <xiyou.wangcong@gmail.com>:
> On 02/19/2012 08:20 PM, Tao Jiang wrote:
>>
>> Hi :
>>
>> At the beginning of start_kernel() -- init/main.c
>> boot_cpu_init() is called
>>
>> and in boot_cpu_init() will call smp_processor_id()
>> it's a macro
>> and it will be expanded as (percpu_read(cpu_number)) and so on
>>
>> but i noticed that it's before setup_per_cpu_areas() in start_kernel()
>> is that mean the percpu areas hadn't be initialized yet
>> but why smp_processor_id() could be called before setup_per_cpu_areas()
>
>
> It doesn't matter, as the percpu var 'cpu_number' is defined statically:
> DECLARE_PER_CPU(int, cpu_number);.
>
> Thanks.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: A problem with percpu variable cpu_number
  2012-02-20 11:04     ` Tao Jiang
@ 2012-02-20 15:11       ` Cong Wang
  2012-02-21 12:41         ` Tao Jiang
  0 siblings, 1 reply; 10+ messages in thread
From: Cong Wang @ 2012-02-20 15:11 UTC (permalink / raw)
  To: Tao Jiang; +Cc: linux-kernel

On 02/20/2012 07:04 PM, Tao Jiang wrote:
>
> I read the macor DEFINE_PER_CPU
> it's decorated by some percpu attributes
> it will be put in section .data..percpu in init section

.data..percpu is not .init section, the .init sections should all have 
".init.*" names.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: A problem with percpu variable cpu_number
  2012-02-20 15:11       ` Cong Wang
@ 2012-02-21 12:41         ` Tao Jiang
  2012-02-21 14:29           ` Cong Wang
  0 siblings, 1 reply; 10+ messages in thread
From: Tao Jiang @ 2012-02-21 12:41 UTC (permalink / raw)
  To: Cong Wang; +Cc: linux-kernel

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?

Thank you.


2012/2/20 Cong Wang <xiyou.wangcong@gmail.com>:
> On 02/20/2012 07:04 PM, Tao Jiang wrote:
>>
>>
>> I read the macor DEFINE_PER_CPU
>> it's decorated by some percpu attributes
>> it will be put in section .data..percpu in init section
>
>
> .data..percpu is not .init section, the .init sections should all have
> ".init.*" names.

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: A problem with percpu variable cpu_number
  2012-02-21 12:41         ` Tao Jiang
@ 2012-02-21 14:29           ` Cong Wang
  2012-02-21 17:58             ` Brian Gerst
  0 siblings, 1 reply; 10+ messages in thread
From: Cong Wang @ 2012-02-21 14:29 UTC (permalink / raw)
  To: Tao Jiang; +Cc: linux-kernel

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>:

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: A problem with percpu variable cpu_number
  2012-02-21 14:29           ` Cong Wang
@ 2012-02-21 17:58             ` Brian Gerst
  2012-02-22 11:13               ` Tao Jiang
  0 siblings, 1 reply; 10+ messages in thread
From: Brian Gerst @ 2012-02-21 17:58 UTC (permalink / raw)
  To: Cong Wang; +Cc: Tao Jiang, linux-kernel

On Tue, Feb 21, 2012 at 9:29 AM, Cong Wang <xiyou.wangcong@gmail.com> 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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: A problem with percpu variable cpu_number
  2012-02-21 17:58             ` Brian Gerst
@ 2012-02-22 11:13               ` Tao Jiang
  2012-02-22 13:21                 ` Hillf Danton
  0 siblings, 1 reply; 10+ messages in thread
From: Tao Jiang @ 2012-02-22 11:13 UTC (permalink / raw)
  To: Brian Gerst; +Cc: Cong Wang, linux-kernel

Hi:

Thank you all.

So in boot_cpu_init(), it will always set bit 0 to these masks.
If the boot cpu is the first processor, it's the right case.
And if the BP is not the first one, is it wrong?
But can it happen that the BP is not cpu0?
Thank you.


2012/2/22 Brian Gerst <brgerst@gmail.com>:
> On Tue, Feb 21, 2012 at 9:29 AM, Cong Wang <xiyou.wangcong@gmail.com> 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

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: A problem with percpu variable cpu_number
  2012-02-22 11:13               ` Tao Jiang
@ 2012-02-22 13:21                 ` Hillf Danton
  2012-02-23 14:29                   ` Tao Jiang
  0 siblings, 1 reply; 10+ messages in thread
From: Hillf Danton @ 2012-02-22 13:21 UTC (permalink / raw)
  To: Tao Jiang; +Cc: Brian Gerst, Cong Wang, linux-kernel

On Wed, Feb 22, 2012 at 7:13 PM, Tao Jiang <jiangtao.jit@gmail.com> wrote:
> Hi:
>
> Thank you all.
>
> So in boot_cpu_init(), it will always set bit 0 to these masks.
> If the boot cpu is the first processor, it's the right case.
> And if the BP is not the first one, is it wrong?
> But can it happen that the BP is not cpu0?

BP could be not "the first one".
Due to that current code boots fine, I guess, you mess
logic CPU with hard CPU.

btw, replying messages in this way looks not fine.

> Thank you.
>
>
> 2012/2/22 Brian Gerst <brgerst@gmail.com>:
>> On Tue, Feb 21, 2012 at 9:29 AM, Cong Wang <xiyou.wangcong@gmail.com> 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
> --

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: A problem with percpu variable cpu_number
  2012-02-22 13:21                 ` Hillf Danton
@ 2012-02-23 14:29                   ` Tao Jiang
  0 siblings, 0 replies; 10+ messages in thread
From: Tao Jiang @ 2012-02-23 14:29 UTC (permalink / raw)
  To: Hillf Danton; +Cc: Brian Gerst, Cong Wang, linux-kernel

Hillf Danton:

Thanks for your remind
and sorry for my poor English.


2012/2/22 Hillf Danton <dhillf@gmail.com>:
> On Wed, Feb 22, 2012 at 7:13 PM, Tao Jiang <jiangtao.jit@gmail.com> wrote:
>> Hi:
>>
>> Thank you all.
>>
>> So in boot_cpu_init(), it will always set bit 0 to these masks.
>> If the boot cpu is the first processor, it's the right case.
>> And if the BP is not the first one, is it wrong?
>> But can it happen that the BP is not cpu0?
>
> BP could be not "the first one".
> Due to that current code boots fine, I guess, you mess
> logic CPU with hard CPU.
>
> btw, replying messages in this way looks not fine.
>
>> Thank you.
>>
>>
>> 2012/2/22 Brian Gerst <brgerst@gmail.com>:
>>> On Tue, Feb 21, 2012 at 9:29 AM, Cong Wang <xiyou.wangcong@gmail.com> 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
>> --

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2012-02-23 14:29 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <CAOe6JY2fQ7UcnVprer9tXPxz0FDEv5h1j6txP576-EKXc9v5PA@mail.gmail.com>
2012-02-19 12:20 ` A problem with percpu variable cpu_number Tao Jiang
2012-02-19 15:21   ` Cong Wang
2012-02-20 11:04     ` Tao Jiang
2012-02-20 15:11       ` Cong Wang
2012-02-21 12:41         ` Tao Jiang
2012-02-21 14:29           ` Cong Wang
2012-02-21 17:58             ` Brian Gerst
2012-02-22 11:13               ` Tao Jiang
2012-02-22 13:21                 ` Hillf Danton
2012-02-23 14:29                   ` Tao Jiang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).