ia64: Use generic idle loop
Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Rusty Russell <rusty@rustcorp.com.au> Cc: Paul McKenney <paulmck@linux.vnet.ibm.com> Cc: Peter Zijlstra <peterz@infradead.org> Reviewed-by: Cc: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com> Cc: Magnus Damm <magnus.damm@gmail.com> Cc: Tony Luck <tony.luck@intel.com> Link: http://lkml.kernel.org/r/20130321215234.406851909@linutronix.de Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
Родитель
4e0fcc5672
Коммит
91d591c387
|
@ -35,6 +35,7 @@ config IA64
|
||||||
select ARCH_HAVE_NMI_SAFE_CMPXCHG
|
select ARCH_HAVE_NMI_SAFE_CMPXCHG
|
||||||
select GENERIC_IOMAP
|
select GENERIC_IOMAP
|
||||||
select GENERIC_SMP_IDLE_THREAD
|
select GENERIC_SMP_IDLE_THREAD
|
||||||
|
select GENERIC_IDLE_LOOP
|
||||||
select ARCH_INIT_TASK
|
select ARCH_INIT_TASK
|
||||||
select ARCH_TASK_STRUCT_ALLOCATOR
|
select ARCH_TASK_STRUCT_ALLOCATOR
|
||||||
select ARCH_THREAD_INFO_ALLOCATOR
|
select ARCH_THREAD_INFO_ALLOCATOR
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include <linux/completion.h>
|
#include <linux/completion.h>
|
||||||
#include <linux/tracehook.h>
|
#include <linux/tracehook.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
|
#include <linux/cpu.h>
|
||||||
|
|
||||||
#include <asm/errno.h>
|
#include <asm/errno.h>
|
||||||
#include <asm/intrinsics.h>
|
#include <asm/intrinsics.h>
|
||||||
|
@ -1322,8 +1323,6 @@ out:
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(pfm_unregister_buffer_fmt);
|
EXPORT_SYMBOL(pfm_unregister_buffer_fmt);
|
||||||
|
|
||||||
extern void update_pal_halt_status(int);
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
|
pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
|
||||||
{
|
{
|
||||||
|
@ -1371,9 +1370,9 @@ pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
|
||||||
cpu));
|
cpu));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* disable default_idle() to go to PAL_HALT
|
* Force idle() into poll mode
|
||||||
*/
|
*/
|
||||||
update_pal_halt_status(0);
|
cpu_idle_poll_ctrl(true);
|
||||||
|
|
||||||
UNLOCK_PFS(flags);
|
UNLOCK_PFS(flags);
|
||||||
|
|
||||||
|
@ -1430,11 +1429,8 @@ pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu)
|
||||||
is_syswide,
|
is_syswide,
|
||||||
cpu));
|
cpu));
|
||||||
|
|
||||||
/*
|
/* Undo forced polling. Last session reenables pal_halt */
|
||||||
* if possible, enable default_idle() to go into PAL_HALT
|
cpu_idle_poll_ctrl(false);
|
||||||
*/
|
|
||||||
if (pfm_sessions.pfs_task_sessions == 0 && pfm_sessions.pfs_sys_sessions == 0)
|
|
||||||
update_pal_halt_status(1);
|
|
||||||
|
|
||||||
UNLOCK_PFS(flags);
|
UNLOCK_PFS(flags);
|
||||||
|
|
||||||
|
|
|
@ -209,41 +209,13 @@ do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
|
||||||
local_irq_disable(); /* force interrupt disable */
|
local_irq_disable(); /* force interrupt disable */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pal_halt = 1;
|
|
||||||
static int can_do_pal_halt = 1;
|
|
||||||
|
|
||||||
static int __init nohalt_setup(char * str)
|
static int __init nohalt_setup(char * str)
|
||||||
{
|
{
|
||||||
pal_halt = can_do_pal_halt = 0;
|
cpu_idle_poll_ctrl(true);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
__setup("nohalt", nohalt_setup);
|
__setup("nohalt", nohalt_setup);
|
||||||
|
|
||||||
void
|
|
||||||
update_pal_halt_status(int status)
|
|
||||||
{
|
|
||||||
can_do_pal_halt = pal_halt && status;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We use this if we don't have any better idle routine..
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
default_idle (void)
|
|
||||||
{
|
|
||||||
local_irq_enable();
|
|
||||||
while (!need_resched()) {
|
|
||||||
if (can_do_pal_halt) {
|
|
||||||
local_irq_disable();
|
|
||||||
if (!need_resched()) {
|
|
||||||
safe_halt();
|
|
||||||
}
|
|
||||||
local_irq_enable();
|
|
||||||
} else
|
|
||||||
cpu_relax();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_HOTPLUG_CPU
|
#ifdef CONFIG_HOTPLUG_CPU
|
||||||
/* We don't actually take CPU down, just spin without interrupts. */
|
/* We don't actually take CPU down, just spin without interrupts. */
|
||||||
static inline void play_dead(void)
|
static inline void play_dead(void)
|
||||||
|
@ -270,47 +242,29 @@ static inline void play_dead(void)
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_HOTPLUG_CPU */
|
#endif /* CONFIG_HOTPLUG_CPU */
|
||||||
|
|
||||||
void __attribute__((noreturn))
|
void arch_cpu_idle_dead(void)
|
||||||
cpu_idle (void)
|
{
|
||||||
|
play_dead();
|
||||||
|
}
|
||||||
|
|
||||||
|
void arch_cpu_idle(void)
|
||||||
{
|
{
|
||||||
void (*mark_idle)(int) = ia64_mark_idle;
|
void (*mark_idle)(int) = ia64_mark_idle;
|
||||||
int cpu = smp_processor_id();
|
|
||||||
|
|
||||||
/* endless idle loop with no priority at all */
|
|
||||||
while (1) {
|
|
||||||
rcu_idle_enter();
|
|
||||||
if (can_do_pal_halt) {
|
|
||||||
current_thread_info()->status &= ~TS_POLLING;
|
|
||||||
/*
|
|
||||||
* TS_POLLING-cleared state must be visible before we
|
|
||||||
* test NEED_RESCHED:
|
|
||||||
*/
|
|
||||||
smp_mb();
|
|
||||||
} else {
|
|
||||||
current_thread_info()->status |= TS_POLLING;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!need_resched()) {
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
min_xtp();
|
min_xtp();
|
||||||
#endif
|
#endif
|
||||||
rmb();
|
rmb();
|
||||||
if (mark_idle)
|
if (mark_idle)
|
||||||
(*mark_idle)(1);
|
(*mark_idle)(1);
|
||||||
|
|
||||||
default_idle();
|
safe_halt();
|
||||||
if (mark_idle)
|
|
||||||
(*mark_idle)(0);
|
if (mark_idle)
|
||||||
|
(*mark_idle)(0);
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
normal_xtp();
|
normal_xtp();
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
rcu_idle_exit();
|
|
||||||
schedule_preempt_disabled();
|
|
||||||
check_pgt_cache();
|
|
||||||
if (cpu_is_offline(cpu))
|
|
||||||
play_dead();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -455,7 +455,7 @@ start_secondary (void *unused)
|
||||||
preempt_disable();
|
preempt_disable();
|
||||||
smp_callin();
|
smp_callin();
|
||||||
|
|
||||||
cpu_idle();
|
cpu_startup_entry(CPUHP_ONLINE);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче