From owner-svn-src-head@FreeBSD.ORG Wed Mar 24 04:52:15 2010 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 694A8106564A; Wed, 24 Mar 2010 04:52:15 +0000 (UTC) (envelope-from neel@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 4D2848FC0C; Wed, 24 Mar 2010 04:52:15 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o2O4qFO2092842; Wed, 24 Mar 2010 04:52:15 GMT (envelope-from neel@svn.freebsd.org) Received: (from neel@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o2O4qF54092840; Wed, 24 Mar 2010 04:52:15 GMT (envelope-from neel@svn.freebsd.org) Message-Id: <201003240452.o2O4qF54092840@svn.freebsd.org> From: Neel Natu Date: Wed, 24 Mar 2010 04:52:15 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r205576 - head/sys/mips/mips X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Mar 2010 04:52:15 -0000 Author: neel Date: Wed Mar 24 04:52:15 2010 New Revision: 205576 URL: http://svn.freebsd.org/changeset/base/205576 Log: Fix periodic "t_delta 16.01359db7eb5eb3c0 too long" messages on the console by accounting for the "lost time" between when the timer interrupt fired and when clock_intr() actually started executing. Modified: head/sys/mips/mips/tick.c Modified: head/sys/mips/mips/tick.c ============================================================================== --- head/sys/mips/mips/tick.c Wed Mar 24 04:37:19 2010 (r205575) +++ head/sys/mips/mips/tick.c Wed Mar 24 04:52:15 2010 (r205576) @@ -63,17 +63,14 @@ static uint64_t cycles_per_hz, cycles_pe static u_int32_t counter_upper = 0; static u_int32_t counter_lower_last = 0; -struct clk_ticks -{ +struct clk_ticks { u_long hard_ticks; u_long stat_ticks; u_long prof_ticks; - /* - * pad for cache line alignment of pcpu info - * cache-line-size - number of used bytes - */ - char pad[32-(3*sizeof (u_long))]; -} static pcpu_ticks[MAXCPU]; + uint32_t compare_ticks; +} __aligned(CACHE_LINE_SIZE); + +static struct clk_ticks pcpu_ticks[MAXCPU]; /* * Device methods @@ -260,25 +257,47 @@ clock_intr(void *arg) { struct clk_ticks *cpu_ticks; struct trapframe *tf; - uint32_t ltick; + uint32_t count, compare, delta; + + cpu_ticks = &pcpu_ticks[PCPU_GET(cpuid)]; + /* * Set next clock edge. */ - ltick = mips_rd_count(); - mips_wr_compare(ltick + cycles_per_tick); - cpu_ticks = &pcpu_ticks[PCPU_GET(cpuid)]; + count = mips_rd_count(); + compare = cpu_ticks->compare_ticks; + cpu_ticks->compare_ticks = count + cycles_per_tick; + mips_wr_compare(cpu_ticks->compare_ticks); critical_enter(); - if (ltick < counter_lower_last) { + if (count < counter_lower_last) { counter_upper++; - counter_lower_last = ltick; + counter_lower_last = count; } /* * Magic. Setting up with an arg of NULL means we get passed tf. */ tf = (struct trapframe *)arg; + delta = cycles_per_tick; + + /* + * Account for the "lost time" between when the timer interrupt fired + * and when 'clock_intr' actually started executing. + */ + delta += count - compare; + + /* + * If the COUNT and COMPARE registers are no longer in sync then make + * up some reasonable value for the 'delta'. + * + * This could happen, for e.g., after we resume normal operations after + * exiting the debugger. + */ + if (delta > cycles_per_hz) + delta = cycles_per_hz; + /* Fire hardclock at hz. */ - cpu_ticks->hard_ticks += cycles_per_tick; + cpu_ticks->hard_ticks += delta; if (cpu_ticks->hard_ticks >= cycles_per_hz) { cpu_ticks->hard_ticks -= cycles_per_hz; if (PCPU_GET(cpuid) == 0) @@ -288,14 +307,14 @@ clock_intr(void *arg) } /* Fire statclock at stathz. */ - cpu_ticks->stat_ticks += cycles_per_tick; + cpu_ticks->stat_ticks += delta; if (cpu_ticks->stat_ticks >= cycles_per_stathz) { cpu_ticks->stat_ticks -= cycles_per_stathz; statclock(USERMODE(tf->sr)); } /* Fire profclock at profhz, but only when needed. */ - cpu_ticks->prof_ticks += cycles_per_tick; + cpu_ticks->prof_ticks += delta; if (cpu_ticks->prof_ticks >= cycles_per_profhz) { cpu_ticks->prof_ticks -= cycles_per_profhz; if (profprocs != 0)