Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 30 Aug 2009 20:19:37 GMT
From:      Marko Zec <zec@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 167988 for review
Message-ID:  <200908302019.n7UKJbvc046704@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=167988

Change 167988 by zec@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,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200908302019.n7UKJbvc046704>