PERFORCE change 167988 for review
Marko Zec
zec at FreeBSD.org
Sun Aug 30 20:19:39 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=167988
Change 167988 by zec at zec_tpx32 on 2009/08/30 20:18:55
Attempt at improving memory housekeeping when vnets get destroyed.
This change seems not to be introducing any new panics, while
succeeding in really freeing up a few hashtables, and making
more visible attempts at destroying UMA zones which still hold
some unreleased elements.
Affected files ...
.. //depot/projects/vimage-commit2/src/sys/compat/linux/linux_ioctl.c#25 edit
.. //depot/projects/vimage-commit2/src/sys/net/flowtable.c#14 edit
.. //depot/projects/vimage-commit2/src/sys/net/flowtable.h#11 edit
.. //depot/projects/vimage-commit2/src/sys/net/route.c#48 edit
.. //depot/projects/vimage-commit2/src/sys/net/vnet.c#8 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/in_proto.c#18 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/in_var.h#15 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/ip_input.c#51 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/ip_var.h#23 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/raw_ip.c#37 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/tcp_hostcache.c#32 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/tcp_reass.c#21 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/tcp_subr.c#58 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/tcp_syncache.c#41 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/tcp_timewait.c#33 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/tcp_var.h#22 edit
.. //depot/projects/vimage-commit2/src/sys/netinet/udp_usrreq.c#47 edit
Differences ...
==== //depot/projects/vimage-commit2/src/sys/compat/linux/linux_ioctl.c#25 (text+ko) ====
==== //depot/projects/vimage-commit2/src/sys/net/flowtable.c#14 (text+ko) ====
@@ -803,6 +803,21 @@
return (ft);
}
+#ifdef VIMAGE
+/*
+ * This should be a reverse of flowtable_alloc(), which is called once
+ * per-protocol per-vnet.
+ */
+void
+flowtable_free(struct flowtable *ft)
+{
+
+#ifdef NOTYET
+ panic("fixme here");
+#endif
+}
+#endif
+
/*
* The rest of the code is devoted to garbage collection of expired entries.
* It is a new additon made necessary by the switch to dynamically allocating
==== //depot/projects/vimage-commit2/src/sys/net/flowtable.h#11 (text+ko) ====
@@ -42,6 +42,7 @@
#define V_ip_ft VNET(ip_ft)
struct flowtable *flowtable_alloc(int nentry, int flags);
+void flowtable_free(struct flowtable *ft);
/*
* Given a flow table, look up the L3 and L2 information and
==== //depot/projects/vimage-commit2/src/sys/net/route.c#48 (text+ko) ====
@@ -247,6 +247,9 @@
}
}
}
+
+ uma_zdestroy(V_rtzone);
+ free(V_rt_tables, M_RTABLE);
}
VNET_SYSUNINIT(vnet_route_uninit, SI_SUB_PROTO_DOMAIN, SI_ORDER_THIRD,
vnet_route_uninit, 0);
==== //depot/projects/vimage-commit2/src/sys/net/vnet.c#8 (text+ko) ====
@@ -56,6 +56,7 @@
#endif
#include <net/if.h>
+#include <net/if_clone.h>
#include <net/if_var.h>
#include <net/vnet.h>
@@ -280,6 +281,21 @@
if_vmove(ifp, ifp->if_home_vnet);
}
+ /*
+ * ifconfig -alias down destroy all the remaining interfaces.
+ * Only lo0 should survive this step, stripped off of any addresses.
+ */
+ TAILQ_FOREACH_SAFE(ifp, &V_ifnet, if_link, nifp) {
+ if_down(ifp);
+ if_purgeaddrs(ifp);
+ if_purgemaddrs(ifp);
+ if (ifp != V_loif) {
+ printf("Ouch, destroying ifnet %s\n", ifp->if_xname);
+ if_clone_destroy(ifp->if_xname);
+ printf("OK\n");
+ }
+ }
+
vnet_sysuninit();
CURVNET_RESTORE();
==== //depot/projects/vimage-commit2/src/sys/netinet/in_proto.c#18 (text+ko) ====
@@ -114,6 +114,9 @@
.pr_domain = &inetdomain,
.pr_protocol = IPPROTO_IP,
.pr_init = ip_init,
+#ifdef VIMAGE
+ .pr_destroy = ip_destroy,
+#endif
.pr_slowtimo = ip_slowtimo,
.pr_drain = ip_drain,
.pr_usrreqs = &nousrreqs
@@ -150,39 +153,42 @@
},
#ifdef SCTP
{
- .pr_type = SOCK_DGRAM,
- .pr_domain = &inetdomain,
- .pr_protocol = IPPROTO_SCTP,
- .pr_flags = PR_WANTRCVD,
- .pr_input = sctp_input,
- .pr_ctlinput = sctp_ctlinput,
- .pr_ctloutput = sctp_ctloutput,
- .pr_init = sctp_init,
- .pr_drain = sctp_drain,
- .pr_usrreqs = &sctp_usrreqs
+ .pr_type = SOCK_DGRAM,
+ .pr_domain = &inetdomain,
+ .pr_protocol = IPPROTO_SCTP,
+ .pr_flags = PR_WANTRCVD,
+ .pr_input = sctp_input,
+ .pr_ctlinput = sctp_ctlinput,
+ .pr_ctloutput = sctp_ctloutput,
+ .pr_init = sctp_init,
+#ifdef VIMAGE
+ .pr_init = sctp_destroy,
+#endif
+ .pr_drain = sctp_drain,
+ .pr_usrreqs = &sctp_usrreqs
},
{
.pr_type = SOCK_SEQPACKET,
.pr_domain = &inetdomain,
- .pr_protocol = IPPROTO_SCTP,
- .pr_flags = PR_WANTRCVD,
- .pr_input = sctp_input,
- .pr_ctlinput = sctp_ctlinput,
- .pr_ctloutput = sctp_ctloutput,
- .pr_drain = sctp_drain,
- .pr_usrreqs = &sctp_usrreqs
+ .pr_protocol = IPPROTO_SCTP,
+ .pr_flags = PR_WANTRCVD,
+ .pr_input = sctp_input,
+ .pr_ctlinput = sctp_ctlinput,
+ .pr_ctloutput = sctp_ctloutput,
+ .pr_drain = sctp_drain,
+ .pr_usrreqs = &sctp_usrreqs
},
{
.pr_type = SOCK_STREAM,
.pr_domain = &inetdomain,
- .pr_protocol = IPPROTO_SCTP,
- .pr_flags = PR_WANTRCVD,
- .pr_input = sctp_input,
- .pr_ctlinput = sctp_ctlinput,
- .pr_ctloutput = sctp_ctloutput,
- .pr_drain = sctp_drain,
- .pr_usrreqs = &sctp_usrreqs
+ .pr_protocol = IPPROTO_SCTP,
+ .pr_flags = PR_WANTRCVD,
+ .pr_input = sctp_input,
+ .pr_ctlinput = sctp_ctlinput,
+ .pr_ctloutput = sctp_ctloutput,
+ .pr_drain = sctp_drain,
+ .pr_usrreqs = &sctp_usrreqs
},
#endif /* SCTP */
{
==== //depot/projects/vimage-commit2/src/sys/netinet/in_var.h#15 (text+ko) ====
==== //depot/projects/vimage-commit2/src/sys/netinet/ip_input.c#51 (text+ko) ====
@@ -368,6 +368,28 @@
netisr_register(&ip_nh);
}
+#ifdef VIMAGE
+/*
+ * Per-vnet state cleanup.
+ */
+void
+ip_destroy(void)
+{
+
+#ifdef FLOWTABLE
+ flowtable_free(V_ip_ft);
+#endif
+#ifdef NOTYET
+ /* Clean up IP reassembly queue. */
+ for (i = 0; i < IPREASS_NHASH; i++)
+ TAILQ_WALK_AND_FREE(&V_ipq[i]);
+#endif
+ uma_zdestroy(V_ipq_zone);
+ KASSERT(TAILQ_EMPTY(&V_in_ifaddrhead), ("V_in_ifaddrhead not empty"));
+ hashdestroy(V_in_ifaddrhashtbl, M_IFADDR, V_in_ifaddrhmask);
+}
+#endif
+
void
ip_fini(void *xtp)
{
==== //depot/projects/vimage-commit2/src/sys/netinet/ip_var.h#23 (text+ko) ====
@@ -212,6 +212,7 @@
u_long if_hwassist_flags, int sw_csum);
void ip_forward(struct mbuf *m, int srcrt);
void ip_init(void);
+void ip_destroy(void);
extern int
(*ip_mforward)(struct ip *, struct ifnet *, struct mbuf *,
struct ip_moptions *);
==== //depot/projects/vimage-commit2/src/sys/netinet/raw_ip.c#37 (text+ko) ====
@@ -194,6 +194,10 @@
V_ripcbinfo.ipi_zone = uma_zcreate("ripcb", sizeof(struct inpcb),
NULL, NULL, rip_inpcb_init, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
uma_zone_set_max(V_ripcbinfo.ipi_zone, maxsockets);
+
+ if (!IS_DEFAULT_VNET(curvnet))
+ return;
+
EVENTHANDLER_REGISTER(maxsockets_change, rip_zone_change, NULL,
EVENTHANDLER_PRI_ANY);
}
@@ -203,10 +207,13 @@
rip_destroy(void)
{
+ KASSERT(LIST_EMPTY(&V_ripcb), ("V_ripcb not empty"));
+ uma_zdestroy(V_ripcbinfo.ipi_zone);
hashdestroy(V_ripcbinfo.ipi_hashbase, M_PCB,
V_ripcbinfo.ipi_hashmask);
hashdestroy(V_ripcbinfo.ipi_porthashbase, M_PCB,
V_ripcbinfo.ipi_porthashmask);
+ INP_INFO_LOCK_DESTROY(&V_ripcbinfo);
}
#endif
==== //depot/projects/vimage-commit2/src/sys/netinet/tcp_hostcache.c#32 (text+ko) ====
@@ -235,10 +235,27 @@
void
tcp_hc_destroy(void)
{
+ int i;
/* XXX TODO walk the hashtable and free all entries */
+#ifdef NOTYET
+ tcp_hc_purge() forced???
+#endif
callout_drain(&V_tcp_hc_callout);
+ uma_zdestroy(V_tcp_hostcache.zone);
+
+ /*
+ * Clean up the hash buckets.
+ */
+ for (i = 0; i < V_tcp_hostcache.hashsize; i++) {
+#ifdef NOTYET
+ TAILQ_WALK_AND_FREE(&V_tcp_hostcache.hashbase[i].hch_bucket);
+#endif
+ mtx_destroy(&V_tcp_hostcache.hashbase[i].hch_mtx);
+ }
+
+ free(V_tcp_hostcache.hashbase, M_HOSTCACHE);
}
#endif
==== //depot/projects/vimage-commit2/src/sys/netinet/tcp_reass.c#21 (text+ko) ====
@@ -132,6 +132,16 @@
tcp_reass_zone_change, NULL, EVENTHANDLER_PRI_ANY);
}
+#ifdef VIMAGE
+void
+tcp_reass_destroy(void)
+{
+
+ /* Walk and free the reas queue */
+ uma_zdestroy(V_tcp_reass_zone);
+}
+#endif
+
int
tcp_reass(struct tcpcb *tp, struct tcphdr *th, int *tlenp, struct mbuf *m)
{
==== //depot/projects/vimage-commit2/src/sys/netinet/tcp_subr.c#58 (text+ko) ====
@@ -445,9 +445,17 @@
tcp_destroy(void)
{
+ tcp_reass_destroy();
+ syncache_destroy();
+ tcp_hc_destroy();
tcp_tw_destroy();
- tcp_hc_destroy();
- syncache_destroy();
+
+#ifdef NOTYET
+ LIST_WALK_AND_FREE_OR_ASSERT_FREE(&V_tcb);
+#endif
+ uma_zdestroy(V_sack_hole_zone);
+ uma_zdestroy(V_tcpcb_zone);
+ uma_zdestroy(V_tcbinfo.ipi_zone);
/* XXX check that hashes are empty! */
hashdestroy(V_tcbinfo.ipi_hashbase, M_PCB,
==== //depot/projects/vimage-commit2/src/sys/netinet/tcp_syncache.c#41 (text+ko) ====
@@ -278,11 +278,20 @@
void
syncache_destroy(void)
{
+ int i;
/* XXX walk the cache, free remaining objects, stop timers */
+ /* Clean up the hash buckets. */
+ for (i = 0; i < V_tcp_syncache.hashsize; i++) {
+#ifdef NOTYET
+ TAILQ_ASSERT_EMPTY(&V_tcp_syncache.hashbase[i].sch_bucket);
+#endif
+ callout_drain(&V_tcp_syncache.hashbase[i].sch_timer);
+ mtx_destroy(&V_tcp_syncache.hashbase[i].sch_mtx);
+ }
+ FREE(V_tcp_syncache.hashbase, M_SYNCACHE);
uma_zdestroy(V_tcp_syncache.zone);
- FREE(V_tcp_syncache.hashbase, M_SYNCACHE);
}
#endif
==== //depot/projects/vimage-commit2/src/sys/netinet/tcp_timewait.c#33 (text+ko) ====
@@ -185,6 +185,7 @@
while((tw = TAILQ_FIRST(&V_twq_2msl)) != NULL)
tcp_twclose(tw, 0);
INP_INFO_WUNLOCK(&V_tcbinfo);
+ uma_zdestroy(V_tcptw_zone);
}
#endif
==== //depot/projects/vimage-commit2/src/sys/netinet/tcp_var.h#22 (text+ko) ====
@@ -649,6 +649,7 @@
const void *);
int tcp_reass(struct tcpcb *, struct tcphdr *, int *, struct mbuf *);
void tcp_reass_init(void);
+void tcp_reass_destroy(void);
void tcp_input(struct mbuf *, int);
u_long tcp_maxmtu(struct in_conninfo *, int *);
u_long tcp_maxmtu6(struct in_conninfo *, int *);
==== //depot/projects/vimage-commit2/src/sys/netinet/udp_usrreq.c#47 (text+ko) ====
@@ -199,6 +199,9 @@
NULL, NULL, NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NOFREE);
uma_zone_set_max(V_udpcb_zone, maxsockets);
+ if (!IS_DEFAULT_VNET(curvnet))
+ return;
+
EVENTHANDLER_REGISTER(maxsockets_change, udp_zone_change, NULL,
EVENTHANDLER_PRI_ANY);
}
@@ -241,6 +244,8 @@
udp_destroy(void)
{
+ uma_zdestroy(V_udbinfo.ipi_zone);
+ uma_zdestroy(V_udpcb_zone);
hashdestroy(V_udbinfo.ipi_hashbase, M_PCB,
V_udbinfo.ipi_hashmask);
hashdestroy(V_udbinfo.ipi_porthashbase, M_PCB,
More information about the p4-projects
mailing list