From owner-svn-src-all@freebsd.org Wed May 15 17:58:10 2019 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 F1832159AEC0; Wed, 15 May 2019 17:58:09 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) server-signature RSA-PSS (4096 bits) client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "Let's Encrypt Authority X3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 950DD97C4E; Wed, 15 May 2019 17:58:09 +0000 (UTC) (envelope-from ian@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 6E944D19A; Wed, 15 May 2019 17:58:09 +0000 (UTC) (envelope-from ian@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.37]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id x4FHw9NM053149; Wed, 15 May 2019 17:58:09 GMT (envelope-from ian@FreeBSD.org) Received: (from ian@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id x4FHw9Rl053148; Wed, 15 May 2019 17:58:09 GMT (envelope-from ian@FreeBSD.org) Message-Id: <201905151758.x4FHw9Rl053148@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: ian set sender to ian@FreeBSD.org using -f From: Ian Lepore Date: Wed, 15 May 2019 17:58:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r347627 - stable/11/sys/dev/dcons X-SVN-Group: stable-11 X-SVN-Commit-Author: ian X-SVN-Commit-Paths: stable/11/sys/dev/dcons X-SVN-Commit-Revision: 347627 X-SVN-Commit-Repository: base MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Rspamd-Queue-Id: 950DD97C4E X-Spamd-Bar: -- Authentication-Results: mx1.freebsd.org X-Spamd-Result: default: False [-2.96 / 15.00]; local_wl_from(0.00)[FreeBSD.org]; NEURAL_HAM_MEDIUM(-1.00)[-0.997,0]; NEURAL_HAM_SHORT(-0.96)[-0.963,0]; NEURAL_HAM_LONG(-1.00)[-1.000,0]; ASN(0.00)[asn:11403, ipnet:2610:1c1:1::/48, country:US] X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.29 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: Wed, 15 May 2019 17:58:10 -0000 Author: ian Date: Wed May 15 17:58:08 2019 New Revision: 347627 URL: https://svnweb.freebsd.org/changeset/base/347627 Log: MFC r347422: Allow dcons(4) to be unloaded when loaded as a module. When the module is unloaded, the tty devices are destroyed. That requires implementing the tsw_free callback to avoid a panic. This driver requires no particular cleanup to be done from the callback, but the module itself must remain in memory until the deferred tsw_free callbacks are invoked. These changes implement that by incrementing a reference count variable in the detach routine, and decrementing it in the tsw_free callback. The MOD_UNLOAD event handler doesn't return until the count drops to zero. PR: 237758 Modified: stable/11/sys/dev/dcons/dcons_os.c Directory Properties: stable/11/ (props changed) Modified: stable/11/sys/dev/dcons/dcons_os.c ============================================================================== --- stable/11/sys/dev/dcons/dcons_os.c Wed May 15 17:57:06 2019 (r347626) +++ stable/11/sys/dev/dcons/dcons_os.c Wed May 15 17:58:08 2019 (r347627) @@ -50,6 +50,7 @@ #include #include +#include #include #include @@ -133,12 +134,16 @@ extern struct gdb_dbgport *gdb_cur; #endif static tsw_outwakeup_t dcons_outwakeup; +static tsw_free_t dcons_free; static struct ttydevsw dcons_ttydevsw = { .tsw_flags = TF_NOPREFIX, .tsw_outwakeup = dcons_outwakeup, + .tsw_free = dcons_free, }; +static int dcons_close_refs; + #if (defined(GDB) || defined(DDB)) static int dcons_check_break(struct dcons_softc *dc, int c) @@ -196,6 +201,14 @@ dcons_os_putc(struct dcons_softc *dc, int c) } static void +dcons_free(void *xsc __unused) +{ + + /* Our deferred free has arrived, now we're waiting for one fewer. */ + atomic_subtract_rel_int(&dcons_close_refs, 1); +} + +static void dcons_outwakeup(struct tty *tp) { struct dcons_softc *dc; @@ -389,6 +402,8 @@ dcons_detach(int port) dc = &sc[port]; tp = dc->tty; + /* tty_rel_gone() schedules a deferred free callback, count it. */ + atomic_add_int(&dcons_close_refs, 1); tty_lock(tp); tty_rel_gone(tp); @@ -423,6 +438,9 @@ dcons_modevent(module_t mode, int type, void *data) contigfree(dg.buf, DCONS_BUF_SIZE, M_DEVBUF); } + /* Wait for tty deferred free callbacks to complete. */ + while (atomic_load_acq_int(&dcons_close_refs) > 0) + pause_sbt("dcunld", mstosbt(50), mstosbt(10), 0); break; case MOD_SHUTDOWN: #if 0 /* Keep connection after halt */