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


Groups > linux.kernel > #1731490 > unrolled thread

[PATCH v9 00/12] Unify the interrupt delivery mode and do its setup in advance

Started byDou Liyang <douly.fnst@cn.fujitsu.com>
First post2017-09-13 11:20 +0200
Last post2017-09-13 11:20 +0200
Articles 13 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v9 00/12] Unify the interrupt delivery mode and do its setup in advance Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-09-13 11:20 +0200
    [PATCH v9 12/12] x86/apic: Remove the init_bsp_APIC() Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-09-13 11:20 +0200
    [PATCH v9] ACPI / init: Invoke early ACPI initialization earlier Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-09-13 11:20 +0200
    [PATCH v9 10/12] x86/xen: Bypass intr mode setup in enlighten_pv system Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-09-13 11:20 +0200
      Re: [Xen-devel] [PATCH v9 10/12] x86/xen: Bypass intr mode setup in  enlighten_pv system Juergen Gross <jgross@suse.com> - 2017-09-13 11:50 +0200
        Re: [Xen-devel] [PATCH v9 10/12] x86/xen: Bypass intr mode setup in  enlighten_pv system Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-09-13 12:10 +0200
      [PATCH v10 10/12] x86/xen: Bypass intr mode setup in enlighten_pv system Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-09-13 12:30 +0200
    [PATCH v9 03/12] x86/apic: Split local APIC timer setup from the APIC setup Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-09-13 11:20 +0200
    [PATCH v9 11/12] x86/time: Initialize interrupt mode behind timer init Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-09-13 11:20 +0200
    [PATCH v9 02/12] x86/apic: Prepare for unifying the interrupt delivery modes setup Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-09-13 11:20 +0200
    [PATCH v9 09/12] x86/init: add intr_mode_init to x86_init_ops Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-09-13 11:20 +0200
    [PATCH v9 05/12] x86/apic: Unify interrupt mode setup for SMP-capable system Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-09-13 11:20 +0200
    [PATCH v9 06/12] x86/apic: Mark the apic_intr_mode extern for sanity check cleanup Dou Liyang <douly.fnst@cn.fujitsu.com> - 2017-09-13 11:20 +0200

#1731490 — [PATCH v9 00/12] Unify the interrupt delivery mode and do its setup in advance

FromDou Liyang <douly.fnst@cn.fujitsu.com>
Date2017-09-13 11:20 +0200
Subject[PATCH v9 00/12] Unify the interrupt delivery mode and do its setup in advance
Message-ID<upbZU-5r0-7@gated-at.bofh.it>
Changes V8 --> V9:
  No functionality change, update and modify the comments.

  - [01/12] patch: modify the comments of apic_intr_mode_select().
       Currently, the check logic of BIOS is based on the original code,
    Baoquan and I have discussed it in V8 for readability, I am not sure
    that I can clean up it correctly, So keep it like before.

  - [06/12] patch: update the comments of init_apic_mappings()

  - [11/12] patch: update the comments of native_smp_prepare_cpus().

  - Post the patch putting acpi_early_init() earlier independently
    suggested by Rafael and Baoquan.

  - Rebase it

[Background]

MP specification defines three different interrupt delivery modes as follows:

 1. PIC Mode
 2. Virtual Wire Mode
 3. Symmetric I/O Mode

They will be setup in the different periods of booting time:
 1. *PIC Mode*, the default interrupt delivery modes, will be set first.
 2. *Virtual Wire Mode* will be setup during ISA IRQ initialization( step 1
    in the figure.1).
 3. *Symmetric I/O Mode*'s setup is related to the system
    3.1 In SMP-capable system, setup during prepares CPUs(step 2) 
    3.2 In UP system, setup during initializes itself(step 3).


 start_kernel
+---------------+
|
+--> .......
|
|    setup_arch
+--> +-------+
|
|    init_IRQ
+-> +--+-----+
|      |        init_ISA_irqs
|      +------> +-+--------+
|                 |         +----------------+
+--->             +------>  | 1.init_bsp_APIC|
|     .......               +----------------+
+--->
|     rest_init
+--->---+-----+
|       |   kernel_init
|       +> ----+-----+
|              |   kernel_init_freeable
|              +->  ----+-------------+
|                       |     smp_prepare_cpus
|                       +---> +----+---------+
|                       |          |   +-------------------+
|                       |          +-> |2.  apic_bsp_setup |
|                       |              +-------------------+
|                       |
v                       |     smp_init
                        +---> +---+----+
                                  |    +-------------------+
                                  +--> |3.  apic_bsp_setup |
                                       +-------------------+
    figure.1 The flow chart of the kernel startup process

[Problem]

1. Cause kernel in an unmatched mode at the beginning of booting time.
2. Cause the dump-capture kernel hangs with 'notsc' option inherited
   from 1st kernel option.
3. Cause the code hard to read and maintain.

As Ingo's and Eric's discusses[1,2], it need to be refactor.

[Solution]

1. Construct a selector to unify these switches

       +------------+
       |disable_apic+--------------------+
       +------------+       true         |
              |false                     |
              |                          |
 +------------v------------------+       |
 |!boot_cpu_has(X86_FEATURE_APIC)+-------+
 +-------------------------------+  true |
              |false                     |
              |                          |
      +-------v---------+                v
      |!smp_found_config|            PIC MODE
      +---------------+-+
       |false         |true
       |              |
       v          +---v---------+
SYMMETRIC IO MODE | !acpi_lapic |
                  +------+------+
                         |
                         v
                   VIRTUAL WIRE MODE 

2. Unifying these setup steps of SMP-capable and UP system

   start_kernel
---------------+
|
|
|
|    x86_late_time_init
+---->---+------------+
|        |
|        |      +------------------------+
|        +----> | 4. init_interrupt_mode |
|               +------------------------+
v


3. Execute the function as soon as possible.

[Link]

[1]. https://lkml.org/lkml/2016/8/2/929
[2]. https://lkml.org/lkml/2016/8/1/506

[History patches]
For previous discussion, please refer to:

  V8:  https://lkml.org/lkml/2017/8/27/265
  V7:  https://lkml.org/lkml/2017/7/14/20
  V6:  https://lkml.org/lkml/2017/7/3/269
  V5:  https://lkml.org/lkml/2017/6/30/17
  V3:  https://lkml.org/lkml/2017/5/10/323
  V2:  https://www.spinics.net/lists/kernel/msg2491620.html
  V1:  https://lkml.org/lkml/2017/3/29/481


Changes V7 --> V8:

  - Change the order of [12/13] patch and [11/13]patch suggested by Rafael J. Wysocki.
  - Fix some comments.
  - Do more tests in Thinkpad x121e   -- Thanks for Borislav Petkov's help.

Changes V6 --> V7:

  - add a new patch: p12

Changes V5 --> V6:

  - change the check order for X86_32 in apic_intr_mode_select()
  - replace the apic_printk with pr_info in apic_intr_mode_init()
  - add a separate helper function for get the logical apicid
  - remove the extra argument upmode in apic_intr_mode_select()
  - cleanup the logic of apic_intr_mode_init()
  - replcae the 'ticks = jiffies' with 'end = jiffies + 4'
  - rewrite the 9th and 10th patches's changelog

Changes V4 --> V5:

  - remove the RFC presix
  - remove the 1/12 patch in V4
  - merge 2 patches together for SMP-capable system
  - replace the *_interrupt_* with *_intr_*
  - replace the pr_info with apic_printk in apic_intr_mode_init()
  - add a patch for PV xen to bypass intr_mode_init()

Changes V3 --> V4:

  - Move interrupt_mode_init to x86_init_ops instead of the use of
    header files
  - Replace "return" with "break" in case of APIC_SYMMETRIC_IO_NO_ROUTING
  - Setup upmode earlier for UP system.
  - Check interrupt mode before per cpu clock event setup.

Changes V2 --> V3:

  - Rebase the patches.
  - Change two function name:
      apic_bsp_mode_check --> apic_interrupt_mode_select
      init_interrupt_mode --> apic_interrupt_mode_init
  - Find a new waiting way to check whether timer IRQs work or not
  - Refine the switch logic in apic_interrupt_mode_init()
  - Consistently start sentences with upper case letters
  - Fix some typos and comments
  - Try my best to rewrite some changelog again

Changes since V1: 

  - Move the initialization from init_IRQ() to x86_late_time_init()
  - Use a threshold to refactor the check logic in timer_irq_works()
  - Rename the framework to a selector
  - Split two patches
  - Consistently start sentences with upper case letters
  - Fix some typos
  - Rewrite the changelog

Cc: xen-devel@lists.xenproject.org
Cc: boris.ostrovsky@oracle.com
Cc: Juergen Gross <jgross@suse.com>
Cc: linux-acpi@vger.kernel.org
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Zheng, Lv <lv.zheng@intel.com>

Dou Liyang (12):
  x86/apic: Construct a selector for the interrupt delivery mode
  x86/apic: Prepare for unifying the interrupt delivery modes setup
  x86/apic: Split local APIC timer setup from the APIC setup
  x86/apic: Move logical APIC ID away from apic_bsp_setup()
  x86/apic: Unify interrupt mode setup for SMP-capable system
  x86/apic: Mark the apic_intr_mode extern for sanity check cleanup
  x86/apic: Unify interrupt mode setup for UP system
  x86/ioapic: Refactor the delay logic in timer_irq_works()
  x86/init: add intr_mode_init to x86_init_ops
  x86/xen: Bypass intr mode setup in enlighten_pv system
  x86/time: Initialize interrupt mode behind timer init
  x86/apic: Remove the init_bsp_APIC()

 arch/x86/include/asm/apic.h     |  15 +++-
 arch/x86/include/asm/x86_init.h |   2 +
 arch/x86/kernel/apic/apic.c     | 188 ++++++++++++++++++++--------------------
 arch/x86/kernel/apic/io_apic.c  |  45 +++++++++-
 arch/x86/kernel/irqinit.c       |   3 -
 arch/x86/kernel/smpboot.c       |  85 ++++++------------
 arch/x86/kernel/time.c          |   5 ++
 arch/x86/kernel/x86_init.c      |   1 +
 arch/x86/xen/enlighten_pv.c     |   1 +
 9 files changed, 184 insertions(+), 161 deletions(-)

-- 
2.5.5

[toc] | [next] | [standalone]


#1731491 — [PATCH v9 12/12] x86/apic: Remove the init_bsp_APIC()

FromDou Liyang <douly.fnst@cn.fujitsu.com>
Date2017-09-13 11:20 +0200
Subject[PATCH v9 12/12] x86/apic: Remove the init_bsp_APIC()
Message-ID<upbZU-5r0-17@gated-at.bofh.it>
In reply to#1731490
The init_bsp_APIC() which works for the virtual wire mode is used
in ISA irq initialization at the booting time.

Currently, enable and setup the interrupt mode has been unified
and advanced just behind the timer IRQ setup. Kernel switches to
the final interrupt delivery mode directly. So init_bsp_APIC()
is redundant.

Remove the init_bsp_APIC() function.

Signed-off-by: Dou Liyang <douly.fnst@cn.fujitsu.com>
---
 arch/x86/include/asm/apic.h |  1 -
 arch/x86/kernel/apic/apic.c | 49 ---------------------------------------------
 arch/x86/kernel/irqinit.c   |  3 ---
 3 files changed, 53 deletions(-)

diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 983a0dc..7d247b2 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -136,7 +136,6 @@ extern void disconnect_bsp_APIC(int virt_wire_setup);
 extern void disable_local_APIC(void);
 extern void lapic_shutdown(void);
 extern void sync_Arb_IDs(void);
-extern void init_bsp_APIC(void);
 extern void apic_intr_mode_init(void);
 extern void setup_local_APIC(void);
 extern void init_apic_mappings(void);
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 3d08649..a4ee367 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1282,55 +1282,6 @@ static int __init apic_intr_mode_select(void)
 	return APIC_SYMMETRIC_IO;
 }
 
-/*
- * An initial setup of the virtual wire mode.
- */
-void __init init_bsp_APIC(void)
-{
-	unsigned int value;
-
-	/*
-	 * Don't do the setup now if we have a SMP BIOS as the
-	 * through-I/O-APIC virtual wire mode might be active.
-	 */
-	if (smp_found_config || !boot_cpu_has(X86_FEATURE_APIC))
-		return;
-
-	/*
-	 * Do not trust the local APIC being empty at bootup.
-	 */
-	clear_local_APIC();
-
-	/*
-	 * Enable APIC.
-	 */
-	value = apic_read(APIC_SPIV);
-	value &= ~APIC_VECTOR_MASK;
-	value |= APIC_SPIV_APIC_ENABLED;
-
-#ifdef CONFIG_X86_32
-	/* This bit is reserved on P4/Xeon and should be cleared */
-	if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) &&
-	    (boot_cpu_data.x86 == 15))
-		value &= ~APIC_SPIV_FOCUS_DISABLED;
-	else
-#endif
-		value |= APIC_SPIV_FOCUS_DISABLED;
-	value |= SPURIOUS_APIC_VECTOR;
-	apic_write(APIC_SPIV, value);
-
-	/*
-	 * Set up the virtual wire mode.
-	 */
-	apic_write(APIC_LVT0, APIC_DM_EXTINT);
-	value = APIC_DM_NMI;
-	if (!lapic_is_integrated())		/* 82489DX */
-		value |= APIC_LVT_LEVEL_TRIGGER;
-	if (apic_extnmi == APIC_EXTNMI_NONE)
-		value |= APIC_LVT_MASKED;
-	apic_write(APIC_LVT1, value);
-}
-
 /* Init the interrupt delivery mode for the BSP */
 void __init apic_intr_mode_init(void)
 {
diff --git a/arch/x86/kernel/irqinit.c b/arch/x86/kernel/irqinit.c
index 1add9e0..beafcf5 100644
--- a/arch/x86/kernel/irqinit.c
+++ b/arch/x86/kernel/irqinit.c
@@ -60,9 +60,6 @@ void __init init_ISA_irqs(void)
 	struct irq_chip *chip = legacy_pic->chip;
 	int i;
 
-#if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)
-	init_bsp_APIC();
-#endif
 	legacy_pic->init(0);
 
 	for (i = 0; i < nr_legacy_irqs(); i++)
-- 
2.5.5

[toc] | [prev] | [next] | [standalone]


#1731493 — [PATCH v9] ACPI / init: Invoke early ACPI initialization earlier

FromDou Liyang <douly.fnst@cn.fujitsu.com>
Date2017-09-13 11:20 +0200
Subject[PATCH v9] ACPI / init: Invoke early ACPI initialization earlier
Message-ID<upbZU-5r0-25@gated-at.bofh.it>
In reply to#1731490
Linux uses acpi_early_init() to put the ACPI table management into the
late stage from the early stage. This two stages are different. the
mapped ACPI tables in early stage is temporary and should be unmapped,
but in late stage, it is permanent and don't need to be unmapped.

Originally, mapping and parsing the DMAR table should be in the late stage.
However, Initializing interrupt delivery mode earlier will move it into
the early stage. This causes an ACPI error warning when Linux reallocates
the ACPI root tables.

Commit b064a8fa77df ("ACPI / init: Switch over platform to the ACPI mode
later") splits the ACPI early initialization code into acpi_early_init()
and acpi_subsystem_init(). This makes acpi_early_init() more independently

So, invoke acpi_early_init() earlier before late_time_init(), Keep the DMAR
be mapped and parsed in late stage like before.

Reported-by: Xiaolong Ye <xiaolong.ye@intel.com>
Signed-off-by: Dou Liyang <douly.fnst@cn.fujitsu.com>
Cc: linux-acpi@vger.kernel.org
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Zheng, Lv <lv.zheng@intel.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Cc: x86@kernel.org
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Will Deacon <will.deacon@arm.com>
Cc: linux-arm-kernel@lists.infradead.org
Cc: Tony Luck <tony.luck@intel.com>
Cc: Fenghua Yu <fenghua.yu@intel.com>
Cc: linux-ia64@vger.kernel.org
Cc: yinghai@kernel.org
Cc: bhe@redhat.com
Cc: bp@alien8.de
---
 init/main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/init/main.c b/init/main.c
index 0ee9c686..2fb98a4 100644
--- a/init/main.c
+++ b/init/main.c
@@ -664,12 +664,12 @@ asmlinkage __visible void __init start_kernel(void)
 	debug_objects_mem_init();
 	setup_per_cpu_pageset();
 	numa_policy_init();
+	acpi_early_init();
 	if (late_time_init)
 		late_time_init();
 	calibrate_delay();
 	pidmap_init();
 	anon_vma_init();
-	acpi_early_init();
 #ifdef CONFIG_X86
 	if (efi_enabled(EFI_RUNTIME_SERVICES))
 		efi_enter_virtual_mode();
-- 
2.5.5

[toc] | [prev] | [next] | [standalone]


#1731494 — [PATCH v9 10/12] x86/xen: Bypass intr mode setup in enlighten_pv system

FromDou Liyang <douly.fnst@cn.fujitsu.com>
Date2017-09-13 11:20 +0200
Subject[PATCH v9 10/12] x86/xen: Bypass intr mode setup in enlighten_pv system
Message-ID<upbZV-5r0-29@gated-at.bofh.it>
In reply to#1731490
XEN PV overrides smp_prepare_cpus(). xen_pv_smp_prepare_cpus()
initializes interrupts in the XEN PV specific way and does not invoke
native_smp_prepare_cpus(). As a consequence, x86_init.intr_mode_init() is
not invoked either.

The invocation of x86_init.intr_mode_init() will be moved from
native_smp_prepare_cpus() in a follow up patch to solve <INSERT
REASON/PROBLEM>.

That move would cause the invocation of x86_init.intr_mode_init() for XEN
PV platforms. To prevent that, override the default x86_init.intr_mode_init()
callback with a noop().

[Rewrited by Thomas Gleixner <tglx@linutronix.de>]

Signed-off-by: Dou Liyang <douly.fnst@cn.fujitsu.com>
Cc: xen-devel@lists.xenproject.org
Cc: boris.ostrovsky@oracle.com
Cc: Juergen Gross <jgross@suse.com>
---
 arch/x86/xen/enlighten_pv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
index ae2a2e2..934dc7f 100644
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -1232,6 +1232,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
 	x86_platform.get_nmi_reason = xen_get_nmi_reason;
 
 	x86_init.resources.memory_setup = xen_memory_setup;
+	x86_init.irqs.intr_mode_init	= x86_init_noop;
 	x86_init.oem.arch_setup = xen_arch_setup;
 	x86_init.oem.banner = xen_banner;
 
-- 
2.5.5

[toc] | [prev] | [next] | [standalone]


#1731513 — Re: [Xen-devel] [PATCH v9 10/12] x86/xen: Bypass intr mode setup in enlighten_pv system

FromJuergen Gross <jgross@suse.com>
Date2017-09-13 11:50 +0200
SubjectRe: [Xen-devel] [PATCH v9 10/12] x86/xen: Bypass intr mode setup in enlighten_pv system
Message-ID<upcsV-5D0-1@gated-at.bofh.it>
In reply to#1731494
On 13/09/17 11:12, Dou Liyang wrote:
> XEN PV overrides smp_prepare_cpus(). xen_pv_smp_prepare_cpus()
> initializes interrupts in the XEN PV specific way and does not invoke
> native_smp_prepare_cpus(). As a consequence, x86_init.intr_mode_init() is
> not invoked either.
> 
> The invocation of x86_init.intr_mode_init() will be moved from
> native_smp_prepare_cpus() in a follow up patch to solve <INSERT
> REASON/PROBLEM>.

I asked you to be more specific here before. So: what will be solved?
Can I select a problem I like? ;-)

> That move would cause the invocation of x86_init.intr_mode_init() for XEN
> PV platforms. To prevent that, override the default x86_init.intr_mode_init()
> callback with a noop().
> 
> [Rewrited by Thomas Gleixner <tglx@linutronix.de>]

Rewritten?

> Signed-off-by: Dou Liyang <douly.fnst@cn.fujitsu.com>
> Cc: xen-devel@lists.xenproject.org
> Cc: boris.ostrovsky@oracle.com
> Cc: Juergen Gross <jgross@suse.com>

Regarding the changes below:

Acked-by: Juergen Gross <jgross@suse.com>


Juergen

> ---
>  arch/x86/xen/enlighten_pv.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
> index ae2a2e2..934dc7f 100644
> --- a/arch/x86/xen/enlighten_pv.c
> +++ b/arch/x86/xen/enlighten_pv.c
> @@ -1232,6 +1232,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
>  	x86_platform.get_nmi_reason = xen_get_nmi_reason;
>  
>  	x86_init.resources.memory_setup = xen_memory_setup;
> +	x86_init.irqs.intr_mode_init	= x86_init_noop;
>  	x86_init.oem.arch_setup = xen_arch_setup;
>  	x86_init.oem.banner = xen_banner;
>  
> 

[toc] | [prev] | [next] | [standalone]


#1731516 — Re: [Xen-devel] [PATCH v9 10/12] x86/xen: Bypass intr mode setup in enlighten_pv system

FromDou Liyang <douly.fnst@cn.fujitsu.com>
Date2017-09-13 12:10 +0200
SubjectRe: [Xen-devel] [PATCH v9 10/12] x86/xen: Bypass intr mode setup in enlighten_pv system
Message-ID<upcMh-60h-1@gated-at.bofh.it>
In reply to#1731513
Hi Juergen,

At 09/13/2017 05:45 PM, Juergen Gross wrote:
> On 13/09/17 11:12, Dou Liyang wrote:
>> XEN PV overrides smp_prepare_cpus(). xen_pv_smp_prepare_cpus()
>> initializes interrupts in the XEN PV specific way and does not invoke
>> native_smp_prepare_cpus(). As a consequence, x86_init.intr_mode_init() is
>> not invoked either.
>>
>> The invocation of x86_init.intr_mode_init() will be moved from
>> native_smp_prepare_cpus() in a follow up patch to solve <INSERT
>> REASON/PROBLEM>.
>
> I asked you to be more specific here before. So: what will be solved?
> Can I select a problem I like? ;-)

Oops, I am sorry I missed it. I will modify it.

...to solve the dump-capture kernel hangs, if there is a notsc option
in its command line.

>
>> That move would cause the invocation of x86_init.intr_mode_init() for XEN
>> PV platforms. To prevent that, override the default x86_init.intr_mode_init()
>> callback with a noop().
>>
>> [Rewrited by Thomas Gleixner <tglx@linutronix.de>]
>
> Rewritten?

Yeah, yeah. poor english skill :-).

>
>> Signed-off-by: Dou Liyang <douly.fnst@cn.fujitsu.com>
>> Cc: xen-devel@lists.xenproject.org
>> Cc: boris.ostrovsky@oracle.com
>> Cc: Juergen Gross <jgross@suse.com>
>
> Regarding the changes below:
>
> Acked-by: Juergen Gross <jgross@suse.com>
>

Thank you for your acked, I will re-post it.

Thanks,
	dou.
>
> Juergen
>
>> ---
>>  arch/x86/xen/enlighten_pv.c | 1 +
>>  1 file changed, 1 insertion(+)
>>
>> diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
>> index ae2a2e2..934dc7f 100644
>> --- a/arch/x86/xen/enlighten_pv.c
>> +++ b/arch/x86/xen/enlighten_pv.c
>> @@ -1232,6 +1232,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
>>  	x86_platform.get_nmi_reason = xen_get_nmi_reason;
>>
>>  	x86_init.resources.memory_setup = xen_memory_setup;
>> +	x86_init.irqs.intr_mode_init	= x86_init_noop;
>>  	x86_init.oem.arch_setup = xen_arch_setup;
>>  	x86_init.oem.banner = xen_banner;
>>
>>
>
>
>
>

[toc] | [prev] | [next] | [standalone]


#1731524 — [PATCH v10 10/12] x86/xen: Bypass intr mode setup in enlighten_pv system

FromDou Liyang <douly.fnst@cn.fujitsu.com>
Date2017-09-13 12:30 +0200
Subject[PATCH v10 10/12] x86/xen: Bypass intr mode setup in enlighten_pv system
Message-ID<upd5D-677-5@gated-at.bofh.it>
In reply to#1731494
XEN PV overrides smp_prepare_cpus(). xen_pv_smp_prepare_cpus()
initializes interrupts in the XEN PV specific way and does not invoke
native_smp_prepare_cpus(). As a consequence, x86_init.intr_mode_init() is
not invoked either.

The invocation of x86_init.intr_mode_init() will be moved from
native_smp_prepare_cpus() in a follow up patch to solve the dump-capture
kernel hangs, if there is a notsc option in its command line.

That move would cause the invocation of x86_init.intr_mode_init() for XEN
PV platforms. To prevent that, override the default x86_init.intr_mode_init()
callback with a noop().

[Rewritten by Thomas Gleixner <tglx@linutronix.de>]

Signed-off-by: Dou Liyang <douly.fnst@cn.fujitsu.com>
Acked-by: Juergen Gross <jgross@suse.com>
Cc: xen-devel@lists.xenproject.org
Cc: boris.ostrovsky@oracle.com
Cc: Juergen Gross <jgross@suse.com>
---
V10 --> V9:
 --Modify the changelog, suggested by Juergen
 arch/x86/xen/enlighten_pv.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/x86/xen/enlighten_pv.c b/arch/x86/xen/enlighten_pv.c
index ae2a2e2..934dc7f 100644
--- a/arch/x86/xen/enlighten_pv.c
+++ b/arch/x86/xen/enlighten_pv.c
@@ -1232,6 +1232,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
 	x86_platform.get_nmi_reason = xen_get_nmi_reason;
 
 	x86_init.resources.memory_setup = xen_memory_setup;
+	x86_init.irqs.intr_mode_init	= x86_init_noop;
 	x86_init.oem.arch_setup = xen_arch_setup;
 	x86_init.oem.banner = xen_banner;
 
-- 
2.5.5

[toc] | [prev] | [next] | [standalone]


#1731497 — [PATCH v9 03/12] x86/apic: Split local APIC timer setup from the APIC setup

FromDou Liyang <douly.fnst@cn.fujitsu.com>
Date2017-09-13 11:20 +0200
Subject[PATCH v9 03/12] x86/apic: Split local APIC timer setup from the APIC setup
Message-ID<upbZV-5r0-33@gated-at.bofh.it>
In reply to#1731490
apic_bsp_setup() sets up the local APIC, I/O APIC and APIC timer.

The local APIC and I/O APIC setup belongs to interrupt delivery mode
setup. Setting up the local APIC timer for booting CPU is another job
and has nothing to do with interrupt delivery mode setup.

Split local APIC timer setup from the APIC setup, keep it in the
original position for SMP and UP kernel for preparation.

Signed-off-by: Dou Liyang <douly.fnst@cn.fujitsu.com>
---
 arch/x86/kernel/apic/apic.c | 4 ++--
 arch/x86/kernel/smpboot.c   | 5 +++++
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 08585bc..ad37324 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -2397,8 +2397,6 @@ int __init apic_bsp_setup(bool upmode)
 	end_local_APIC_setup();
 	irq_remap_enable_fault_handling();
 	setup_IO_APIC();
-	/* Setup local timer */
-	x86_init.timers.setup_percpu_clockev();
 	return id;
 }
 
@@ -2438,6 +2436,8 @@ int __init APIC_init_uniprocessor(void)
 
 	default_setup_apic_routing();
 	apic_bsp_setup(true);
+	/* Setup local timer */
+	x86_init.timers.setup_percpu_clockev();
 	return 0;
 }
 
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index cd6622c..dde8f1c 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1337,6 +1337,8 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
 	case SMP_FORCE_UP:
 		disable_smp();
 		apic_bsp_setup(false);
+		/* Setup local timer */
+		x86_init.timers.setup_percpu_clockev();
 		return;
 	case SMP_OK:
 		break;
@@ -1351,6 +1353,9 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
 	default_setup_apic_routing();
 	cpu0_logical_apicid = apic_bsp_setup(false);
 
+	/* Setup local timer */
+	x86_init.timers.setup_percpu_clockev();
+
 	pr_info("CPU0: ");
 	print_cpu_info(&cpu_data(0));
 
-- 
2.5.5

[toc] | [prev] | [next] | [standalone]


#1731498 — [PATCH v9 11/12] x86/time: Initialize interrupt mode behind timer init

FromDou Liyang <douly.fnst@cn.fujitsu.com>
Date2017-09-13 11:20 +0200
Subject[PATCH v9 11/12] x86/time: Initialize interrupt mode behind timer init
Message-ID<upbZV-5r0-39@gated-at.bofh.it>
In reply to#1731490
In start_kernel(), firstly, it works on the default interrupy mode, then
switch to the final mode. Normally, Booting with BIOS reset is OK.

But, At dump-capture kernel, it boot up without BIOS reset, default mode
may not be compatible with the actual registers, that causes the delivery
interrupt to fail.

Try to set up the final mode as soon as possible. according to the parts
which split from that initialization:

1) Set up the APIC/IOAPIC (including testing whether the timer
   interrupt works)

2) Calibrate TSC

3) Set up the local APIC timer

-- From Thomas Gleixner

Initializing the mode should be earlier than calibrating TSC as soon as
possible and needs testing whether the timer interrupt works at the same
time.

call it behind timers init, which meets the above conditions.

Signed-off-by: Dou Liyang <douly.fnst@cn.fujitsu.com>
---
 arch/x86/kernel/apic/apic.c | 2 --
 arch/x86/kernel/smpboot.c   | 7 +++----
 arch/x86/kernel/time.c      | 5 +++++
 3 files changed, 8 insertions(+), 6 deletions(-)

diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 8dbcff2..3d08649 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -2423,8 +2423,6 @@ void __init apic_bsp_setup(bool upmode)
 #ifdef CONFIG_UP_LATE_INIT
 void __init up_late_init(void)
 {
-	x86_init.irqs.intr_mode_init();
-
 	if (apic_intr_mode == APIC_PIC)
 		return;
 
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 76fc857..6263d63 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1260,8 +1260,9 @@ static void __init smp_get_logical_apicid(void)
 }
 
 /*
- * Prepare for SMP bootup.  The MP table or ACPI has been read
- * earlier.  Just do some sanity checking here and enable APIC mode.
+ * Prepare for SMP bootup.
+ * @max_cpus: configured maximum number of CPUs, It is a legacy parameter
+ *            for common interface support.
  */
 void __init native_smp_prepare_cpus(unsigned int max_cpus)
 {
@@ -1293,8 +1294,6 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
 
 	set_cpu_sibling_map(0);
 
-	x86_init.irqs.intr_mode_init();
-
 	smp_sanity_check();
 
 	switch (apic_intr_mode) {
diff --git a/arch/x86/kernel/time.c b/arch/x86/kernel/time.c
index e0754cd..3ceb834 100644
--- a/arch/x86/kernel/time.c
+++ b/arch/x86/kernel/time.c
@@ -84,6 +84,11 @@ void __init hpet_time_init(void)
 static __init void x86_late_time_init(void)
 {
 	x86_init.timers.timer_init();
+	/*
+	 * After PIT/HPET timers init, select and setup
+	 * the final interrupt mode for delivering IRQs.
+	 */
+	x86_init.irqs.intr_mode_init();
 	tsc_init();
 }
 
-- 
2.5.5

[toc] | [prev] | [next] | [standalone]


#1731499 — [PATCH v9 02/12] x86/apic: Prepare for unifying the interrupt delivery modes setup

FromDou Liyang <douly.fnst@cn.fujitsu.com>
Date2017-09-13 11:20 +0200
Subject[PATCH v9 02/12] x86/apic: Prepare for unifying the interrupt delivery modes setup
Message-ID<upbZV-5r0-41@gated-at.bofh.it>
In reply to#1731490
There are three positions for initializing the interrupt delivery
modes:

1) In IRQ initial function, may setup the through-local-APIC
   virtual wire mode.

2) In an SMP-capable system, will try to switch to symmetric I/O
   model when preparing the cpus in native_smp_prepare_cpus().

3) In UP system with UP_LATE_INIT=y, will set up local APIC and
   I/O APIC in smp_init().

Switching to symmetric I/O mode is so late, which causes kernel
in an unmatched mode at the beginning of booting time. And it
causes the dump-capture kernel hangs with 'notsc' option inherited
from 1st kernel option.

Provide a new function to unify that three positions. Preparatory
patch to initialize an interrupt mode directly.

Signed-off-by: Dou Liyang <douly.fnst@cn.fujitsu.com>
---
 arch/x86/include/asm/apic.h |  2 ++
 arch/x86/kernel/apic/apic.c | 16 ++++++++++++++++
 2 files changed, 18 insertions(+)

diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 5f01671..1a970f5 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -128,6 +128,7 @@ extern void disable_local_APIC(void);
 extern void lapic_shutdown(void);
 extern void sync_Arb_IDs(void);
 extern void init_bsp_APIC(void);
+extern void apic_intr_mode_init(void);
 extern void setup_local_APIC(void);
 extern void init_apic_mappings(void);
 void register_lapic_address(unsigned long address);
@@ -170,6 +171,7 @@ static inline void disable_local_APIC(void) { }
 # define setup_boot_APIC_clock x86_init_noop
 # define setup_secondary_APIC_clock x86_init_noop
 static inline void lapic_update_tsc_freq(void) { }
+static inline void apic_intr_mode_init(void) { }
 #endif /* !CONFIG_X86_LOCAL_APIC */
 
 #ifdef CONFIG_X86_X2APIC
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 39cb8c1..08585bc 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1319,6 +1319,22 @@ void __init init_bsp_APIC(void)
 	apic_write(APIC_LVT1, value);
 }
 
+/* Init the interrupt delivery mode for the BSP */
+void __init apic_intr_mode_init(void)
+{
+	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;
+	case APIC_SYMMETRIC_IO:
+		pr_info("APIC: Switch to symmectic I/O mode setup\n");
+		return;
+	}
+}
+
 static void lapic_setup_esr(void)
 {
 	unsigned int oldvalue, value, maxlvt;
-- 
2.5.5

[toc] | [prev] | [next] | [standalone]


#1731501 — [PATCH v9 09/12] x86/init: add intr_mode_init to x86_init_ops

FromDou Liyang <douly.fnst@cn.fujitsu.com>
Date2017-09-13 11:20 +0200
Subject[PATCH v9 09/12] x86/init: add intr_mode_init to x86_init_ops
Message-ID<upbZW-5r0-45@gated-at.bofh.it>
In reply to#1731490
X86 and XEN initialize interrupt delivery mode in different way.

Ordinary conditional function calls will make the code mess.

Add an unconditional x86_init_ops function which defaults to the
standard function and can be overridden by the early platform code.

Signed-off-by: Dou Liyang <douly.fnst@cn.fujitsu.com>
---
 arch/x86/include/asm/x86_init.h | 2 ++
 arch/x86/kernel/apic/apic.c     | 2 +-
 arch/x86/kernel/smpboot.c       | 2 +-
 arch/x86/kernel/x86_init.c      | 1 +
 4 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index 7ba7e90..f45acdf 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -50,11 +50,13 @@ struct x86_init_resources {
  *				are set up.
  * @intr_init:			interrupt init code
  * @trap_init:			platform specific trap setup
+ * @intr_mode_init:		interrupt delivery mode setup
  */
 struct x86_init_irqs {
 	void (*pre_vector_init)(void);
 	void (*intr_init)(void);
 	void (*trap_init)(void);
+	void (*intr_mode_init)(void);
 };
 
 /**
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index efc5fbd..8dbcff2 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -2423,7 +2423,7 @@ void __init apic_bsp_setup(bool upmode)
 #ifdef CONFIG_UP_LATE_INIT
 void __init up_late_init(void)
 {
-	apic_intr_mode_init();
+	x86_init.irqs.intr_mode_init();
 
 	if (apic_intr_mode == APIC_PIC)
 		return;
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index fa535d4..76fc857 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1293,7 +1293,7 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
 
 	set_cpu_sibling_map(0);
 
-	apic_intr_mode_init();
+	x86_init.irqs.intr_mode_init();
 
 	smp_sanity_check();
 
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index a088b2c..a7889b9 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -55,6 +55,7 @@ struct x86_init_ops x86_init __initdata = {
 		.pre_vector_init	= init_ISA_irqs,
 		.intr_init		= native_init_IRQ,
 		.trap_init		= x86_init_noop,
+		.intr_mode_init		= apic_intr_mode_init
 	},
 
 	.oem = {
-- 
2.5.5

[toc] | [prev] | [next] | [standalone]


#1731502 — [PATCH v9 05/12] x86/apic: Unify interrupt mode setup for SMP-capable system

FromDou Liyang <douly.fnst@cn.fujitsu.com>
Date2017-09-13 11:20 +0200
Subject[PATCH v9 05/12] x86/apic: Unify interrupt mode setup for SMP-capable system
Message-ID<upbZW-5r0-55@gated-at.bofh.it>
In reply to#1731490
In the SMP-capable system, Linux enables and setups the interrupt
delivery mode by 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 | 38 +++++++++++++++++++++++++++++++++++---
 arch/x86/kernel/smpboot.c   | 14 ++------------
 2 files changed, 37 insertions(+), 15 deletions(-)

diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index eafed8f..7ae97c2 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1221,7 +1221,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)
@@ -1262,11 +1264,27 @@ static int __init apic_intr_mode_select(void)
 	/* Check MP table or ACPI MADT configuration */
 	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;
 }
 
@@ -1322,17 +1340,31 @@ 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 82f2e79..73d95f2 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1333,18 +1333,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;
@@ -1352,15 +1351,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

[toc] | [prev] | [next] | [standalone]


#1731503 — [PATCH v9 06/12] x86/apic: Mark the apic_intr_mode extern for sanity check cleanup

FromDou Liyang <douly.fnst@cn.fujitsu.com>
Date2017-09-13 11:20 +0200
Subject[PATCH v9 06/12] x86/apic: Mark the apic_intr_mode extern for sanity check cleanup
Message-ID<upbZW-5r0-53@gated-at.bofh.it>
In reply to#1731490
Calling native_smp_prepare_cpus() to prepare for SMP bootup, does
some sanity checking, enables APIC mode and disables SMP feature.

Now, APIC mode setup has been unified to apic_intr_mode_init(),
some sanity checks are redundant and need to be cleanup.

Mark the apic_intr_mode extern to refine the switch and remove
the redundant sanity check.

Signed-off-by: Dou Liyang <douly.fnst@cn.fujitsu.com>
---
 arch/x86/include/asm/apic.h |  9 +++++++
 arch/x86/kernel/apic/apic.c | 16 +++++--------
 arch/x86/kernel/smpboot.c   | 57 +++++++--------------------------------------
 3 files changed, 24 insertions(+), 58 deletions(-)

diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 4e550c7..01f3fc8 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -53,6 +53,15 @@ extern int local_apic_timer_c2_ok;
 extern int disable_apic;
 extern unsigned int lapic_timer_frequency;
 
+extern enum apic_intr_mode_id apic_intr_mode;
+enum apic_intr_mode_id {
+	APIC_PIC,
+	APIC_VIRTUAL_WIRE,
+	APIC_VIRTUAL_WIRE_NO_CONFIG,
+	APIC_SYMMETRIC_IO,
+	APIC_SYMMETRIC_IO_NO_ROUTING
+};
+
 #ifdef CONFIG_SMP
 extern void __inquire_remote_apic(int apicid);
 #else /* CONFIG_SMP */
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 7ae97c2..21d584d 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1218,13 +1218,7 @@ void __init sync_Arb_IDs(void)
 			APIC_INT_LEVELTRIG | APIC_DM_INIT);
 }
 
-enum apic_intr_mode {
-	APIC_PIC,
-	APIC_VIRTUAL_WIRE,
-	APIC_VIRTUAL_WIRE_NO_CONFIG,
-	APIC_SYMMETRIC_IO,
-	APIC_SYMMETRIC_IO_NO_ROUTING,
-};
+enum apic_intr_mode_id apic_intr_mode;
 
 static int __init apic_intr_mode_select(void)
 {
@@ -1342,7 +1336,9 @@ void __init apic_intr_mode_init(void)
 {
 	bool upmode = false;
 
-	switch (apic_intr_mode_select()) {
+	apic_intr_mode = apic_intr_mode_select();
+
+	switch (apic_intr_mode) {
 	case APIC_PIC:
 		pr_info("APIC: Keep in PIC mode(8259)\n");
 		return;
@@ -1974,8 +1970,8 @@ void __init init_apic_mappings(void)
 		 * yeah -- we lie about apic_version
 		 * in case if apic was disabled via boot option
 		 * but it's not a problem for SMP compiled kernel
-		 * since smp_sanity_check is prepared for such a case
-		 * and disable smp mode
+		 * since apic_intr_mode_select is prepared for such
+		 * a case and disable smp mode
 		 */
 		boot_cpu_apic_version = GET_APIC_VERSION(apic_read(APIC_LVR));
 	}
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index 73d95f2..fa535d4 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -1187,17 +1187,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();
 
@@ -1235,16 +1228,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.
 	 */
@@ -1254,29 +1237,6 @@ static int __init smp_sanity_check(unsigned max_cpus)
 		physid_set(hard_smp_processor_id(), phys_cpu_present_map);
 	}
 	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)
@@ -1335,19 +1295,20 @@ void __init native_smp_prepare_cpus(unsigned int max_cpus)
 
 	apic_intr_mode_init();
 
-	switch (smp_sanity_check(max_cpus)) {
-	case SMP_NO_CONFIG:
-		disable_smp();
-		return;
-	case SMP_NO_APIC:
+	smp_sanity_check();
+
+	switch (apic_intr_mode) {
+	case APIC_PIC:
+	case APIC_VIRTUAL_WIRE_NO_CONFIG:
 		disable_smp();
 		return;
-	case SMP_FORCE_UP:
+	case APIC_SYMMETRIC_IO_NO_ROUTING:
 		disable_smp();
 		/* Setup local timer */
 		x86_init.timers.setup_percpu_clockev();
 		return;
-	case SMP_OK:
+	case APIC_VIRTUAL_WIRE:
+	case APIC_SYMMETRIC_IO:
 		break;
 	}
 
-- 
2.5.5

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web