From owner-p4-projects@FreeBSD.ORG Sun Aug 30 20:19:39 2009 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id DE7A510656AD; Sun, 30 Aug 2009 20:19:38 +0000 (UTC) Delivered-To: perforce@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A26241065694 for ; Sun, 30 Aug 2009 20:19:38 +0000 (UTC) (envelope-from zec@fer.hr) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 9040B8FC0A for ; Sun, 30 Aug 2009 20:19:38 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.3/8.14.3) with ESMTP id n7UKJcn0046706 for ; Sun, 30 Aug 2009 20:19:38 GMT (envelope-from zec@fer.hr) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.3/8.14.3/Submit) id n7UKJbvc046704 for perforce@freebsd.org; Sun, 30 Aug 2009 20:19:37 GMT (envelope-from zec@fer.hr) Date: Sun, 30 Aug 2009 20:19:37 GMT Message-Id: <200908302019.n7UKJbvc046704@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to zec@fer.hr using -f From: Marko Zec To: Perforce Change Reviews Cc: Subject: PERFORCE change 167988 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 30 Aug 2009 20:19:39 -0000 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 +#include #include #include @@ -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,