x86: send_IPI_mask() ignores offline CPUs in given cpumask.
authorKeir Fraser <keir.fraser@citrix.com>
Tue, 29 Jun 2010 12:16:22 +0000 (13:16 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Tue, 29 Jun 2010 12:16:22 +0000 (13:16 +0100)
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
xen/arch/x86/genapic/x2apic.c
xen/arch/x86/smp.c

index bea9cb0ade3fc32379fd8c1d616dfdcfb34fc048..8c8d52ab013daa6df9e07b63cd7563c451952223 100644 (file)
@@ -77,7 +77,7 @@ cpumask_t target_cpus_x2apic(void)
 
 cpumask_t vector_allocation_domain_x2apic(int cpu)
 {
-       return cpumask_of_cpu(cpu);
+    return cpumask_of_cpu(cpu);
 }
 
 unsigned int cpu_mask_to_apicid_x2apic_phys(cpumask_t cpumask)
@@ -90,9 +90,10 @@ unsigned int cpu_mask_to_apicid_x2apic_cluster(cpumask_t cpumask)
     return cpu_2_logical_apicid[first_cpu(cpumask)];
 }
 
-void send_IPI_mask_x2apic_phys(const cpumask_t *cpumask, int vector)
+static void __send_IPI_mask_x2apic(
+    const cpumask_t *cpumask, int vector, unsigned int dest_mode)
 {
-    unsigned int cpu, cfg;
+    unsigned int cpu;
     unsigned long flags;
     uint64_t msr_content;
 
@@ -110,32 +111,25 @@ void send_IPI_mask_x2apic_phys(const cpumask_t *cpumask, int vector)
 
     local_irq_save(flags);
 
-    cfg = APIC_DM_FIXED | 0 /* no shorthand */ | APIC_DEST_PHYSICAL | vector;
     for_each_cpu_mask ( cpu, *cpumask )
-        if ( cpu != smp_processor_id() ) {
-            msr_content = cfg | ((uint64_t)cpu_physical_id(cpu) << 32);
-            apic_wrmsr(APIC_ICR, msr_content);
-        }
+    {
+        if ( !cpu_online(cpu) || (cpu == smp_processor_id()) )
+            continue;
+        msr_content = (dest_mode == APIC_DEST_PHYSICAL)
+            ? cpu_physical_id(cpu) : cpu_2_logical_apicid[cpu];
+        msr_content = (msr_content << 32) | APIC_DM_FIXED | dest_mode | vector;
+        apic_wrmsr(APIC_ICR, msr_content);
+    }
 
     local_irq_restore(flags);
 }
 
-void send_IPI_mask_x2apic_cluster(const cpumask_t *cpumask, int vector)
+void send_IPI_mask_x2apic_phys(const cpumask_t *cpumask, int vector)
 {
-    unsigned int cpu, cfg;
-    unsigned long flags;
-    uint64_t msr_content;
-
-    mb(); /* see the comment in send_IPI_mask_x2apic_phys() */
-
-    local_irq_save(flags);
-
-    cfg = APIC_DM_FIXED | 0 /* no shorthand */ | APIC_DEST_LOGICAL | vector;
-    for_each_cpu_mask ( cpu, *cpumask )
-        if ( cpu != smp_processor_id() ) {
-            msr_content = cfg | ((uint64_t)cpu_2_logical_apicid[cpu] << 32);
-            apic_wrmsr(APIC_ICR, msr_content);
-        }
+    __send_IPI_mask_x2apic(cpumask, vector, APIC_DEST_PHYSICAL);
+}
 
-    local_irq_restore(flags);
+void send_IPI_mask_x2apic_cluster(const cpumask_t *cpumask, int vector)
+{
+    __send_IPI_mask_x2apic(cpumask, vector, APIC_DEST_LOGICAL);
 }
index 239dde6fb714a3123379c8e3568f5d43a499adbc..1c231b00b165994213c36865f577ca0666e7fb2c 100644 (file)
@@ -144,6 +144,7 @@ void send_IPI_mask_flat(const cpumask_t *cpumask, int vector)
     unsigned long cfg;
     unsigned long flags;
 
+    mask &= cpus_addr(cpu_online_map)[0];
     mask &= ~(1UL << smp_processor_id());
     if ( mask == 0 )
         return;
@@ -183,7 +184,7 @@ void send_IPI_mask_phys(const cpumask_t *mask, int vector)
 
     for_each_cpu_mask ( query_cpu, *mask )
     {
-        if ( query_cpu == smp_processor_id() )
+        if ( !cpu_online(query_cpu) || (query_cpu == smp_processor_id()) )
             continue;
 
         /*