Author: bz
Date: Tue Feb  9 21:31:53 2010
New Revision: 203724
URL: http://svn.freebsd.org/changeset/base/203724

Log:
  Properly free resources when destroying the TCP hostcache while
  tearing down a network stack (in the VIMAGE jail+vnet case).
  
  For that break out the logic from tcp_hc_purge() into an internal
  function we can call from both, the sysctl handler and the
  tcp_hc_destroy().
  
  Sponsored by: ISPsystem
  Reviewed by:  silby, lstewart
  MFC After:    8 days

Modified:
  head/sys/netinet/tcp_hostcache.c

Modified: head/sys/netinet/tcp_hostcache.c
==============================================================================
--- head/sys/netinet/tcp_hostcache.c    Tue Feb  9 21:24:41 2010        
(r203723)
+++ head/sys/netinet/tcp_hostcache.c    Tue Feb  9 21:31:53 2010        
(r203724)
@@ -115,6 +115,7 @@ static VNET_DEFINE(struct callout, tcp_h
 static struct hc_metrics *tcp_hc_lookup(struct in_conninfo *);
 static struct hc_metrics *tcp_hc_insert(struct in_conninfo *);
 static int sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS);
+static void tcp_hc_purge_internal(int);
 static void tcp_hc_purge(void *);
 
 SYSCTL_NODE(_net_inet_tcp, OID_AUTO, hostcache, CTLFLAG_RW, 0,
@@ -235,10 +236,19 @@ tcp_hc_init(void)
 void
 tcp_hc_destroy(void)
 {
-
-       /* XXX TODO walk the hashtable and free all entries  */
+       int i;
 
        callout_drain(&V_tcp_hc_callout);
+
+       /* Purge all hc entries. */
+       tcp_hc_purge_internal(1);
+
+       /* Free the uma zone and the allocated hash table. */
+       uma_zdestroy(V_tcp_hostcache.zone);
+
+       for (i = 0; i < V_tcp_hostcache.hashsize; i++)
+               mtx_destroy(&V_tcp_hostcache.hashbase[i].hch_mtx);
+       free(V_tcp_hostcache.hashbase, M_HOSTCACHE);
 }
 #endif
 
@@ -633,22 +643,14 @@ sysctl_tcp_hc_list(SYSCTL_HANDLER_ARGS)
 }
 
 /*
- * Expire and purge (old|all) entries in the tcp_hostcache.  Runs
- * periodically from the callout.
+ * Caller has to make sure the curvnet is set properly.
  */
 static void
-tcp_hc_purge(void *arg)
+tcp_hc_purge_internal(int all)
 {
-       CURVNET_SET((struct vnet *) arg);
        struct hc_metrics *hc_entry, *hc_next;
-       int all = 0;
        int i;
 
-       if (V_tcp_hostcache.purgeall) {
-               all = 1;
-               V_tcp_hostcache.purgeall = 0;
-       }
-
        for (i = 0; i < V_tcp_hostcache.hashsize; i++) {
                THC_LOCK(&V_tcp_hostcache.hashbase[i].hch_mtx);
                TAILQ_FOREACH_SAFE(hc_entry,
@@ -664,6 +666,24 @@ tcp_hc_purge(void *arg)
                }
                THC_UNLOCK(&V_tcp_hostcache.hashbase[i].hch_mtx);
        }
+}
+
+/*
+ * Expire and purge (old|all) entries in the tcp_hostcache.  Runs
+ * periodically from the callout.
+ */
+static void
+tcp_hc_purge(void *arg)
+{
+       CURVNET_SET((struct vnet *) arg);
+       int all = 0;
+
+       if (V_tcp_hostcache.purgeall) {
+               all = 1;
+               V_tcp_hostcache.purgeall = 0;
+       }
+
+       tcp_hc_purge_internal(all);
 
        callout_reset(&V_tcp_hc_callout, V_tcp_hostcache.prune * hz,
            tcp_hc_purge, arg);
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to