x86: apic: Do not use stacked physid_mask_t
authorCyrill Gorcunov <gorcunov@gmail.com>
Mon, 9 Nov 2009 22:06:59 +0000 (01:06 +0300)
committerIngo Molnar <mingo@elte.hu>
Tue, 10 Nov 2009 04:52:07 +0000 (05:52 +0100)
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>
arch/x86/include/asm/apic.h
arch/x86/include/asm/mpspec.h
arch/x86/kernel/apic/apic_noop.c
arch/x86/kernel/apic/bigsmp_32.c
arch/x86/kernel/apic/es7000_32.c
arch/x86/kernel/apic/io_apic.c
arch/x86/kernel/apic/numaq_32.c
arch/x86/kernel/apic/probe_32.c
arch/x86/kernel/apic/summit_32.c
arch/x86/kernel/visws_quirks.c

index 08a5f42..b4ac2cd 100644 (file)
@@ -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
index 79c9450..61d90b1 100644 (file)
@@ -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)                                  \
index 89629f6..d9acc3b 100644 (file)
@@ -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,
index 77a0641..38dcecf 100644 (file)
@@ -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,
index 89174f8..e85f8fb 100644 (file)
@@ -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)
index 24d1458..20ea839 100644 (file)
@@ -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) {
index efa00e2..07cdbdc 100644 (file)
@@ -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 */
index 0c0182c..1a6559f 100644 (file)
@@ -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,
index 645ecc4..9b41926 100644 (file)
@@ -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)
index f068553..cff70c8 100644 (file)
@@ -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