svn commit: r236230 - projects/pf/head/sys/contrib/pf/net
Gleb Smirnoff
glebius at FreeBSD.org
Tue May 29 12:33:10 UTC 2012
Author: glebius
Date: Tue May 29 12:33:09 2012
New Revision: 236230
URL: http://svn.freebsd.org/changeset/base/236230
Log:
We can't trust V_pf_status.states++ and V_pf_status.states--
in the forwarding path as soon as we get out of the pf giant lock.
o Use uma_zone_get_cur() to estimate current number of states.
Since function is considered too expensive, run it in the expiry
thread only, and not for every state examined.
XXX: this may make adaptive timeouts and expire times sent via
pfsync less precise under certain circumctances.
o Run state expiry 10 times more often with 10 times smaller
chunk argument.
Modified:
projects/pf/head/sys/contrib/pf/net/pf.c
projects/pf/head/sys/contrib/pf/net/pfvar.h
Modified: projects/pf/head/sys/contrib/pf/net/pf.c
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pf.c Tue May 29 11:48:53 2012 (r236229)
+++ projects/pf/head/sys/contrib/pf/net/pf.c Tue May 29 12:33:09 2012 (r236230)
@@ -1048,7 +1048,6 @@ pf_state_insert(struct pfi_kif *kif, str
refcount_init(&s->refs, 2);
V_pf_status.fcounters[FCNT_STATE_INSERT]++;
- V_pf_status.states++;
if (pfsync_insert_state_ptr != NULL)
pfsync_insert_state_ptr(s);
@@ -1289,7 +1288,7 @@ pf_purge_thread(void *v)
CURVNET_SET((struct vnet *)v);
for (;;) {
- tsleep(pf_purge_thread, PWAIT, "pftm", 1 * hz);
+ tsleep(pf_purge_thread, PWAIT, "pftm", hz / 10);
PF_LOCK();
@@ -1303,9 +1302,9 @@ pf_purge_thread(void *v)
kproc_exit(0);
}
- /* Process a fraction of the state table every second. */
+ /* Process 1/interval fraction of the state table every run. */
fullrun = pf_purge_expired_states(V_pf_hashmask /
- V_pf_default_rule.timeout[PFTM_INTERVAL]);
+ (V_pf_default_rule.timeout[PFTM_INTERVAL] * 10));
/* Purge other expired types every PFTM_INTERVAL seconds. */
if (fullrun) {
@@ -1349,7 +1348,7 @@ pf_state_expires(const struct pf_state *
start = state->rule.ptr->timeout[PFTM_ADAPTIVE_START];
if (start) {
end = state->rule.ptr->timeout[PFTM_ADAPTIVE_END];
- states = state->rule.ptr->states_cur;
+ states = state->rule.ptr->states_cur; /* XXXGL */
} else {
start = V_pf_default_rule.timeout[PFTM_ADAPTIVE_START];
end = V_pf_default_rule.timeout[PFTM_ADAPTIVE_END];
@@ -1421,7 +1420,7 @@ pf_src_tree_remove_state(struct pf_state
* called with ID hash row locked, but always returns
* unlocked, since it needs to go through key hash locking.
*/
-void
+int
pf_unlink_state(struct pf_state *s, u_int flags)
{
struct pf_idhash *ih = &V_pf_idhash[PF_IDHASH(s)];
@@ -1457,7 +1456,7 @@ pf_unlink_state(struct pf_state *s, u_in
pf_detach_state(s);
refcount_release(&s->refs);
- pf_release_state(s);
+ return (pf_release_state(s));
}
void
@@ -1475,7 +1474,6 @@ pf_free_state(struct pf_state *cur)
pf_normalize_tcp_cleanup(cur);
uma_zfree(V_pf_state_z, cur);
V_pf_status.fcounters[FCNT_STATE_REMOVALS]++;
- V_pf_status.states--;
}
/*
@@ -1490,6 +1488,8 @@ pf_purge_expired_states(int maxcheck)
struct pf_state *s;
int rv = 0;
+ V_pf_status.states = uma_zone_get_cur(V_pf_state_z);
+
/*
* Go through hash and unlink states that expire now.
*/
@@ -1506,7 +1506,8 @@ relock:
PF_HASHROW_LOCK(ih);
LIST_FOREACH(s, &ih->states, entry) {
if (pf_state_expires(s) <= time_uptime) {
- pf_unlink_state(s, PF_ENTER_LOCKED);
+ V_pf_status.states -=
+ pf_unlink_state(s, PF_ENTER_LOCKED);
goto relock;
}
s->rule.ptr->rule_flag |= PFRULE_REFS;
@@ -1523,6 +1524,8 @@ relock:
maxcheck--;
}
+ V_pf_status.states = uma_zone_get_cur(V_pf_state_z);
+
return (rv);
}
Modified: projects/pf/head/sys/contrib/pf/net/pfvar.h
==============================================================================
--- projects/pf/head/sys/contrib/pf/net/pfvar.h Tue May 29 11:48:53 2012 (r236229)
+++ projects/pf/head/sys/contrib/pf/net/pfvar.h Tue May 29 12:33:09 2012 (r236230)
@@ -1757,7 +1757,7 @@ extern void pf_purge_thread(void *);
extern void pf_intr(void *);
extern void pf_purge_expired_src_nodes(void);
-extern void pf_unlink_state(struct pf_state *, u_int);
+extern int pf_unlink_state(struct pf_state *, u_int);
#define PF_ENTER_LOCKED 0x00000001
#define PF_RETURN_LOCKED 0x00000002
extern int pf_state_insert(struct pfi_kif *,
@@ -1794,12 +1794,15 @@ pf_ref_state(struct pf_state *s)
refcount_acquire(&s->refs);
}
-static __inline void
+static __inline int
pf_release_state(struct pf_state *s)
{
- if (refcount_release(&s->refs))
+ if (refcount_release(&s->refs)) {
pf_free_state(s);
+ return (1);
+ } else
+ return (0);
}
extern struct pf_state *pf_find_state_byid(uint64_t, uint32_t);
More information about the svn-src-projects
mailing list