Skip to content

Commit

Permalink
Instead of creating a purge thread for every vnet, create
Browse files Browse the repository at this point in the history
a single purge thread and clean up all vnets from this thread.

PR:                     194515
Differential Revision:  D1315
Submitted by:           Nikos Vassiliadis <[email protected]>
  • Loading branch information
rodrigc committed Jan 6, 2015
1 parent 58319f8 commit b15d5b0
Showing 1 changed file with 24 additions and 58 deletions.
82 changes: 24 additions & 58 deletions sys/netpfil/pf/pf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1384,71 +1384,37 @@ pf_intr(void *v)
}

void
pf_purge_thread(void *v)
pf_purge_thread(void *v __unused)
{
u_int idx = 0;

CURVNET_SET((struct vnet *)v);
VNET_ITERATOR_DECL(vnet_iter);

for (;;) {
PF_RULES_RLOCK();
rw_sleep(pf_purge_thread, &pf_rules_lock, 0, "pftm", hz / 10);

if (V_pf_end_threads) {
/*
* To cleanse up all kifs and rules we need
* two runs: first one clears reference flags,
* then pf_purge_expired_states() doesn't
* raise them, and then second run frees.
*/
PF_RULES_RUNLOCK();
pf_purge_unlinked_rules();
pfi_kif_purge();

/*
* Now purge everything.
*/
pf_purge_expired_states(0, pf_hashmask);
pf_purge_expired_fragments();
pf_purge_expired_src_nodes();

/*
* Now all kifs & rules should be unreferenced,
* thus should be successfully freed.
*/
pf_purge_unlinked_rules();
pfi_kif_purge();

/*
* Announce success and exit.
*/
PF_RULES_RLOCK();
V_pf_end_threads++;
PF_RULES_RUNLOCK();
wakeup(pf_purge_thread);
kproc_exit(0);
}
PF_RULES_RUNLOCK();

/* Process 1/interval fraction of the state table every run. */
idx = pf_purge_expired_states(idx, pf_hashmask /
(V_pf_default_rule.timeout[PFTM_INTERVAL] * 10));

/* Purge other expired types every PFTM_INTERVAL seconds. */
if (idx == 0) {
/*
* Order is important:
* - states and src nodes reference rules
* - states and rules reference kifs
*/
pf_purge_expired_fragments();
pf_purge_expired_src_nodes();
pf_purge_unlinked_rules();
pfi_kif_purge();
tsleep(pf_purge_thread, PWAIT, "pftm", hz / 10);
VNET_LIST_RLOCK();
VNET_FOREACH(vnet_iter) {
CURVNET_SET(vnet_iter);
/* Process 1/interval fraction of the state table every run. */
idx = pf_purge_expired_states(idx, pf_hashmask /
(V_pf_default_rule.timeout[PFTM_INTERVAL] * 10));

/* Purge other expired types every PFTM_INTERVAL seconds. */
if (idx == 0) {
/*
* Order is important:
* - states and src nodes reference rules
* - states and rules reference kifs
*/
pf_purge_expired_fragments();
pf_purge_expired_src_nodes();
pf_purge_unlinked_rules();
pfi_kif_purge();
}
CURVNET_RESTORE();
}
VNET_LIST_RUNLOCK();
}
/* not reached */
CURVNET_RESTORE();
}

u_int32_t
Expand Down

0 comments on commit b15d5b0

Please sign in to comment.