From 23ea8e282d0f5c53d5c8449a4d9c5774e6ed418b Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Tue, 14 Mar 2017 11:37:00 +0100 Subject: [PATCH 1/2] net/if_bridge: Create the uma zone with UMA_ZONE_NOFREE This makes it less likely that the bridge stops working after a while due to other zones hogging all the memory. The symptoms are similar to the ones reported in: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=209680 but this is a less obvious regression as if_bridge didn't use the UMA_ZONE_NOFREE flag in the past. This is a workaround and the downside of setting the flag is that unloading the bridge module leaks the memory allocated for the zone. This seems preferable to systems behind the bridge becoming unreachable, though, it's not a lot of memory and most systems never unload the module anyway. It's conceivable that removing the M_NOWAIT flag from the uma_zalloc() calls would help as well but I didn't test it. PR: https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=217606 Obtained from: ElectroBSD --- sys/net/if_bridge.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 3fbb8420b3b7..021ca7c856d9 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -553,7 +553,7 @@ bridge_modevent(module_t mod, int type, void *data) case MOD_LOAD: bridge_rtnode_zone = uma_zcreate("bridge_rtnode", sizeof(struct bridge_rtnode), NULL, NULL, NULL, NULL, - UMA_ALIGN_PTR, 0); + UMA_ALIGN_PTR|UMA_ZONE_NOFREE, 0); bridge_input_p = bridge_input; bridge_output_p = bridge_output; bridge_dn_p = bridge_dummynet; -- 2.14.1 From c9170ae0f2daf3f0cc7ca8cbe12243f40766ef17 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Mon, 20 Mar 2017 15:28:43 +0100 Subject: [PATCH 2/2] net/if_bridge: Add a sysctl to pre-allocate items for the uma zone ... and default to pre-allocating one item. Setting the UMA_ZONE_NOFREE flag is probably suffcient to workaround the uma_zalloc() failures but keeping this commit around doesn't hurt. Obtained from: ElectroBSD --- sys/net/if_bridge.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 021ca7c856d9..f3dd39c0bf9e 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -412,6 +412,10 @@ SYSCTL_INT(_net_link_bridge, OID_AUTO, allow_llz_overlap, "Allow overlap of link-local scope " "zones of a bridge interface and the member interfaces"); +static u_int bridge_uma_reserve = 1; +SYSCTL_UINT(_net_link_bridge, OID_AUTO, bridge_uma_reserve, CTLFLAG_RWTUN, + &bridge_uma_reserve, 0, "Number of items to pre-allocate for the uma zone"); + struct bridge_control { int (*bc_func)(struct bridge_softc *, void *); int bc_argsize; @@ -554,6 +558,8 @@ bridge_modevent(module_t mod, int type, void *data) bridge_rtnode_zone = uma_zcreate("bridge_rtnode", sizeof(struct bridge_rtnode), NULL, NULL, NULL, NULL, UMA_ALIGN_PTR|UMA_ZONE_NOFREE, 0); + uma_prealloc(bridge_rtnode_zone, bridge_uma_reserve); + uma_zone_reserve(bridge_rtnode_zone, bridge_uma_reserve); bridge_input_p = bridge_input; bridge_output_p = bridge_output; bridge_dn_p = bridge_dummynet; -- 2.14.1