Commit 7abc0753 authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Ingo Molnar

x86: apic: Do not use stacked physid_mask_t

We should not use physid_mask_t as a stack based
variable in apic code. This type depends on MAX_APICS
parameter which may be huge enough.

Especially it became a problem with apic NOOP driver which
is portable between 32 bit and 64 bit environment
(where we have really huge MAX_APICS).

So apic driver should operate with pointers and a caller
in turn should aware of allocation physid_mask_t variable.

As a side (but positive) effect -- we may use already
implemented physid_set_mask_of_physid function eliminating
default_apicid_to_cpu_present completely.

Note that physids_coerce and physids_promote turned into static
inline from macro (since macro hides the fact that parameter is
being interpreted as unsigned long, make it explicit).
Signed-off-by: default avatarCyrill Gorcunov <gorcunov@openvz.org>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: Maciej W. Rozycki <macro@linux-mips.org>
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
LKML-Reference: <20091109220659.GA5568@lenovo>
Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
parent f4a70c55
...@@ -297,20 +297,20 @@ struct apic { ...@@ -297,20 +297,20 @@ struct apic {
int disable_esr; int disable_esr;
int dest_logical; int dest_logical;
unsigned long (*check_apicid_used)(physid_mask_t bitmap, int apicid); unsigned long (*check_apicid_used)(physid_mask_t *map, int apicid);
unsigned long (*check_apicid_present)(int apicid); unsigned long (*check_apicid_present)(int apicid);
void (*vector_allocation_domain)(int cpu, struct cpumask *retmask); void (*vector_allocation_domain)(int cpu, struct cpumask *retmask);
void (*init_apic_ldr)(void); void (*init_apic_ldr)(void);
physid_mask_t (*ioapic_phys_id_map)(physid_mask_t map); void (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap);
void (*setup_apic_routing)(void); void (*setup_apic_routing)(void);
int (*multi_timer_check)(int apic, int irq); int (*multi_timer_check)(int apic, int irq);
int (*apicid_to_node)(int logical_apicid); int (*apicid_to_node)(int logical_apicid);
int (*cpu_to_logical_apicid)(int cpu); int (*cpu_to_logical_apicid)(int cpu);
int (*cpu_present_to_apicid)(int mps_cpu); int (*cpu_present_to_apicid)(int mps_cpu);
physid_mask_t (*apicid_to_cpu_present)(int phys_apicid); void (*apicid_to_cpu_present)(int phys_apicid, physid_mask_t *retmap);
void (*setup_portio_remap)(void); void (*setup_portio_remap)(void);
int (*check_phys_apicid_present)(int phys_apicid); int (*check_phys_apicid_present)(int phys_apicid);
void (*enable_apic_mode)(void); void (*enable_apic_mode)(void);
...@@ -534,9 +534,9 @@ default_cpu_mask_to_apicid_and(const struct cpumask *cpumask, ...@@ -534,9 +534,9 @@ default_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
return (unsigned int)(mask1 & mask2 & mask3); return (unsigned int)(mask1 & mask2 & mask3);
} }
static inline unsigned long default_check_apicid_used(physid_mask_t bitmap, int apicid) static inline unsigned long default_check_apicid_used(physid_mask_t *map, int apicid)
{ {
return physid_isset(apicid, bitmap); return physid_isset(apicid, *map);
} }
static inline unsigned long default_check_apicid_present(int bit) static inline unsigned long default_check_apicid_present(int bit)
...@@ -544,9 +544,9 @@ static inline unsigned long default_check_apicid_present(int bit) ...@@ -544,9 +544,9 @@ static inline unsigned long default_check_apicid_present(int bit)
return physid_isset(bit, phys_cpu_present_map); return physid_isset(bit, phys_cpu_present_map);
} }
static inline physid_mask_t default_ioapic_phys_id_map(physid_mask_t phys_map) static inline void default_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
{ {
return phys_map; *retmap = *phys_map;
} }
/* Mapping from cpu number to logical apicid */ /* Mapping from cpu number to logical apicid */
...@@ -585,11 +585,6 @@ extern int default_cpu_present_to_apicid(int mps_cpu); ...@@ -585,11 +585,6 @@ extern int default_cpu_present_to_apicid(int mps_cpu);
extern int default_check_phys_apicid_present(int phys_apicid); extern int default_check_phys_apicid_present(int phys_apicid);
#endif #endif
static inline physid_mask_t default_apicid_to_cpu_present(int phys_apicid)
{
return physid_mask_of_physid(phys_apicid);
}
#endif /* CONFIG_X86_LOCAL_APIC */ #endif /* CONFIG_X86_LOCAL_APIC */
#ifdef CONFIG_X86_32 #ifdef CONFIG_X86_32
......
...@@ -163,14 +163,16 @@ typedef struct physid_mask physid_mask_t; ...@@ -163,14 +163,16 @@ typedef struct physid_mask physid_mask_t;
#define physids_shift_left(d, s, n) \ #define physids_shift_left(d, s, n) \
bitmap_shift_left((d).mask, (s).mask, n, MAX_APICS) bitmap_shift_left((d).mask, (s).mask, n, MAX_APICS)
#define physids_coerce(map) ((map).mask[0]) static inline unsigned long physids_coerce(physid_mask_t *map)
{
return map->mask[0];
}
#define physids_promote(physids) \ static inline void physids_promote(unsigned long physids, physid_mask_t *map)
({ \ {
physid_mask_t __physid_mask = PHYSID_MASK_NONE; \ physids_clear(*map);
__physid_mask.mask[0] = physids; \ map->mask[0] = physids;
__physid_mask; \ }
})
/* Note: will create very large stack frames if physid_mask_t is big */ /* Note: will create very large stack frames if physid_mask_t is big */
#define physid_mask_of_physid(physid) \ #define physid_mask_of_physid(physid) \
......
...@@ -54,11 +54,6 @@ static u64 noop_apic_icr_read(void) ...@@ -54,11 +54,6 @@ static u64 noop_apic_icr_read(void)
return 0; return 0;
} }
static physid_mask_t noop_ioapic_phys_id_map(physid_mask_t phys_map)
{
return phys_map;
}
static int noop_cpu_to_logical_apicid(int cpu) static int noop_cpu_to_logical_apicid(int cpu)
{ {
return 0; return 0;
...@@ -100,9 +95,9 @@ static const struct cpumask *noop_target_cpus(void) ...@@ -100,9 +95,9 @@ static const struct cpumask *noop_target_cpus(void)
return cpumask_of(0); return cpumask_of(0);
} }
static unsigned long noop_check_apicid_used(physid_mask_t bitmap, int apicid) static unsigned long noop_check_apicid_used(physid_mask_t *map, int apicid)
{ {
return physid_isset(apicid, bitmap); return physid_isset(apicid, *map);
} }
static unsigned long noop_check_apicid_present(int bit) static unsigned long noop_check_apicid_present(int bit)
...@@ -155,19 +150,14 @@ struct apic apic_noop = { ...@@ -155,19 +150,14 @@ struct apic apic_noop = {
.vector_allocation_domain = noop_vector_allocation_domain, .vector_allocation_domain = noop_vector_allocation_domain,
.init_apic_ldr = noop_init_apic_ldr, .init_apic_ldr = noop_init_apic_ldr,
.ioapic_phys_id_map = noop_ioapic_phys_id_map, .ioapic_phys_id_map = default_ioapic_phys_id_map,
.setup_apic_routing = NULL, .setup_apic_routing = NULL,
.multi_timer_check = NULL, .multi_timer_check = NULL,
.apicid_to_node = noop_apicid_to_node, .apicid_to_node = noop_apicid_to_node,
.cpu_to_logical_apicid = noop_cpu_to_logical_apicid, .cpu_to_logical_apicid = noop_cpu_to_logical_apicid,
.cpu_present_to_apicid = default_cpu_present_to_apicid, .cpu_present_to_apicid = default_cpu_present_to_apicid,
.apicid_to_cpu_present = physid_set_mask_of_physid,
#ifdef CONFIG_X86_32
.apicid_to_cpu_present = default_apicid_to_cpu_present,
#else
.apicid_to_cpu_present = NULL,
#endif
.setup_portio_remap = NULL, .setup_portio_remap = NULL,
.check_phys_apicid_present = default_check_phys_apicid_present, .check_phys_apicid_present = default_check_phys_apicid_present,
......
...@@ -35,7 +35,7 @@ static const struct cpumask *bigsmp_target_cpus(void) ...@@ -35,7 +35,7 @@ static const struct cpumask *bigsmp_target_cpus(void)
#endif #endif
} }
static unsigned long bigsmp_check_apicid_used(physid_mask_t bitmap, int apicid) static unsigned long bigsmp_check_apicid_used(physid_mask_t *map, int apicid)
{ {
return 0; return 0;
} }
...@@ -93,11 +93,6 @@ static int bigsmp_cpu_present_to_apicid(int mps_cpu) ...@@ -93,11 +93,6 @@ static int bigsmp_cpu_present_to_apicid(int mps_cpu)
return BAD_APICID; return BAD_APICID;
} }
static physid_mask_t bigsmp_apicid_to_cpu_present(int phys_apicid)
{
return physid_mask_of_physid(phys_apicid);
}
/* Mapping from cpu number to logical apicid */ /* Mapping from cpu number to logical apicid */
static inline int bigsmp_cpu_to_logical_apicid(int cpu) static inline int bigsmp_cpu_to_logical_apicid(int cpu)
{ {
...@@ -106,10 +101,10 @@ static inline int bigsmp_cpu_to_logical_apicid(int cpu) ...@@ -106,10 +101,10 @@ static inline int bigsmp_cpu_to_logical_apicid(int cpu)
return cpu_physical_id(cpu); return cpu_physical_id(cpu);
} }
static physid_mask_t bigsmp_ioapic_phys_id_map(physid_mask_t phys_map) static void bigsmp_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
{ {
/* For clustered we don't have a good way to do this yet - hack */ /* For clustered we don't have a good way to do this yet - hack */
return physids_promote(0xFFL); physids_promote(0xFFL, retmap);
} }
static int bigsmp_check_phys_apicid_present(int phys_apicid) static int bigsmp_check_phys_apicid_present(int phys_apicid)
...@@ -230,7 +225,7 @@ struct apic apic_bigsmp = { ...@@ -230,7 +225,7 @@ struct apic apic_bigsmp = {
.apicid_to_node = bigsmp_apicid_to_node, .apicid_to_node = bigsmp_apicid_to_node,
.cpu_to_logical_apicid = bigsmp_cpu_to_logical_apicid, .cpu_to_logical_apicid = bigsmp_cpu_to_logical_apicid,
.cpu_present_to_apicid = bigsmp_cpu_present_to_apicid, .cpu_present_to_apicid = bigsmp_cpu_present_to_apicid,
.apicid_to_cpu_present = bigsmp_apicid_to_cpu_present, .apicid_to_cpu_present = physid_set_mask_of_physid,
.setup_portio_remap = NULL, .setup_portio_remap = NULL,
.check_phys_apicid_present = bigsmp_check_phys_apicid_present, .check_phys_apicid_present = bigsmp_check_phys_apicid_present,
.enable_apic_mode = NULL, .enable_apic_mode = NULL,
......
...@@ -466,11 +466,11 @@ static const struct cpumask *es7000_target_cpus(void) ...@@ -466,11 +466,11 @@ static const struct cpumask *es7000_target_cpus(void)
return cpumask_of(smp_processor_id()); return cpumask_of(smp_processor_id());
} }
static unsigned long static unsigned long es7000_check_apicid_used(physid_mask_t *map, int apicid)
es7000_check_apicid_used(physid_mask_t bitmap, int apicid)
{ {
return 0; return 0;
} }
static unsigned long es7000_check_apicid_present(int bit) static unsigned long es7000_check_apicid_present(int bit)
{ {
return physid_isset(bit, phys_cpu_present_map); return physid_isset(bit, phys_cpu_present_map);
...@@ -539,14 +539,10 @@ static int es7000_cpu_present_to_apicid(int mps_cpu) ...@@ -539,14 +539,10 @@ static int es7000_cpu_present_to_apicid(int mps_cpu)
static int cpu_id; static int cpu_id;
static physid_mask_t es7000_apicid_to_cpu_present(int phys_apicid) static void es7000_apicid_to_cpu_present(int phys_apicid, physid_mask_t *retmap)
{ {
physid_mask_t mask; physid_set_mask_of_physid(cpu_id, retmap);
mask = physid_mask_of_physid(cpu_id);
++cpu_id; ++cpu_id;
return mask;
} }
/* Mapping from cpu number to logical apicid */ /* Mapping from cpu number to logical apicid */
...@@ -561,10 +557,10 @@ static int es7000_cpu_to_logical_apicid(int cpu) ...@@ -561,10 +557,10 @@ static int es7000_cpu_to_logical_apicid(int cpu)
#endif #endif
} }
static physid_mask_t es7000_ioapic_phys_id_map(physid_mask_t phys_map) static void es7000_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
{ {
/* For clustered we don't have a good way to do this yet - hack */ /* For clustered we don't have a good way to do this yet - hack */
return physids_promote(0xff); physids_promote(0xFFL, retmap);
} }
static int es7000_check_phys_apicid_present(int cpu_physical_apicid) static int es7000_check_phys_apicid_present(int cpu_physical_apicid)
......
...@@ -2031,7 +2031,7 @@ void __init setup_ioapic_ids_from_mpc(void) ...@@ -2031,7 +2031,7 @@ void __init setup_ioapic_ids_from_mpc(void)
* This is broken; anything with a real cpu count has to * This is broken; anything with a real cpu count has to
* circumvent this idiocy regardless. * circumvent this idiocy regardless.
*/ */
phys_id_present_map = apic->ioapic_phys_id_map(phys_cpu_present_map); apic->ioapic_phys_id_map(&phys_cpu_present_map, &phys_id_present_map);
/* /*
* Set the IOAPIC ID to the value stored in the MPC table. * Set the IOAPIC ID to the value stored in the MPC table.
...@@ -2058,7 +2058,7 @@ void __init setup_ioapic_ids_from_mpc(void) ...@@ -2058,7 +2058,7 @@ void __init setup_ioapic_ids_from_mpc(void)
* system must have a unique ID or we get lots of nice * system must have a unique ID or we get lots of nice
* 'stuck on smp_invalidate_needed IPI wait' messages. * 'stuck on smp_invalidate_needed IPI wait' messages.
*/ */
if (apic->check_apicid_used(phys_id_present_map, if (apic->check_apicid_used(&phys_id_present_map,
mp_ioapics[apic_id].apicid)) { mp_ioapics[apic_id].apicid)) {
printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n", printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
apic_id, mp_ioapics[apic_id].apicid); apic_id, mp_ioapics[apic_id].apicid);
...@@ -2073,7 +2073,7 @@ void __init setup_ioapic_ids_from_mpc(void) ...@@ -2073,7 +2073,7 @@ void __init setup_ioapic_ids_from_mpc(void)
mp_ioapics[apic_id].apicid = i; mp_ioapics[apic_id].apicid = i;
} else { } else {
physid_mask_t tmp; physid_mask_t tmp;
tmp = apic->apicid_to_cpu_present(mp_ioapics[apic_id].apicid); apic->apicid_to_cpu_present(mp_ioapics[apic_id].apicid, &tmp);
apic_printk(APIC_VERBOSE, "Setting %d in the " apic_printk(APIC_VERBOSE, "Setting %d in the "
"phys_id_present_map\n", "phys_id_present_map\n",
mp_ioapics[apic_id].apicid); mp_ioapics[apic_id].apicid);
...@@ -3904,7 +3904,7 @@ int __init io_apic_get_unique_id(int ioapic, int apic_id) ...@@ -3904,7 +3904,7 @@ int __init io_apic_get_unique_id(int ioapic, int apic_id)
*/ */
if (physids_empty(apic_id_map)) if (physids_empty(apic_id_map))
apic_id_map = apic->ioapic_phys_id_map(phys_cpu_present_map); apic->ioapic_phys_id_map(&phys_cpu_present_map, &apic_id_map);
spin_lock_irqsave(&ioapic_lock, flags); spin_lock_irqsave(&ioapic_lock, flags);
reg_00.raw = io_apic_read(ioapic, 0); reg_00.raw = io_apic_read(ioapic, 0);
...@@ -3920,10 +3920,10 @@ int __init io_apic_get_unique_id(int ioapic, int apic_id) ...@@ -3920,10 +3920,10 @@ int __init io_apic_get_unique_id(int ioapic, int apic_id)
* Every APIC in a system must have a unique ID or we get lots of nice * Every APIC in a system must have a unique ID or we get lots of nice
* 'stuck on smp_invalidate_needed IPI wait' messages. * 'stuck on smp_invalidate_needed IPI wait' messages.
*/ */
if (apic->check_apicid_used(apic_id_map, apic_id)) { if (apic->check_apicid_used(&apic_id_map, apic_id)) {
for (i = 0; i < get_physical_broadcast(); i++) { for (i = 0; i < get_physical_broadcast(); i++) {
if (!apic->check_apicid_used(apic_id_map, i)) if (!apic->check_apicid_used(&apic_id_map, i))
break; break;
} }
...@@ -3936,7 +3936,7 @@ int __init io_apic_get_unique_id(int ioapic, int apic_id) ...@@ -3936,7 +3936,7 @@ int __init io_apic_get_unique_id(int ioapic, int apic_id)
apic_id = i; apic_id = i;
} }
tmp = apic->apicid_to_cpu_present(apic_id); apic->apicid_to_cpu_present(apic_id, &tmp);
physids_or(apic_id_map, apic_id_map, tmp); physids_or(apic_id_map, apic_id_map, tmp);
if (reg_00.bits.ID != apic_id) { if (reg_00.bits.ID != apic_id) {
......
...@@ -334,10 +334,9 @@ static inline const struct cpumask *numaq_target_cpus(void) ...@@ -334,10 +334,9 @@ static inline const struct cpumask *numaq_target_cpus(void)
return cpu_all_mask; return cpu_all_mask;
} }
static inline unsigned long static unsigned long numaq_check_apicid_used(physid_mask_t *map, int apicid)
numaq_check_apicid_used(physid_mask_t bitmap, int apicid)
{ {
return physid_isset(apicid, bitmap); return physid_isset(apicid, *map);
} }
static inline unsigned long numaq_check_apicid_present(int bit) static inline unsigned long numaq_check_apicid_present(int bit)
...@@ -371,10 +370,10 @@ static inline int numaq_multi_timer_check(int apic, int irq) ...@@ -371,10 +370,10 @@ static inline int numaq_multi_timer_check(int apic, int irq)
return apic != 0 && irq == 0; return apic != 0 && irq == 0;
} }
static inline physid_mask_t numaq_ioapic_phys_id_map(physid_mask_t phys_map) static inline void numaq_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap)
{ {
/* We don't have a good way to do this yet - hack */ /* We don't have a good way to do this yet - hack */
return physids_promote(0xFUL); return physids_promote(0xFUL, retmap);
} }
static inline int numaq_cpu_to_logical_apicid(int cpu) static inline int numaq_cpu_to_logical_apicid(int cpu)
...@@ -402,12 +401,12 @@ static inline int numaq_apicid_to_node(int logical_apicid) ...@@ -402,12 +401,12 @@ static inline int numaq_apicid_to_node(int logical_apicid)
return logical_apicid >> 4; return logical_apicid >> 4;
} }
static inline physid_mask_t numaq_apicid_to_cpu_present(int logical_apicid) static void numaq_apicid_to_cpu_present(int logical_apicid, physid_mask_t *retmap)
{ {
int node = numaq_apicid_to_node(logical_apicid); int node = numaq_apicid_to_node(logical_apicid);
int cpu = __ffs(logical_apicid & 0xf); int cpu = __ffs(logical_apicid & 0xf);
return physid_mask_of_physid(cpu + 4*node); physid_set_mask_of_physid(cpu + 4*node, retmap);
} }
/* Where the IO area was mapped on multiquad, always 0 otherwise */ /* Where the IO area was mapped on multiquad, always 0 otherwise */
......
...@@ -108,7 +108,7 @@ struct apic apic_default = { ...@@ -108,7 +108,7 @@ struct apic apic_default = {
.apicid_to_node = default_apicid_to_node, .apicid_to_node = default_apicid_to_node,
.cpu_to_logical_apicid = default_cpu_to_logical_apicid, .cpu_to_logical_apicid = default_cpu_to_logical_apicid,
.cpu_present_to_apicid = default_cpu_present_to_apicid, .cpu_present_to_apicid = default_cpu_present_to_apicid,
.apicid_to_cpu_present = default_apicid_to_cpu_present, .apicid_to_cpu_present = physid_set_mask_of_physid,
.setup_portio_remap = NULL, .setup_portio_remap = NULL,
.check_phys_apicid_present = default_check_phys_apicid_present, .check_phys_apicid_present = default_check_phys_apicid_present,
.enable_apic_mode = NULL, .enable_apic_mode = NULL,
......
...@@ -183,7 +183,7 @@ static const struct cpumask *summit_target_cpus(void) ...@@ -183,7 +183,7 @@ static const struct cpumask *summit_target_cpus(void)
return cpumask_of(0); return cpumask_of(0);
} }
static unsigned long summit_check_apicid_used(physid_mask_t bitmap, int apicid) static unsigned long summit_check_apicid_used(physid_mask_t *map, int apicid)
{ {
return 0; return 0;
} }
...@@ -261,15 +261,15 @@ static int summit_cpu_present_to_apicid(int mps_cpu) ...@@ -261,15 +261,15 @@ static int summit_cpu_present_to_apicid(int mps_cpu)
return BAD_APICID; return BAD_APICID;
} }
static physid_mask_t summit_ioapic_phys_id_map(physid_mask_t phys_id_map) static void summit_ioapic_phys_id_map(physid_mask_t *phys_id_map, physid_mask_t *retmap)
{ {
/* For clustered we don't have a good way to do this yet - hack */ /* For clustered we don't have a good way to do this yet - hack */
return physids_promote(0x0F); physids_promote(0x0FL, retmap);
} }
static physid_mask_t summit_apicid_to_cpu_present(int apicid) static void summit_apicid_to_cpu_present(int apicid, physid_mask_t *retmap)
{ {
return physid_mask_of_physid(0); physid_set_mask_of_physid(0, retmap);
} }
static int summit_check_phys_apicid_present(int physical_apicid) static int summit_check_phys_apicid_present(int physical_apicid)
......
...@@ -183,7 +183,7 @@ static void __init MP_processor_info(struct mpc_cpu *m) ...@@ -183,7 +183,7 @@ static void __init MP_processor_info(struct mpc_cpu *m)
return; return;
} }
apic_cpus = apic->apicid_to_cpu_present(m->apicid); apic->apicid_to_cpu_present(m->apicid, &apic_cpus);
physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus); physids_or(phys_cpu_present_map, phys_cpu_present_map, apic_cpus);
/* /*
* Validate version * Validate version
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment