Skip to content

Commit

Permalink
Merge branch 'timers-fixes-for-linus' of git://git.kernel.org/pub/scm…
Browse files Browse the repository at this point in the history
…/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
  • Loading branch information
Linus Torvalds committed Jul 24, 2008
2 parents 2528ce3 + e338125 commit ecc8b65
Show file tree
Hide file tree
Showing 15 changed files with 27 additions and 18 deletions.
2 changes: 1 addition & 1 deletion arch/arm/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ void cpu_idle(void)
if (!idle)
idle = default_idle;
leds_event(led_idle_start);
tick_nohz_stop_sched_tick();
tick_nohz_stop_sched_tick(1);
while (!need_resched())
idle();
leds_event(led_idle_end);
Expand Down
2 changes: 1 addition & 1 deletion arch/avr32/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ void cpu_idle(void)
{
/* endless idle loop with no priority at all */
while (1) {
tick_nohz_stop_sched_tick();
tick_nohz_stop_sched_tick(1);
while (!need_resched())
cpu_idle_sleep();
tick_nohz_restart_sched_tick();
Expand Down
2 changes: 1 addition & 1 deletion arch/blackfin/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ void cpu_idle(void)
#endif
if (!idle)
idle = default_idle;
tick_nohz_stop_sched_tick();
tick_nohz_stop_sched_tick(1);
while (!need_resched())
idle();
tick_nohz_restart_sched_tick();
Expand Down
2 changes: 1 addition & 1 deletion arch/mips/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ void __noreturn cpu_idle(void)
{
/* endless idle loop with no priority at all */
while (1) {
tick_nohz_stop_sched_tick();
tick_nohz_stop_sched_tick(1);
while (!need_resched()) {
#ifdef CONFIG_SMTC_IDLE_HOOK_DEBUG
extern void smtc_idle_loop_hook(void);
Expand Down
2 changes: 1 addition & 1 deletion arch/powerpc/kernel/idle.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ void cpu_idle(void)

set_thread_flag(TIF_POLLING_NRFLAG);
while (1) {
tick_nohz_stop_sched_tick();
tick_nohz_stop_sched_tick(1);
while (!need_resched() && !cpu_should_die()) {
ppc64_runlatch_off();

Expand Down
4 changes: 2 additions & 2 deletions arch/powerpc/platforms/iseries/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -561,7 +561,7 @@ static void yield_shared_processor(void)
static void iseries_shared_idle(void)
{
while (1) {
tick_nohz_stop_sched_tick();
tick_nohz_stop_sched_tick(1);
while (!need_resched() && !hvlpevent_is_pending()) {
local_irq_disable();
ppc64_runlatch_off();
Expand Down Expand Up @@ -591,7 +591,7 @@ static void iseries_dedicated_idle(void)
set_thread_flag(TIF_POLLING_NRFLAG);

while (1) {
tick_nohz_stop_sched_tick();
tick_nohz_stop_sched_tick(1);
if (!need_resched()) {
while (!need_resched()) {
ppc64_runlatch_off();
Expand Down
2 changes: 1 addition & 1 deletion arch/s390/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ static void default_idle(void)
void cpu_idle(void)
{
for (;;) {
tick_nohz_stop_sched_tick();
tick_nohz_stop_sched_tick(1);
while (!need_resched())
default_idle();
tick_nohz_restart_sched_tick();
Expand Down
2 changes: 1 addition & 1 deletion arch/sh/kernel/process_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ void cpu_idle(void)
if (!idle)
idle = default_idle;

tick_nohz_stop_sched_tick();
tick_nohz_stop_sched_tick(1);
while (!need_resched())
idle();
tick_nohz_restart_sched_tick();
Expand Down
2 changes: 1 addition & 1 deletion arch/sparc64/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ void cpu_idle(void)
set_thread_flag(TIF_POLLING_NRFLAG);

while(1) {
tick_nohz_stop_sched_tick();
tick_nohz_stop_sched_tick(1);

while (!need_resched() && !cpu_is_offline(cpu))
sparc64_yield(cpu);
Expand Down
2 changes: 1 addition & 1 deletion arch/um/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ void default_idle(void)
if (need_resched())
schedule();

tick_nohz_stop_sched_tick();
tick_nohz_stop_sched_tick(1);
nsecs = disable_timer();
idle_sleep(nsecs);
tick_nohz_restart_sched_tick();
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/process_32.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ void cpu_idle(void)

/* endless idle loop with no priority at all */
while (1) {
tick_nohz_stop_sched_tick();
tick_nohz_stop_sched_tick(1);
while (!need_resched()) {

check_pgt_cache();
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/process_64.c
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ void cpu_idle(void)
current_thread_info()->status |= TS_POLLING;
/* endless idle loop with no priority at all */
while (1) {
tick_nohz_stop_sched_tick();
tick_nohz_stop_sched_tick(1);
while (!need_resched()) {

rmb();
Expand Down
5 changes: 3 additions & 2 deletions include/linux/tick.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ struct tick_sched {
unsigned long check_clocks;
enum tick_nohz_mode nohz_mode;
ktime_t idle_tick;
int inidle;
int tick_stopped;
unsigned long idle_jiffies;
unsigned long idle_calls;
Expand Down Expand Up @@ -105,14 +106,14 @@ static inline int tick_check_oneshot_change(int allow_nohz) { return 0; }
#endif /* !CONFIG_GENERIC_CLOCKEVENTS */

# 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_update_jiffies(void);
extern ktime_t tick_nohz_get_sleep_length(void);
extern void tick_nohz_stop_idle(int cpu);
extern u64 get_cpu_idle_time_us(int cpu, u64 *last_update_time);
# 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_update_jiffies(void) { }
static inline ktime_t tick_nohz_get_sleep_length(void)
Expand Down
2 changes: 1 addition & 1 deletion kernel/softirq.c
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ void irq_exit(void)
#ifdef CONFIG_NO_HZ
/* Make sure that timer wheel updates are propagated */
if (!in_interrupt() && idle_cpu(smp_processor_id()) && !need_resched())
tick_nohz_stop_sched_tick();
tick_nohz_stop_sched_tick(0);
rcu_irq_exit();
#endif
preempt_enable_no_resched();
Expand Down
12 changes: 10 additions & 2 deletions kernel/time/tick-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
* 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;
struct tick_sched *ts;
Expand Down Expand Up @@ -224,6 +224,11 @@ void tick_nohz_stop_sched_tick(void)
if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE))
goto end;

if (!inidle && !ts->inidle)
goto end;

ts->inidle = 1;

if (need_resched())
goto end;

Expand Down Expand Up @@ -373,11 +378,14 @@ void tick_nohz_restart_sched_tick(void)
local_irq_disable();
tick_nohz_stop_idle(cpu);

if (!ts->tick_stopped) {
if (!ts->inidle || !ts->tick_stopped) {
ts->inidle = 0;
local_irq_enable();
return;
}

ts->inidle = 0;

rcu_exit_nohz();

/* Update jiffies first */
Expand Down

0 comments on commit ecc8b65

Please sign in to comment.