Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 312382
b: refs/heads/master
c: 5b39939
h: refs/heads/master
v: v3
  • Loading branch information
Frederic Weisbecker committed Jun 11, 2012
1 parent 1bca280 commit c8aedf9
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 40 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: f5d411c91ede162240f34e05a233f2759412988e
refs/heads/master: 5b39939a40801f0c17e31adaf643d6e974227856
86 changes: 47 additions & 39 deletions trunk/kernel/time/tick-sched.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,47 +271,15 @@ u64 get_cpu_iowait_time_us(int cpu, u64 *last_update_time)
}
EXPORT_SYMBOL_GPL(get_cpu_iowait_time_us);

static void tick_nohz_stop_sched_tick(struct tick_sched *ts, ktime_t now)
static void tick_nohz_stop_sched_tick(struct tick_sched *ts,
ktime_t now, int cpu)
{
unsigned long seq, last_jiffies, next_jiffies, delta_jiffies;
ktime_t last_update, expires;
struct clock_event_device *dev = __get_cpu_var(tick_cpu_device).evtdev;
u64 time_delta;
int cpu;

cpu = smp_processor_id();
ts = &per_cpu(tick_cpu_sched, cpu);

/*
* If this cpu is offline and it is the one which updates
* jiffies, then give up the assignment and let it be taken by
* the cpu which runs the tick timer next. If we don't drop
* this here the jiffies might be stale and do_timer() never
* invoked.
*/
if (unlikely(!cpu_online(cpu))) {
if (cpu == tick_do_timer_cpu)
tick_do_timer_cpu = TICK_DO_TIMER_NONE;
}

if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE))
return;

if (need_resched())
return;

if (unlikely(local_softirq_pending() && cpu_online(cpu))) {
static int ratelimit;

if (ratelimit < 10) {
printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n",
(unsigned int) local_softirq_pending());
ratelimit++;
}
return;
}

ts->idle_calls++;
/* Read jiffies and the time when jiffies were updated last */
do {
seq = read_seqbegin(&xtime_lock);
Expand Down Expand Up @@ -441,16 +409,56 @@ static void tick_nohz_stop_sched_tick(struct tick_sched *ts, ktime_t now)
ts->sleep_length = ktime_sub(dev->next_event, now);
}

static bool can_stop_idle_tick(int cpu, struct tick_sched *ts)
{
/*
* If this cpu is offline and it is the one which updates
* jiffies, then give up the assignment and let it be taken by
* the cpu which runs the tick timer next. If we don't drop
* this here the jiffies might be stale and do_timer() never
* invoked.
*/
if (unlikely(!cpu_online(cpu))) {
if (cpu == tick_do_timer_cpu)
tick_do_timer_cpu = TICK_DO_TIMER_NONE;
}

if (unlikely(ts->nohz_mode == NOHZ_MODE_INACTIVE))
return false;

if (need_resched())
return false;

if (unlikely(local_softirq_pending() && cpu_online(cpu))) {
static int ratelimit;

if (ratelimit < 10) {
printk(KERN_ERR "NOHZ: local_softirq_pending %02x\n",
(unsigned int) local_softirq_pending());
ratelimit++;
}
return false;
}

return true;
}

static void __tick_nohz_idle_enter(struct tick_sched *ts)
{
ktime_t now;
int was_stopped = ts->tick_stopped;
int cpu = smp_processor_id();

now = tick_nohz_start_idle(smp_processor_id(), ts);
tick_nohz_stop_sched_tick(ts, now);
now = tick_nohz_start_idle(cpu, ts);

if (!was_stopped && ts->tick_stopped)
ts->idle_jiffies = ts->last_jiffies;
if (can_stop_idle_tick(cpu, ts)) {
int was_stopped = ts->tick_stopped;

ts->idle_calls++;
tick_nohz_stop_sched_tick(ts, now, cpu);

if (!was_stopped && ts->tick_stopped)
ts->idle_jiffies = ts->last_jiffies;
}
}

/**
Expand Down

0 comments on commit c8aedf9

Please sign in to comment.