sched: improve rq-clock overflow logic
improve the rq-clock overflow logic: limit the absolute rq->clock delta since the last scheduler tick, instead of limiting the delta itself. tested by Arjan van de Ven - whole laptop was misbehaving due to an incorrectly calibrated cpu_khz confusing sched_clock(). Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
This commit is contained in:
parent
ac07860264
commit
529c77261b
@ -263,6 +263,7 @@ struct rq {
|
|||||||
|
|
||||||
unsigned int clock_warps, clock_overflows;
|
unsigned int clock_warps, clock_overflows;
|
||||||
unsigned int clock_unstable_events;
|
unsigned int clock_unstable_events;
|
||||||
|
u64 tick_timestamp;
|
||||||
|
|
||||||
atomic_t nr_iowait;
|
atomic_t nr_iowait;
|
||||||
|
|
||||||
@ -341,7 +342,10 @@ static void __update_rq_clock(struct rq *rq)
|
|||||||
/*
|
/*
|
||||||
* Catch too large forward jumps too:
|
* Catch too large forward jumps too:
|
||||||
*/
|
*/
|
||||||
if (unlikely(delta > 2*TICK_NSEC)) {
|
if (unlikely(clock + delta > rq->tick_timestamp + TICK_NSEC)) {
|
||||||
|
if (clock < rq->tick_timestamp + TICK_NSEC)
|
||||||
|
clock = rq->tick_timestamp + TICK_NSEC;
|
||||||
|
else
|
||||||
clock++;
|
clock++;
|
||||||
rq->clock_overflows++;
|
rq->clock_overflows++;
|
||||||
} else {
|
} else {
|
||||||
@ -3308,9 +3312,16 @@ void scheduler_tick(void)
|
|||||||
int cpu = smp_processor_id();
|
int cpu = smp_processor_id();
|
||||||
struct rq *rq = cpu_rq(cpu);
|
struct rq *rq = cpu_rq(cpu);
|
||||||
struct task_struct *curr = rq->curr;
|
struct task_struct *curr = rq->curr;
|
||||||
|
u64 next_tick = rq->tick_timestamp + TICK_NSEC;
|
||||||
|
|
||||||
spin_lock(&rq->lock);
|
spin_lock(&rq->lock);
|
||||||
__update_rq_clock(rq);
|
__update_rq_clock(rq);
|
||||||
|
/*
|
||||||
|
* Let rq->clock advance by at least TICK_NSEC:
|
||||||
|
*/
|
||||||
|
if (unlikely(rq->clock < next_tick))
|
||||||
|
rq->clock = next_tick;
|
||||||
|
rq->tick_timestamp = rq->clock;
|
||||||
update_cpu_load(rq);
|
update_cpu_load(rq);
|
||||||
if (curr != rq->idle) /* FIXME: needed? */
|
if (curr != rq->idle) /* FIXME: needed? */
|
||||||
curr->sched_class->task_tick(rq, curr);
|
curr->sched_class->task_tick(rq, curr);
|
||||||
|
Loading…
Reference in New Issue
Block a user