The attempt to round up values leads to cpu values fluctuating above 100% so remove the unnecessary complexity, and avoid going through calculations if no nanoseconds have been registered. -ck --- kernel/sched/bfs.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) Index: linux-3.7-bfs/kernel/sched/bfs.c =================================================================== --- linux-3.7-bfs.orig/kernel/sched/bfs.c 2013-01-29 01:22:36.408780261 +1100 +++ linux-3.7-bfs/kernel/sched/bfs.c 2013-01-29 01:22:36.807775273 +1100 @@ -256,7 +256,6 @@ struct rq { u64 timekeep_clock; unsigned long user_pc, nice_pc, irq_pc, softirq_pc, system_pc, iowait_pc, idle_pc; - long account_pc; atomic_t nr_iowait; #ifdef CONFIG_SMP @@ -2475,34 +2474,21 @@ static void update_cpu_clock(struct rq *rq, struct task_struct *p, bool tick) { long account_ns = rq->clock - rq->timekeep_clock; - struct task_struct *idle = rq->idle; + struct task_struct *idle; unsigned long account_pc; if (unlikely(account_ns < 0)) - account_ns = 0; + goto out; account_pc = NS_TO_PC(account_ns); + idle = rq->idle; if (tick) { - int user_tick; - /* Accurate tick timekeeping */ - rq->account_pc += account_pc - 128; - if (rq->account_pc < 0) { - /* - * Small errors in micro accounting may not make the - * accounting add up to 128 each tick so we keep track - * of the percentage and round it up when less than 128 - */ - account_pc += -rq->account_pc; - rq->account_pc = 0; - } if (steal_account_process_tick()) goto ts_account; - user_tick = user_mode(get_irq_regs()); - - if (user_tick) + if (user_mode(get_irq_regs())) pc_user_time(rq, p, account_pc, account_ns); else if (p != idle || (irq_count() != HARDIRQ_OFFSET)) pc_system_time(rq, p, HARDIRQ_OFFSET, @@ -2514,7 +2500,6 @@ update_cpu_clock(struct rq *rq, struct t irqtime_account_hi_si(); } else { /* Accurate subtick timekeeping */ - rq->account_pc += account_pc; if (p == idle) pc_idle_time(rq, account_pc); else @@ -2529,6 +2514,7 @@ ts_account: niffy_diff(&time_diff, 1); rq->rq_time_slice -= NS_TO_US(time_diff); } +out: rq->rq_last_ran = rq->timekeep_clock = rq->clock; }