From owner-svn-src-all@freebsd.org Thu Feb 22 02:26:30 2018 Return-Path: Delivered-To: svn-src-all@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 21B2FF1AEDC; Thu, 22 Feb 2018 02:26:30 +0000 (UTC) (envelope-from jhb@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 C5847829C6; Thu, 22 Feb 2018 02:26:29 +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 mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id C05D8211F2; Thu, 22 Feb 2018 02:26:29 +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 w1M2QT4G068452; Thu, 22 Feb 2018 02:26:29 GMT (envelope-from jhb@FreeBSD.org) Received: (from jhb@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id w1M2QTR2068451; Thu, 22 Feb 2018 02:26:29 GMT (envelope-from jhb@FreeBSD.org) Message-Id: <201802220226.w1M2QTR2068451@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: jhb set sender to jhb@FreeBSD.org using -f From: John Baldwin Date: Thu, 22 Feb 2018 02:26:29 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r329796 - head/sys/dev/vt X-SVN-Group: head X-SVN-Commit-Author: jhb X-SVN-Commit-Paths: head/sys/dev/vt X-SVN-Commit-Revision: 329796 X-SVN-Commit-Repository: base 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.25 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, 22 Feb 2018 02:26:30 -0000 Author: jhb Date: Thu Feb 22 02:26:29 2018 New Revision: 329796 URL: https://svnweb.freebsd.org/changeset/base/329796 Log: Avoid grabbing locks when grabbing the vt(4) console for DDB. Trying to grab locks during cngrab() when entering the debugger is deadlock prone as all other CPUs are already halted (and thus unable to release locks) when cngrab() is invoked. One could instead use try-locks. However, the case that the try-lock fails still has to be handled. In addition, if the try-lock works it doesn't provide any greater ordering guarantees than is already provided by entering and exiting DDB. It is simpler to define a simpler path for the case that the try-lock would fail and always use that when entering DDB. Messing with timers, etc. when entering DDB is dubious even if the try-lock succeeds. This patch attempts to use the smallest possible set of operations to grab the vt(4) console when entering DDB without using any locks. Reviewed by: emaste Tested by: Matthew Macy MFC after: 1 week Modified: head/sys/dev/vt/vt_core.c Modified: head/sys/dev/vt/vt_core.c ============================================================================== --- head/sys/dev/vt/vt_core.c Thu Feb 22 02:25:09 2018 (r329795) +++ head/sys/dev/vt/vt_core.c Thu Feb 22 02:26:29 2018 (r329796) @@ -520,6 +520,27 @@ vt_window_switch(struct vt_window *vw) struct vt_window *curvw = vd->vd_curwindow; keyboard_t *kbd; + if (kdb_active) { + /* + * When grabbing the console for the debugger, avoid + * locks as that can result in deadlock. While this + * could use try locks, that wouldn't really make a + * difference as there are sufficient barriers in + * debugger entry/exit to be equivalent to + * successfully try-locking here. + */ + if (curvw == vw) + return (0); + if (!(vw->vw_flags & (VWF_OPENED|VWF_CONSOLE))) + return (EINVAL); + + vd->vd_curwindow = vw; + vd->vd_flags |= VDF_INVALID; + if (vd->vd_driver->vd_postswitch) + vd->vd_driver->vd_postswitch(vd); + return (0); + } + VT_LOCK(vd); if (curvw == vw) { /* Nothing to do. */