From owner-dev-commits-src-all@freebsd.org Thu Mar 11 20:46:08 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 5899B5ACA03; Thu, 11 Mar 2021 20:46:08 +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 4DxLZS26y5z3t1N; Thu, 11 Mar 2021 20:46:08 +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 3BB2E3825; Thu, 11 Mar 2021 20:46:08 +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 12BKk8Ff003179; Thu, 11 Mar 2021 20:46:08 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 12BKk8Aa003178; Thu, 11 Mar 2021 20:46:08 GMT (envelope-from git) Date: Thu, 11 Mar 2021 20:46:08 GMT Message-Id: <202103112046.12BKk8Aa003178@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Mark Johnston Subject: git: 2f1cfb7f63ca - main - gmirror: Pre-allocate the timeout event structure MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: markj X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 2f1cfb7f63ca744e7a143896347bdc8606c291d6 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, 11 Mar 2021 20:46:08 -0000 The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=2f1cfb7f63ca744e7a143896347bdc8606c291d6 commit 2f1cfb7f63ca744e7a143896347bdc8606c291d6 Author: Mark Johnston AuthorDate: 2021-03-11 20:43:04 +0000 Commit: Mark Johnston CommitDate: 2021-03-11 20:45:15 +0000 gmirror: Pre-allocate the timeout event structure We can't call malloc(M_WAITOK) in a callout handler. Reviewed by: imp Reported by: pho Tested by: pho MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D29223 --- sys/geom/mirror/g_mirror.c | 43 ++++++++++++++++++++++++++++++++++--------- sys/geom/mirror/g_mirror.h | 1 + 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/sys/geom/mirror/g_mirror.c b/sys/geom/mirror/g_mirror.c index 350845205485..51836b7eabb8 100644 --- a/sys/geom/mirror/g_mirror.c +++ b/sys/geom/mirror/g_mirror.c @@ -115,6 +115,7 @@ static int g_mirror_update_disk(struct g_mirror_disk *disk, u_int state); static void g_mirror_update_device(struct g_mirror_softc *sc, bool force); static void g_mirror_dumpconf(struct sbuf *sb, const char *indent, struct g_geom *gp, struct g_consumer *cp, struct g_provider *pp); +static void g_mirror_timeout_drain(struct g_mirror_softc *sc); static int g_mirror_refresh_device(struct g_mirror_softc *sc, const struct g_provider *pp, const struct g_mirror_metadata *md); static void g_mirror_sync_reinit(const struct g_mirror_disk *disk, @@ -183,15 +184,14 @@ g_mirror_event_free(struct g_mirror_event *ep) free(ep, M_MIRROR); } -int -g_mirror_event_send(void *arg, int state, int flags) +static int +g_mirror_event_dispatch(struct g_mirror_event *ep, void *arg, int state, + int flags) { struct g_mirror_softc *sc; struct g_mirror_disk *disk; - struct g_mirror_event *ep; int error; - ep = malloc(sizeof(*ep), M_MIRROR, M_WAITOK); G_MIRROR_DEBUG(4, "%s: Sending event %p.", __func__, ep); if ((flags & G_MIRROR_EVENT_DEVICE) != 0) { disk = NULL; @@ -226,6 +226,15 @@ g_mirror_event_send(void *arg, int state, int flags) return (error); } +int +g_mirror_event_send(void *arg, int state, int flags) +{ + struct g_mirror_event *ep; + + ep = malloc(sizeof(*ep), M_MIRROR, M_WAITOK); + return (g_mirror_event_dispatch(ep, arg, state, flags)); +} + static struct g_mirror_event * g_mirror_event_first(struct g_mirror_softc *sc) { @@ -582,7 +591,7 @@ g_mirror_destroy_device(struct g_mirror_softc *sc) mtx_unlock(&sc->sc_events_mtx); } } - callout_drain(&sc->sc_callout); + g_mirror_timeout_drain(sc); g_topology_lock(); LIST_FOREACH_SAFE(cp, &sc->sc_sync.ds_geom->consumer, consumer, tmpcp) { @@ -2291,13 +2300,26 @@ static void g_mirror_go(void *arg) { struct g_mirror_softc *sc; + struct g_mirror_event *ep; sc = arg; G_MIRROR_DEBUG(0, "Force device %s start due to timeout.", sc->sc_name); - g_mirror_event_send(sc, 0, + ep = sc->sc_timeout_event; + sc->sc_timeout_event = NULL; + g_mirror_event_dispatch(ep, sc, 0, G_MIRROR_EVENT_DONTWAIT | G_MIRROR_EVENT_DEVICE); } +static void +g_mirror_timeout_drain(struct g_mirror_softc *sc) +{ + sx_assert(&sc->sc_lock, SX_XLOCKED); + + callout_drain(&sc->sc_callout); + g_mirror_event_free(sc->sc_timeout_event); + sc->sc_timeout_event = NULL; +} + static u_int g_mirror_determine_state(struct g_mirror_disk *disk) { @@ -2454,7 +2476,7 @@ g_mirror_update_device(struct g_mirror_softc *sc, bool force) * Disks went down in starting phase, so destroy * device. */ - callout_drain(&sc->sc_callout); + g_mirror_timeout_drain(sc); sc->sc_flags |= G_MIRROR_DEVICE_FLAG_DESTROY; G_MIRROR_DEBUG(1, "root_mount_rel[%u] %p", __LINE__, sc->sc_rootmount); @@ -2491,7 +2513,7 @@ g_mirror_update_device(struct g_mirror_softc *sc, bool force) } } else { /* Cancel timeout. */ - callout_drain(&sc->sc_callout); + g_mirror_timeout_drain(sc); } /* @@ -3153,10 +3175,13 @@ g_mirror_create(struct g_class *mp, const struct g_mirror_metadata *md, sc->sc_rootmount = root_mount_hold("GMIRROR"); G_MIRROR_DEBUG(1, "root_mount_hold %p", sc->sc_rootmount); + /* - * Run timeout. + * Schedule startup timeout. */ timeout = g_mirror_timeout * hz; + sc->sc_timeout_event = malloc(sizeof(struct g_mirror_event), M_MIRROR, + M_WAITOK); callout_reset(&sc->sc_callout, timeout, g_mirror_go, sc); return (sc->sc_geom); } diff --git a/sys/geom/mirror/g_mirror.h b/sys/geom/mirror/g_mirror.h index 57f341f752e1..7cec94adae18 100644 --- a/sys/geom/mirror/g_mirror.h +++ b/sys/geom/mirror/g_mirror.h @@ -207,6 +207,7 @@ struct g_mirror_softc { TAILQ_HEAD(, g_mirror_event) sc_events; struct mtx sc_events_mtx; + struct g_mirror_event *sc_timeout_event; struct callout sc_callout;