diff options
author | Martin Pieuchot <mpi@cvs.openbsd.org> | 2017-08-06 13:16:12 +0000 |
---|---|---|
committer | Martin Pieuchot <mpi@cvs.openbsd.org> | 2017-08-06 13:16:12 +0000 |
commit | 9103069faf13baea09b4c2b89b0865883a330ec7 (patch) | |
tree | 496e6f4f1d61c52e0c9d20c0525ed110cb743032 /sys/net/pf.c | |
parent | 60499875c5fd69046be9f535b6de58b8240eee85 (diff) |
Reduce contention on the NET_LOCK() by moving the logic of the pfpurge
thread to a task running on the `softnettq`.
Tested and inputs from Hrvoje Popovski.
ok visa@, sashan@
Diffstat (limited to 'sys/net/pf.c')
-rw-r--r-- | sys/net/pf.c | 59 |
1 files changed, 35 insertions, 24 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c index 14c71ea118e..f8c2e49e1d4 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.1037 2017/07/04 14:10:15 mpi Exp $ */ +/* $OpenBSD: pf.c,v 1.1038 2017/08/06 13:16:11 mpi Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -121,6 +121,10 @@ u_char pf_tcp_secret[16]; int pf_tcp_secret_init; int pf_tcp_iss_off; +int pf_npurge; +struct task pf_purge_task = TASK_INITIALIZER(pf_purge, &pf_npurge); +struct timeout pf_purge_to = TIMEOUT_INITIALIZER(pf_purge_timeout, NULL); + enum pf_test_status { PF_TEST_FAIL = -1, PF_TEST_OK, @@ -1200,36 +1204,43 @@ pf_purge_expired_rules(void) } void -pf_purge_thread(void *v) +pf_purge_timeout(void *unused) { - int nloops = 0, s; + task_add(softnettq, &pf_purge_task); +} - for (;;) { - tsleep(pf_purge_thread, PWAIT, "pftm", 1 * hz); +void +pf_purge(void *xnloops) +{ + int *nloops = xnloops; + int s; - NET_LOCK(s); + KERNEL_LOCK(); + NET_LOCK(s); - PF_LOCK(); - /* process a fraction of the state table every second */ - pf_purge_expired_states(1 + (pf_status.states - / pf_default_rule.timeout[PFTM_INTERVAL])); + PF_LOCK(); + /* process a fraction of the state table every second */ + pf_purge_expired_states(1 + (pf_status.states + / pf_default_rule.timeout[PFTM_INTERVAL])); - /* purge other expired types every PFTM_INTERVAL seconds */ - if (++nloops >= pf_default_rule.timeout[PFTM_INTERVAL]) { - pf_purge_expired_src_nodes(0); - pf_purge_expired_rules(); - } - PF_UNLOCK(); - /* - * Fragments don't require PF_LOCK(), they use their own lock. - */ - if (nloops >= pf_default_rule.timeout[PFTM_INTERVAL]) { - pf_purge_expired_fragments(); - nloops = 0; - } + /* purge other expired types every PFTM_INTERVAL seconds */ + if (++(*nloops) >= pf_default_rule.timeout[PFTM_INTERVAL]) { + pf_purge_expired_src_nodes(0); + pf_purge_expired_rules(); + } + PF_UNLOCK(); - NET_UNLOCK(s); + /* + * Fragments don't require PF_LOCK(), they use their own lock. + */ + if ((*nloops) >= pf_default_rule.timeout[PFTM_INTERVAL]) { + pf_purge_expired_fragments(); + *nloops = 0; } + NET_UNLOCK(s); + KERNEL_UNLOCK(); + + timeout_add(&pf_purge_to, 1 * hz); } int32_t |