Skip to content

Commit

Permalink
x86: cleanup remaining cpumask_t ops in smpboot code
Browse files Browse the repository at this point in the history
Impact: use new cpumask API to reduce memory and stack usage

Allocate the following local cpumasks based on the number of cpus that
are present.  References will use new cpumask API.  (Currently only
modified for x86_64, x86_32 continues to use the *_map variants.)

    cpu_callin_mask
    cpu_callout_mask
    cpu_initialized_mask
    cpu_sibling_setup_mask

Provide the following accessor functions:

    struct cpumask *cpu_sibling_mask(int cpu)
    struct cpumask *cpu_core_mask(int cpu)

Other changes are when setting or clearing the cpu online, possible
or present maps, use the accessor functions.

Signed-off-by: Mike Travis <travis@sgi.com>
Acked-by: Rusty Russell <rusty@rustcorp.com.au>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
  • Loading branch information
Mike Travis authored and Ingo Molnar committed Jan 4, 2009
1 parent 588235b commit c2d1cec
Show file tree
Hide file tree
Showing 5 changed files with 152 additions and 76 deletions.
32 changes: 29 additions & 3 deletions arch/x86/include/asm/smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,26 @@
#include <asm/pda.h>
#include <asm/thread_info.h>

#ifdef CONFIG_X86_64

extern cpumask_var_t cpu_callin_mask;
extern cpumask_var_t cpu_callout_mask;
extern cpumask_var_t cpu_initialized_mask;
extern cpumask_var_t cpu_sibling_setup_mask;

#else /* CONFIG_X86_32 */

extern cpumask_t cpu_callin_map;
extern cpumask_t cpu_callout_map;
extern cpumask_t cpu_initialized;
extern cpumask_t cpu_callin_map;
extern cpumask_t cpu_sibling_setup_map;

#define cpu_callin_mask ((struct cpumask *)&cpu_callin_map)
#define cpu_callout_mask ((struct cpumask *)&cpu_callout_map)
#define cpu_initialized_mask ((struct cpumask *)&cpu_initialized)
#define cpu_sibling_setup_mask ((struct cpumask *)&cpu_sibling_setup_map)

#endif /* CONFIG_X86_32 */

extern void (*mtrr_hook)(void);
extern void zap_low_mappings(void);
Expand All @@ -29,7 +46,6 @@ extern int __cpuinit get_local_pda(int cpu);

extern int smp_num_siblings;
extern unsigned int num_processors;
extern cpumask_t cpu_initialized;

DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
DECLARE_PER_CPU(cpumask_t, cpu_core_map);
Expand All @@ -38,6 +54,16 @@ DECLARE_PER_CPU(u16, cpu_llc_id);
DECLARE_PER_CPU(int, cpu_number);
#endif

static inline struct cpumask *cpu_sibling_mask(int cpu)
{
return &per_cpu(cpu_sibling_map, cpu);
}

static inline struct cpumask *cpu_core_mask(int cpu)
{
return &per_cpu(cpu_core_map, cpu);
}

DECLARE_EARLY_PER_CPU(u16, x86_cpu_to_apicid);
DECLARE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid);

Expand Down Expand Up @@ -149,7 +175,7 @@ void smp_store_cpu_info(int id);
/* We don't mark CPUs online until __cpu_up(), so we need another measure */
static inline int num_booting_cpus(void)
{
return cpus_weight(cpu_callout_map);
return cpumask_weight(cpu_callout_mask);
}
#else
static inline void prefill_possible_map(void)
Expand Down
26 changes: 22 additions & 4 deletions arch/x86/kernel/cpu/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,26 @@

#include "cpu.h"

#ifdef CONFIG_X86_64

/* all of these masks are initialized in setup_cpu_local_masks() */
cpumask_var_t cpu_callin_mask;
cpumask_var_t cpu_callout_mask;
cpumask_var_t cpu_initialized_mask;

/* representing cpus for which sibling maps can be computed */
cpumask_var_t cpu_sibling_setup_mask;

#else /* CONFIG_X86_32 */

cpumask_t cpu_callin_map;
cpumask_t cpu_callout_map;
cpumask_t cpu_initialized;
cpumask_t cpu_sibling_setup_map;

#endif /* CONFIG_X86_32 */


static struct cpu_dev *this_cpu __cpuinitdata;

#ifdef CONFIG_X86_64
Expand Down Expand Up @@ -856,8 +876,6 @@ static __init int setup_disablecpuid(char *arg)
}
__setup("clearcpuid=", setup_disablecpuid);

cpumask_t cpu_initialized __cpuinitdata = CPU_MASK_NONE;

#ifdef CONFIG_X86_64
struct x8664_pda **_cpu_pda __read_mostly;
EXPORT_SYMBOL(_cpu_pda);
Expand Down Expand Up @@ -976,7 +994,7 @@ void __cpuinit cpu_init(void)

me = current;

if (cpu_test_and_set(cpu, cpu_initialized))
if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask))
panic("CPU#%d already initialized!\n", cpu);

printk(KERN_INFO "Initializing CPU#%d\n", cpu);
Expand Down Expand Up @@ -1085,7 +1103,7 @@ void __cpuinit cpu_init(void)
struct tss_struct *t = &per_cpu(init_tss, cpu);
struct thread_struct *thread = &curr->thread;

if (cpu_test_and_set(cpu, cpu_initialized)) {
if (cpumask_test_and_set_cpu(cpu, cpu_initialized_mask)) {
printk(KERN_WARNING "CPU#%d already initialized!\n", cpu);
for (;;) local_irq_enable();
}
Expand Down
25 changes: 24 additions & 1 deletion arch/x86/kernel/setup_percpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,27 @@ static void __init setup_cpu_pda_map(void)
/* point to new pointer table */
_cpu_pda = new_cpu_pda;
}
#endif

#endif /* CONFIG_SMP && CONFIG_X86_64 */

#ifdef CONFIG_X86_64

/* correctly size the local cpu masks */
static void setup_cpu_local_masks(void)
{
alloc_bootmem_cpumask_var(&cpu_initialized_mask);
alloc_bootmem_cpumask_var(&cpu_callin_mask);
alloc_bootmem_cpumask_var(&cpu_callout_mask);
alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask);
}

#else /* CONFIG_X86_32 */

static inline void setup_cpu_local_masks(void)
{
}

#endif /* CONFIG_X86_32 */

/*
* Great future plan:
Expand Down Expand Up @@ -187,6 +207,9 @@ void __init setup_per_cpu_areas(void)

/* Setup node to cpumask map */
setup_node_to_cpumask_map();

/* Setup cpu initialized, callin, callout masks */
setup_cpu_local_masks();
}

#endif
Expand Down
17 changes: 12 additions & 5 deletions arch/x86/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,16 +128,23 @@ void native_send_call_func_single_ipi(int cpu)

void native_send_call_func_ipi(const struct cpumask *mask)
{
cpumask_t allbutself;
cpumask_var_t allbutself;

allbutself = cpu_online_map;
cpu_clear(smp_processor_id(), allbutself);
if (!alloc_cpumask_var(&allbutself, GFP_ATOMIC)) {
send_IPI_mask(mask, CALL_FUNCTION_VECTOR);
return;
}

if (cpus_equal(*mask, allbutself) &&
cpus_equal(cpu_online_map, cpu_callout_map))
cpumask_copy(allbutself, cpu_online_mask);
cpumask_clear_cpu(smp_processor_id(), allbutself);

if (cpumask_equal(mask, allbutself) &&
cpumask_equal(cpu_online_mask, cpu_callout_mask))
send_IPI_allbutself(CALL_FUNCTION_VECTOR);
else
send_IPI_mask(mask, CALL_FUNCTION_VECTOR);

free_cpumask_var(allbutself);
}

/*
Expand Down
Loading

0 comments on commit c2d1cec

Please sign in to comment.