From owner-dev-commits-src-branches@freebsd.org Sun Sep 12 16:35:18 2021 Return-Path: Delivered-To: dev-commits-src-branches@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 87D716694C1; Sun, 12 Sep 2021 16:35:18 +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 4H6wFf3Npzz3nRW; Sun, 12 Sep 2021 16:35:18 +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 50E8216DC9; Sun, 12 Sep 2021 16:35:18 +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 18CGZIvr073940; Sun, 12 Sep 2021 16:35:18 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 18CGZIef073939; Sun, 12 Sep 2021 16:35:18 GMT (envelope-from git) Date: Sun, 12 Sep 2021 16:35:18 GMT Message-Id: <202109121635.18CGZIef073939@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Warner Losh Subject: git: 55f527816ddb - stable/13 - geom: create an API to allocate events, and use that storage to send them 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/stable/13 X-Git-Reftype: branch X-Git-Commit: 55f527816ddbacb9fcce7b95d5be20fb0617d5c2 Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-branches@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commits to the stable branches of the FreeBSD src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 12 Sep 2021 16:35:18 -0000 The branch stable/13 has been updated by imp: URL: https://cgit.FreeBSD.org/src/commit/?id=55f527816ddbacb9fcce7b95d5be20fb0617d5c2 commit 55f527816ddbacb9fcce7b95d5be20fb0617d5c2 Author: Warner Losh AuthorDate: 2021-07-23 21:16:57 +0000 Commit: Warner Losh CommitDate: 2021-09-12 15:56:13 +0000 geom: create an API to allocate events, and use that storage to send them g_alloc_event will allocate storage for an opaque event. g_post_event_ep can use memory returned by g_alloc_event to send an event from a context that might not be able to allocate the event. Occasionally, we can alloate memory when we create an object, but not while we're destroy it. This allows one to allocate at creation time memory to use when destorying the object. Reviewed by: jhb Sponsored by: Netflix Differential Revision: https://reviews.freebsd.org/D30544 (cherry picked from commit 380710a5c8c1fd638ec961351b75b667e91667c9) --- share/man/man9/g_event.9 | 32 ++++++++++++++++++++++++++++- sys/geom/geom.h | 3 +++ sys/geom/geom_event.c | 52 +++++++++++++++++++++++++++++++++++++----------- 3 files changed, 74 insertions(+), 13 deletions(-) diff --git a/share/man/man9/g_event.9 b/share/man/man9/g_event.9 index 0bdd0ab6688b..32c4703100d8 100644 --- a/share/man/man9/g_event.9 +++ b/share/man/man9/g_event.9 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd January 16, 2004 +.Dd July 23, 2021 .Dt G_EVENT 9 .Os .Sh NAME @@ -40,6 +40,10 @@ .Fn g_waitfor_event "g_event_t *func" "void *arg" "int flag" ... .Ft void .Fn g_cancel_event "void *ref" +.Ft "struct g_event *" +.Fn g_alloc_event "int flag" +.Ft void +.Fn g_post_event_ep "g_event_t *func" "void *arg" "struct g_event *ep" ... .Sh DESCRIPTION The GEOM framework has its own event queue to inform classes about important events. @@ -80,6 +84,13 @@ function. It waits until the event is finished or canceled and then returns. .Pp The +.Fn g_post_event_ep +function posts the event with a pre-allocated +.Va struct g_event . +An event may be pre-allocated with +.Fn g_alloc_event . +.Pp +The .Fn g_cancel_event function cancels all event(s) identified by .Fa ref . @@ -123,6 +134,25 @@ The function cannot be called from an event, since doing so would result in a deadlock. .El +.Pp +.Fn g_alloc_event : +.Bl -item -offset indent +.It +The argument +.Fa flag +has to be +.Dv M_WAITOK +or +.Dv M_NOWAIT . +.It +The returned +.Va struct g_event * +must be freed with +.Fn g_free +if +.Fn g_post_event_ep +is not called. +.El .Sh RETURN VALUES The .Fn g_post_event diff --git a/sys/geom/geom.h b/sys/geom/geom.h index cb294e2c7451..1aba1f46d6d5 100644 --- a/sys/geom/geom.h +++ b/sys/geom/geom.h @@ -260,6 +260,7 @@ extern int g_debugflags; /* geom_event.c */ typedef void g_event_t(void *, int flag); +struct g_event; #define EV_CANCEL 1 int g_post_event(g_event_t *func, void *arg, int flag, ...); int g_waitfor_event(g_event_t *func, void *arg, int flag, ...); @@ -269,6 +270,8 @@ int g_media_changed(struct g_provider *pp, int flag); int g_media_gone(struct g_provider *pp, int flag); void g_orphan_provider(struct g_provider *pp, int error); void g_waitidlelock(void); +struct g_event *g_alloc_event(int flag); +void g_post_event_ep(g_event_t *func, void *arg, struct g_event *ep, ...); /* geom_subr.c */ int g_access(struct g_consumer *cp, int nread, int nwrite, int nexcl); diff --git a/sys/geom/geom_event.c b/sys/geom/geom_event.c index b829d2ef637c..f9a1d445d36a 100644 --- a/sys/geom/geom_event.c +++ b/sys/geom/geom_event.c @@ -341,20 +341,22 @@ g_cancel_event(void *ref) mtx_unlock(&g_eventlock); } -static int -g_post_event_x(g_event_t *func, void *arg, int flag, int wuflag, struct g_event **epp, va_list ap) +struct g_event * +g_alloc_event(int flag) +{ + KASSERT(flag == M_WAITOK || flag == M_NOWAIT, + ("Wrong flag to g_alloc_event")); + + return (g_malloc(sizeof(struct g_event), flag | M_ZERO)); +} + +static void +g_post_event_ep_va(g_event_t *func, void *arg, int wuflag, + struct g_event *ep, va_list ap) { - struct g_event *ep; void *p; u_int n; - g_trace(G_T_TOPOLOGY, "g_post_event_x(%p, %p, %d, %d)", - func, arg, flag, wuflag); - KASSERT(wuflag == 0 || wuflag == EV_WAKEUP, - ("Wrong wuflag in g_post_event_x(0x%x)", wuflag)); - ep = g_malloc(sizeof *ep, flag | M_ZERO); - if (ep == NULL) - return (ENOMEM); ep->flag = wuflag; for (n = 0; n < G_N_EVENTREFS; n++) { p = va_arg(ap, void *); @@ -371,12 +373,38 @@ g_post_event_x(g_event_t *func, void *arg, int flag, int wuflag, struct g_event TAILQ_INSERT_TAIL(&g_events, ep, events); mtx_unlock(&g_eventlock); wakeup(&g_wait_event); - if (epp != NULL) - *epp = ep; curthread->td_pflags |= TDP_GEOM; thread_lock(curthread); curthread->td_flags |= TDF_ASTPENDING; thread_unlock(curthread); +} + +void +g_post_event_ep(g_event_t *func, void *arg, struct g_event *ep, ...) +{ + va_list ap; + + va_start(ap, ep); + g_post_event_ep_va(func, arg, 0, ep, ap); + va_end(ap); +} + + +static int +g_post_event_x(g_event_t *func, void *arg, int flag, int wuflag, struct g_event **epp, va_list ap) +{ + struct g_event *ep; + + g_trace(G_T_TOPOLOGY, "g_post_event_x(%p, %p, %d, %d)", + func, arg, flag, wuflag); + KASSERT(wuflag == 0 || wuflag == EV_WAKEUP, + ("Wrong wuflag in g_post_event_x(0x%x)", wuflag)); + ep = g_alloc_event(flag); + if (ep == NULL) + return (ENOMEM); + if (epp != NULL) + *epp = ep; + g_post_event_ep_va(func, arg, wuflag, ep, ap); return (0); }