From owner-svn-src-all@freebsd.org Thu Mar 31 18:10:30 2016 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id B40F4AD6475; Thu, 31 Mar 2016 18:10:30 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 722F01E99; Thu, 31 Mar 2016 18:10:30 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id u2VIAT8f089199; Thu, 31 Mar 2016 18:10:29 GMT (envelope-from jhb@FreeBSD.org) Received: (from jhb@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id u2VIATsi089196; Thu, 31 Mar 2016 18:10:29 GMT (envelope-from jhb@FreeBSD.org) Message-Id: <201603311810.u2VIATsi089196@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhb set sender to jhb@FreeBSD.org using -f From: John Baldwin Date: Thu, 31 Mar 2016 18:10:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r297466 - head/sys/kern X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.21 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: Thu, 31 Mar 2016 18:10:30 -0000 Author: jhb Date: Thu Mar 31 18:10:29 2016 New Revision: 297466 URL: https://svnweb.freebsd.org/changeset/base/297466 Log: Rework handling of thread sleeps before timers are working. Previously, calls to *sleep() and cv_*wait*() immediately returned during early boot. Instead, permit threads that request a sleep without a timeout to sleep as wakeup() works during early boot. Sleeps with timeouts are harder to emulate without working timers, so just punt and panic explicitly if any thread tries to use those before timers are working. Any threads that depend on timeouts should either wait until SI_SUB_KICK_SCHEDULER to start or they should use DELAY() until timers are available. Until APs are started earlier this should be a no-op as other kthreads shouldn't get a chance to start running until after timers are working regardless of when they were created. Reviewed by: kib Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D5724 Modified: head/sys/kern/kern_condvar.c head/sys/kern/kern_synch.c head/sys/kern/subr_sleepqueue.c Modified: head/sys/kern/kern_condvar.c ============================================================================== --- head/sys/kern/kern_condvar.c Thu Mar 31 17:32:28 2016 (r297465) +++ head/sys/kern/kern_condvar.c Thu Mar 31 18:10:29 2016 (r297466) @@ -122,15 +122,8 @@ _cv_wait(struct cv *cvp, struct lock_obj "Waiting on \"%s\"", cvp->cv_description); class = LOCK_CLASS(lock); - if (cold || SCHEDULER_STOPPED()) { - /* - * During autoconfiguration, just give interrupts - * a chance, then just return. Don't run any other - * thread or panic below, in case this is the idle - * process and already asleep. - */ + if (SCHEDULER_STOPPED()) return; - } sleepq_lock(cvp); @@ -183,13 +176,7 @@ _cv_wait_unlock(struct cv *cvp, struct l ("cv_wait_unlock cannot be used with Giant")); class = LOCK_CLASS(lock); - if (cold || SCHEDULER_STOPPED()) { - /* - * During autoconfiguration, just give interrupts - * a chance, then just return. Don't run any other - * thread or panic below, in case this is the idle - * process and already asleep. - */ + if (SCHEDULER_STOPPED()) { class->lc_unlock(lock); return; } @@ -240,15 +227,8 @@ _cv_wait_sig(struct cv *cvp, struct lock "Waiting on \"%s\"", cvp->cv_description); class = LOCK_CLASS(lock); - if (cold || SCHEDULER_STOPPED()) { - /* - * After a panic, or during autoconfiguration, just give - * interrupts a chance, then just return; don't run any other - * procs or panic below, in case this is the idle process and - * already asleep. - */ + if (SCHEDULER_STOPPED()) return (0); - } sleepq_lock(cvp); @@ -307,15 +287,8 @@ _cv_timedwait_sbt(struct cv *cvp, struct "Waiting on \"%s\"", cvp->cv_description); class = LOCK_CLASS(lock); - if (cold || SCHEDULER_STOPPED()) { - /* - * After a panic, or during autoconfiguration, just give - * interrupts a chance, then just return; don't run any other - * thread or panic below, in case this is the idle process and - * already asleep. - */ - return 0; - } + if (SCHEDULER_STOPPED()) + return (0); sleepq_lock(cvp); @@ -376,15 +349,8 @@ _cv_timedwait_sig_sbt(struct cv *cvp, st "Waiting on \"%s\"", cvp->cv_description); class = LOCK_CLASS(lock); - if (cold || SCHEDULER_STOPPED()) { - /* - * After a panic, or during autoconfiguration, just give - * interrupts a chance, then just return; don't run any other - * thread or panic below, in case this is the idle process and - * already asleep. - */ - return 0; - } + if (SCHEDULER_STOPPED()) + return (0); sleepq_lock(cvp); Modified: head/sys/kern/kern_synch.c ============================================================================== --- head/sys/kern/kern_synch.c Thu Mar 31 17:32:28 2016 (r297465) +++ head/sys/kern/kern_synch.c Thu Mar 31 18:10:29 2016 (r297466) @@ -162,15 +162,7 @@ _sleep(void *ident, struct lock_object * else class = NULL; - if (cold || SCHEDULER_STOPPED()) { - /* - * 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. - */ + if (SCHEDULER_STOPPED()) { if (lock != NULL && priority & PDROP) class->lc_unlock(lock); return (0); @@ -264,17 +256,8 @@ msleep_spin_sbt(void *ident, struct mtx KASSERT(p != NULL, ("msleep1")); KASSERT(ident != NULL && TD_IS_RUNNING(td), ("msleep")); - if (cold || SCHEDULER_STOPPED()) { - /* - * 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. - */ + if (SCHEDULER_STOPPED()) return (0); - } sleepq_lock(ident); CTR5(KTR_PROC, "msleep_spin: thread %ld (pid %ld, %s) on %s (%p)", Modified: head/sys/kern/subr_sleepqueue.c ============================================================================== --- head/sys/kern/subr_sleepqueue.c Thu Mar 31 17:32:28 2016 (r297465) +++ head/sys/kern/subr_sleepqueue.c Thu Mar 31 18:10:29 2016 (r297466) @@ -385,6 +385,8 @@ sleepq_set_timeout_sbt(void *wchan, sbin MPASS(TD_ON_SLEEPQ(td)); MPASS(td->td_sleepqueue == NULL); MPASS(wchan != NULL); + if (cold) + panic("timed sleep before timers are working"); callout_reset_sbt_on(&td->td_slpcallout, sbt, pr, sleepq_timeout, td, PCPU_GET(cpuid), flags | C_DIRECT_EXEC); }