mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-16 00:34:20 +08:00
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: Cyrill 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: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
parent
f4a70c5537
commit
7abc075313
@ -297,20 +297,20 @@ struct apic {
|
||||
int disable_esr;
|
||||
|
||||
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);
|
||||
|
||||
void (*vector_allocation_domain)(int cpu, struct cpumask *retmask);
|
||||
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);
|
||||
int (*multi_timer_check)(int apic, int irq);
|
||||
int (*apicid_to_node)(int logical_apicid);
|
||||
int (*cpu_to_logical_apicid)(int 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);
|
||||
int (*check_phys_apicid_present)(int phys_apicid);
|
||||
void (*enable_apic_mode)(void);
|
||||
@ -534,9 +534,9 @@ default_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
|
||||
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)
|
||||
@ -544,9 +544,9 @@ static inline unsigned long default_check_apicid_present(int bit)
|
||||
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 */
|
||||
@ -585,11 +585,6 @@ extern int default_cpu_present_to_apicid(int mps_cpu);
|
||||
extern int default_check_phys_apicid_present(int phys_apicid);
|
||||
#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 */
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
|
@ -163,14 +163,16 @@ typedef struct physid_mask physid_mask_t;
|
||||
#define physids_shift_left(d, s, n) \
|
||||
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) \
|
||||
({ \
|
||||
physid_mask_t __physid_mask = PHYSID_MASK_NONE; \
|
||||
__physid_mask.mask[0] = physids; \
|
||||
__physid_mask; \
|
||||
})
|
||||
static inline void physids_promote(unsigned long physids, physid_mask_t *map)
|
||||
{
|
||||
physids_clear(*map);
|
||||
map->mask[0] = physids;
|
||||
}
|
||||
|
||||
/* Note: will create very large stack frames if physid_mask_t is big */
|
||||
#define physid_mask_of_physid(physid) \
|
||||
|
@ -54,11 +54,6 @@ static u64 noop_apic_icr_read(void)
|
||||
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)
|
||||
{
|
||||
return 0;
|
||||
@ -100,9 +95,9 @@ static const struct cpumask *noop_target_cpus(void)
|
||||
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)
|
||||
@ -155,19 +150,14 @@ struct apic apic_noop = {
|
||||
.vector_allocation_domain = noop_vector_allocation_domain,
|
||||
.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,
|
||||
.multi_timer_check = NULL,
|
||||
.apicid_to_node = noop_apicid_to_node,
|
||||
|
||||
.cpu_to_logical_apicid = noop_cpu_to_logical_apicid,
|
||||
.cpu_present_to_apicid = default_cpu_present_to_apicid,
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
.apicid_to_cpu_present = default_apicid_to_cpu_present,
|
||||
#else
|
||||
.apicid_to_cpu_present = NULL,
|
||||
#endif
|
||||
.apicid_to_cpu_present = physid_set_mask_of_physid,
|
||||
|
||||
.setup_portio_remap = NULL,
|
||||
.check_phys_apicid_present = default_check_phys_apicid_present,
|
||||
|
@ -35,7 +35,7 @@ static const struct cpumask *bigsmp_target_cpus(void)
|
||||
#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;
|
||||
}
|
||||
@ -93,11 +93,6 @@ static int bigsmp_cpu_present_to_apicid(int mps_cpu)
|
||||
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 */
|
||||
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);
|
||||
}
|
||||
|
||||
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 */
|
||||
return physids_promote(0xFFL);
|
||||
physids_promote(0xFFL, retmap);
|
||||
}
|
||||
|
||||
static int bigsmp_check_phys_apicid_present(int phys_apicid)
|
||||
@ -230,7 +225,7 @@ struct apic apic_bigsmp = {
|
||||
.apicid_to_node = bigsmp_apicid_to_node,
|
||||
.cpu_to_logical_apicid = bigsmp_cpu_to_logical_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,
|
||||
.check_phys_apicid_present = bigsmp_check_phys_apicid_present,
|
||||
.enable_apic_mode = NULL,
|
||||
|
@ -466,11 +466,11 @@ static const struct cpumask *es7000_target_cpus(void)
|
||||
return cpumask_of(smp_processor_id());
|
||||
}
|
||||
|
||||
static unsigned long
|
||||
es7000_check_apicid_used(physid_mask_t bitmap, int apicid)
|
||||
static unsigned long es7000_check_apicid_used(physid_mask_t *map, int apicid)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned long es7000_check_apicid_present(int bit)
|
||||
{
|
||||
return physid_isset(bit, phys_cpu_present_map);
|
||||
@ -539,14 +539,10 @@ static int es7000_cpu_present_to_apicid(int mps_cpu)
|
||||
|
||||
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;
|
||||
|
||||
mask = physid_mask_of_physid(cpu_id);
|
||||
physid_set_mask_of_physid(cpu_id, retmap);
|
||||
++cpu_id;
|
||||
|
||||
return mask;
|
||||
}
|
||||
|
||||
/* Mapping from cpu number to logical apicid */
|
||||
@ -561,10 +557,10 @@ static int es7000_cpu_to_logical_apicid(int cpu)
|
||||
#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 */
|
||||
return physids_promote(0xff);
|
||||
physids_promote(0xFFL, retmap);
|
||||
}
|
||||
|
||||
static int es7000_check_phys_apicid_present(int cpu_physical_apicid)
|
||||
|
@ -2031,7 +2031,7 @@ void __init setup_ioapic_ids_from_mpc(void)
|
||||
* This is broken; anything with a real cpu count has to
|
||||
* 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.
|
||||
@ -2058,7 +2058,7 @@ void __init setup_ioapic_ids_from_mpc(void)
|
||||
* system must have a unique ID or we get lots of nice
|
||||
* '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)) {
|
||||
printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
|
||||
apic_id, mp_ioapics[apic_id].apicid);
|
||||
@ -2073,7 +2073,7 @@ void __init setup_ioapic_ids_from_mpc(void)
|
||||
mp_ioapics[apic_id].apicid = i;
|
||||
} else {
|
||||
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 "
|
||||
"phys_id_present_map\n",
|
||||
mp_ioapics[apic_id].apicid);
|
||||
@ -3904,7 +3904,7 @@ int __init io_apic_get_unique_id(int ioapic, int apic_id)
|
||||
*/
|
||||
|
||||
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);
|
||||
reg_00.raw = io_apic_read(ioapic, 0);
|
||||
@ -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
|
||||
* '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++) {
|
||||
if (!apic->check_apicid_used(apic_id_map, i))
|
||||
if (!apic->check_apicid_used(&apic_id_map, i))
|
||||
break;
|
||||
}
|
||||
|
||||
@ -3936,7 +3936,7 @@ int __init io_apic_get_unique_id(int ioapic, int apic_id)
|
||||
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);
|
||||
|
||||
if (reg_00.bits.ID != apic_id) {
|
||||
|
@ -334,10 +334,9 @@ static inline const struct cpumask *numaq_target_cpus(void)
|
||||
return cpu_all_mask;
|
||||
}
|
||||
|
||||
static inline unsigned long
|
||||
numaq_check_apicid_used(physid_mask_t bitmap, int apicid)
|
||||
static unsigned long numaq_check_apicid_used(physid_mask_t *map, int apicid)
|
||||
{
|
||||
return physid_isset(apicid, bitmap);
|
||||
return physid_isset(apicid, *map);
|
||||
}
|
||||
|
||||
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)
|
||||
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 */
|
||||
return physids_promote(0xFUL);
|
||||
return physids_promote(0xFUL, retmap);
|
||||
}
|
||||
|
||||
static inline int numaq_cpu_to_logical_apicid(int cpu)
|
||||
@ -402,12 +401,12 @@ static inline int numaq_apicid_to_node(int logical_apicid)
|
||||
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 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 */
|
||||
|
@ -108,7 +108,7 @@ struct apic apic_default = {
|
||||
.apicid_to_node = default_apicid_to_node,
|
||||
.cpu_to_logical_apicid = default_cpu_to_logical_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,
|
||||
.check_phys_apicid_present = default_check_phys_apicid_present,
|
||||
.enable_apic_mode = NULL,
|
||||
|
@ -183,7 +183,7 @@ static const struct cpumask *summit_target_cpus(void)
|
||||
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;
|
||||
}
|
||||
@ -261,15 +261,15 @@ static int summit_cpu_present_to_apicid(int mps_cpu)
|
||||
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 */
|
||||
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)
|
||||
|
@ -183,7 +183,7 @@ static void __init MP_processor_info(struct mpc_cpu *m)
|
||||
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);
|
||||
/*
|
||||
* Validate version
|
||||
|
Loading…
Reference in New Issue
Block a user