From mboxrd@z Thu Jan 1 00:00:00 1970 From: peterz@infradead.org (Peter Zijlstra) Date: Thu, 09 Dec 2010 19:55:39 +0100 Subject: [BUG] 2.6.37-rc3 massive interactivity regression on ARM In-Reply-To: References: <20101208142814.GE9777@n2100.arm.linux.org.uk> <1291851079-27061-1-git-send-email-venki@google.com> <1291899120.29292.7.camel@twins> <1291917330.6803.7.camel@twins> Message-ID: <1291920939.6803.38.camel@twins> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On Thu, 2010-12-09 at 10:11 -0800, Venkatesh Pallipadi wrote: > On Thu, Dec 9, 2010 at 9:55 AM, Peter Zijlstra wrote: > > On Thu, 2010-12-09 at 09:43 -0800, Venkatesh Pallipadi wrote: > >> > >> The same problem will be there with below code, with irq_delta > > >> delta, clock_task can go backwards which is not good. > >> + delta -= irq_delta; > >> + rq->clock_task += delta; > >> > >> The reason for this is rq->clock and irqtime updates kind of happen > >> independently and specifically, if a rq->clock update happens while we > >> are in a softirq, we may have this case of going backwards on the next > >> update. > > > > But how can irq_delta > delta?, we measure it using the same clock. > > > > This would be mostly a corner case like: > - softirq start time t1 > - rq->clock updated at t2 and rq->clock_task updated at t2 without > accounting for current softirq > - softirq end time t3 > - cpu spends most time here in softirq or hardirq > - next rq->clock update at t4 and rq->clock_task update, with delta = > t4-t2 and irq_delta ~= t4 - t1 Ah, something like that would happen when we do a wakeup from soft/hard-irq context, not an altogether uncommon occurrence. Wouldn't that be cured by updating the irq-time when asking for it, something like the below? (on top of my earlier patch) --- Index: linux-2.6/kernel/sched.c =================================================================== --- linux-2.6.orig/kernel/sched.c +++ linux-2.6/kernel/sched.c @@ -1843,8 +1843,9 @@ void account_system_vtime(struct task_st } EXPORT_SYMBOL_GPL(account_system_vtime); -static inline u64 irq_time_cpu(int cpu) +static u64 irq_time_cpu(int cpu) { + account_system_vtime(current); return per_cpu(cpu_softirq_time, cpu) + per_cpu(cpu_hardirq_time, cpu); }