From owner-freebsd-hackers Thu Aug 30 15:59:12 2001 Delivered-To: freebsd-hackers@freebsd.org Received: from midten.fast.no (midten.fast.no [213.188.8.11]) by hub.freebsd.org (Postfix) with ESMTP id DEE0F37B407; Thu, 30 Aug 2001 15:59:03 -0700 (PDT) (envelope-from Tor.Egge@fast.no) Received: from fast.no (IDENT:tegge@midten.fast.no [213.188.8.11]) by midten.fast.no (8.9.3/8.9.3) with ESMTP id AAA75808; Fri, 31 Aug 2001 00:54:23 +0200 (CEST) Message-Id: <200108302254.AAA75808@midten.fast.no> To: mb@imp.ch Cc: bde@zeta.org.au, bkarp@icsi.berkeley.edu, kpielorz@tdx.co.uk, sthaug@nethelp.no, atrn@zeta.org.au, roberto@eurocontrol.fr, drussell@saturn-tech.com, phk@FreeBSD.ORG, Patrick.Guelat@imp.ch, freebsd-hackers@FreeBSD.ORG, freebsd-smp@FreeBSD.ORG Subject: Re: Clock speedup on 4.X FreeBSD SMP and serverworks chipset From: Tor.Egge@fast.no In-Reply-To: Your message of "Thu, 30 Aug 2001 17:14:33 +0200 (CEST)" References: <20010830171101.I676-100000@levais.imp.ch> X-Mailer: Mew version 1.70 on Emacs 19.34.1 Mime-Version: 1.0 Content-Type: Text/Plain; charset=us-ascii Content-Transfer-Encoding: 7bit Date: Fri, 31 Aug 2001 00:54:21 +0200 Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG > --- sys/i386/isa/clock.c Thu Aug 30 17:01:31 2001 > +++ sys/i386/isa/clock.c.new Thu Aug 30 17:01:29 2001 > @@ -1203,7 +1203,7 @@ > high = inb(TIMER_CNTR0); > count = timer0_max_count - ((high << 8) | low); > if (count < i8254_lastcount || > - (!i8254_ticked && (clkintr_pending || > + (!i8254_ticked && (/*clkintr_pending || */ > ((count < 20 || (!(ef & PSL_I) && count < timer0_max_count / > 2u)) && > #ifdef APIC_IO > #define lapic_irr1 ((volatile u_int *)&lapic)[0x210 / 4] /* > XXX XXX */ > > We are looking now why this happens. One scenario where this problem will happen: CPU #0 CPU#1 calls i8254_gettimecount locks clock_lock reads high value for count Gets interrupt from i8254 sets clkintr_pending fails to get Giant forward interrupt sees clkintr_pending steps i8254_offset due to clkintr_pending sets i8254_ticked to 1 sets i8254_lastcount to high value unlocks clock_lock receive forwarded interrupt locks clock_lock doesn't step i8254_offset due to i8254_ticked being 1 doesn't set i8254_lastcount calls i8254_gettimecount again locks clock_lock reads low value for count steps i8254_offset due to count < i8254_lastcount sets i8254_ticked to 1 The problem here is that CPU#1 fails to hold clock_lock while setting clkintr_pending, causing i8254_offset to be stepped twice, first due to clkintr_pending, then due to i8254_lastcount being larger than count. According to icu_setup(), CPU interrupt vector TPR_FAST_INTS + apic_8254_intr is used, normally 0x60. Thus any check for lapic_irr1 is bogus. Checking lapic_irr3 isn't failsafe since the interrupt can be in the process of being delivered to another CPU. - Tor Egge To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message