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

[Xen-devel] [PATCH v5 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   | 13 ++-----------
 2 files changed, 38 insertions(+), 16 deletions(-)

diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 498edbe..bea8032 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1160,10 +1160,12 @@ 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)
+static int __init apic_intr_mode_select(int *upmode)
 {
        /* Check kernel option */
        if (disable_apic) {
@@ -1206,12 +1208,30 @@ 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");
+                       *upmode = true;
+
+                       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
+
        /* Other checks of APIC options will be done in each setup function */
 
        return APIC_SYMMETRIC_IO;
@@ -1269,20 +1289,31 @@ void __init init_bsp_APIC(void)
 /* Init the interrupt delivery mode for the BSP */
 void __init apic_intr_mode_init(void)
 {
-       switch (apic_intr_mode_select()) {
+       int upmode = false;
+
+       switch (apic_intr_mode_select(&upmode)) {
        case APIC_PIC:
                apic_printk(APIC_VERBOSE, KERN_INFO
                        "Keep in PIC mode(8259)\n");
                return;
        case APIC_VIRTUAL_WIRE:
+       case APIC_VIRTUAL_WIRE_NO_CONFIG:
                apic_printk(APIC_VERBOSE, KERN_INFO
                        "Switch to virtual wire mode setup\n");
-               return;
+               default_setup_apic_routing();
+               break;
        case APIC_SYMMETRIC_IO:
                apic_printk(APIC_VERBOSE, KERN_INFO
                        "Switch to symmectic I/O mode setup\n");
-               return;
+               default_setup_apic_routing();
+               break;
+       case APIC_SYMMETRIC_IO_NO_ROUTING:
+               apic_printk(APIC_VERBOSE, KERN_INFO
+                       "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 d6721f0..b9b2a43 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1321,18 +1321,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;
@@ -1340,14 +1339,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);
        if (x2apic_mode)
                cpu0_logical_apicid = apic_read(APIC_LDR);
        else
-- 
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®.