Merge branch 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip
* 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: nohz: adjust tick_nohz_stop_sched_tick() call of s390 as well nohz: prevent tick stop outside of the idle loop
This commit is contained in:
Коммит
ecc8b655b3
|
@ -162,7 +162,7 @@ void cpu_idle(void)
|
||||||
if (!idle)
|
if (!idle)
|
||||||
idle = default_idle;
|
idle = default_idle;
|
||||||
leds_event(led_idle_start);
|
leds_event(led_idle_start);
|
||||||
tick_nohz_stop_sched_tick();
|
tick_nohz_stop_sched_tick(1);
|
||||||
while (!need_resched())
|
while (!need_resched())
|
||||||
idle();
|
idle();
|
||||||
leds_event(led_idle_end);
|
leds_event(led_idle_end);
|
||||||
|
|
|
@ -31,7 +31,7 @@ void cpu_idle(void)
|
||||||
{
|
{
|
||||||
/* endless idle loop with no priority at all */
|
/* endless idle loop with no priority at all */
|
||||||
while (1) {
|
while (1) {
|
||||||
tick_nohz_stop_sched_tick();
|
tick_nohz_stop_sched_tick(1);
|
||||||
while (!need_resched())
|
while (!need_resched())
|
||||||
cpu_idle_sleep();
|
cpu_idle_sleep();
|
||||||
tick_nohz_restart_sched_tick();
|
tick_nohz_restart_sched_tick();
|
||||||
|
|
|
@ -105,7 +105,7 @@ void cpu_idle(void)
|
||||||
#endif
|
#endif
|
||||||
if (!idle)
|
if (!idle)
|
||||||
idle = default_idle;
|
idle = default_idle;
|
||||||
tick_nohz_stop_sched_tick();
|
tick_nohz_stop_sched_tick(1);
|
||||||
while (!need_resched())
|
while (!need_resched())
|
||||||
idle();
|
idle();
|
||||||
tick_nohz_restart_sched_tick();
|
tick_nohz_restart_sched_tick();
|
||||||
|
|
|
@ -53,7 +53,7 @@ void __noreturn cpu_idle(void)
|
||||||
{
|
{
|
||||||
/* endless idle loop with no priority at all */
|
/* endless idle loop with no priority at all */
|
||||||
while (1) {
|
while (1) {
|
||||||
tick_nohz_stop_sched_tick();
|
tick_nohz_stop_sched_tick(1);
|
||||||
while (!need_resched()) {
|
while (!need_resched()) {
|
||||||
#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
|
#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
|
||||||
extern void smtc_idle_loop_hook(void);
|
extern void smtc_idle_loop_hook(void);
|
||||||
|
|
|
@ -60,7 +60,7 @@ void cpu_idle(void)
|
||||||
|
|
||||||
set_thread_flag(TIF_POLLING_NRFLAG);
|
set_thread_flag(TIF_POLLING_NRFLAG);
|
||||||
while (1) {
|
while (1) {
|
||||||
tick_nohz_stop_sched_tick();
|
tick_nohz_stop_sched_tick(1);
|
||||||
while (!need_resched() && !cpu_should_die()) {
|
while (!need_resched() && !cpu_should_die()) {
|
||||||
ppc64_runlatch_off();
|
ppc64_runlatch_off();
|
||||||
|
|
||||||
|
|
|
@ -561,7 +561,7 @@ static void yield_shared_processor(void)
|
||||||
static void iseries_shared_idle(void)
|
static void iseries_shared_idle(void)
|
||||||
{
|
{
|
||||||
while (1) {
|
while (1) {
|
||||||
tick_nohz_stop_sched_tick();
|
tick_nohz_stop_sched_tick(1);
|
||||||
while (!need_resched() && !hvlpevent_is_pending()) {
|
while (!need_resched() && !hvlpevent_is_pending()) {
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
ppc64_runlatch_off();
|
ppc64_runlatch_off();
|
||||||
|
@ -591,7 +591,7 @@ static void iseries_dedicated_idle(void)
|
||||||
set_thread_flag(TIF_POLLING_NRFLAG);
|
set_thread_flag(TIF_POLLING_NRFLAG);
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
tick_nohz_stop_sched_tick();
|
tick_nohz_stop_sched_tick(1);
|
||||||
if (!need_resched()) {
|
if (!need_resched()) {
|
||||||
while (!need_resched()) {
|
while (!need_resched()) {
|
||||||
ppc64_runlatch_off();
|
ppc64_runlatch_off();
|
||||||
|
|
|
@ -142,7 +142,7 @@ static void default_idle(void)
|
||||||
void cpu_idle(void)
|
void cpu_idle(void)
|
||||||
{
|
{
|
||||||
for (;;) {
|
for (;;) {
|
||||||
tick_nohz_stop_sched_tick();
|
tick_nohz_stop_sched_tick(1);
|
||||||
while (!need_resched())
|
while (!need_resched())
|
||||||
default_idle();
|
default_idle();
|
||||||
tick_nohz_restart_sched_tick();
|
tick_nohz_restart_sched_tick();
|
||||||
|
|
|
@ -86,7 +86,7 @@ void cpu_idle(void)
|
||||||
if (!idle)
|
if (!idle)
|
||||||
idle = default_idle;
|
idle = default_idle;
|
||||||
|
|
||||||
tick_nohz_stop_sched_tick();
|
tick_nohz_stop_sched_tick(1);
|
||||||
while (!need_resched())
|
while (!need_resched())
|
||||||
idle();
|
idle();
|
||||||
tick_nohz_restart_sched_tick();
|
tick_nohz_restart_sched_tick();
|
||||||
|
|
|
@ -96,7 +96,7 @@ void cpu_idle(void)
|
||||||
set_thread_flag(TIF_POLLING_NRFLAG);
|
set_thread_flag(TIF_POLLING_NRFLAG);
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
tick_nohz_stop_sched_tick();
|
tick_nohz_stop_sched_tick(1);
|
||||||
|
|
||||||
while (!need_resched() && !cpu_is_offline(cpu))
|
while (!need_resched() && !cpu_is_offline(cpu))
|
||||||
sparc64_yield(cpu);
|
sparc64_yield(cpu);
|
||||||
|
|
|
@ -243,7 +243,7 @@ void default_idle(void)
|
||||||
if (need_resched())
|
if (need_resched())
|
||||||
schedule();
|
schedule();
|
||||||
|
|
||||||
tick_nohz_stop_sched_tick();
|
tick_nohz_stop_sched_tick(1);
|
||||||
nsecs = disable_timer();
|
nsecs = disable_timer();
|
||||||
idle_sleep(nsecs);
|
idle_sleep(nsecs);
|
||||||
tick_nohz_restart_sched_tick();
|
tick_nohz_restart_sched_tick();
|
||||||
|
|
|
@ -128,7 +128,7 @@ void cpu_idle(void)
|
||||||
|
|
||||||
/* endless idle loop with no priority at all */
|
/* endless idle loop with no priority at all */
|
||||||
while (1) {
|
while (1) {
|
||||||
tick_nohz_stop_sched_tick();
|
tick_nohz_stop_sched_tick(1);
|
||||||
while (!need_resched()) {
|
while (!need_resched()) {
|
||||||
|
|
||||||
check_pgt_cache();
|
check_pgt_cache();
|
||||||
|
|
|
@ -120,7 +120,7 @@ void cpu_idle(void)
|
||||||
current_thread_info()->status |= TS_POLLING;
|
current_thread_info()->status |= TS_POLLING;
|
||||||
/* endless idle loop with no priority at all */
|
/* endless idle loop with no priority at all */
|
||||||
while (1) {
|
while (1) {
|
||||||
tick_nohz_stop_sched_tick();
|
tick_nohz_stop_sched_tick(1);
|
||||||
while (!need_resched()) {
|
while (!need_resched()) {
|
||||||
|
|
||||||
rmb();
|
rmb();
|
||||||
|
|
|
@ -49,6 +49,7 @@ struct tick_sched {
|
||||||
unsigned long check_clocks;
|
unsigned long check_clocks;
|
||||||
enum tick_nohz_mode nohz_mode;
|
enum tick_nohz_mode nohz_mode;
|
||||||
ktime_t idle_tick;
|
ktime_t idle_tick;
|
||||||
|
int inidle;
|
||||||
int tick_stopped;
|
int tick_stopped;
|
||||||
unsigned long idle_jiffies;
|
unsigned long idle_jiffies;
|
||||||
unsigned long idle_calls;
|
unsigned long idle_calls;
|
||||||
|
@ -105,14 +106,14 @@ static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
|
||||||
#endif /* !CONFIG_GENERIC_CLOCKEVENTS */
|
#endif /* !CONFIG_GENERIC_CLOCKEVENTS */
|
||||||
|
|
||||||
# ifdef CONFIG_NO_HZ
|
# ifdef CONFIG_NO_HZ
|
||||||
extern void tick_nohz_stop_sched_tick(void);
|
extern void tick_nohz_stop_sched_tick(int inidle);
|
||||||
extern void tick_nohz_restart_sched_tick(void);
|
extern void tick_nohz_restart_sched_tick(void);
|
||||||
extern void tick_nohz_update_jiffies(void);
|
extern void tick_nohz_update_jiffies(void);
|
||||||
extern ktime_t tick_nohz_get_sleep_length(void);
|
extern ktime_t tick_nohz_get_sleep_length(void);
|
||||||
extern void tick_nohz_stop_idle(int cpu);
|
extern void tick_nohz_stop_idle(int cpu);
|
||||||
extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time);
|
extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time);
|
||||||
# else
|
# else
|
||||||
static inline void tick_nohz_stop_sched_tick(void) { }
|
static inline void tick_nohz_stop_sched_tick(int inidle) { }
|
||||||
static inline void tick_nohz_restart_sched_tick(void) { }
|
static inline void tick_nohz_restart_sched_tick(void) { }
|
||||||
static inline void tick_nohz_update_jiffies(void) { }
|
static inline void tick_nohz_update_jiffies(void) { }
|
||||||
static inline ktime_t tick_nohz_get_sleep_length(void)
|
static inline ktime_t tick_nohz_get_sleep_length(void)
|
||||||
|
|
|
@ -286,7 +286,7 @@ void irq_exit(void)
|
||||||
#ifdef CONFIG_NO_HZ
|
#ifdef CONFIG_NO_HZ
|
||||||
/* Make sure that timer wheel updates are propagated */
|
/* Make sure that timer wheel updates are propagated */
|
||||||
if (!in_interrupt() && idle_cpu(smp_processor_id()) && !need_resched())
|
if (!in_interrupt() && idle_cpu(smp_processor_id()) && !need_resched())
|
||||||
tick_nohz_stop_sched_tick();
|
tick_nohz_stop_sched_tick(0);
|
||||||
rcu_irq_exit();
|
rcu_irq_exit();
|
||||||
#endif
|
#endif
|
||||||
preempt_enable_no_resched();
|
preempt_enable_no_resched();
|
||||||
|
|
|
@ -195,7 +195,7 @@ u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time)
|
||||||
* Called either from the idle loop or from irq_exit() when an idle period was
|
* Called either from the idle loop or from irq_exit() when an idle period was
|
||||||
* just interrupted by an interrupt which did not cause a reschedule.
|
* just interrupted by an interrupt which did not cause a reschedule.
|
||||||
*/
|
*/
|
||||||
void tick_nohz_stop_sched_tick(void)
|
void tick_nohz_stop_sched_tick(int inidle)
|
||||||
{
|
{
|
||||||
unsigned long seq, last_jiffies, next_jiffies, delta_jiffies, flags;
|
unsigned long seq, last_jiffies, next_jiffies, delta_jiffies, flags;
|
||||||
struct tick_sched *ts;
|
struct tick_sched *ts;
|
||||||
|
@ -224,6 +224,11 @@ void tick_nohz_stop_sched_tick(void)
|
||||||
if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE))
|
if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE))
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
if (!inidle && !ts->inidle)
|
||||||
|
goto end;
|
||||||
|
|
||||||
|
ts->inidle = 1;
|
||||||
|
|
||||||
if (need_resched())
|
if (need_resched())
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
|
@ -373,11 +378,14 @@ void tick_nohz_restart_sched_tick(void)
|
||||||
local_irq_disable();
|
local_irq_disable();
|
||||||
tick_nohz_stop_idle(cpu);
|
tick_nohz_stop_idle(cpu);
|
||||||
|
|
||||||
if (!ts->tick_stopped) {
|
if (!ts->inidle || !ts->tick_stopped) {
|
||||||
|
ts->inidle = 0;
|
||||||
local_irq_enable();
|
local_irq_enable();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ts->inidle = 0;
|
||||||
|
|
||||||
rcu_exit_nohz();
|
rcu_exit_nohz();
|
||||||
|
|
||||||
/* Update jiffies first */
|
/* Update jiffies first */
|
||||||
|
|
Загрузка…
Ссылка в новой задаче