Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1679891

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

From Dou Liyang <douly.fnst@cn.fujitsu.com>
Newsgroups linux.kernel
Subject [PATCH v6 05/12] x86/apic: Unify interrupt mode setup for SMP-capable system
Date 2017-07-03 13:10 +0200
Message-ID <tZ7oS-xQ-25@gated-at.bofh.it> (permalink)
References <tZ7oR-xQ-7@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


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@cn.fujitsu.com>
---
 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

Back to linux.kernel | Previous | NextPrevious in thread | Next in thread | Find similar | Unroll thread


Thread

[PATCH v6 00/12] Unify the interrupt delivery mode and do its setup in advance Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-07-03 13:10 +0200
  [PATCH v6 08/12] x86/ioapic: Refactor the delay logic in timer_irq_works() Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-07-03 13:10 +0200
  [PATCH v6 05/12] x86/apic: Unify interrupt mode setup for SMP-capable system Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-07-03 13:10 +0200
  [PATCH v6 10/12] x86/xen: Bypass intr mode setup in enlighten_pv system Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-07-03 13:10 +0200
  [PATCH v6 04/12] x86/apic: Move logical APIC ID away from apic_bsp_setup() Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-07-03 13:10 +0200
  [PATCH v6 01/12] x86/apic: Construct a selector for the interrupt delivery mode Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-07-03 13:20 +0200
  [PATCH v6 06/12] x86/apic: Mark the apic_intr_mode extern for sanity check cleanup Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-07-03 13:20 +0200
  [PATCH v6 03/12] x86/apic: Split local APIC timer setup from the APIC setup Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-07-03 13:20 +0200
  [PATCH v6 09/12] x86/init: add intr_mode_init to x86_init_ops Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-07-03 13:20 +0200

csiph-web