From owner-svn-src-all@FreeBSD.ORG Wed Aug 25 07:33:35 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 91B441065672; Wed, 25 Aug 2010 07:33:35 +0000 (UTC) (envelope-from jchandra@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 66F7F8FC12; Wed, 25 Aug 2010 07:33:35 +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 o7P7XZvD003178; Wed, 25 Aug 2010 07:33:35 GMT (envelope-from jchandra@svn.freebsd.org) Received: (from jchandra@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o7P7XZNU003176; Wed, 25 Aug 2010 07:33:35 GMT (envelope-from jchandra@svn.freebsd.org) Message-Id: <201008250733.o7P7XZNU003176@svn.freebsd.org> From: "Jayachandran C." Date: Wed, 25 Aug 2010 07:33:35 +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: r211799 - head/sys/mips/rmi X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 25 Aug 2010 07:33:35 -0000 Author: jchandra Date: Wed Aug 25 07:33:35 2010 New Revision: 211799 URL: http://svn.freebsd.org/changeset/base/211799 Log: Sync up XLR tick.c with the new MIPS tick.c Modified: head/sys/mips/rmi/tick.c Modified: head/sys/mips/rmi/tick.c ============================================================================== --- head/sys/mips/rmi/tick.c Wed Aug 25 07:31:18 2010 (r211798) +++ head/sys/mips/rmi/tick.c Wed Aug 25 07:33:35 2010 (r211799) @@ -62,8 +62,8 @@ struct timecounter *platform_timecounter static DPCPU_DEFINE(uint32_t, cycles_per_tick); static uint32_t cycles_per_usec; -static DPCPU_DEFINE(uint32_t, counter_upper); -static DPCPU_DEFINE(uint32_t, counter_lower_last); +static DPCPU_DEFINE(volatile uint32_t, counter_upper); +static DPCPU_DEFINE(volatile uint32_t, counter_lower_last); static DPCPU_DEFINE(uint32_t, compare_ticks); static DPCPU_DEFINE(uint32_t, lost_ticks); @@ -108,23 +108,32 @@ tick_ticker(void) uint32_t t_lower_last, t_upper; /* - * XXX: MIPS64 platforms can read 64-bits of counter directly. - * Also: the tc code is supposed to cope with things wrapping - * from the time counter, so I'm not sure why all these hoops - * are even necessary. + * Disable preemption because we are working with cpu specific data. */ - ticktock = mips_rd_count(); critical_enter(); - t_lower_last = DPCPU_GET(counter_lower_last); - t_upper = DPCPU_GET(counter_upper); + + /* + * Note that even though preemption is disabled, interrupts are + * still enabled. In particular there is a race with clock_intr() + * reading the values of 'counter_upper' and 'counter_lower_last'. + * + * XXX this depends on clock_intr() being executed periodically + * so that 'counter_upper' and 'counter_lower_last' are not stale. + */ + do { + t_upper = DPCPU_GET(counter_upper); + t_lower_last = DPCPU_GET(counter_lower_last); + } while (t_upper != DPCPU_GET(counter_upper)); + + ticktock = mips_rd_count(); + + critical_exit(); + + /* COUNT register wrapped around */ if (ticktock < t_lower_last) t_upper++; - t_lower_last = ticktock; - DPCPU_SET(counter_upper, t_upper); - DPCPU_SET(counter_lower_last, t_lower_last); - critical_exit(); - ret = ((uint64_t)t_upper << 32) | t_lower_last; + ret = ((uint64_t)t_upper << 32) | ticktock; return (ret); } @@ -268,11 +277,11 @@ clock_intr(void *arg) } else /* In one-shot mode timer should be stopped after the event. */ mips_wr_compare(0xffffffff); - critical_enter(); + /* COUNT register wrapped around */ if (count < DPCPU_GET(counter_lower_last)) { DPCPU_SET(counter_upper, DPCPU_GET(counter_upper) + 1); - DPCPU_SET(counter_lower_last, count); } + DPCPU_SET(counter_lower_last, count); if (cycles_per_tick > 0) { @@ -302,7 +311,6 @@ clock_intr(void *arg) } if (sc->et.et_active) sc->et.et_event_cb(&sc->et, sc->et.et_arg); - critical_exit(); return (FILTER_HANDLED); }