Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 137075
b: refs/heads/master
c: 9a4f8a8
h: refs/heads/master
i:
  137073: 52ac06b
  137071: 9921244
v: v3
  • Loading branch information
Tejun Heo committed Mar 6, 2009
1 parent 4d0461e commit 619d0b6
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 17 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cafe8816b217b98dc3f268d3b77445da498beb4f
refs/heads/master: 9a4f8a878b68d5a5d9ee60908a52cf6a55e1b823
44 changes: 28 additions & 16 deletions trunk/arch/x86/kernel/setup_percpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,24 +241,31 @@ static ssize_t __init setup_pcpu_remap(size_t static_size)
* Embedding allocator
*
* The first chunk is sized to just contain the static area plus
* PERCPU_DYNAMIC_RESERVE and allocated as a contiguous area using
* bootmem allocator and used as-is without being mapped into vmalloc
* area. This enables the first chunk to piggy back on the linear
* physical PMD mapping and doesn't add any additional pressure to
* TLB.
* module and dynamic reserves, and allocated as a contiguous area
* using bootmem allocator and used as-is without being mapped into
* vmalloc area. This enables the first chunk to piggy back on the
* linear physical PMD mapping and doesn't add any additional pressure
* to TLB. Note that if the needed size is smaller than the minimum
* unit size, the leftover is returned to the bootmem allocator.
*/
static void *pcpue_ptr __initdata;
static size_t pcpue_size __initdata;
static size_t pcpue_unit_size __initdata;

static struct page * __init pcpue_get_page(unsigned int cpu, int pageno)
{
return virt_to_page(pcpue_ptr + cpu * pcpue_unit_size
+ ((size_t)pageno << PAGE_SHIFT));
size_t off = (size_t)pageno << PAGE_SHIFT;

if (off >= pcpue_size)
return NULL;

return virt_to_page(pcpue_ptr + cpu * pcpue_unit_size + off);
}

static ssize_t __init setup_pcpu_embed(size_t static_size)
{
unsigned int cpu;
size_t dyn_size;

/*
* If large page isn't supported, there's no benefit in doing
Expand All @@ -269,25 +276,30 @@ static ssize_t __init setup_pcpu_embed(size_t static_size)
return -EINVAL;

/* allocate and copy */
pcpue_unit_size = PFN_ALIGN(static_size + PERCPU_DYNAMIC_RESERVE);
pcpue_unit_size = max_t(size_t, pcpue_unit_size, PCPU_MIN_UNIT_SIZE);
pcpue_size = PFN_ALIGN(static_size + PERCPU_DYNAMIC_RESERVE);
pcpue_unit_size = max_t(size_t, pcpue_size, PCPU_MIN_UNIT_SIZE);
dyn_size = pcpue_size - static_size;

pcpue_ptr = pcpu_alloc_bootmem(0, num_possible_cpus() * pcpue_unit_size,
PAGE_SIZE);
if (!pcpue_ptr)
return -ENOMEM;

for_each_possible_cpu(cpu)
memcpy(pcpue_ptr + cpu * pcpue_unit_size, __per_cpu_load,
static_size);
for_each_possible_cpu(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);
}

/* we're ready, commit */
pr_info("PERCPU: Embedded %zu pages at %p, static data %zu bytes\n",
pcpue_unit_size >> PAGE_SHIFT, pcpue_ptr, static_size);
pcpue_size >> PAGE_SHIFT, pcpue_ptr, static_size);

return pcpu_setup_first_chunk(pcpue_get_page, static_size,
pcpue_unit_size,
pcpue_unit_size - static_size, pcpue_ptr,
NULL);
pcpue_unit_size, dyn_size,
pcpue_ptr, NULL);
}

/*
Expand Down

0 comments on commit 619d0b6

Please sign in to comment.