From: Florian Westphal <fw@strlen.de>
To: <netfilter-devel@vger.kernel.org>
Cc: pablo@netfilter.org
Subject: [RFC nf-next 02/11] netfilter: conntrack: don't schedule gc worker when table is empty
Date: Wed, 5 Nov 2025 17:47:56 +0100 [thread overview]
Message-ID: <20251105164805.3992-3-fw@strlen.de> (raw)
In-Reply-To: <20251105164805.3992-1-fw@strlen.de>
No need to wakeup every minute when there are no entries.
Instead of doing a scan at least once a minute, check of the worker
is pending (its expected to be except on idle system) and queue it
if its not.
In case the gc worker was executing at time of check (means, it wasn't
pending), then the gc worker should re-run at the newly computed next_run
interval. Switch it to mod_delayed_work() to allow this.
While at it, get rid of 'exiting' toggle:
use disable_delayed_work_sync instead of the 'cancel_' version at exit
time to prevent rearming.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
net/netfilter/nf_conntrack_core.c | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 210792a2275d..fa6e5047d15b 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -69,7 +69,6 @@ struct conntrack_gc_work {
u32 avg_timeout;
u32 count;
u32 start_time;
- bool exiting;
bool early_drop;
};
@@ -91,7 +90,7 @@ static DEFINE_MUTEX(nf_conntrack_mutex);
* allowing non-idle machines to wakeup more often when needed.
*/
#define GC_SCAN_INITIAL_COUNT 100
-#define GC_SCAN_INTERVAL_INIT GC_SCAN_INTERVAL_MAX
+#define GC_SCAN_INTERVAL_INIT (GC_SCAN_INTERVAL_MAX / 2)
#define GC_SCAN_MAX_DURATION msecs_to_jiffies(10)
#define GC_SCAN_EXPIRED_MAX (64000u / HZ)
@@ -1639,19 +1638,17 @@ static void gc_worker(struct work_struct *work)
next_run = 1;
early_exit:
- if (gc_work->exiting)
- return;
-
if (next_run)
gc_work->early_drop = false;
- queue_delayed_work(system_power_efficient_wq, &gc_work->dwork, next_run);
+ if (gc_work->count > GC_SCAN_INITIAL_COUNT || gc_work->next_bucket > 0)
+ mod_delayed_work(system_power_efficient_wq, &gc_work->dwork, next_run);
}
static void conntrack_gc_work_init(struct conntrack_gc_work *gc_work)
{
+ /* work is started on first conntrack allocation. */
INIT_DELAYED_WORK(&gc_work->dwork, gc_worker);
- gc_work->exiting = false;
}
static struct nf_conn *
@@ -1709,6 +1706,15 @@ __nf_conntrack_alloc(struct net *net,
* this is inserted in any list.
*/
refcount_set(&ct->ct_general.use, 0);
+
+ /* Re-arm gc_work if needed, but do not modify
+ * in case it was already pending.
+ */
+ if (unlikely(!delayed_work_pending(&conntrack_gc_work.dwork)))
+ queue_delayed_work(system_power_efficient_wq,
+ &conntrack_gc_work.dwork,
+ GC_SCAN_INTERVAL_INIT);
+
return ct;
out:
atomic_dec(&cnet->count);
@@ -2458,13 +2464,12 @@ static int kill_all(struct nf_conn *i, void *data)
void nf_conntrack_cleanup_start(void)
{
cleanup_nf_conntrack_bpf();
- conntrack_gc_work.exiting = true;
}
void nf_conntrack_cleanup_end(void)
{
RCU_INIT_POINTER(nf_ct_hook, NULL);
- cancel_delayed_work_sync(&conntrack_gc_work.dwork);
+ disable_delayed_work_sync(&conntrack_gc_work.dwork);
kvfree(nf_conntrack_hash);
nf_conntrack_proto_fini();
@@ -2687,7 +2692,6 @@ int nf_conntrack_init_start(void)
goto err_proto;
conntrack_gc_work_init(&conntrack_gc_work);
- queue_delayed_work(system_power_efficient_wq, &conntrack_gc_work.dwork, HZ);
ret = register_nf_conntrack_bpf();
if (ret < 0)
--
2.51.0
next prev parent reply other threads:[~2025-11-05 16:48 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-11-05 16:47 [RFC nf-next 00/11] netfilter: conntrack: pernet hash tables Florian Westphal
2025-11-05 16:47 ` [RFC nf-next 01/11] netfilter: netns nf_conntrack: per-netns net.netfilter.nf_conntrack_max sysctl Florian Westphal
2025-11-05 16:47 ` Florian Westphal [this message]
2025-11-05 16:47 ` [RFC nf-next 03/11] tests: netfilter: conntrack_resize: prepare for pernet conntrack table Florian Westphal
2025-11-05 16:47 ` [RFC nf-next 04/11] netfilter: conntrack: pass pointer to buckets instead of index Florian Westphal
2025-11-05 16:47 ` [RFC nf-next 05/11] netfilter: conntrack: split hashtable auto-size to helper function Florian Westphal
2025-11-05 16:48 ` [RFC nf-next 06/11] netfilter: conntrack: move nf_conntrack_hash to struct net Florian Westphal
2025-11-07 14:03 ` kernel test robot
2025-11-05 16:48 ` [RFC nf-next 07/11] netfilter: conntrack: init and start independent gc workers when needed Florian Westphal
2025-11-05 16:48 ` [RFC nf-next 08/11] netfilter: conntrack: make nf_conntrack hash table pernet Florian Westphal
2025-11-07 16:05 ` kernel test robot
2025-11-05 16:48 ` [RFC nf-next 09/11] netfilter: conntrack: delay conntrack hashtable allocation until needed Florian Westphal
2025-11-05 16:48 ` [RFC nf-next 10/11] netfilter: conntrack: allow non-init-net to change table size Florian Westphal
2025-11-05 16:48 ` [RFC nf-next 11/11] netfilter: nf_nat: make bysource hash table pernet Florian Westphal
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20251105164805.3992-3-fw@strlen.de \
--to=fw@strlen.de \
--cc=netfilter-devel@vger.kernel.org \
--cc=pablo@netfilter.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.