diff mbox

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

Message ID a8d9b8d0b6c908a570f3ee40c59ef20bd61a21e4.1498795030.git.douly.fnst@cn.fujitsu.com (mailing list archive)
State New, archived
Headers show

Commit Message

Dou Liyang June 30, 2017, 4:07 a.m. UTC
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   | 13 ++-----------
 2 files changed, 38 insertions(+), 16 deletions(-)

Comments

Thomas Gleixner July 2, 2017, 6:07 p.m. UTC | #1
On Fri, 30 Jun 2017, Dou Liyang wrote:
> -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;

That store and extra argument is pointless. 

> +
> +			return APIC_VIRTUAL_WIRE_NO_CONFIG;

You added an extra return code, which you can use exactly for that purpose
at the callsite.


Aside of that, if you use int * then use numbers, if you use bool then use
true/false. But mixing that is horrible.

> +		}

Thanks,

	tglx
Dou Liyang July 3, 2017, 2:34 a.m. UTC | #2
Hi Thomas,

At 07/03/2017 02:07 AM, Thomas Gleixner wrote:
> On Fri, 30 Jun 2017, Dou Liyang wrote:
>> -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;
>
> That store and extra argument is pointless.
>
>> +
>> +			return APIC_VIRTUAL_WIRE_NO_CONFIG;
>
> You added an extra return code, which you can use exactly for that purpose
> at the callsite.
>

Actually indeed. Great! Why didn't I think of that?

>
> Aside of that, if you use int * then use numbers, if you use bool then use
> true/false. But mixing that is horrible.
>

Yes, it is, I will remove the 'upmode' argument.


Thanks,

	dou.

>> +		}
>
> Thanks,
>
> 	tglx
>
>
>
diff mbox

Patch

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