From owner-dev-commits-src-all@freebsd.org Thu Sep 30 02:19:55 2021 Return-Path: Delivered-To: dev-commits-src-all@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id D06826A827C; Thu, 30 Sep 2021 02:19:55 +0000 (UTC) (envelope-from git@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) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4HKcQM5QLRz3r2h; Thu, 30 Sep 2021 02:19:55 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 9A904236C5; Thu, 30 Sep 2021 02:19:55 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 18U2Jt72006391; Thu, 30 Sep 2021 02:19:55 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 18U2Jtq3006390; Thu, 30 Sep 2021 02:19:55 GMT (envelope-from git) Date: Thu, 30 Sep 2021 02:19:55 GMT Message-Id: <202109300219.18U2Jtq3006390@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Warner Losh Subject: git: e2c1243f427b - main - fd: Move from using device_busy to a refcount MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: imp X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: e2c1243f427b7dd387efd42669cc199cbb9b514c Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-all@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commit messages for all branches of the src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 30 Sep 2021 02:19:55 -0000 The branch main has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=e2c1243f427b7dd387efd42669cc199cbb9b514c commit e2c1243f427b7dd387efd42669cc199cbb9b514c Author: Warner Losh AuthorDate: 2021-09-30 02:18:28 +0000 Commit: Warner Losh CommitDate: 2021-09-30 02:18:28 +0000 fd: Move from using device_busy to a refcount Use refcounting to delay the detach rather than device_busy and/or device_unbusy. fd/fdc is one of the few consumers of device_busy in the tree for that, and it's not a good fit. Also, nothing is waking 'fd' and other drivers don't loop like this. Return EBUSY if we still have active users. Sponsored by: Netflix Reviewed by: mav Differential Revision: https://reviews.freebsd.org/D31830 --- sys/dev/fdc/fdc.c | 34 +++++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 11 deletions(-) diff --git a/sys/dev/fdc/fdc.c b/sys/dev/fdc/fdc.c index 11262231c3b2..6f035e9689f1 100644 --- a/sys/dev/fdc/fdc.c +++ b/sys/dev/fdc/fdc.c @@ -261,6 +261,7 @@ struct fd_data { struct g_provider *fd_provider; device_t dev; struct bio_queue_head fd_bq; + bool gone; }; #define FD_NOT_VALID -2 @@ -1398,6 +1399,7 @@ fdautoselect(struct fd_data *fd) static g_access_t fd_access; static g_start_t fd_start; static g_ioctl_t fd_ioctl; +static g_provgone_t fd_providergone; struct g_class g_fd_class = { .name = "FD", @@ -1405,6 +1407,7 @@ struct g_class g_fd_class = { .start = fd_start, .access = fd_access, .ioctl = fd_ioctl, + .providergone = fd_providergone, }; static int @@ -1413,7 +1416,6 @@ fd_access(struct g_provider *pp, int r, int w, int e) struct fd_data *fd; struct fdc_data *fdc; int ar, aw, ae; - int busy; fd = pp->geom->softc; fdc = fd->fdc; @@ -1431,11 +1433,9 @@ fd_access(struct g_provider *pp, int r, int w, int e) if (ar == 0 && aw == 0 && ae == 0) { fd->options &= ~(FDOPT_NORETRY | FDOPT_NOERRLOG | FDOPT_NOERROR); - device_unbusy(fd->dev); return (0); } - busy = 0; if (pp->acr == 0 && pp->acw == 0 && pp->ace == 0) { if (fdmisccmd(fd, BIO_PROBE, NULL)) return (ENXIO); @@ -1453,13 +1453,9 @@ fd_access(struct g_provider *pp, int r, int w, int e) fd->flags &= ~FD_NEWDISK; mtx_unlock(&fdc->fdc_mtx); } - device_busy(fd->dev); - busy = 1; } if (w > 0 && (fd->flags & FD_WP)) { - if (busy) - device_unbusy(fd->dev); return (EROFS); } @@ -1588,8 +1584,6 @@ fd_ioctl(struct g_provider *pp, u_long cmd, void *data, int fflag, struct thread return (error); }; - - /* * Configuration/initialization stuff, per controller. */ @@ -2055,6 +2049,16 @@ fd_attach(device_t dev) return (0); } +static void +fd_providergone(struct g_provider *pp) +{ + struct fd_data *fd; + + fd = pp->geom->softc; + fd->gone = true; + wakeup(fd); +} + static void fd_detach_geom(void *arg, int flag) { @@ -2070,9 +2074,17 @@ fd_detach(device_t dev) struct fd_data *fd; fd = device_get_softc(dev); + g_waitfor_event(fd_detach_geom, fd, M_WAITOK, NULL); - while (device_get_state(dev) == DS_BUSY) - tsleep(fd, PZERO, "fdd", hz/10); + while (!fd->gone) { + tsleep(fd, PZERO, "fdgone", hz/10); + } + + /* + * There may be accesses to the floppy while we're waitng, so drain the + * motor callback here. fdc_detach turns off motor if it's still on when + * we get to this point. + */ callout_drain(&fd->toffhandle); return (0);