From: Tejun Heo <tj@kernel.org>
To: rusty@rustcorp.com.au, tglx@linutronix.de, x86@kernel.org,
linux-kernel@vger.kernel.org, hpa@zytor.com, jeremy@goop.org,
cpw@sgi.com, mingo@elte.hu
Cc: Tejun Heo <tj@kernel.org>
Subject: [PATCH 10/10] x86: convert to the new dynamic percpu allocator
Date: Wed, 18 Feb 2009 21:04:36 +0900 [thread overview]
Message-ID: <1234958676-27618-11-git-send-email-tj@kernel.org> (raw)
In-Reply-To: <1234958676-27618-1-git-send-email-tj@kernel.org>
Impact: use new dynamic allocator, unified access to static/dynamic
percpu memory
Convert to the new dynamic percpu allocator.
* implement populate_extra_pte() for both 32 and 64
* update setup_per_cpu_areas() to use pcpu_setup_static()
* define __addr_to_pcpu_ptr() and __pcpu_ptr_to_addr()
* define config HAVE_DYNAMIC_PER_CPU_AREA
Signed-off-by: Tejun Heo <tj@kernel.org>
---
arch/x86/Kconfig | 3 ++
arch/x86/include/asm/percpu.h | 8 +++++
arch/x86/include/asm/pgtable.h | 1 +
arch/x86/kernel/setup_percpu.c | 62 +++++++++++++++++++++++++--------------
arch/x86/mm/init_32.c | 10 ++++++
arch/x86/mm/init_64.c | 19 ++++++++++++
6 files changed, 81 insertions(+), 22 deletions(-)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index f760a22..d3f6ead 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -135,6 +135,9 @@ config ARCH_HAS_CACHE_LINE_SIZE
config HAVE_SETUP_PER_CPU_AREA
def_bool y
+config HAVE_DYNAMIC_PER_CPU_AREA
+ def_bool y
+
config HAVE_CPUMASK_OF_CPU_MAP
def_bool X86_64_SMP
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index aee103b..8f1d2fb 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -43,6 +43,14 @@
#else /* ...!ASSEMBLY */
#include <linux/stringify.h>
+#include <asm/sections.h>
+
+#define __addr_to_pcpu_ptr(addr) \
+ (void *)((unsigned long)(addr) - (unsigned long)pcpu_base_addr \
+ + (unsigned long)__per_cpu_start)
+#define __pcpu_ptr_to_addr(ptr) \
+ (void *)((unsigned long)(ptr) + (unsigned long)pcpu_base_addr \
+ - (unsigned long)__per_cpu_start)
#ifdef CONFIG_SMP
#define __percpu_arg(x) "%%"__stringify(__percpu_seg)":%P" #x
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 6f7c102..dd91c25 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -402,6 +402,7 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
/* Install a pte for a particular vaddr in kernel space. */
void set_pte_vaddr(unsigned long vaddr, pte_t pte);
+void populate_extra_pte(unsigned long vaddr);
#ifdef CONFIG_X86_32
extern void native_pagetable_setup_start(pgd_t *base);
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index d992e6c..2dce435 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -61,38 +61,56 @@ static inline void setup_percpu_segment(int cpu)
*/
void __init setup_per_cpu_areas(void)
{
- ssize_t size;
- char *ptr;
- int cpu;
-
- /* Copy section for each CPU (we discard the original) */
- size = roundup(PERCPU_ENOUGH_ROOM, PAGE_SIZE);
+ ssize_t size = __per_cpu_end - __per_cpu_start;
+ unsigned int nr_cpu_pages = DIV_ROUND_UP(size, PAGE_SIZE);
+ static struct page **pages;
+ size_t pages_size;
+ unsigned int cpu, i, j;
+ unsigned long delta;
+ size_t pcpu_unit_size;
pr_info("NR_CPUS:%d nr_cpumask_bits:%d nr_cpu_ids:%d nr_node_ids:%d\n",
NR_CPUS, nr_cpumask_bits, nr_cpu_ids, nr_node_ids);
+ pr_info("PERCPU: Allocating %zd bytes for static per cpu data\n", size);
- pr_info("PERCPU: Allocating %zd bytes of per cpu data\n", size);
+ pages_size = nr_cpu_pages * num_possible_cpus() * sizeof(pages[0]);
+ pages = alloc_bootmem(pages_size);
+ j = 0;
for_each_possible_cpu(cpu) {
+ void *ptr;
+
+ for (i = 0; i < nr_cpu_pages; i++) {
#ifndef CONFIG_NEED_MULTIPLE_NODES
- ptr = alloc_bootmem_pages(size);
+ ptr = alloc_bootmem_pages(PAGE_SIZE);
#else
- int node = early_cpu_to_node(cpu);
- if (!node_online(node) || !NODE_DATA(node)) {
- ptr = alloc_bootmem_pages(size);
- pr_info("cpu %d has no node %d or node-local memory\n",
- cpu, node);
- pr_debug("per cpu data for cpu%d at %016lx\n",
- cpu, __pa(ptr));
- } else {
- ptr = alloc_bootmem_pages_node(NODE_DATA(node), size);
- pr_debug("per cpu data for cpu%d on node%d at %016lx\n",
- cpu, node, __pa(ptr));
- }
+ int node = early_cpu_to_node(cpu);
+
+ if (!node_online(node) || !NODE_DATA(node)) {
+ ptr = alloc_bootmem_pages(PAGE_SIZE);
+ pr_info("cpu %d has no node %d or node-local "
+ "memory\n", cpu, node);
+ pr_debug("per cpu data for cpu%d at %016lx\n",
+ cpu, __pa(ptr));
+ } else {
+ ptr = alloc_bootmem_pages_node(NODE_DATA(node),
+ PAGE_SIZE);
+ pr_debug("per cpu data for cpu%d on node%d "
+ "at %016lx\n", cpu, node, __pa(ptr));
+ }
#endif
+ memcpy(ptr, __per_cpu_load + i * PAGE_SIZE, PAGE_SIZE);
+ pages[j++] = virt_to_page(ptr);
+ }
+ }
+
+ pcpu_unit_size = pcpu_setup_static(populate_extra_pte, pages, size);
- memcpy(ptr, __per_cpu_load, __per_cpu_end - __per_cpu_start);
- per_cpu_offset(cpu) = ptr - __per_cpu_start;
+ free_bootmem(__pa(pages), pages_size);
+
+ delta = (unsigned long)pcpu_base_addr - (unsigned long)__per_cpu_start;
+ for_each_possible_cpu(cpu) {
+ per_cpu_offset(cpu) = delta + cpu * pcpu_unit_size;
per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu);
per_cpu(cpu_number, cpu) = cpu;
setup_percpu_segment(cpu);
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 00263bf..8b1a0ef 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -137,6 +137,16 @@ static pte_t * __init one_page_table_init(pmd_t *pmd)
return pte_offset_kernel(pmd, 0);
}
+void __init populate_extra_pte(unsigned long vaddr)
+{
+ int pgd_idx = pgd_index(vaddr);
+ int pmd_idx = pmd_index(vaddr);
+ pmd_t *pmd;
+
+ pmd = one_md_table_init(swapper_pg_dir + pgd_idx);
+ one_page_table_init(pmd + pmd_idx);
+}
+
static pte_t *__init page_table_kmap_check(pte_t *pte, pmd_t *pmd,
unsigned long vaddr, pte_t *lastpte)
{
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index e6d36b4..7f91e2c 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -223,6 +223,25 @@ set_pte_vaddr(unsigned long vaddr, pte_t pteval)
set_pte_vaddr_pud(pud_page, vaddr, pteval);
}
+void __init populate_extra_pte(unsigned long vaddr)
+{
+ pgd_t *pgd;
+ pud_t *pud;
+
+ pgd = pgd_offset_k(vaddr);
+ if (pgd_none(*pgd)) {
+ pud = (pud_t *)spp_getpage();
+ pgd_populate(&init_mm, pgd, pud);
+ if (pud != pud_offset(pgd, 0)) {
+ printk(KERN_ERR "PAGETABLE BUG #00! %p <-> %p\n",
+ pud, pud_offset(pgd, 0));
+ return;
+ }
+ }
+
+ set_pte_vaddr_pud((pud_t *)pgd_page_vaddr(*pgd), vaddr, __pte(0));
+}
+
/*
* Create large page table mappings for a range of physical addresses.
*/
--
1.6.0.2
next prev parent reply other threads:[~2009-02-18 12:07 UTC|newest]
Thread overview: 78+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-02-18 12:04 [PATCHSET x86/core/percpu] implement dynamic percpu allocator Tejun Heo
2009-02-18 12:04 ` [PATCH 01/10] vmalloc: call flush_cache_vunmap() from unmap_kernel_range() Tejun Heo
2009-02-19 12:06 ` Nick Piggin
2009-02-19 22:36 ` David Miller
2009-02-18 12:04 ` [PATCH 02/10] module: fix out-of-range memory access Tejun Heo
2009-02-19 12:08 ` Nick Piggin
2009-02-20 7:16 ` Tejun Heo
2009-02-18 12:04 ` [PATCH 03/10] module: reorder module pcpu related functions Tejun Heo
2009-02-18 12:04 ` [PATCH 04/10] alloc_percpu: change percpu_ptr to per_cpu_ptr Tejun Heo
2009-02-18 12:04 ` [PATCH 05/10] alloc_percpu: add align argument to __alloc_percpu Tejun Heo
2009-02-18 12:04 ` [PATCH 06/10] percpu: kill percpu_alloc() and friends Tejun Heo
2009-02-19 0:17 ` Rusty Russell
2009-03-11 18:36 ` Tony Luck
2009-03-11 22:44 ` Rusty Russell
2009-03-12 2:06 ` Tejun Heo
2009-02-18 12:04 ` [PATCH 07/10] vmalloc: implement vm_area_register_early() Tejun Heo
2009-02-19 0:55 ` Tejun Heo
2009-02-19 12:09 ` Nick Piggin
2009-02-18 12:04 ` [PATCH 08/10] vmalloc: add un/map_kernel_range_noflush() Tejun Heo
2009-02-19 12:17 ` Nick Piggin
2009-02-20 1:27 ` Tejun Heo
2009-02-20 7:15 ` Subject: [PATCH 08/10 UPDATED] " Tejun Heo
2009-02-20 8:32 ` Andrew Morton
2009-02-21 3:21 ` Tejun Heo
2009-02-18 12:04 ` [PATCH 09/10] percpu: implement new dynamic percpu allocator Tejun Heo
2009-02-19 10:10 ` Andrew Morton
2009-02-19 11:01 ` Ingo Molnar
2009-02-20 2:45 ` Tejun Heo
2009-02-19 12:07 ` Rusty Russell
2009-02-20 2:35 ` Tejun Heo
2009-02-20 3:04 ` Andrew Morton
2009-02-20 5:29 ` Tejun Heo
2009-02-24 2:52 ` Rusty Russell
2009-02-19 11:51 ` Rusty Russell
2009-02-20 3:01 ` Tejun Heo
2009-02-20 3:02 ` Tejun Heo
2009-02-24 2:56 ` Rusty Russell
2009-02-24 5:27 ` [PATCH tj-percpu] percpu: add __read_mostly to variables which are mostly read only Tejun Heo
2009-02-24 5:47 ` [PATCH 09/10] percpu: implement new dynamic percpu allocator Tejun Heo
2009-02-24 17:41 ` Luck, Tony
2009-02-26 3:17 ` Tejun Heo
2009-02-27 19:41 ` Luck, Tony
2009-02-19 12:36 ` Nick Piggin
2009-02-20 3:04 ` Tejun Heo
2009-02-20 7:30 ` [PATCH UPDATED " Tejun Heo
2009-02-20 8:37 ` Andrew Morton
2009-02-21 3:23 ` Tejun Heo
2009-02-21 3:42 ` [PATCH tj-percpu] percpu: s/size/bytes/g in new percpu allocator and interface Tejun Heo
2009-02-21 7:48 ` Tejun Heo
2009-02-21 7:55 ` [PATCH tj-percpu] percpu: clean up size usage Tejun Heo
2009-02-21 7:56 ` Tejun Heo
2009-02-18 12:04 ` Tejun Heo [this message]
2009-02-18 13:43 ` [PATCHSET x86/core/percpu] implement dynamic percpu allocator Ingo Molnar
2009-02-19 0:31 ` Tejun Heo
2009-02-19 10:51 ` Rusty Russell
2009-02-19 11:06 ` Ingo Molnar
2009-02-19 12:14 ` Rusty Russell
2009-02-20 3:08 ` Tejun Heo
2009-02-20 5:36 ` Tejun Heo
2009-02-20 7:33 ` Tejun Heo
2009-02-19 0:30 ` Tejun Heo
2009-02-19 11:07 ` Ingo Molnar
2009-02-20 3:17 ` Tejun Heo
2009-02-20 9:32 ` Ingo Molnar
2009-02-21 7:10 ` Tejun Heo
2009-02-21 7:33 ` Tejun Heo
2009-02-22 19:38 ` Ingo Molnar
2009-02-23 0:43 ` Tejun Heo
2009-02-23 10:17 ` Ingo Molnar
2009-02-23 13:38 ` [patch] x86: optimize __pa() to be linear again on 64-bit x86 Ingo Molnar
2009-02-23 14:08 ` Nick Piggin
2009-02-23 14:53 ` Ingo Molnar
2009-02-24 16:00 ` Andi Kleen
2009-02-27 5:57 ` Tejun Heo
2009-02-27 6:57 ` Ingo Molnar
2009-02-27 7:11 ` Tejun Heo
2009-02-22 19:27 ` [PATCHSET x86/core/percpu] implement dynamic percpu allocator Ingo Molnar
2009-02-23 0:47 ` Tejun Heo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1234958676-27618-11-git-send-email-tj@kernel.org \
--to=tj@kernel.org \
--cc=cpw@sgi.com \
--cc=hpa@zytor.com \
--cc=jeremy@goop.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=rusty@rustcorp.com.au \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.