]> Pileus Git - ~andy/linux/commitdiff
x86/apic: Make cpu_mask_to_apicid() operations check cpu_online_mask
authorAlexander Gordeev <agordeev@redhat.com>
Thu, 7 Jun 2012 13:16:25 +0000 (15:16 +0200)
committerIngo Molnar <mingo@kernel.org>
Fri, 8 Jun 2012 09:44:30 +0000 (11:44 +0200)
Currently cpu_mask_to_apicid() should not get a offline CPU with
the cpumask. Otherwise some apic drivers might try to access
non-existent per-cpu variables (i.e. x2apic). In that regard
cpu_mask_to_apicid() and cpu_mask_to_apicid_and() operations are
inconsistent.

This fix makes the two operations do not rely on calling
functions and always return the apicid for only online CPUs. As
result, the meaning and implementations of cpu_mask_to_apicid()
and cpu_mask_to_apicid_and() operations become straight.

Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
Acked-by: Suresh Siddha <suresh.b.siddha@intel.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Link: http://lkml.kernel.org/r/20120607131624.GG4759@dhcp-26-207.brq.redhat.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
arch/x86/include/asm/apic.h
arch/x86/kernel/apic/apic.c
arch/x86/kernel/apic/es7000_32.c
arch/x86/kernel/apic/summit_32.c
arch/x86/kernel/apic/x2apic_cluster.c
arch/x86/kernel/apic/x2apic_uv_x.c

index ae91f9c7e360a04bb31f27a9f83ba00cca7e0192..1ed3eead20390d8c5ef4d39dea5cad69619251d2 100644 (file)
@@ -596,7 +596,7 @@ static inline int default_phys_pkg_id(int cpuid_apic, int index_msb)
 static inline int
 __flat_cpu_mask_to_apicid(unsigned long cpu_mask, unsigned int *apicid)
 {
-       cpu_mask &= APIC_ALL_CPUS;
+       cpu_mask = cpu_mask & APIC_ALL_CPUS & cpumask_bits(cpu_online_mask)[0];
        if (likely(cpu_mask)) {
                *apicid = (unsigned int)cpu_mask;
                return 0;
@@ -619,9 +619,7 @@ flat_cpu_mask_to_apicid_and(const struct cpumask *cpumask,
 {
        unsigned long mask1 = cpumask_bits(cpumask)[0];
        unsigned long mask2 = cpumask_bits(andmask)[0];
-       unsigned long mask3 = cpumask_bits(cpu_online_mask)[0];
-
-       return __flat_cpu_mask_to_apicid(mask1 & mask2 & mask3, apicid);
+       return __flat_cpu_mask_to_apicid(mask1 & mask2, apicid);
 }
 
 extern int
index b8d92606f84fa2c079b26a8e9c008d13336975f9..7e9bbe73bc5a54a256b58acc0a1d11c95a7aab91 100644 (file)
@@ -2136,7 +2136,7 @@ static inline int __default_cpu_to_apicid(int cpu, unsigned int *apicid)
 int default_cpu_mask_to_apicid(const struct cpumask *cpumask,
                               unsigned int *apicid)
 {
-       int cpu = cpumask_first(cpumask);
+       int cpu = cpumask_first_and(cpumask, cpu_online_mask);
        return __default_cpu_to_apicid(cpu, apicid);
 }
 
index 515ebb00a9fc087b6f0b13e677b5ede7b7a5e4f6..b35cfb9b69629710f8c43ef4bb76c74a7fa63394 100644 (file)
@@ -534,7 +534,7 @@ es7000_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id)
        /*
         * The cpus in the mask must all be on the apic cluster.
         */
-       for_each_cpu(cpu, cpumask) {
+       for_each_cpu_and(cpu, cpumask, cpu_online_mask) {
                int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
 
                if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
@@ -561,7 +561,6 @@ es7000_cpu_mask_to_apicid_and(const struct cpumask *inmask,
                return 0;
 
        cpumask_and(cpumask, inmask, andmask);
-       cpumask_and(cpumask, cpumask, cpu_online_mask);
        es7000_cpu_mask_to_apicid(cpumask, apicid);
 
        free_cpumask_var(cpumask);
index 5766d84f12d66e47fb643740d1683425b069ced5..79d360f6729e8a35d0fb3aeced004d09bb65dee7 100644 (file)
@@ -272,7 +272,7 @@ summit_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *dest_id)
        /*
         * The cpus in the mask must all be on the apic cluster.
         */
-       for_each_cpu(cpu, cpumask) {
+       for_each_cpu_and(cpu, cpumask, cpu_online_mask) {
                int new_apicid = early_per_cpu(x86_cpu_to_logical_apicid, cpu);
 
                if (round && APIC_CLUSTER(apicid) != APIC_CLUSTER(new_apicid)) {
@@ -298,7 +298,6 @@ summit_cpu_mask_to_apicid_and(const struct cpumask *inmask,
                return 0;
 
        cpumask_and(cpumask, inmask, andmask);
-       cpumask_and(cpumask, cpumask, cpu_online_mask);
        summit_cpu_mask_to_apicid(cpumask, apicid);
 
        free_cpumask_var(cpumask);
index 5f86f79335f414a80c0c6e7ccc16e9a307e799c8..23a46cf5b6fdcac1e180a130ad8ad6c14f4d48df 100644 (file)
@@ -99,7 +99,7 @@ static void x2apic_send_IPI_all(int vector)
 static int
 x2apic_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *apicid)
 {
-       int cpu = cpumask_first(cpumask);
+       int cpu = cpumask_first_and(cpumask, cpu_online_mask);
        int i;
 
        if (cpu >= nr_cpu_ids)
index 2f3030fef31e45751efc18eb46cdfb75df3aa3a3..307aa076bd6211d66220fc8abe329d8cfd23d8bd 100644 (file)
@@ -286,7 +286,7 @@ uv_cpu_mask_to_apicid(const struct cpumask *cpumask, unsigned int *apicid)
         * We're using fixed IRQ delivery, can only return one phys APIC ID.
         * May as well be the first.
         */
-       int cpu = cpumask_first(cpumask);
+       int cpu = cpumask_first_and(cpumask, cpu_online_mask);
        return __uv_cpu_to_apicid(cpu, apicid);
 }