x86: cleanup early per cpu variables/accesses v4
authorMike Travis <travis@sgi.com>
Mon, 12 May 2008 19:21:12 +0000 (21:21 +0200)
committerIngo Molnar <mingo@elte.hu>
Tue, 8 Jul 2008 09:31:20 +0000 (11:31 +0200)
commit23ca4bba3e20c6c3cb11c1bb0ab4770b724d39ac
tree39ba5f7705e48717d7a6f2621b8ca7e7015c9802
parent1184dc2ffe2c8fb9afb766d870850f2c3165ef25
x86: cleanup early per cpu variables/accesses v4

  * Introduce a new PER_CPU macro called "EARLY_PER_CPU".  This is
    used by some per_cpu variables that are initialized and accessed
    before there are per_cpu areas allocated.

    ["Early" in respect to per_cpu variables is "earlier than the per_cpu
    areas have been setup".]

    This patchset adds these new macros:

DEFINE_EARLY_PER_CPU(_type, _name, _initvalue)
EXPORT_EARLY_PER_CPU_SYMBOL(_name)
DECLARE_EARLY_PER_CPU(_type, _name)

early_per_cpu_ptr(_name)
early_per_cpu_map(_name, _idx)
early_per_cpu(_name, _cpu)

    The DEFINE macro defines the per_cpu variable as well as the early
    map and pointer.  It also initializes the per_cpu variable and map
    elements to "_initvalue".  The early_* macros provide access to
    the initial map (usually setup during system init) and the early
    pointer.  This pointer is initialized to point to the early map
    but is then NULL'ed when the actual per_cpu areas are setup.  After
    that the per_cpu variable is the correct access to the variable.

    The early_per_cpu() macro is not very efficient but does show how to
    access the variable if you have a function that can be called both
    "early" and "late".  It tests the early ptr to be NULL, and if not
    then it's still valid.  Otherwise, the per_cpu variable is used
    instead:

#define early_per_cpu(_name, _cpu)  \
(early_per_cpu_ptr(_name) ? \
early_per_cpu_ptr(_name)[_cpu] : \
per_cpu(_name, _cpu))

    A better method is to actually check the pointer manually.  In the
    case below, numa_set_node can be called both "early" and "late":

void __cpuinit numa_set_node(int cpu, int node)
{
    int *cpu_to_node_map = early_per_cpu_ptr(x86_cpu_to_node_map);

    if (cpu_to_node_map)
    cpu_to_node_map[cpu] = node;
    else
    per_cpu(x86_cpu_to_node_map, cpu) = node;
}

  * Add a flag "arch_provides_topology_pointers" that indicates pointers
    to topology cpumask_t maps are available.  Otherwise, use the function
    returning the cpumask_t value.  This is useful if cpumask_t set size
    is very large to avoid copying data on to/off of the stack.

  * The coverage of CONFIG_DEBUG_PER_CPU_MAPS has been increased while
    the non-debug case has been optimized a bit.

  * Remove an unreferenced compiler warning in drivers/base/topology.c

  * Clean up #ifdef in setup.c

For inclusion into sched-devel/latest tree.

Based on:
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
    +   sched-devel/latest  .../mingo/linux-2.6-sched-devel.git

Signed-off-by: Mike Travis <travis@sgi.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
15 files changed:
arch/x86/Kconfig
arch/x86/Kconfig.debug
arch/x86/kernel/apic_32.c
arch/x86/kernel/apic_64.c
arch/x86/kernel/setup.c
arch/x86/kernel/setup_32.c
arch/x86/kernel/setup_64.c
arch/x86/kernel/smpboot.c
arch/x86/mm/numa_64.c
arch/x86/mm/srat_64.c
drivers/base/topology.c
include/asm-x86/numa_64.h
include/asm-x86/percpu.h
include/asm-x86/smp.h
include/asm-x86/topology.h