From owner-p4-projects@FreeBSD.ORG Wed Dec 28 16:17:44 2005 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 20FA216A422; Wed, 28 Dec 2005 16:17:44 +0000 (GMT) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D18CC16A41F for ; Wed, 28 Dec 2005 16:17:43 +0000 (GMT) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 810D343D62 for ; Wed, 28 Dec 2005 16:17:43 +0000 (GMT) (envelope-from jhb@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id jBSGHhqW048566 for ; Wed, 28 Dec 2005 16:17:43 GMT (envelope-from jhb@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id jBSGHhS2048563 for perforce@freebsd.org; Wed, 28 Dec 2005 16:17:43 GMT (envelope-from jhb@freebsd.org) Date: Wed, 28 Dec 2005 16:17:43 GMT Message-Id: <200512281617.jBSGHhS2048563@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to jhb@freebsd.org using -f From: John Baldwin To: Perforce Change Reviews Cc: Subject: PERFORCE change 88838 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 28 Dec 2005 16:17:45 -0000 http://perforce.freebsd.org/chv.cgi?CH=88838 Change 88838 by jhb@jhb_slimer on 2005/12/28 16:17:15 Implement msleep_spin() which is a stripped down version of msleep() (no PCATCH or PDROP and no priority at all) that works with spin mutexes. Add a test event to crash.ko as well. Affected files ... .. //depot/projects/smpng/sys/kern/kern_synch.c#93 edit .. //depot/projects/smpng/sys/modules/crash/crash.c#26 edit .. //depot/projects/smpng/sys/sys/systm.h#68 edit Differences ... ==== //depot/projects/smpng/sys/kern/kern_synch.c#93 (text+ko) ==== @@ -241,6 +241,88 @@ return (rval); } +int +msleep_spin(ident, mtx, wmesg, timo) + void *ident; + struct mtx *mtx; + const char *wmesg; + int timo; +{ + struct thread *td; + struct proc *p; + int rval; + WITNESS_SAVE_DECL(mtx); + + td = curthread; + p = td->td_proc; + KASSERT(mtx != NULL, ("sleeping without a mutex")); + KASSERT(p != NULL, ("msleep1")); + KASSERT(ident != NULL && TD_IS_RUNNING(td), ("msleep")); + + if (cold) { + /* + * During autoconfiguration, just return; + * don't run any other threads or panic below, + * in case this is the idle thread and already asleep. + * XXX: this used to do "s = splhigh(); splx(safepri); + * splx(s);" to give interrupts a chance, but there is + * no way to give interrupts a chance now. + */ + return (0); + } + + sleepq_lock(ident); + CTR5(KTR_PROC, "msleep_spin: thread %p (pid %ld, %s) on %s (%p)", + (void *)td, (long)p->p_pid, p->p_comm, wmesg, ident); + + DROP_GIANT(); + mtx_assert(mtx, MA_OWNED | MA_NOTRECURSED); + WITNESS_SAVE(&mtx->mtx_object, mtx); + mtx_unlock_spin(mtx); + + /* + * We put ourselves on the sleep queue and start our timeout. + */ + sleepq_add(ident, mtx, wmesg, SLEEPQ_MSLEEP); + if (timo) + sleepq_set_timeout(ident, timo); + + /* + * Can't call ktrace with any spin locks held so it can lock the + * ktrace_mtx lock, and WITNESS_WARN considers it an error to hold + * any spin lock. Thus, we have to drop the sleepq spin lock while + * we handle those requests. This is safe since we have placed our + * thread on the sleep queue already. + */ +#ifdef KTRACE + if (KTRPOINT(td, KTR_CSW)) { + sleepq_release(ident); + ktrcsw(1, 0); + sleepq_lock(ident); + } +#endif +#ifdef WITNESS + sleepq_release(ident); + WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL, "Sleeping on \"%s\"", + wmesg); + sleepq_lock(ident); +#endif + if (timo) + rval = sleepq_timedwait(ident); + else { + sleepq_wait(ident); + rval = 0; + } +#ifdef KTRACE + if (KTRPOINT(td, KTR_CSW)) + ktrcsw(0, 0); +#endif + PICKUP_GIANT(); + mtx_lock_spin(mtx); + WITNESS_RESTORE(&mtx->mtx_object, mtx); + return (rval); +} + /* * Make all threads sleeping on the specified identifier runnable. */ ==== //depot/projects/smpng/sys/modules/crash/crash.c#26 (text+ko) ==== @@ -84,6 +84,31 @@ /* Events. */ static void +msleep_spin_callout(void *dummy) +{ + + wakeup(&test1_mtx); +} + +static void +msleep_spin_test(void) +{ + int error; + + bzero(&test1_mtx, sizeof(test1_mtx)); + mtx_init(&test1_mtx, "test1", NULL, MTX_SPIN); + error = msleep_spin(&test1_mtx, &test1_mtx, "spincr", 5); + printf("msleep_spin returned %d\n", error); + kdb_enter("timed out"); + timeout(msleep_spin_callout, NULL, 5); + error = msleep_spin(&test1_mtx, &test1_mtx, "spincr2", 0); + printf("msleep_spin returned %d\n", error); + kdb_enter("awoke from spin"); + mtx_destroy(&test1_mtx); +} +CRASH_EVENT("msleep_spin", msleep_spin_test); + +static void ddblock_test(void) { ==== //depot/projects/smpng/sys/sys/systm.h#68 (text+ko) ==== @@ -295,6 +295,7 @@ */ int msleep(void *chan, struct mtx *mtx, int pri, const char *wmesg, int timo); +int msleep_spin(void *chan, struct mtx *mtx, const char *wmesg, int timo); #define tsleep(chan, pri, wmesg, timo) msleep(chan, NULL, pri, wmesg, timo) void wakeup(void *chan) __nonnull(1); void wakeup_one(void *chan) __nonnull(1);