From owner-svn-src-head@freebsd.org Thu Jul 5 17:06:55 2018 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 4A4B2103E3DE; Thu, 5 Jul 2018 17:06:55 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id F38D1899C5; Thu, 5 Jul 2018 17:06:54 +0000 (UTC) (envelope-from bz@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 mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id D16971CCAD; Thu, 5 Jul 2018 17:06:54 +0000 (UTC) (envelope-from bz@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id w65H6sl9059989; Thu, 5 Jul 2018 17:06:54 GMT (envelope-from bz@FreeBSD.org) Received: (from bz@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w65H6sVP059988; Thu, 5 Jul 2018 17:06:54 GMT (envelope-from bz@FreeBSD.org) Message-Id: <201807051706.w65H6sVP059988@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: bz set sender to bz@FreeBSD.org using -f From: "Bjoern A. Zeeb" Date: Thu, 5 Jul 2018 17:06:54 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r336003 - head/sys/kern X-SVN-Group: head X-SVN-Commit-Author: bz X-SVN-Commit-Paths: head/sys/kern X-SVN-Commit-Revision: 336003 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.27 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 05 Jul 2018 17:06:55 -0000 Author: bz Date: Thu Jul 5 17:06:54 2018 New Revision: 336003 URL: https://svnweb.freebsd.org/changeset/base/336003 Log: Split up deadlkres() to make it more readable in anticipation of further changes adding another level of indentation. Some of the logic got simplified with the break out functions. There should be no functional changes. Reviewed by: kib Sponsored by: iXsystems, Inc. Differential Revision: https://reviews.freebsd.org/D15914 Modified: head/sys/kern/kern_clock.c Modified: head/sys/kern/kern_clock.c ============================================================================== --- head/sys/kern/kern_clock.c Thu Jul 5 17:02:10 2018 (r336002) +++ head/sys/kern/kern_clock.c Thu Jul 5 17:06:54 2018 (r336003) @@ -185,12 +185,70 @@ static int blktime_threshold = 900; static int sleepfreq = 3; static void +deadlres_td_on_lock(struct proc *p, struct thread *td, int blkticks) +{ + int tticks; + + sx_assert(&allproc_lock, SX_LOCKED); + PROC_LOCK_ASSERT(p, MA_OWNED); + THREAD_LOCK_ASSERT(td, MA_OWNED); + /* + * The thread should be blocked on a turnstile, simply check + * if the turnstile channel is in good state. + */ + MPASS(td->td_blocked != NULL); + + tticks = ticks - td->td_blktick; + if (tticks > blkticks) + /* + * Accordingly with provided thresholds, this thread is stuck + * for too long on a turnstile. + */ + panic("%s: possible deadlock detected for %p, " + "blocked for %d ticks\n", __func__, td, tticks); +} + +static void +deadlres_td_sleep_q(struct proc *p, struct thread *td, int slpticks) +{ + void *wchan; + int i, slptype, tticks; + + sx_assert(&allproc_lock, SX_LOCKED); + PROC_LOCK_ASSERT(p, MA_OWNED); + THREAD_LOCK_ASSERT(td, MA_OWNED); + /* + * Check if the thread is sleeping on a lock, otherwise skip the check. + * Drop the thread lock in order to avoid a LOR with the sleepqueue + * spinlock. + */ + wchan = td->td_wchan; + tticks = ticks - td->td_slptick; + slptype = sleepq_type(wchan); + if ((slptype == SLEEPQ_SX || slptype == SLEEPQ_LK) && + tticks > slpticks) { + + /* + * Accordingly with provided thresholds, this thread is stuck + * for too long on a sleepqueue. + * However, being on a sleepqueue, we might still check for the + * blessed list. + */ + for (i = 0; blessed[i] != NULL; i++) + if (!strcmp(blessed[i], td->td_wmesg)) + return; + + panic("%s: possible deadlock detected for %p, " + "blocked for %d ticks\n", __func__, td, tticks); + } +} + +static void deadlkres(void) { struct proc *p; struct thread *td; - void *wchan; - int blkticks, i, slpticks, slptype, tryl, tticks; + int blkticks, slpticks, tryl; tryl = 0; for (;;) { @@ -198,14 +256,15 @@ deadlkres(void) slpticks = slptime_threshold * hz; /* - * Avoid to sleep on the sx_lock in order to avoid a possible - * priority inversion problem leading to starvation. + * Avoid to sleep on the sx_lock in order to avoid a + * possible priority inversion problem leading to + * starvation. * If the lock can't be held after 100 tries, panic. */ if (!sx_try_slock(&allproc_lock)) { if (tryl > 100) - panic("%s: possible deadlock detected on allproc_lock\n", - __func__); + panic("%s: possible deadlock detected " + "on allproc_lock\n", __func__); tryl++; pause("allproc", sleepfreq * hz); continue; @@ -218,80 +277,15 @@ deadlkres(void) continue; } FOREACH_THREAD_IN_PROC(p, td) { - thread_lock(td); - if (TD_ON_LOCK(td)) { - - /* - * The thread should be blocked on a - * turnstile, simply check if the - * turnstile channel is in good state. - */ - MPASS(td->td_blocked != NULL); - - tticks = ticks - td->td_blktick; - thread_unlock(td); - if (tticks > blkticks) { - - /* - * Accordingly with provided - * thresholds, this thread is - * stuck for too long on a - * turnstile. - */ - PROC_UNLOCK(p); - sx_sunlock(&allproc_lock); - panic("%s: possible deadlock detected for %p, blocked for %d ticks\n", - __func__, td, tticks); - } - } else if (TD_IS_SLEEPING(td) && - TD_ON_SLEEPQ(td)) { - - /* - * Check if the thread is sleeping on a - * lock, otherwise skip the check. - * Drop the thread lock in order to - * avoid a LOR with the sleepqueue - * spinlock. - */ - wchan = td->td_wchan; - tticks = ticks - td->td_slptick; - thread_unlock(td); - slptype = sleepq_type(wchan); - if ((slptype == SLEEPQ_SX || - slptype == SLEEPQ_LK) && - tticks > slpticks) { - - /* - * Accordingly with provided - * thresholds, this thread is - * stuck for too long on a - * sleepqueue. - * However, being on a - * sleepqueue, we might still - * check for the blessed - * list. - */ - tryl = 0; - for (i = 0; blessed[i] != NULL; - i++) { - if (!strcmp(blessed[i], - td->td_wmesg)) { - tryl = 1; - break; - } - } - if (tryl != 0) { - tryl = 0; - continue; - } - PROC_UNLOCK(p); - sx_sunlock(&allproc_lock); - panic("%s: possible deadlock detected for %p, blocked for %d ticks\n", - __func__, td, tticks); - } - } else - thread_unlock(td); + if (TD_ON_LOCK(td)) + deadlres_td_on_lock(p, td, + blkticks); + else if (TD_IS_SLEEPING(td) && + TD_ON_SLEEPQ(td)) + deadlres_td_sleep_q(p, td, + slpticks); + thread_unlock(td); } PROC_UNLOCK(p); }