* 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