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

[Xen-devel] [PATCH v6 05/12] x86/apic: Unify interrupt mode setup for SMP-capable system



In the SMP-capable system, enable and setup the interrupt delivery
mode in native_smp_prepare_cpus().

This design mixs the APIC and SMP together, it has highly coupling.

Make the initialization of interrupt mode independent, Unify and
refine it to apic_intr_mode_init() for SMP-capable system.

Signed-off-by: Dou Liyang <douly.fnst@xxxxxxxxxxxxxx>
---
 arch/x86/kernel/apic/apic.c | 41 ++++++++++++++++++++++++++++++++++++++---
 arch/x86/kernel/smpboot.c   | 14 ++------------
 2 files changed, 40 insertions(+), 15 deletions(-)

diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 51536b9..4e24aaf 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1160,7 +1160,9 @@ void __init sync_Arb_IDs(void)
 enum apic_intr_mode {
        APIC_PIC,
        APIC_VIRTUAL_WIRE,
+       APIC_VIRTUAL_WIRE_NO_CONFIG,
        APIC_SYMMETRIC_IO,
+       APIC_SYMMETRIC_IO_NO_ROUTING,
 };
 
 static int __init apic_intr_mode_select(void)
@@ -1207,12 +1209,29 @@ static int __init apic_intr_mode_select(void)
        if (!smp_found_config) {
                disable_ioapic_support();
 
-               if (!acpi_lapic)
+               if (!acpi_lapic) {
                        pr_info("APIC: ACPI MADT or MP tables are not 
detected\n");
 
+                       return APIC_VIRTUAL_WIRE_NO_CONFIG;
+               }
+
                return APIC_VIRTUAL_WIRE;
        }
 
+#ifdef CONFIG_SMP
+       /* If SMP should be disabled, then really disable it! */
+       if (!setup_max_cpus) {
+               pr_info("APIC: SMP mode deactivated\n");
+               return APIC_SYMMETRIC_IO_NO_ROUTING;
+       }
+
+       if (read_apic_id() != boot_cpu_physical_apicid) {
+               panic("Boot APIC ID in local APIC unexpected (%d vs %d)",
+                    read_apic_id(), boot_cpu_physical_apicid);
+               /* Or can we switch back to PIC here? */
+       }
+#endif
+
        return APIC_SYMMETRIC_IO;
 }
 
@@ -1268,17 +1287,33 @@ void __init init_bsp_APIC(void)
 /* Init the interrupt delivery mode for the BSP */
 void __init apic_intr_mode_init(void)
 {
+       bool upmode = false;
+
        switch (apic_intr_mode_select()) {
        case APIC_PIC:
                pr_info("APIC: keep in PIC mode(8259)\n");
                return;
        case APIC_VIRTUAL_WIRE:
                pr_info("APIC: switch to virtual wire mode setup\n");
-               return;
+               default_setup_apic_routing();
+               break;
+       case APIC_VIRTUAL_WIRE_NO_CONFIG:
+               pr_info("APIC: switch to virtual wire mode setup "
+                       "with no configuration\n");
+               upmode = true;
+               default_setup_apic_routing();
+               break;
        case APIC_SYMMETRIC_IO:
                pr_info("APIC: switch to symmectic I/O mode setup\n");
-               return;
+               default_setup_apic_routing();
+               break;
+       case APIC_SYMMETRIC_IO_NO_ROUTING:
+               pr_info("APIC: switch to symmectic I/O mode setup "
+                       "in no SMP routine\n");
+               break;
        }
+
+       apic_bsp_setup(upmode);
 }
 
 static void lapic_setup_esr(void)
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 3f74288..a4b072d 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1329,18 +1329,17 @@ void __init native_smp_prepare_cpus(unsigned int 
max_cpus)
 
        set_cpu_sibling_map(0);
 
+       apic_intr_mode_init();
+
        switch (smp_sanity_check(max_cpus)) {
        case SMP_NO_CONFIG:
                disable_smp();
-               if (APIC_init_uniprocessor())
-                       pr_notice("Local APIC not detected. Using dummy APIC 
emulation.\n");
                return;
        case SMP_NO_APIC:
                disable_smp();
                return;
        case SMP_FORCE_UP:
                disable_smp();
-               apic_bsp_setup(false);
                /* Setup local timer */
                x86_init.timers.setup_percpu_clockev();
                return;
@@ -1348,15 +1347,6 @@ void __init native_smp_prepare_cpus(unsigned int 
max_cpus)
                break;
        }
 
-       if (read_apic_id() != boot_cpu_physical_apicid) {
-               panic("Boot APIC ID in local APIC unexpected (%d vs %d)",
-                    read_apic_id(), boot_cpu_physical_apicid);
-               /* Or can we switch back to PIC here? */
-       }
-
-       default_setup_apic_routing();
-       apic_bsp_setup(false);
-
        /* Setup local timer */
        x86_init.timers.setup_percpu_clockev();
 
-- 
2.5.5




_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

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