提交 0aa002fe 编写于 作者: T Tejun Heo 提交者: Thomas Gleixner

x86: apic: Cleanup and simplify setup_local_APIC()

setup_local_APIC() is used to setup local APIC early during CPU
initialization and already assumes that preemption is disabled on
entry. However, The function unnecessarily disables and enables
preemption and uses smp_processor_id() multiple times in and out of
the nested preemption disabled section. This gives the wrong
impression that the function might be able to handle being called with
preemption enabled and/or migrated to another processor in the middle.

Make it clear that the function is always called with preemption
disabled, drop the confusing preemption disable block and call
smp_processor_id() once at the beginning of the function.
Signed-off-by: NTejun Heo <tj@kernel.org>
Acked-by: NCyrill Gorcunov <gorcunov@gmail.com>
Reviewed-by: NPekka Enberg <penberg@kernel.org>
Cc: Yinghai Lu <yinghai@kernel.org>
Cc: brgerst@gmail.com
LKML-Reference: <4D00B3B9.7060702@kernel.org>
Signed-off-by: NThomas Gleixner <tglx@linutronix.de>
上级 0e3fa13f
...@@ -1195,12 +1195,15 @@ static void __cpuinit lapic_setup_esr(void) ...@@ -1195,12 +1195,15 @@ static void __cpuinit lapic_setup_esr(void)
oldvalue, value); oldvalue, value);
} }
/** /**
* setup_local_APIC - setup the local APIC * setup_local_APIC - setup the local APIC
*
* Used to setup local APIC while initializing BSP or bringin up APs.
* Always called with preemption disabled.
*/ */
void __cpuinit setup_local_APIC(void) void __cpuinit setup_local_APIC(void)
{ {
int cpu = smp_processor_id();
unsigned int value, queued; unsigned int value, queued;
int i, j, acked = 0; int i, j, acked = 0;
unsigned long long tsc = 0, ntsc; unsigned long long tsc = 0, ntsc;
...@@ -1225,8 +1228,6 @@ void __cpuinit setup_local_APIC(void) ...@@ -1225,8 +1228,6 @@ void __cpuinit setup_local_APIC(void)
#endif #endif
perf_events_lapic_init(); perf_events_lapic_init();
preempt_disable();
/* /*
* Double-check whether this APIC is really registered. * Double-check whether this APIC is really registered.
* This is meaningless in clustered apic mode, so we skip it. * This is meaningless in clustered apic mode, so we skip it.
...@@ -1342,21 +1343,19 @@ void __cpuinit setup_local_APIC(void) ...@@ -1342,21 +1343,19 @@ void __cpuinit setup_local_APIC(void)
* TODO: set up through-local-APIC from through-I/O-APIC? --macro * TODO: set up through-local-APIC from through-I/O-APIC? --macro
*/ */
value = apic_read(APIC_LVT0) & APIC_LVT_MASKED; value = apic_read(APIC_LVT0) & APIC_LVT_MASKED;
if (!smp_processor_id() && (pic_mode || !value)) { if (!cpu && (pic_mode || !value)) {
value = APIC_DM_EXTINT; value = APIC_DM_EXTINT;
apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", apic_printk(APIC_VERBOSE, "enabled ExtINT on CPU#%d\n", cpu);
smp_processor_id());
} else { } else {
value = APIC_DM_EXTINT | APIC_LVT_MASKED; value = APIC_DM_EXTINT | APIC_LVT_MASKED;
apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n", apic_printk(APIC_VERBOSE, "masked ExtINT on CPU#%d\n", cpu);
smp_processor_id());
} }
apic_write(APIC_LVT0, value); apic_write(APIC_LVT0, value);
/* /*
* only the BP should see the LINT1 NMI signal, obviously. * only the BP should see the LINT1 NMI signal, obviously.
*/ */
if (!smp_processor_id()) if (!cpu)
value = APIC_DM_NMI; value = APIC_DM_NMI;
else else
value = APIC_DM_NMI | APIC_LVT_MASKED; value = APIC_DM_NMI | APIC_LVT_MASKED;
...@@ -1364,11 +1363,9 @@ void __cpuinit setup_local_APIC(void) ...@@ -1364,11 +1363,9 @@ void __cpuinit setup_local_APIC(void)
value |= APIC_LVT_LEVEL_TRIGGER; value |= APIC_LVT_LEVEL_TRIGGER;
apic_write(APIC_LVT1, value); apic_write(APIC_LVT1, value);
preempt_enable();
#ifdef CONFIG_X86_MCE_INTEL #ifdef CONFIG_X86_MCE_INTEL
/* Recheck CMCI information after local APIC is up on CPU #0 */ /* Recheck CMCI information after local APIC is up on CPU #0 */
if (smp_processor_id() == 0) if (!cpu)
cmci_recheck(); cmci_recheck();
#endif #endif
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册