* [PATCH 1/2 2.6.31-rc5 REPOST] init: set nr_cpu_ids before setup_per_cpu_areas()
@ 2009-08-06 9:33 Tejun Heo
2009-08-06 9:36 ` [PATCH 2/2 2.6.31-rc5 REPOST] percpu, sparc64: fix sparse possible cpu map handling Tejun Heo
0 siblings, 1 reply; 8+ messages in thread
From: Tejun Heo @ 2009-08-06 9:33 UTC (permalink / raw)
To: Linux Kernel, Ingo Molnar, David Miller, sparclinux
nr_cpu_ids is dependent only on cpu_possible_map and
setup_per_cpu_areas() already depends on cpu_possible_map and will use
nr_cpu_ids. Initialize nr_cpu_ids before setting up percpu areas.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
This is repost of the following two patches with sparclinux mailing
list cc'd because I couldn't get any response from David Miller.
Nothing has changed code-wise.
http://thread.gmane.org/gmane.linux.kernel/867587
These two patches fix boot failure on sparc64 which happens if the
cpus don't have consecutive cpu numbers.
Thanks.
init/main.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/init/main.c b/init/main.c
index 2c5ade7..2d9d6bd 100644
--- a/init/main.c
+++ b/init/main.c
@@ -584,8 +584,8 @@ asmlinkage void __init start_kernel(void)
setup_arch(&command_line);
mm_init_owner(&init_mm, &init_task);
setup_command_line(command_line);
- setup_per_cpu_areas();
setup_nr_cpu_ids();
+ setup_per_cpu_areas();
smp_prepare_boot_cpu(); /* arch-specific boot-cpu hooks */
build_all_zonelists();
--
1.6.0.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* [PATCH 2/2 2.6.31-rc5 REPOST] percpu, sparc64: fix sparse possible cpu map handling
2009-08-06 9:33 [PATCH 1/2 2.6.31-rc5 REPOST] init: set nr_cpu_ids before setup_per_cpu_areas() Tejun Heo
@ 2009-08-06 9:36 ` Tejun Heo
2009-08-06 11:57 ` Ingo Molnar
0 siblings, 1 reply; 8+ messages in thread
From: Tejun Heo @ 2009-08-06 9:36 UTC (permalink / raw)
To: Linux Kernel, Ingo Molnar, David Miller, sparclinux
percpu code has been assuming num_possible_cpus() == nr_cpu_ids which
is incorrect if cpu_possible_map contains holes. This causes percpu
code to access beyond allocated memories and vmalloc areas. On a
sparc64 machine with cpus 0 and 2 (u60), this triggers the following
warning or fails boot.
WARNING: at /devel/tj/os/work/mm/vmalloc.c:106 vmap_page_range_noflush+0x1f0/0x240()
Modules linked in:
Call Trace:
[00000000004b17d0] vmap_page_range_noflush+0x1f0/0x240
[00000000004b1840] map_vm_area+0x20/0x60
[00000000004b1950] __vmalloc_area_node+0xd0/0x160
[0000000000593434] deflate_init+0x14/0xe0
[0000000000583b94] __crypto_alloc_tfm+0xd4/0x1e0
[00000000005844f0] crypto_alloc_base+0x50/0xa0
[000000000058b898] alg_test_comp+0x18/0x80
[000000000058dad4] alg_test+0x54/0x180
[000000000058af00] cryptomgr_test+0x40/0x60
[0000000000473098] kthread+0x58/0x80
[000000000042b590] kernel_thread+0x30/0x60
[0000000000472fd0] kthreadd+0xf0/0x160
---[ end trace 429b268a213317ba ]---
This patch fixes generic percpu functions and sparc64
setup_per_cpu_areas() so that they handle sparse cpu_possible_map
properly.
Please note that on x86, cpu_possible_map() doesn't contain holes and
thus num_possible_cpus() == nr_cpu_ids and this patch doesn't cause
any behavior difference.
Signed-off-by: Tejun Heo <tj@kernel.org>
Cc: David S. Miller <davem@davemloft.net>
Cc: Ingo Molnar <mingo@elte.hu>
---
As written in the previous mail, this fixes rather critical boot
problem on sparc64. Upon ack, I can get it through the percpu tree.
Not really sure who could ack this one other than David tho. Anyone?
Thanks.
arch/sparc/kernel/smp_64.c | 4 ++--
arch/x86/kernel/setup_percpu.c | 14 +++++++-------
mm/percpu.c | 31 +++++++++++++++++++------------
3 files changed, 28 insertions(+), 21 deletions(-)
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index fa44eaf..3691907 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -1499,7 +1499,7 @@ void __init setup_per_cpu_areas(void)
dyn_size = pcpur_size - static_size - PERCPU_MODULE_RESERVE;
- ptrs_size = PFN_ALIGN(num_possible_cpus() * sizeof(pcpur_ptrs[0]));
+ ptrs_size = PFN_ALIGN(nr_cpu_ids * sizeof(pcpur_ptrs[0]));
pcpur_ptrs = alloc_bootmem(ptrs_size);
for_each_possible_cpu(cpu) {
@@ -1514,7 +1514,7 @@ void __init setup_per_cpu_areas(void)
/* allocate address and map */
vm.flags = VM_ALLOC;
- vm.size = num_possible_cpus() * PCPU_CHUNK_SIZE;
+ vm.size = nr_cpu_ids * PCPU_CHUNK_SIZE;
vm_area_register_early(&vm, PCPU_CHUNK_SIZE);
for_each_possible_cpu(cpu) {
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 29a3eef..07d8191 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -165,7 +165,7 @@ static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen)
if (!chosen) {
size_t vm_size = VMALLOC_END - VMALLOC_START;
- size_t tot_size = num_possible_cpus() * PMD_SIZE;
+ size_t tot_size = nr_cpu_ids * PMD_SIZE;
/* on non-NUMA, embedding is better */
if (!pcpu_need_numa())
@@ -199,7 +199,7 @@ static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen)
dyn_size = pcpul_size - static_size - PERCPU_FIRST_CHUNK_RESERVE;
/* allocate pointer array and alloc large pages */
- map_size = PFN_ALIGN(num_possible_cpus() * sizeof(pcpul_map[0]));
+ map_size = PFN_ALIGN(nr_cpu_ids * sizeof(pcpul_map[0]));
pcpul_map = alloc_bootmem(map_size);
for_each_possible_cpu(cpu) {
@@ -228,7 +228,7 @@ static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen)
/* allocate address and map */
pcpul_vm.flags = VM_ALLOC;
- pcpul_vm.size = num_possible_cpus() * PMD_SIZE;
+ pcpul_vm.size = nr_cpu_ids * PMD_SIZE;
vm_area_register_early(&pcpul_vm, PMD_SIZE);
for_each_possible_cpu(cpu) {
@@ -250,8 +250,8 @@ static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen)
PMD_SIZE, pcpul_vm.addr, NULL);
/* sort pcpul_map array for pcpu_lpage_remapped() */
- for (i = 0; i < num_possible_cpus() - 1; i++)
- for (j = i + 1; j < num_possible_cpus(); j++)
+ for (i = 0; i < nr_cpu_ids - 1; i++)
+ for (j = i + 1; j < nr_cpu_ids; j++)
if (pcpul_map[i].ptr > pcpul_map[j].ptr) {
struct pcpul_ent tmp = pcpul_map[i];
pcpul_map[i] = pcpul_map[j];
@@ -288,7 +288,7 @@ void *pcpu_lpage_remapped(void *kaddr)
{
void *pmd_addr = (void *)((unsigned long)kaddr & PMD_MASK);
unsigned long offset = (unsigned long)kaddr & ~PMD_MASK;
- int left = 0, right = num_possible_cpus() - 1;
+ int left = 0, right = nr_cpu_ids - 1;
int pos;
/* pcpul in use at all? */
@@ -377,7 +377,7 @@ static ssize_t __init setup_pcpu_4k(size_t static_size)
pcpu4k_nr_static_pages = PFN_UP(static_size);
/* unaligned allocations can't be freed, round up to page size */
- pages_size = PFN_ALIGN(pcpu4k_nr_static_pages * num_possible_cpus()
+ pages_size = PFN_ALIGN(pcpu4k_nr_static_pages * nr_cpu_ids
* sizeof(pcpu4k_pages[0]));
pcpu4k_pages = alloc_bootmem(pages_size);
diff --git a/mm/percpu.c b/mm/percpu.c
index b70f2ac..f772f02 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -8,12 +8,12 @@
*
* This is percpu allocator which can handle both static and dynamic
* areas. Percpu areas are allocated in chunks in vmalloc area. Each
- * chunk is consisted of num_possible_cpus() units and the first chunk
- * is used for static percpu variables in the kernel image (special
- * boot time alloc/init handling necessary as these areas need to be
- * brought up before allocation services are running). Unit grows as
- * necessary and all units grow or shrink in unison. When a chunk is
- * filled up, another chunk is allocated. ie. in vmalloc area
+ * chunk is consisted of nr_cpu_ids units and the first chunk is used
+ * for static percpu variables in the kernel image (special boot time
+ * alloc/init handling necessary as these areas need to be brought up
+ * before allocation services are running). Unit grows as necessary
+ * and all units grow or shrink in unison. When a chunk is filled up,
+ * another chunk is allocated. ie. in vmalloc area
*
* c0 c1 c2
* ------------------- ------------------- ------------
@@ -558,7 +558,7 @@ static void pcpu_free_area(struct pcpu_chunk *chunk, int freeme)
static void pcpu_unmap(struct pcpu_chunk *chunk, int page_start, int page_end,
bool flush_tlb)
{
- unsigned int last = num_possible_cpus() - 1;
+ unsigned int last = nr_cpu_ids - 1;
unsigned int cpu;
/* unmap must not be done on immutable chunk */
@@ -643,7 +643,7 @@ static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, int off, int size,
*/
static int pcpu_map(struct pcpu_chunk *chunk, int page_start, int page_end)
{
- unsigned int last = num_possible_cpus() - 1;
+ unsigned int last = nr_cpu_ids - 1;
unsigned int cpu;
int err;
@@ -1067,9 +1067,9 @@ size_t __init pcpu_setup_first_chunk(pcpu_get_page_fn_t get_page_fn,
PFN_UP(size_sum));
pcpu_unit_size = pcpu_unit_pages << PAGE_SHIFT;
- pcpu_chunk_size = num_possible_cpus() * pcpu_unit_size;
+ pcpu_chunk_size = nr_cpu_ids * pcpu_unit_size;
pcpu_chunk_struct_size = sizeof(struct pcpu_chunk)
- + num_possible_cpus() * pcpu_unit_pages * sizeof(struct page *);
+ + nr_cpu_ids * pcpu_unit_pages * sizeof(struct page *);
if (dyn_size < 0)
dyn_size = pcpu_unit_size - static_size - reserved_size;
@@ -1248,7 +1248,7 @@ ssize_t __init pcpu_embed_first_chunk(size_t static_size, size_t reserved_size,
} else
pcpue_unit_size = max_t(size_t, pcpue_size, PCPU_MIN_UNIT_SIZE);
- chunk_size = pcpue_unit_size * num_possible_cpus();
+ chunk_size = pcpue_unit_size * nr_cpu_ids;
pcpue_ptr = __alloc_bootmem_nopanic(chunk_size, PAGE_SIZE,
__pa(MAX_DMA_ADDRESS));
@@ -1259,9 +1259,16 @@ ssize_t __init pcpu_embed_first_chunk(size_t static_size, size_t reserved_size,
}
/* return the leftover and copy */
- for_each_possible_cpu(cpu) {
+ for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
void *ptr = pcpue_ptr + cpu * pcpue_unit_size;
+ if (cpu_possible(cpu)) {
+ free_bootmem(__pa(ptr + pcpue_size),
+ pcpue_unit_size - pcpue_size);
+ memcpy(ptr, __per_cpu_load, static_size);
+ } else
+ free_bootmem(__pa(ptr), pcpue_unit_size);
+
free_bootmem(__pa(ptr + pcpue_size),
pcpue_unit_size - pcpue_size);
memcpy(ptr, __per_cpu_load, static_size);
--
1.6.0.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2 2.6.31-rc5 REPOST] percpu, sparc64: fix sparse possible cpu map handling
2009-08-06 9:36 ` [PATCH 2/2 2.6.31-rc5 REPOST] percpu, sparc64: fix sparse possible cpu map handling Tejun Heo
@ 2009-08-06 11:57 ` Ingo Molnar
2009-08-06 16:15 ` Tejun Heo
0 siblings, 1 reply; 8+ messages in thread
From: Ingo Molnar @ 2009-08-06 11:57 UTC (permalink / raw)
To: Tejun Heo; +Cc: Linux Kernel, David Miller, sparclinux
* Tejun Heo <tj@kernel.org> wrote:
> percpu code has been assuming num_possible_cpus() == nr_cpu_ids which
> is incorrect if cpu_possible_map contains holes. This causes percpu
> code to access beyond allocated memories and vmalloc areas. On a
> sparc64 machine with cpus 0 and 2 (u60), this triggers the following
> warning or fails boot.
>
> WARNING: at /devel/tj/os/work/mm/vmalloc.c:106 vmap_page_range_noflush+0x1f0/0x240()
> Modules linked in:
> Call Trace:
> [00000000004b17d0] vmap_page_range_noflush+0x1f0/0x240
> [00000000004b1840] map_vm_area+0x20/0x60
> [00000000004b1950] __vmalloc_area_node+0xd0/0x160
> [0000000000593434] deflate_init+0x14/0xe0
> [0000000000583b94] __crypto_alloc_tfm+0xd4/0x1e0
> [00000000005844f0] crypto_alloc_base+0x50/0xa0
> [000000000058b898] alg_test_comp+0x18/0x80
> [000000000058dad4] alg_test+0x54/0x180
> [000000000058af00] cryptomgr_test+0x40/0x60
> [0000000000473098] kthread+0x58/0x80
> [000000000042b590] kernel_thread+0x30/0x60
> [0000000000472fd0] kthreadd+0xf0/0x160
> ---[ end trace 429b268a213317ba ]---
>
> This patch fixes generic percpu functions and sparc64
> setup_per_cpu_areas() so that they handle sparse cpu_possible_map
> properly.
>
> Please note that on x86, cpu_possible_map() doesn't contain holes and
> thus num_possible_cpus() == nr_cpu_ids and this patch doesn't cause
> any behavior difference.
>
> Signed-off-by: Tejun Heo <tj@kernel.org>
> Cc: David S. Miller <davem@davemloft.net>
> Cc: Ingo Molnar <mingo@elte.hu>
> ---
> As written in the previous mail, this fixes rather critical boot
> problem on sparc64. Upon ack, I can get it through the percpu tree.
> Not really sure who could ack this one other than David tho. Anyone?
>
> Thanks.
>
> arch/sparc/kernel/smp_64.c | 4 ++--
> arch/x86/kernel/setup_percpu.c | 14 +++++++-------
> mm/percpu.c | 31 +++++++++++++++++++------------
> 3 files changed, 28 insertions(+), 21 deletions(-)
for the x86 bits:
Acked-by: Ingo Molnar <mingo@elte.hu>
Once Dave acks it i suspect you can send it to Linus directly?
Ingo
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2 2.6.31-rc5 REPOST] percpu, sparc64: fix sparse possible cpu map handling
2009-08-06 11:57 ` Ingo Molnar
@ 2009-08-06 16:15 ` Tejun Heo
2009-08-12 6:10 ` Tejun Heo
0 siblings, 1 reply; 8+ messages in thread
From: Tejun Heo @ 2009-08-06 16:15 UTC (permalink / raw)
To: Ingo Molnar; +Cc: Linux Kernel, David Miller, sparclinux
Ingo Molnar wrote:
> for the x86 bits:
>
> Acked-by: Ingo Molnar <mingo@elte.hu>
>
> Once Dave acks it i suspect you can send it to Linus directly?
Yeap, I'll.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2 2.6.31-rc5 REPOST] percpu, sparc64: fix sparse possible cpu map handling
2009-08-06 16:15 ` Tejun Heo
@ 2009-08-12 6:10 ` Tejun Heo
2009-08-12 23:25 ` David Miller
0 siblings, 1 reply; 8+ messages in thread
From: Tejun Heo @ 2009-08-12 6:10 UTC (permalink / raw)
To: Ingo Molnar; +Cc: Linux Kernel, David Miller, sparclinux
Tejun Heo wrote:
> Ingo Molnar wrote:
>> for the x86 bits:
>>
>> Acked-by: Ingo Molnar <mingo@elte.hu>
>>
>> Once Dave acks it i suspect you can send it to Linus directly?
Aieeeee, no response. I'll push these two patches into linux-next
today. Wait a few days and then push them to Linus. :-(
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2 2.6.31-rc5 REPOST] percpu, sparc64: fix sparse possible cpu map handling
2009-08-12 6:10 ` Tejun Heo
@ 2009-08-12 23:25 ` David Miller
2009-08-14 4:26 ` Tejun Heo
0 siblings, 1 reply; 8+ messages in thread
From: David Miller @ 2009-08-12 23:25 UTC (permalink / raw)
To: tj; +Cc: mingo, linux-kernel, sparclinux
From: Tejun Heo <tj@kernel.org>
Date: Wed, 12 Aug 2009 15:10:29 +0900
> Tejun Heo wrote:
>> Ingo Molnar wrote:
>>> for the x86 bits:
>>>
>>> Acked-by: Ingo Molnar <mingo@elte.hu>
>>>
>>> Once Dave acks it i suspect you can send it to Linus directly?
>
> Aieeeee, no response.
These patches look fine, and I've tested them also on my
Niagara-2 box.
Acked-by: David S. Miller <davem@davemloft.net>
Sorry for the delay :)
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [PATCH 2/2 2.6.31-rc5 REPOST] percpu, sparc64: fix sparse possible cpu map handling
2009-08-12 23:25 ` David Miller
@ 2009-08-14 4:26 ` Tejun Heo
2009-08-14 4:27 ` [PATCH 2/2 2.6.31-rc5 UPDATED] " Tejun Heo
0 siblings, 1 reply; 8+ messages in thread
From: Tejun Heo @ 2009-08-14 4:26 UTC (permalink / raw)
To: David Miller; +Cc: mingo, linux-kernel, sparclinux
David Miller wrote:
> From: Tejun Heo <tj@kernel.org>
> Date: Wed, 12 Aug 2009 15:10:29 +0900
>
>> Tejun Heo wrote:
>>> Ingo Molnar wrote:
>>>> for the x86 bits:
>>>>
>>>> Acked-by: Ingo Molnar <mingo@elte.hu>
>>>>
>>>> Once Dave acks it i suspect you can send it to Linus directly?
>> Aieeeee, no response.
>
> These patches look fine, and I've tested them also on my
> Niagara-2 box.
>
> Acked-by: David S. Miller <davem@davemloft.net>
>
> Sorry for the delay :)
Great. Oops, last review pass revealed a bug in the following chunk.
@@ -1259,9 +1259,16 @@ ssize_t __init pcpu_embed_first_chunk(size_t static_size, size_t reserved_size,
}
/* return the leftover and copy */
- for_each_possible_cpu(cpu) {
+ for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
void *ptr = pcpue_ptr + cpu * pcpue_unit_size;
+ if (cpu_possible(cpu)) {
+ free_bootmem(__pa(ptr + pcpue_size),
+ pcpue_unit_size - pcpue_size);
+ memcpy(ptr, __per_cpu_load, static_size);
+ } else
+ free_bootmem(__pa(ptr), pcpue_unit_size);
+
free_bootmem(__pa(ptr + pcpue_size),
pcpue_unit_size - pcpue_size);
memcpy(ptr, __per_cpu_load, static_size);
The if-else block should replace the original free_bootmem()/memcpy()
not added in front of it. Fixed. Will reply with updated patch.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 8+ messages in thread
* [PATCH 2/2 2.6.31-rc5 UPDATED] percpu, sparc64: fix sparse possible cpu map handling
2009-08-14 4:26 ` Tejun Heo
@ 2009-08-14 4:27 ` Tejun Heo
0 siblings, 0 replies; 8+ messages in thread
From: Tejun Heo @ 2009-08-14 4:27 UTC (permalink / raw)
To: David Miller; +Cc: mingo, linux-kernel, sparclinux
percpu code has been assuming num_possible_cpus() == nr_cpu_ids which
is incorrect if cpu_possible_map contains holes. This causes percpu
code to access beyond allocated memories and vmalloc areas. On a
sparc64 machine with cpus 0 and 2 (u60), this triggers the following
warning or fails boot.
WARNING: at /devel/tj/os/work/mm/vmalloc.c:106 vmap_page_range_noflush+0x1f0/0x240()
Modules linked in:
Call Trace:
[00000000004b17d0] vmap_page_range_noflush+0x1f0/0x240
[00000000004b1840] map_vm_area+0x20/0x60
[00000000004b1950] __vmalloc_area_node+0xd0/0x160
[0000000000593434] deflate_init+0x14/0xe0
[0000000000583b94] __crypto_alloc_tfm+0xd4/0x1e0
[00000000005844f0] crypto_alloc_base+0x50/0xa0
[000000000058b898] alg_test_comp+0x18/0x80
[000000000058dad4] alg_test+0x54/0x180
[000000000058af00] cryptomgr_test+0x40/0x60
[0000000000473098] kthread+0x58/0x80
[000000000042b590] kernel_thread+0x30/0x60
[0000000000472fd0] kthreadd+0xf0/0x160
---[ end trace 429b268a213317ba ]---
This patch fixes generic percpu functions and sparc64
setup_per_cpu_areas() so that they handle sparse cpu_possible_map
properly.
Please note that on x86, cpu_possible_map() doesn't contain holes and
thus num_possible_cpus() == nr_cpu_ids and this patch doesn't cause
any behavior difference.
Signed-off-by: Tejun Heo <tj@kernel.org>
Acked-by: David S. Miller <davem@davemloft.net>
Cc: Ingo Molnar <mingo@elte.hu>
---
The previously mentioned bug fixed.
arch/sparc/kernel/smp_64.c | 4 ++--
arch/x86/kernel/setup_percpu.c | 14 +++++++-------
mm/percpu.c | 33 ++++++++++++++++++---------------
3 files changed, 27 insertions(+), 24 deletions(-)
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c
index fa44eaf..3691907 100644
--- a/arch/sparc/kernel/smp_64.c
+++ b/arch/sparc/kernel/smp_64.c
@@ -1499,7 +1499,7 @@ void __init setup_per_cpu_areas(void)
dyn_size = pcpur_size - static_size - PERCPU_MODULE_RESERVE;
- ptrs_size = PFN_ALIGN(num_possible_cpus() * sizeof(pcpur_ptrs[0]));
+ ptrs_size = PFN_ALIGN(nr_cpu_ids * sizeof(pcpur_ptrs[0]));
pcpur_ptrs = alloc_bootmem(ptrs_size);
for_each_possible_cpu(cpu) {
@@ -1514,7 +1514,7 @@ void __init setup_per_cpu_areas(void)
/* allocate address and map */
vm.flags = VM_ALLOC;
- vm.size = num_possible_cpus() * PCPU_CHUNK_SIZE;
+ vm.size = nr_cpu_ids * PCPU_CHUNK_SIZE;
vm_area_register_early(&vm, PCPU_CHUNK_SIZE);
for_each_possible_cpu(cpu) {
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 29a3eef..07d8191 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -165,7 +165,7 @@ static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen)
if (!chosen) {
size_t vm_size = VMALLOC_END - VMALLOC_START;
- size_t tot_size = num_possible_cpus() * PMD_SIZE;
+ size_t tot_size = nr_cpu_ids * PMD_SIZE;
/* on non-NUMA, embedding is better */
if (!pcpu_need_numa())
@@ -199,7 +199,7 @@ static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen)
dyn_size = pcpul_size - static_size - PERCPU_FIRST_CHUNK_RESERVE;
/* allocate pointer array and alloc large pages */
- map_size = PFN_ALIGN(num_possible_cpus() * sizeof(pcpul_map[0]));
+ map_size = PFN_ALIGN(nr_cpu_ids * sizeof(pcpul_map[0]));
pcpul_map = alloc_bootmem(map_size);
for_each_possible_cpu(cpu) {
@@ -228,7 +228,7 @@ static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen)
/* allocate address and map */
pcpul_vm.flags = VM_ALLOC;
- pcpul_vm.size = num_possible_cpus() * PMD_SIZE;
+ pcpul_vm.size = nr_cpu_ids * PMD_SIZE;
vm_area_register_early(&pcpul_vm, PMD_SIZE);
for_each_possible_cpu(cpu) {
@@ -250,8 +250,8 @@ static ssize_t __init setup_pcpu_lpage(size_t static_size, bool chosen)
PMD_SIZE, pcpul_vm.addr, NULL);
/* sort pcpul_map array for pcpu_lpage_remapped() */
- for (i = 0; i < num_possible_cpus() - 1; i++)
- for (j = i + 1; j < num_possible_cpus(); j++)
+ for (i = 0; i < nr_cpu_ids - 1; i++)
+ for (j = i + 1; j < nr_cpu_ids; j++)
if (pcpul_map[i].ptr > pcpul_map[j].ptr) {
struct pcpul_ent tmp = pcpul_map[i];
pcpul_map[i] = pcpul_map[j];
@@ -288,7 +288,7 @@ void *pcpu_lpage_remapped(void *kaddr)
{
void *pmd_addr = (void *)((unsigned long)kaddr & PMD_MASK);
unsigned long offset = (unsigned long)kaddr & ~PMD_MASK;
- int left = 0, right = num_possible_cpus() - 1;
+ int left = 0, right = nr_cpu_ids - 1;
int pos;
/* pcpul in use at all? */
@@ -377,7 +377,7 @@ static ssize_t __init setup_pcpu_4k(size_t static_size)
pcpu4k_nr_static_pages = PFN_UP(static_size);
/* unaligned allocations can't be freed, round up to page size */
- pages_size = PFN_ALIGN(pcpu4k_nr_static_pages * num_possible_cpus()
+ pages_size = PFN_ALIGN(pcpu4k_nr_static_pages * nr_cpu_ids
* sizeof(pcpu4k_pages[0]));
pcpu4k_pages = alloc_bootmem(pages_size);
diff --git a/mm/percpu.c b/mm/percpu.c
index b70f2ac..e0be114 100644
--- a/mm/percpu.c
+++ b/mm/percpu.c
@@ -8,12 +8,12 @@
*
* This is percpu allocator which can handle both static and dynamic
* areas. Percpu areas are allocated in chunks in vmalloc area. Each
- * chunk is consisted of num_possible_cpus() units and the first chunk
- * is used for static percpu variables in the kernel image (special
- * boot time alloc/init handling necessary as these areas need to be
- * brought up before allocation services are running). Unit grows as
- * necessary and all units grow or shrink in unison. When a chunk is
- * filled up, another chunk is allocated. ie. in vmalloc area
+ * chunk is consisted of nr_cpu_ids units and the first chunk is used
+ * for static percpu variables in the kernel image (special boot time
+ * alloc/init handling necessary as these areas need to be brought up
+ * before allocation services are running). Unit grows as necessary
+ * and all units grow or shrink in unison. When a chunk is filled up,
+ * another chunk is allocated. ie. in vmalloc area
*
* c0 c1 c2
* ------------------- ------------------- ------------
@@ -558,7 +558,7 @@ static void pcpu_free_area(struct pcpu_chunk *chunk, int freeme)
static void pcpu_unmap(struct pcpu_chunk *chunk, int page_start, int page_end,
bool flush_tlb)
{
- unsigned int last = num_possible_cpus() - 1;
+ unsigned int last = nr_cpu_ids - 1;
unsigned int cpu;
/* unmap must not be done on immutable chunk */
@@ -643,7 +643,7 @@ static void pcpu_depopulate_chunk(struct pcpu_chunk *chunk, int off, int size,
*/
static int pcpu_map(struct pcpu_chunk *chunk, int page_start, int page_end)
{
- unsigned int last = num_possible_cpus() - 1;
+ unsigned int last = nr_cpu_ids - 1;
unsigned int cpu;
int err;
@@ -1067,9 +1067,9 @@ size_t __init pcpu_setup_first_chunk(pcpu_get_page_fn_t get_page_fn,
PFN_UP(size_sum));
pcpu_unit_size = pcpu_unit_pages << PAGE_SHIFT;
- pcpu_chunk_size = num_possible_cpus() * pcpu_unit_size;
+ pcpu_chunk_size = nr_cpu_ids * pcpu_unit_size;
pcpu_chunk_struct_size = sizeof(struct pcpu_chunk)
- + num_possible_cpus() * pcpu_unit_pages * sizeof(struct page *);
+ + nr_cpu_ids * pcpu_unit_pages * sizeof(struct page *);
if (dyn_size < 0)
dyn_size = pcpu_unit_size - static_size - reserved_size;
@@ -1248,7 +1248,7 @@ ssize_t __init pcpu_embed_first_chunk(size_t static_size, size_t reserved_size,
} else
pcpue_unit_size = max_t(size_t, pcpue_size, PCPU_MIN_UNIT_SIZE);
- chunk_size = pcpue_unit_size * num_possible_cpus();
+ chunk_size = pcpue_unit_size * nr_cpu_ids;
pcpue_ptr = __alloc_bootmem_nopanic(chunk_size, PAGE_SIZE,
__pa(MAX_DMA_ADDRESS));
@@ -1259,12 +1259,15 @@ ssize_t __init pcpu_embed_first_chunk(size_t static_size, size_t reserved_size,
}
/* return the leftover and copy */
- for_each_possible_cpu(cpu) {
+ for (cpu = 0; cpu < nr_cpu_ids; cpu++) {
void *ptr = pcpue_ptr + cpu * pcpue_unit_size;
- free_bootmem(__pa(ptr + pcpue_size),
- pcpue_unit_size - pcpue_size);
- memcpy(ptr, __per_cpu_load, static_size);
+ if (cpu_possible(cpu)) {
+ free_bootmem(__pa(ptr + pcpue_size),
+ pcpue_unit_size - pcpue_size);
+ memcpy(ptr, __per_cpu_load, static_size);
+ } else
+ free_bootmem(__pa(ptr), pcpue_unit_size);
}
/* we're ready, commit */
--
1.6.0.2
^ permalink raw reply related [flat|nested] 8+ messages in thread
end of thread, other threads:[~2009-08-14 4:27 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-06 9:33 [PATCH 1/2 2.6.31-rc5 REPOST] init: set nr_cpu_ids before setup_per_cpu_areas() Tejun Heo
2009-08-06 9:36 ` [PATCH 2/2 2.6.31-rc5 REPOST] percpu, sparc64: fix sparse possible cpu map handling Tejun Heo
2009-08-06 11:57 ` Ingo Molnar
2009-08-06 16:15 ` Tejun Heo
2009-08-12 6:10 ` Tejun Heo
2009-08-12 23:25 ` David Miller
2009-08-14 4:26 ` Tejun Heo
2009-08-14 4:27 ` [PATCH 2/2 2.6.31-rc5 UPDATED] " Tejun Heo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox