netfilter: nf_conncount: reduce unnecessary GC
authorWilliam Tu <u9012063@gmail.com>
Wed, 4 May 2022 15:35:59 +0000 (08:35 -0700)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 16 May 2022 11:05:40 +0000 (13:05 +0200)
commitd265929930e2ffafc744c0ae05fb70acd53be1ee
treed26c34a8536b365e1b334d5f2b37598cd18d1736
parent2c50fc04757f16427e6213989cee9182c50e2c8a
netfilter: nf_conncount: reduce unnecessary GC

Currently nf_conncount can trigger garbage collection (GC)
at multiple places. Each GC process takes a spin_lock_bh
to traverse the nf_conncount_list. We found that when testing
port scanning use two parallel nmap, because the number of
connection increase fast, the nf_conncount_count and its
subsequent call to __nf_conncount_add take too much time,
causing several CPU lockup. This happens when user set the
conntrack limit to +20,000, because the larger the limit,
the longer the list that GC has to traverse.

The patch mitigate the performance issue by avoiding unnecessary
GC with a timestamp. Whenever nf_conncount has done a GC,
a timestamp is updated, and beforce the next time GC is
triggered, we make sure it's more than a jiffies.
By doin this we can greatly reduce the CPU cycles and
avoid the softirq lockup.

To reproduce it in OVS,
$ ovs-appctl dpctl/ct-set-limits zone=1,limit=20000
$ ovs-appctl dpctl/ct-get-limits

At another machine, runs two nmap
$ nmap -p1- <IP>
$ nmap -p1- <IP>

Signed-off-by: William Tu <u9012063@gmail.com>
Co-authored-by: Yifeng Sun <pkusunyifeng@gmail.com>
Reported-by: Greg Rose <gvrose8192@gmail.com>
Suggested-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/net/netfilter/nf_conntrack_count.h
net/netfilter/nf_conncount.c