[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Add the support of x2apic logical cluster mode.



# HG changeset patch
# User Keir Fraser <keir.fraser@xxxxxxxxxx>
# Date 1252309606 -3600
# Node ID 9c84d25e6d88738164ea08814d801ff806277bbb
# Parent  cb249398f3eff1560b2a4934b0da08ec6b355eba
Add the support of x2apic logical cluster mode.
Add a xen boolean parameter 'x2apic'.
Add a xen boolean parameter 'x2apic_phys'(by default, we use logical
cluster mode).

Signed-off-by: Dexuan Cui <dexuan.cui@xxxxxxxxx>
---
 xen/arch/x86/apic.c           |   35 ++++++++++++++++-------
 xen/arch/x86/genapic/x2apic.c |   62 +++++++++++++++++++++++++++++++++++-------
 xen/include/asm-x86/genapic.h |   31 +++++++++++++++------
 3 files changed, 100 insertions(+), 28 deletions(-)

diff -r cb249398f3ef -r 9c84d25e6d88 xen/arch/x86/apic.c
--- a/xen/arch/x86/apic.c       Mon Sep 07 08:46:03 2009 +0100
+++ b/xen/arch/x86/apic.c       Mon Sep 07 08:46:46 2009 +0100
@@ -848,8 +848,31 @@ void enable_x2apic(void)
 {
     u32 lo, hi;
 
-    if ( !iommu_supports_eim() )
-        return;
+    if ( smp_processor_id() == 0 )
+    {
+        if ( !iommu_supports_eim() )
+        {
+            printk("x2APIC would not be enabled without EIM.\n");
+            return;
+        }
+
+        if ( apic_x2apic_phys.probe() )
+            genapic = &apic_x2apic_phys;
+        else if ( apic_x2apic_cluster.probe() )
+            genapic = &apic_x2apic_cluster;
+        else
+        {
+            printk("x2APIC would not be enabled due to x2apic=off.\n");
+            return;
+        }
+
+        x2apic_enabled = 1;
+        printk("Switched to APIC driver %s.\n", genapic->name);
+    }
+    else
+    {
+        BUG_ON(!x2apic_enabled); /* APs only enable x2apic when BSP did so. */
+    }
 
     rdmsr(MSR_IA32_APICBASE, lo, hi);
     if ( !(lo & MSR_IA32_APICBASE_EXTD) )
@@ -860,14 +883,6 @@ void enable_x2apic(void)
     }
     else
         printk("x2APIC mode enabled by BIOS.\n");
-
-    if ( !x2apic_enabled )
-    {
-        x2apic_enabled = 1;
-        genapic = &apic_x2apic;
-        printk(KERN_INFO "Switched to APIC driver %s.\n",
-                       genapic->name);
-    }
 }
 
 void __init init_apic_mappings(void)
diff -r cb249398f3ef -r 9c84d25e6d88 xen/arch/x86/genapic/x2apic.c
--- a/xen/arch/x86/genapic/x2apic.c     Mon Sep 07 08:46:03 2009 +0100
+++ b/xen/arch/x86/genapic/x2apic.c     Mon Sep 07 08:46:46 2009 +0100
@@ -23,25 +23,46 @@
 #include <xen/smp.h>
 #include <asm/mach-default/mach_mpparse.h>
 
-__init int probe_x2apic(void)
+static int x2apic = 1;
+boolean_param("x2apic", x2apic);
+
+static int x2apic_phys = 0; /* By default we use logical cluster mode. */
+boolean_param("x2apic_phys", x2apic_phys);
+
+__init int probe_x2apic_phys(void)
 {
-    return x2apic_is_available();
+    return x2apic && x2apic_phys && x2apic_is_available() &&
+        iommu_supports_eim();
 }
 
-struct genapic apic_x2apic= {
-    APIC_INIT("x2apic", probe_x2apic),
-    GENAPIC_X2APIC
+__init int probe_x2apic_cluster(void)
+{
+    return x2apic && !x2apic_phys && x2apic_is_available() &&
+        iommu_supports_eim();
+}
+
+struct genapic apic_x2apic_phys= {
+    APIC_INIT("x2apic_phys", probe_x2apic_phys),
+    GENAPIC_X2APIC_PHYS
 };
 
-void init_apic_ldr_x2apic(void)
+struct genapic apic_x2apic_cluster= {
+    APIC_INIT("x2apic_cluster", probe_x2apic_cluster),
+    GENAPIC_X2APIC_CLUSTER
+};
+
+void init_apic_ldr_x2apic_phys(void)
 {
-    /* We only use physical delivery mode. */
     return;
 }
 
+void init_apic_ldr_x2apic_cluster(void)
+{
+    int cpu = smp_processor_id();
+    cpu_2_logical_apicid[cpu] = apic_read(APIC_LDR);
+}
 void clustered_apic_check_x2apic(void)
 {
-    /* We only use physical delivery mode. */
     return;
 }
 
@@ -55,12 +76,17 @@ cpumask_t vector_allocation_domain_x2api
        return cpumask_of_cpu(cpu);
 }
 
-unsigned int cpu_mask_to_apicid_x2apic(cpumask_t cpumask)
+unsigned int cpu_mask_to_apicid_x2apic_phys(cpumask_t cpumask)
 {
     return cpu_physical_id(first_cpu(cpumask));
 }
 
-void send_IPI_mask_x2apic(const cpumask_t *cpumask, int vector)
+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)
 {
     unsigned int cpu, cfg;
     unsigned long flags;
@@ -87,3 +113,19 @@ void send_IPI_mask_x2apic(const cpumask_
     local_irq_restore(flags);
 }
 
+void send_IPI_mask_x2apic_cluster(const cpumask_t *cpumask, int vector)
+{
+    unsigned int cpu, cfg;
+    unsigned long flags;
+
+    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() )
+            apic_wrmsr(APIC_ICR, cfg, cpu_2_logical_apicid[cpu]);
+
+    local_irq_restore(flags);
+}
diff -r cb249398f3ef -r 9c84d25e6d88 xen/include/asm-x86/genapic.h
--- a/xen/include/asm-x86/genapic.h     Mon Sep 07 08:46:03 2009 +0100
+++ b/xen/include/asm-x86/genapic.h     Mon Sep 07 08:46:46 2009 +0100
@@ -49,7 +49,8 @@ struct genapic {
        APICFUNC(acpi_madt_oem_check)
 
 extern struct genapic *genapic;
-extern struct genapic apic_x2apic;
+extern struct genapic apic_x2apic_phys;
+extern struct genapic apic_x2apic_cluster;
 
 void init_apic_ldr_flat(void);
 void clustered_apic_check_flat(void);
@@ -69,23 +70,37 @@ cpumask_t vector_allocation_domain_flat(
        .send_IPI_mask = send_IPI_mask_flat, \
        .send_IPI_self = send_IPI_self_flat
 
-void init_apic_ldr_x2apic(void);
+void init_apic_ldr_x2apic_phys(void);
+void init_apic_ldr_x2apic_cluster(void);
 void clustered_apic_check_x2apic(void);
 cpumask_t target_cpus_x2apic(void);
-unsigned int cpu_mask_to_apicid_x2apic(cpumask_t cpumask);
-void send_IPI_mask_x2apic(const cpumask_t *mask, int vector);
+unsigned int cpu_mask_to_apicid_x2apic_phys(cpumask_t cpumask);
+unsigned int cpu_mask_to_apicid_x2apic_cluster(cpumask_t cpumask);
+void send_IPI_mask_x2apic_phys(const cpumask_t *mask, int vector);
+void send_IPI_mask_x2apic_cluster(const cpumask_t *mask, int vector);
 void send_IPI_self_x2apic(int vector);
 cpumask_t vector_allocation_domain_x2apic(int cpu);
-#define GENAPIC_X2APIC \
+#define GENAPIC_X2APIC_PHYS \
        .int_delivery_mode = dest_Fixed, \
        .int_dest_mode = 0 /* physical delivery */, \
-       .init_apic_ldr = init_apic_ldr_x2apic, \
+       .init_apic_ldr = init_apic_ldr_x2apic_phys, \
        .clustered_apic_check = clustered_apic_check_x2apic, \
        .target_cpus = target_cpus_x2apic, \
        .vector_allocation_domain = vector_allocation_domain_x2apic, \
-       .cpu_mask_to_apicid = cpu_mask_to_apicid_x2apic, \
-       .send_IPI_mask = send_IPI_mask_x2apic,       \
+       .cpu_mask_to_apicid = cpu_mask_to_apicid_x2apic_phys, \
+       .send_IPI_mask = send_IPI_mask_x2apic_phys,       \
        .send_IPI_self = send_IPI_self_x2apic
+
+#define GENAPIC_X2APIC_CLUSTER \
+    .int_delivery_mode = dest_LowestPrio, \
+    .int_dest_mode = 1 /* logical delivery */, \
+    .init_apic_ldr = init_apic_ldr_x2apic_cluster, \
+    .clustered_apic_check = clustered_apic_check_x2apic, \
+    .target_cpus = target_cpus_x2apic, \
+    .vector_allocation_domain = vector_allocation_domain_x2apic, \
+    .cpu_mask_to_apicid = cpu_mask_to_apicid_x2apic_cluster, \
+    .send_IPI_mask = send_IPI_mask_x2apic_cluster,       \
+    .send_IPI_self = send_IPI_self_x2apic
 
 void init_apic_ldr_phys(void);
 void clustered_apic_check_phys(void);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.