Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932172AbdC2O4Q (ORCPT ); Wed, 29 Mar 2017 10:56:16 -0400 Received: from cn.fujitsu.com ([59.151.112.132]:37913 "EHLO heian.cn.fujitsu.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1752891AbdC2O4E (ORCPT ); Wed, 29 Mar 2017 10:56:04 -0400 X-IronPort-AV: E=Sophos;i="5.22,518,1449504000"; d="scan'208";a="17139562" From: Dou Liyang To: , CC: , , , , , , Dou Liyang Subject: [RFC PATCH 5/6] x86/apic: Make the APIC mode setup earlier for UP system Date: Wed, 29 Mar 2017 22:55:32 +0800 Message-ID: <1490799333-18242-6-git-send-email-douly.fnst@cn.fujitsu.com> X-Mailer: git-send-email 2.5.5 In-Reply-To: <1490799333-18242-1-git-send-email-douly.fnst@cn.fujitsu.com> References: <1490799333-18242-1-git-send-email-douly.fnst@cn.fujitsu.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.167.226.106] X-yoursite-MailScanner-ID: 635CF47EE1E3.A4C24 X-yoursite-MailScanner: Found to be clean X-yoursite-MailScanner-From: douly.fnst@cn.fujitsu.com Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6997 Lines: 271 The SMP-capable system has already enable and setup the APIC mode as soon as possible. Do it for UP system and make the code clear. Signed-off-by: Dou Liyang --- arch/x86/include/asm/apic.h | 2 ++ arch/x86/kernel/apic/apic.c | 81 +++++++++++++++++---------------------------- arch/x86/kernel/smpboot.c | 58 ++++---------------------------- 3 files changed, 38 insertions(+), 103 deletions(-) diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h index be2abc3..fb06fe5 100644 --- a/arch/x86/include/asm/apic.h +++ b/arch/x86/include/asm/apic.h @@ -55,6 +55,8 @@ extern unsigned int lapic_timer_frequency; #ifdef CONFIG_SMP extern void __inquire_remote_apic(int apicid); +extern int disable_smp_by_APIC; + #else /* CONFIG_SMP */ static inline void __inquire_remote_apic(int apicid) { diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c index ce8f88d..c93c33d 100644 --- a/arch/x86/kernel/apic/apic.c +++ b/arch/x86/kernel/apic/apic.c @@ -169,6 +169,9 @@ __setup("apicpmtimer", setup_apicpmtimer); unsigned long mp_lapic_addr; int disable_apic; +/* disable smp flag according to APIC configuration */ +int disable_smp_by_APIC; + /* Disable local APIC timer from the kernel commandline or via dmi quirk */ static int disable_apic_timer __initdata; /* Local APIC timer works in C2 */ @@ -1157,13 +1160,13 @@ enum apic_bsp_mode { APIC_BSP_MODEL_PIC = 0, APIC_BSP_MODEL_VIRTUAL_WIRE, APIC_BSP_MODEL_SYMMETRIC_IO, + APIC_BSP_MODEL_SYMMETRIC_IO_NO_CONFIG, APIC_BSP_MODEL_SYMMETRIC_IO_NO_ROUTING, APIC_BSP_MODEL_COUNT }; -static int __init apic_bsp_mode_check(void) +static int __init apic_bsp_mode_check(int *upmode) { - /* Check kernel option */ if (disable_apic) { pr_info("APIC disabled by kernel option\n"); @@ -1200,8 +1203,11 @@ static int __init apic_bsp_mode_check(void) disable_ioapic_support(); /* Check local APIC, if SMP_NO_CONFIG */ - if (!acpi_lapic) - pr_info("SMP motherboard not detected\n"); + if (!acpi_lapic) { + *upmode = true; + pr_info("SMP motherboard not detected.\n"); + return APIC_BSP_MODEL_SYMMETRIC_IO_NO_CONFIG; + } return APIC_BSP_MODEL_VIRTUAL_WIRE; } @@ -1229,7 +1235,13 @@ static int __init apic_bsp_mode_check(void) return APIC_BSP_MODEL_SYMMETRIC_IO; #else - return APIC_BSP_MODEL_PIC; +#ifdef CONFIG_UP_LATE_INIT + /* In UP system, If it supports late init */ + *upmode = true; + return APIC_BSP_MODEL_SYMMETRIC_IO; +#else + return APIC_BSP_MODEL_PIC; +#endif #endif } @@ -1285,9 +1297,12 @@ void apic_virture_wire_mode_setup(void) /* init the interrupt routing model for the BSP */ void __init init_bsp_APIC(void) { - switch (apic_bsp_mode_check()) { + int upmode = false; + + switch (apic_bsp_mode_check(&upmode)) { case APIC_BSP_MODEL_PIC: pr_info("Keep in PIC mode(8259)\n"); + disable_smp_by_APIC = 1; return; case APIC_BSP_MODEL_VIRTUAL_WIRE: pr_info("switch to virtual wire model.\n"); @@ -1295,13 +1310,17 @@ void __init init_bsp_APIC(void) case APIC_BSP_MODEL_SYMMETRIC_IO: pr_info("switch to symmectic I/O model.\n"); default_setup_apic_routing(); - apic_bsp_setup(false); - return; + break; + case APIC_BSP_MODEL_SYMMETRIC_IO_NO_CONFIG: + pr_info("switch to symmectic I/O model with no SMP config.\n"); + disable_smp_by_APIC = 2; + default_setup_apic_routing(); + break; case APIC_BSP_MODEL_SYMMETRIC_IO_NO_ROUTING: pr_info("switch to symmectic I/O model with no apic routing.\n"); - apic_bsp_setup(false); - return; + break; } + apic_bsp_setup(upmode); } static void lapic_setup_esr(void) @@ -2392,50 +2411,10 @@ void __init apic_bsp_setup(bool upmode) setup_IO_APIC(); } -/* - * This initializes the IO-APIC and APIC hardware if this is - * a UP kernel. - */ -int __init APIC_init_uniprocessor(void) -{ - if (disable_apic) { - pr_info("Apic disabled\n"); - return -1; - } -#ifdef CONFIG_X86_64 - if (!boot_cpu_has(X86_FEATURE_APIC)) { - disable_apic = 1; - pr_info("Apic disabled by BIOS\n"); - return -1; - } -#else - if (!smp_found_config && !boot_cpu_has(X86_FEATURE_APIC)) - return -1; - - /* - * Complain if the BIOS pretends there is one. - */ - if (!boot_cpu_has(X86_FEATURE_APIC) && - APIC_INTEGRATED(boot_cpu_apic_version)) { - pr_err("BIOS bug, local APIC 0x%x not detected!...\n", - boot_cpu_physical_apicid); - return -1; - } -#endif - - if (!smp_found_config) - disable_ioapic_support(); - - default_setup_apic_routing(); - apic_bsp_setup(true); - apic_bsp_timer_setup(); - return 0; -} - #ifdef CONFIG_UP_LATE_INIT void __init up_late_init(void) { - APIC_init_uniprocessor(); + apic_bsp_timer_setup(); } #endif diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c index a556281..b7a810c 100644 --- a/arch/x86/kernel/smpboot.c +++ b/arch/x86/kernel/smpboot.c @@ -1183,17 +1183,10 @@ static __init void disable_smp(void) cpumask_set_cpu(0, topology_core_cpumask(0)); } -enum { - SMP_OK, - SMP_NO_CONFIG, - SMP_NO_APIC, - SMP_FORCE_UP, -}; - /* * Various sanity checks. */ -static int __init smp_sanity_check(unsigned max_cpus) +static void __init smp_sanity_check(void) { preempt_disable(); @@ -1231,16 +1224,6 @@ static int __init smp_sanity_check(unsigned max_cpus) } /* - * If we couldn't find an SMP configuration at boot time, - * get out of here now! - */ - if (!smp_found_config && !acpi_lapic) { - preempt_enable(); - pr_notice("SMP motherboard not detected\n"); - return SMP_NO_CONFIG; - } - - /* * Should not be necessary because the MP table should list the boot * CPU too, but we do it for the sake of robustness anyway. */ @@ -1251,28 +1234,6 @@ static int __init smp_sanity_check(unsigned max_cpus) } preempt_enable(); - /* - * If we couldn't find a local APIC, then get out of here now! - */ - if (APIC_INTEGRATED(boot_cpu_apic_version) && - !boot_cpu_has(X86_FEATURE_APIC)) { - if (!disable_apic) { - pr_err("BIOS bug, local APIC #%d not detected!...\n", - boot_cpu_physical_apicid); - pr_err("... forcing use of dummy APIC emulation (tell your hw vendor)\n"); - } - return SMP_NO_APIC; - } - - /* - * If SMP should be disabled, then really disable it! - */ - if (!max_cpus) { - pr_info("SMP mode deactivated\n"); - return SMP_FORCE_UP; - } - - return SMP_OK; } static void __init smp_cpu_index_default(void) @@ -1321,20 +1282,13 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus) set_cpu_sibling_map(0); - 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: + smp_sanity_check(); + + if (disable_smp_by_APIC) { + if (disable_smp_by_APIC == 2) + apic_bsp_timer_setup(); disable_smp(); return; - case SMP_OK: - break; } cpu0_logical_apicid = apic_bsp_timer_setup(); -- 2.5.5