Index: sys/netinet6/frag6.c =================================================================== --- sys/netinet6/frag6.c +++ sys/netinet6/frag6.c @@ -116,7 +116,7 @@ /* System wide (global) maximum and count of packets in reassembly queues. */ static int ip6_maxfrags; -static volatile u_int frag6_nfrags = 0; +static u_int __exclusive_cache_line frag6_nfrags; /* Maximum and current packets in per-VNET reassembly queue. */ VNET_DEFINE_STATIC(int, ip6_maxfragpackets); @@ -164,7 +164,7 @@ SYSCTL_DECL(_net_inet6_ip6); SYSCTL_UINT(_net_inet6_ip6, OID_AUTO, frag6_nfrags, - CTLFLAG_RD, __DEVOLATILE(u_int *, &frag6_nfrags), 0, + CTLFLAG_RD, &frag6_nfrags, 0, "Global number of IPv6 fragments across all reassembly queues."); static void @@ -891,10 +891,15 @@ struct ip6q *q6, *q6tmp; uint32_t bucket; + if (atomic_load_int(&frag6_nfrags) == 0) + return; + VNET_LIST_RLOCK_NOSLEEP(); VNET_FOREACH(vnet_iter) { CURVNET_SET(vnet_iter); for (bucket = 0; bucket < IP6REASS_NHASH; bucket++) { + if (V_ip6qb[bucket].count == 0) + continue; IP6QB_LOCK(bucket); head = IP6QB_HEAD(bucket); TAILQ_FOREACH_SAFE(q6, head, ip6q_tq, q6tmp)