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
This commit is contained in:
bz 2010-02-09 21:31:53 +00:00
parent d09bdfe2c5
commit 0cce20af31

View File

@ -115,6 +115,7 @@ static VNET_DEFINE(struct callout, tcp_hc_callout);
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);