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:
Thomas Gleixner 2013-03-21 22:49:47 +01:00
Родитель 4e0fcc5672
Коммит 91d591c387
4 изменённых файлов: 23 добавлений и 72 удалений

Просмотреть файл

@ -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;
} }