On Sat, Feb 8, 2014 at 9:20 AM, Alex Bligh <a...@alex.org.uk> wrote: > Paolo, > > On 8 Feb 2014, at 13:26, Paolo Bonzini wrote: > >>> >>> What I'd suggest you do is run qemu within gdb, and when you have >>> seen the sluggish behaviour, set a breakpoint in timerlist_run_timers >>> just before the line saying cb(opaque). If I'm right your breakpoint >>> should immediately hit. Step in to the callback and note which it is. >>> It should always (or nearly always) be the same timer (note the process >>> of debugging will cause other timers to expire). >> >> Alex, could you add a trace event to timerlist_run_timers and mod_timer? >> For timerlist_run_timer it should include the timer (ts), the callback and >> the opaque value. >> >> This would make it simpler to find if this is the cause, and to debug it >> without introducing as much perturbation. > > A while ago a wrote some instrumentation. I can't recall how far I got with > testing it, but here it is rebased onto master without so much as a compile > test > (top 4 commits - ignore the 5th): > > https://github.com/abligh/qemu/commit/e711816da9831c97f7d8a111b610ef42f7ba69fa
This doesn't appear to be too useful. The AvgLength is large because INT64_MAX / GTIMER_SCALE is used as the next timer value when no timer is needed. I also changed the code to just call timer_del instead of setting a max timeout and the length looks normal (~10ms). Timer list at 0x7fae6463d680 clock 1: Address Expiries AvgLength NumShort Source 0x7fae646659e0 673 13704855334071269 0 cpu.c:229 0x7fae646650f0 691 -6386455212 0 cpu.c:229 0x7fae6480e630 1 4294967294556 0 ptimer.c:229 This seems to be more related to interaction between the 2 timers as the same timer works fine for single core use. The relevant code is target-arm/helper.c:gt_recalc_timer. I did find one bug that would seem to cause interrupts to be missed or fire twice, but it didn't make any difference: diff --git a/target-arm/helper.c b/target-arm/helper.c index ca5b000..325515f 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -905,7 +905,7 @@ static int gt_ctl_write(CPUARMState *env, const ARMCPRegInfo *ri, if ((oldval ^ value) & 1) { /* Enable toggled */ gt_recalc_timer(cpu, timeridx); - } else if ((oldval & value) & 2) { + } else if ((oldval ^ value) & 2) { /* IMASK toggled: don't need to recalculate, * just set the interrupt line based on ISTATUS */ Rob