Date: Fri, 13 Aug 2021 13:58:56 GMT From: Mark Johnston <markj@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: e0e3ded78a5d - main - ng_bridge: Use M_NOWAIT when allocating memory in the newhook routine Message-ID: <202108131358.17DDwuex088194@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=e0e3ded78a5d0859f3520c541726b815897ba7b0 commit e0e3ded78a5d0859f3520c541726b815897ba7b0 Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2021-08-13 13:49:43 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2021-08-13 13:49:43 +0000 ng_bridge: Use M_NOWAIT when allocating memory in the newhook routine newhook can be invoked by ngthread, which runs in a network epoch section and is thus not permitted to perform M_WAITOK allocations. Reported by: Jenkins Reviewed by: donner, afedorov MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D31486 --- sys/netgraph/ng_bridge.c | 84 ++++++++++++++++++++++++++++++------------------ 1 file changed, 52 insertions(+), 32 deletions(-) diff --git a/sys/netgraph/ng_bridge.c b/sys/netgraph/ng_bridge.c index 03d5125972d0..12cc619241b6 100644 --- a/sys/netgraph/ng_bridge.c +++ b/sys/netgraph/ng_bridge.c @@ -154,6 +154,7 @@ static ng_rcvdata_t ng_bridge_rcvdata; static ng_disconnect_t ng_bridge_disconnect; /* Other internal functions */ +static void ng_bridge_free_link(link_p link); static struct ng_bridge_host *ng_bridge_get(priv_cp priv, const u_char *addr); static int ng_bridge_put(priv_p priv, const u_char *addr, link_p link); static void ng_bridge_rehash(priv_p priv); @@ -395,28 +396,36 @@ ng_bridge_newhook(node_p node, hook_p hook, const char *name) if(NG_PEER_NODE(hook) == node) return (ELOOP); - link = malloc(sizeof(*link), M_NETGRAPH_BRIDGE, M_WAITOK | M_ZERO); - - link->stats.recvOctets = counter_u64_alloc(M_WAITOK); - link->stats.recvPackets = counter_u64_alloc(M_WAITOK); - link->stats.recvMulticasts = counter_u64_alloc(M_WAITOK); - link->stats.recvBroadcasts = counter_u64_alloc(M_WAITOK); - link->stats.recvUnknown = counter_u64_alloc(M_WAITOK); - link->stats.recvRunts = counter_u64_alloc(M_WAITOK); - link->stats.recvInvalid = counter_u64_alloc(M_WAITOK); - link->stats.xmitOctets = counter_u64_alloc(M_WAITOK); - link->stats.xmitPackets = counter_u64_alloc(M_WAITOK); - link->stats.xmitMulticasts = counter_u64_alloc(M_WAITOK); - link->stats.xmitBroadcasts = counter_u64_alloc(M_WAITOK); - link->stats.loopDrops = counter_u64_alloc(M_WAITOK); - link->stats.memoryFailures = counter_u64_alloc(M_WAITOK); + link = malloc(sizeof(*link), M_NETGRAPH_BRIDGE, M_NOWAIT | M_ZERO); + if (link == NULL) + return (ENOMEM); + +#define NG_BRIDGE_COUNTER_ALLOC(f) do { \ + link->stats.f = counter_u64_alloc(M_NOWAIT); \ + if (link->stats.f == NULL) \ + goto nomem; \ +} while (0) + NG_BRIDGE_COUNTER_ALLOC(recvOctets); + NG_BRIDGE_COUNTER_ALLOC(recvPackets); + NG_BRIDGE_COUNTER_ALLOC(recvMulticasts); + NG_BRIDGE_COUNTER_ALLOC(recvBroadcasts); + NG_BRIDGE_COUNTER_ALLOC(recvUnknown); + NG_BRIDGE_COUNTER_ALLOC(recvRunts); + NG_BRIDGE_COUNTER_ALLOC(recvInvalid); + NG_BRIDGE_COUNTER_ALLOC(xmitOctets); + NG_BRIDGE_COUNTER_ALLOC(xmitPackets); + NG_BRIDGE_COUNTER_ALLOC(xmitMulticasts); + NG_BRIDGE_COUNTER_ALLOC(xmitBroadcasts); + NG_BRIDGE_COUNTER_ALLOC(loopDrops); + NG_BRIDGE_COUNTER_ALLOC(memoryFailures); +#undef NG_BRIDGE_COUNTER_ALLOC link->hook = hook; if (isUplink) { link->learnMac = 0; link->sendUnknown = 1; if (priv->numLinks == 0) /* if the first link is an uplink */ - priv->sendUnknown = 0; /* switch to restrictive mode */ + priv->sendUnknown = 0; /* switch to restrictive mode */ } else { link->learnMac = 1; link->sendUnknown = priv->sendUnknown; @@ -425,12 +434,17 @@ ng_bridge_newhook(node_p node, hook_p hook, const char *name) NG_HOOK_SET_PRIVATE(hook, link); priv->numLinks++; return (0); + +nomem: + ng_bridge_free_link(link); + return (ENOMEM); } /* * Receive a control message */ -static void ng_bridge_clear_link_stats(struct ng_bridge_link_kernel_stats * p) +static void +ng_bridge_clear_link_stats(struct ng_bridge_link_kernel_stats *p) { counter_u64_zero(p->recvOctets); counter_u64_zero(p->recvPackets); @@ -446,7 +460,26 @@ static void ng_bridge_clear_link_stats(struct ng_bridge_link_kernel_stats * p) counter_u64_zero(p->loopDrops); p->loopDetects = 0; counter_u64_zero(p->memoryFailures); -}; +} + +static void +ng_bridge_free_link(link_p link) +{ + counter_u64_free(link->stats.recvOctets); + counter_u64_free(link->stats.recvPackets); + counter_u64_free(link->stats.recvMulticasts); + counter_u64_free(link->stats.recvBroadcasts); + counter_u64_free(link->stats.recvUnknown); + counter_u64_free(link->stats.recvRunts); + counter_u64_free(link->stats.recvInvalid); + counter_u64_free(link->stats.xmitOctets); + counter_u64_free(link->stats.xmitPackets); + counter_u64_free(link->stats.xmitMulticasts); + counter_u64_free(link->stats.xmitBroadcasts); + counter_u64_free(link->stats.loopDrops); + counter_u64_free(link->stats.memoryFailures); + free(link, M_NETGRAPH_BRIDGE); +} static int ng_bridge_reset_link(hook_p hook, void *arg __unused) @@ -915,20 +948,7 @@ ng_bridge_disconnect(hook_p hook) ng_bridge_remove_hosts(priv, link); /* Free associated link information */ - counter_u64_free(link->stats.recvOctets); - counter_u64_free(link->stats.recvPackets); - counter_u64_free(link->stats.recvMulticasts); - counter_u64_free(link->stats.recvBroadcasts); - counter_u64_free(link->stats.recvUnknown); - counter_u64_free(link->stats.recvRunts); - counter_u64_free(link->stats.recvInvalid); - counter_u64_free(link->stats.xmitOctets); - counter_u64_free(link->stats.xmitPackets); - counter_u64_free(link->stats.xmitMulticasts); - counter_u64_free(link->stats.xmitBroadcasts); - counter_u64_free(link->stats.loopDrops); - counter_u64_free(link->stats.memoryFailures); - free(link, M_NETGRAPH_BRIDGE); + ng_bridge_free_link(link); priv->numLinks--; /* If no more hooks, go away */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202108131358.17DDwuex088194>