diff options
author | Bjoern A. Zeeb <bz@FreeBSD.org> | 2010-03-27 17:34:57 +0000 |
---|---|---|
committer | Bjoern A. Zeeb <bz@FreeBSD.org> | 2010-03-27 17:34:57 +0000 |
commit | e47658ce90a2aea4fac40b8f74fc8b568d4f2cd8 (patch) | |
tree | 4a7f09fa17fe42c80f530a205774c8fa06549f2a /sys/netinet/ip_input.c | |
parent | 9bdad32791730b0289c515ea47a566b79ed01aec (diff) | |
download | src-e47658ce90a2aea4fac40b8f74fc8b568d4f2cd8.tar.gz src-e47658ce90a2aea4fac40b8f74fc8b568d4f2cd8.zip |
MFC r204140:
Split up ip_drain() into an outer lock and iterator part and
a "locked" version that will only handle a single network stack
instance. The latter is called directly from ip_destroy().
Hook up an ip_destroy() function to release resources from the
legacy IP network layer upon virtual network stack teardown.
Reviewed by: rwatson
Notes
Notes:
svn path=/stable/8/; revision=205754
Diffstat (limited to 'sys/netinet/ip_input.c')
-rw-r--r-- | sys/netinet/ip_input.c | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 8ffa01ab8a23..084bac069559 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -199,6 +199,7 @@ static struct mtx ipqlock; static void maxnipq_update(void); static void ipq_zone_change(void *); +static void ip_drain_locked(void); SYSCTL_VNET_INT(_net_inet_ip, OID_AUTO, fragpackets, CTLFLAG_RD, &VNET_NAME(nipq), 0, @@ -368,6 +369,22 @@ ip_init(void) netisr_register(&ip_nh); } +#ifdef VIMAGE +void +ip_destroy(void) +{ + + /* Cleanup in_ifaddr hash table; should be empty. */ + hashdestroy(V_in_ifaddrhashtbl, M_IFADDR, V_in_ifaddrhmask); + + IPQ_LOCK(); + ip_drain_locked(); + IPQ_UNLOCK(); + + uma_zdestroy(V_ipq_zone); +} +#endif + void ip_fini(void *xtp) { @@ -1237,23 +1254,32 @@ ip_slowtimo(void) /* * Drain off all datagram fragments. */ +static void +ip_drain_locked(void) +{ + int i; + + IPQ_LOCK_ASSERT(); + + for (i = 0; i < IPREASS_NHASH; i++) { + while(!TAILQ_EMPTY(&V_ipq[i])) { + IPSTAT_ADD(ips_fragdropped, + TAILQ_FIRST(&V_ipq[i])->ipq_nfrags); + ip_freef(&V_ipq[i], TAILQ_FIRST(&V_ipq[i])); + } + } +} + void ip_drain(void) { VNET_ITERATOR_DECL(vnet_iter); - int i; VNET_LIST_RLOCK_NOSLEEP(); IPQ_LOCK(); VNET_FOREACH(vnet_iter) { CURVNET_SET(vnet_iter); - for (i = 0; i < IPREASS_NHASH; i++) { - while(!TAILQ_EMPTY(&V_ipq[i])) { - IPSTAT_ADD(ips_fragdropped, - TAILQ_FIRST(&V_ipq[i])->ipq_nfrags); - ip_freef(&V_ipq[i], TAILQ_FIRST(&V_ipq[i])); - } - } + ip_drain_locked(); CURVNET_RESTORE(); } IPQ_UNLOCK(); |