From owner-freebsd-current@FreeBSD.ORG Fri Sep 10 14:40:41 2010 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 2D5801065675; Fri, 10 Sep 2010 14:40:41 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from mail.zoral.com.ua (mx0.zoral.com.ua [91.193.166.200]) by mx1.freebsd.org (Postfix) with ESMTP id 8466B8FC24; Fri, 10 Sep 2010 14:40:40 +0000 (UTC) Received: from deviant.kiev.zoral.com.ua (root@deviant.kiev.zoral.com.ua [10.1.1.148]) by mail.zoral.com.ua (8.14.2/8.14.2) with ESMTP id o8AEeQrD090984 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 10 Sep 2010 17:40:26 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: from deviant.kiev.zoral.com.ua (kostik@localhost [127.0.0.1]) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4) with ESMTP id o8AEeQ1e061529; Fri, 10 Sep 2010 17:40:26 +0300 (EEST) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4/Submit) id o8AEePii061528; Fri, 10 Sep 2010 17:40:26 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: deviant.kiev.zoral.com.ua: kostik set sender to kostikbel@gmail.com using -f Date: Fri, 10 Sep 2010 17:40:25 +0300 From: Kostik Belousov To: Dimitry Andric Message-ID: <20100910144025.GQ2465@deviant.kiev.zoral.com.ua> References: <4C8A379E.6080909@deepbone.net> <4C8A414C.6000603@FreeBSD.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="v+Mbu5iuT/5Blw/K" Content-Disposition: inline In-Reply-To: <4C8A414C.6000603@FreeBSD.org> User-Agent: Mutt/1.4.2.3i X-Virus-Scanned: clamav-milter 0.95.2 at skuns.kiev.zoral.com.ua X-Virus-Status: Clean X-Spam-Status: No, score=-2.2 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_50, DNS_FROM_OPENWHOIS autolearn=no version=3.2.5 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on skuns.kiev.zoral.com.ua Cc: "Thomas E. Spanjaard" , freebsd-current@freebsd.org Subject: Re: Eventtimers b0rking w/ math/atlas X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 10 Sep 2010 14:40:41 -0000 --v+Mbu5iuT/5Blw/K Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Fri, Sep 10, 2010 at 04:31:40PM +0200, Dimitry Andric wrote: > On 2010-09-10 15:50, Thomas E. Spanjaard wrote: > >While trying to build math/atlas on a FreeBSD/amd64 9.0-CURRENT r212411, > >the kernel hangs at some point when math/atlas tries to run some tests > >(presumably the ones to profile the code and optimise). The kernel > >spouts messages about Starting event timers: LAPIC @ 1000Hz, HPET @ > >127Hz; then LAPIC @ 1000Hz, HPET @ 8128Hz (iirc), back, then back again. >=20 > It's probably running profiled executables (e.g. compiled with -pg)? > This can lead to the above messages, and apparently also to deadlocks. >=20 > I am not sure what to do about it though, except confirm that this is > very likely your problem... Try this. diff --git a/sys/kern/kern_clocksource.c b/sys/kern/kern_clocksource.c index 6b005de..7f0c781 100644 --- a/sys/kern/kern_clocksource.c +++ b/sys/kern/kern_clocksource.c @@ -65,6 +65,7 @@ inline static int doconfigtimer(int i); static void configtimer(int i); =20 static struct eventtimer *timer[2] =3D { NULL, NULL }; +static int blocked_timer[2]; static int timertest =3D 0; static int timerticks[2] =3D { 0, 0 }; static int profiling_on =3D 0; @@ -91,6 +92,22 @@ static DPCPU_DEFINE(tc, configtimer); (((uint64_t)0x8000000000000000 + ((bt)->frac >> 2)) / \ ((bt)->frac >> 1)) =20 +static void +block_timer(int i) +{ + + critical_enter(); + atomic_add_acq_int(&blocked_timer[i], 1); +} + +static void +unblock_timer(int i) +{ + + atomic_add_rel_int(&blocked_timer[i], -1); + critical_exit(); +} + /* Per-CPU timer1 handler. */ static int hardclockhandler(struct trapframe *frame) @@ -246,6 +263,8 @@ doconfigtimer(int i) atomic_store_rel_int(*conf + i, 0); return (1); } + if (atomic_load_acq_int(&blocked_timer[i]) > 0) + return (1); return (0); } =20 @@ -366,9 +385,7 @@ cpu_initclocks_bsp(void) profhz =3D round_freq(timer[1], stathz * 64); } tick =3D 1000000 / hz; - ET_LOCK(); cpu_restartclocks(); - ET_UNLOCK(); } =20 /* Start per-CPU event timers on APs. */ @@ -376,12 +393,10 @@ void cpu_initclocks_ap(void) { =20 - ET_LOCK(); if (timer[0]->et_flags & ET_FLAGS_PERCPU) et_start(timer[0], NULL, &timerperiod[0]); if (timer[1] && timer[1]->et_flags & ET_FLAGS_PERCPU) et_start(timer[1], NULL, &timerperiod[1]); - ET_UNLOCK(); } =20 /* Reconfigure and restart event timers after configuration changes. */ @@ -411,9 +426,11 @@ cpu_restartclocks(void) timer2hz =3D round_freq(timer[1], timer2hz); } timer1hz =3D round_freq(timer[0], timer1hz); +#ifdef notyet printf("Starting kernel event timers: %s @ %dHz, %s @ %dHz\n", timer[0]->et_name, timer1hz, timer[1] ? timer[1]->et_name : "NONE", timer2hz); +#endif /* Restart event timers. */ FREQ2BT(timer1hz, &timerperiod[0]); configtimer(0); @@ -422,7 +439,9 @@ cpu_restartclocks(void) timerticks[1] =3D 0; FREQ2BT(timer2hz, &timerperiod[1]); configtimer(1); +#ifdef notyet timertest =3D 1; +#endif } } =20 @@ -433,7 +452,11 @@ cpu_startprofclock(void) =20 ET_LOCK(); profiling_on =3D 1; + block_timer(0); + block_timer(1); cpu_restartclocks(); + unblock_timer(1); + unblock_timer(0); ET_UNLOCK(); } =20 @@ -444,7 +467,11 @@ cpu_stopprofclock(void) =20 ET_LOCK(); profiling_on =3D 0; + block_timer(0); + block_timer(1); cpu_restartclocks(); + unblock_timer(1); + unblock_timer(0); ET_UNLOCK(); } =20 @@ -461,10 +488,11 @@ sysctl_kern_eventtimer_timer1(SYSCTL_HANDLER_ARGS) snprintf(buf, sizeof(buf), "%s", et->et_name); ET_UNLOCK(); error =3D sysctl_handle_string(oidp, buf, sizeof(buf), req); + if (error !=3D 0 || req->newptr =3D=3D NULL) + return (error); ET_LOCK(); et =3D timer[0]; - if (error !=3D 0 || req->newptr =3D=3D NULL || - strcmp(buf, et->et_name) =3D=3D 0) { + if (strcmp(buf, et->et_name) =3D=3D 0) { ET_UNLOCK(); return (error); } @@ -473,12 +501,14 @@ sysctl_kern_eventtimer_timer1(SYSCTL_HANDLER_ARGS) ET_UNLOCK(); return (ENOENT); } + block_timer(0); timer1hz =3D 0; configtimer(0); et_free(timer[0]); timer[0] =3D et; et_init(timer[0], timer1cb, NULL, NULL); cpu_restartclocks(); + unblock_timer(0); ET_UNLOCK(); return (error); } @@ -501,10 +531,11 @@ sysctl_kern_eventtimer_timer2(SYSCTL_HANDLER_ARGS) snprintf(buf, sizeof(buf), "%s", et->et_name); ET_UNLOCK(); error =3D sysctl_handle_string(oidp, buf, sizeof(buf), req); + if (error !=3D 0 || req->newptr =3D=3D NULL) + return (error); ET_LOCK(); et =3D timer[1]; - if (error !=3D 0 || req->newptr =3D=3D NULL || - strcmp(buf, et ? et->et_name : "NONE") =3D=3D 0) { + if (strcmp(buf, et ? et->et_name : "NONE") =3D=3D 0) { ET_UNLOCK(); return (error); } @@ -513,6 +544,7 @@ sysctl_kern_eventtimer_timer2(SYSCTL_HANDLER_ARGS) ET_UNLOCK(); return (ENOENT); } + block_timer(1); if (timer[1] !=3D NULL) { timer2hz =3D 0; configtimer(1); @@ -522,6 +554,7 @@ sysctl_kern_eventtimer_timer2(SYSCTL_HANDLER_ARGS) if (timer[1] !=3D NULL) et_init(timer[1], timer2cb, NULL, NULL); cpu_restartclocks(); + unblock_timer(1); ET_UNLOCK(); return (error); } diff --git a/sys/kern/kern_et.c b/sys/kern/kern_et.c index 6a56b1d..94e1466 100644 --- a/sys/kern/kern_et.c +++ b/sys/kern/kern_et.c @@ -38,7 +38,7 @@ SLIST_HEAD(et_eventtimers_list, eventtimer); static struct et_eventtimers_list eventtimers =3D SLIST_HEAD_INITIALIZER(e= t_eventtimers); =20 struct mtx et_eventtimers_mtx; -MTX_SYSINIT(et_eventtimers_init, &et_eventtimers_mtx, "et_mtx", MTX_SPIN); +MTX_SYSINIT(et_eventtimers_init, &et_eventtimers_mtx, "et_mtx", MTX_DEF); =20 SYSCTL_NODE(_kern, OID_AUTO, eventtimer, CTLFLAG_RW, 0, "Event timers"); SYSCTL_NODE(_kern_eventtimer, OID_AUTO, et, CTLFLAG_RW, 0, ""); diff --git a/sys/sys/timeet.h b/sys/sys/timeet.h index bc713d6..87392a2 100644 --- a/sys/sys/timeet.h +++ b/sys/sys/timeet.h @@ -83,8 +83,8 @@ struct eventtimer { }; =20 extern struct mtx et_eventtimers_mtx; -#define ET_LOCK() mtx_lock_spin(&et_eventtimers_mtx) -#define ET_UNLOCK() mtx_unlock_spin(&et_eventtimers_mtx) +#define ET_LOCK() mtx_lock(&et_eventtimers_mtx) +#define ET_UNLOCK() mtx_unlock(&et_eventtimers_mtx) =20 /* Driver API */ int et_register(struct eventtimer *et); diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c index f479bbe..7811441 100644 --- a/sys/x86/x86/local_apic.c +++ b/sys/x86/x86/local_apic.c @@ -500,9 +500,11 @@ lapic_et_start(struct eventtimer *et, } while (lapic_timer_divisor <=3D 128); if (lapic_timer_divisor > 128) panic("lapic: Divisor too big"); +#ifdef notyet if (bootverbose) printf("lapic: Divisor %lu, Frequency %lu Hz\n", lapic_timer_divisor, value); +#endif et->et_frequency =3D value; et->et_min_period.sec =3D 0; et->et_min_period.frac =3D --v+Mbu5iuT/5Blw/K Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (FreeBSD) iEYEARECAAYFAkyKQ1kACgkQC3+MBN1Mb4hqiwCgof9TYCaBytdtm0dIOZaYmliT u24AoI/Fg/27D5LKV1yPP5hlAO+4mZTE =xEOU -----END PGP SIGNATURE----- --v+Mbu5iuT/5Blw/K--