From owner-svn-src-projects@FreeBSD.ORG Tue May 29 12:33:10 2012 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 213F1106566C; Tue, 29 May 2012 12:33:10 +0000 (UTC) (envelope-from glebius@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 0B9398FC14; Tue, 29 May 2012 12:33:10 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.4/8.14.4) with ESMTP id q4TCX96T077268; Tue, 29 May 2012 12:33:09 GMT (envelope-from glebius@svn.freebsd.org) Received: (from glebius@localhost) by svn.freebsd.org (8.14.4/8.14.4/Submit) id q4TCX9xQ077265; Tue, 29 May 2012 12:33:09 GMT (envelope-from glebius@svn.freebsd.org) Message-Id: <201205291233.q4TCX9xQ077265@svn.freebsd.org> From: Gleb Smirnoff Date: Tue, 29 May 2012 12:33:09 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r236230 - projects/pf/head/sys/contrib/pf/net X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 29 May 2012 12:33:10 -0000 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);