Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 updates from Ingo Molnar. This touches some non-x86 files due to the sanitized INLINE_SPIN_UNLOCK config usage. Fixed up trivial conflicts due to just header include changes (removing headers due to cpu_idle() merge clashing with the <asm/system.h> split). * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/apic/amd: Be more verbose about LVT offset assignments x86, tls: Off by one limit check x86/ioapic: Add io_apic_ops driver layer to allow interception x86/olpc: Add debugfs interface for EC commands x86: Merge the x86_32 and x86_64 cpu_idle() functions x86/kconfig: Remove CONFIG_TR=y from the defconfigs x86: Stop recursive fault in print_context_stack after stack overflow x86/io_apic: Move and reenable irq only when CONFIG_GENERIC_PENDING_IRQ=y x86/apic: Add separate apic_id_valid() functions for selected apic drivers locking/kconfig: Simplify INLINE_SPIN_UNLOCK usage x86/kconfig: Update defconfigs x86: Fix excessive MSR print out when show_msr is not specified
This commit is contained in:
@@ -12,6 +12,9 @@
|
||||
#include <linux/user-return-notifier.h>
|
||||
#include <linux/dmi.h>
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/stackprotector.h>
|
||||
#include <linux/tick.h>
|
||||
#include <linux/cpuidle.h>
|
||||
#include <trace/events/power.h>
|
||||
#include <linux/hw_breakpoint.h>
|
||||
#include <asm/cpu.h>
|
||||
@@ -22,6 +25,24 @@
|
||||
#include <asm/i387.h>
|
||||
#include <asm/fpu-internal.h>
|
||||
#include <asm/debugreg.h>
|
||||
#include <asm/nmi.h>
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
static DEFINE_PER_CPU(unsigned char, is_idle);
|
||||
static ATOMIC_NOTIFIER_HEAD(idle_notifier);
|
||||
|
||||
void idle_notifier_register(struct notifier_block *n)
|
||||
{
|
||||
atomic_notifier_chain_register(&idle_notifier, n);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(idle_notifier_register);
|
||||
|
||||
void idle_notifier_unregister(struct notifier_block *n)
|
||||
{
|
||||
atomic_notifier_chain_unregister(&idle_notifier, n);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(idle_notifier_unregister);
|
||||
#endif
|
||||
|
||||
struct kmem_cache *task_xstate_cachep;
|
||||
EXPORT_SYMBOL_GPL(task_xstate_cachep);
|
||||
@@ -370,6 +391,99 @@ static inline int hlt_use_halt(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
static inline void play_dead(void)
|
||||
{
|
||||
BUG();
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
void enter_idle(void)
|
||||
{
|
||||
percpu_write(is_idle, 1);
|
||||
atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL);
|
||||
}
|
||||
|
||||
static void __exit_idle(void)
|
||||
{
|
||||
if (x86_test_and_clear_bit_percpu(0, is_idle) == 0)
|
||||
return;
|
||||
atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL);
|
||||
}
|
||||
|
||||
/* Called from interrupts to signify idle end */
|
||||
void exit_idle(void)
|
||||
{
|
||||
/* idle loop has pid 0 */
|
||||
if (current->pid)
|
||||
return;
|
||||
__exit_idle();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* The idle thread. There's no useful work to be
|
||||
* done, so just try to conserve power and have a
|
||||
* low exit latency (ie sit in a loop waiting for
|
||||
* somebody to say that they'd like to reschedule)
|
||||
*/
|
||||
void cpu_idle(void)
|
||||
{
|
||||
/*
|
||||
* If we're the non-boot CPU, nothing set the stack canary up
|
||||
* for us. CPU0 already has it initialized but no harm in
|
||||
* doing it again. This is a good place for updating it, as
|
||||
* we wont ever return from this function (so the invalid
|
||||
* canaries already on the stack wont ever trigger).
|
||||
*/
|
||||
boot_init_stack_canary();
|
||||
current_thread_info()->status |= TS_POLLING;
|
||||
|
||||
while (1) {
|
||||
tick_nohz_idle_enter();
|
||||
|
||||
while (!need_resched()) {
|
||||
rmb();
|
||||
|
||||
if (cpu_is_offline(smp_processor_id()))
|
||||
play_dead();
|
||||
|
||||
/*
|
||||
* Idle routines should keep interrupts disabled
|
||||
* from here on, until they go to idle.
|
||||
* Otherwise, idle callbacks can misfire.
|
||||
*/
|
||||
local_touch_nmi();
|
||||
local_irq_disable();
|
||||
|
||||
enter_idle();
|
||||
|
||||
/* Don't trace irqs off for idle */
|
||||
stop_critical_timings();
|
||||
|
||||
/* enter_idle() needs rcu for notifiers */
|
||||
rcu_idle_enter();
|
||||
|
||||
if (cpuidle_idle_call())
|
||||
pm_idle();
|
||||
|
||||
rcu_idle_exit();
|
||||
start_critical_timings();
|
||||
|
||||
/* In many cases the interrupt that ended idle
|
||||
has already called exit_idle. But some idle
|
||||
loops can be woken up without interrupt. */
|
||||
__exit_idle();
|
||||
}
|
||||
|
||||
tick_nohz_idle_exit();
|
||||
preempt_enable_no_resched();
|
||||
schedule();
|
||||
preempt_disable();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We use this if we don't have any better
|
||||
* idle routine..
|
||||
|
Reference in New Issue
Block a user