Date: Fri, 20 Aug 2021 12:42:52 GMT From: Mark Johnston <markj@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org Subject: git: 8ad5619ec3b8 - stable/13 - ng_bridge: Use M_NOWAIT when allocating memory in the newhook routine Message-ID: <202108201242.17KCgq2R063902@gitrepo.freebsd.org>
next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=8ad5619ec3b848844cb278582e9a4a32ed0f863d commit 8ad5619ec3b848844cb278582e9a4a32ed0f863d Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2021-08-13 13:49:43 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2021-08-20 12:42: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 Sponsored by: The FreeBSD Foundation (cherry picked from commit e0e3ded78a5d0859f3520c541726b815897ba7b0) --- 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 3f3d8b3c406e..9bcc7aac271b 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) @@ -984,20 +1017,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?202108201242.17KCgq2R063902>