Skip to content
/ linux Public

Commit 0792ad0

Browse files
Fernando Fernandez ManceraSasha Levin
authored andcommitted
netfilter: nf_conncount: increase the connection clean up limit to 64
[ Upstream commit 21d033e ] After the optimization to only perform one GC per jiffy, a new problem was introduced. If more than 8 new connections are tracked per jiffy the list won't be cleaned up fast enough possibly reaching the limit wrongly. In order to prevent this issue, only skip the GC if it was already triggered during the same jiffy and the increment is lower than the clean up limit. In addition, increase the clean up limit to 64 connections to avoid triggering GC too often and do more effective GCs. This has been tested using a HTTP server and several performance tools while having nft_connlimit/xt_connlimit or OVS limit configured. Output of slowhttptest + OVS limit at 52000 connections: slow HTTP test status on 340th second: initializing: 0 pending: 432 connected: 51998 error: 0 closed: 0 service available: YES Fixes: d265929 ("netfilter: nf_conncount: reduce unnecessary GC") Reported-by: Aleksandra Rukomoinikova <ARukomoinikova@k2.cloud> Closes: https://lore.kernel.org/netfilter/b2064e7b-0776-4e14-adb6-c68080987471@k2.cloud/ Signed-off-by: Fernando Fernandez Mancera <fmancera@suse.de> Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent d12e9e9 commit 0792ad0

File tree

2 files changed

+11
-5
lines changed

2 files changed

+11
-5
lines changed

include/net/netfilter/nf_conntrack_count.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ struct nf_conncount_list {
1313
u32 last_gc; /* jiffies at most recent gc */
1414
struct list_head head; /* connections with the same filtering key */
1515
unsigned int count; /* length of list */
16+
unsigned int last_gc_count; /* length of list at most recent gc */
1617
};
1718

1819
struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family,

net/netfilter/nf_conncount.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@
3434

3535
#define CONNCOUNT_SLOTS 256U
3636

37-
#define CONNCOUNT_GC_MAX_NODES 8
38-
#define MAX_KEYLEN 5
37+
#define CONNCOUNT_GC_MAX_NODES 8
38+
#define CONNCOUNT_GC_MAX_COLLECT 64
39+
#define MAX_KEYLEN 5
3940

4041
/* we will save the tuples of all connections we care about */
4142
struct nf_conncount_tuple {
@@ -182,12 +183,13 @@ static int __nf_conncount_add(struct net *net,
182183
goto out_put;
183184
}
184185

185-
if ((u32)jiffies == list->last_gc)
186+
if ((u32)jiffies == list->last_gc &&
187+
(list->count - list->last_gc_count) < CONNCOUNT_GC_MAX_COLLECT)
186188
goto add_new_node;
187189

188190
/* check the saved connections */
189191
list_for_each_entry_safe(conn, conn_n, &list->head, node) {
190-
if (collect > CONNCOUNT_GC_MAX_NODES)
192+
if (collect > CONNCOUNT_GC_MAX_COLLECT)
191193
break;
192194

193195
found = find_or_evict(net, list, conn);
@@ -230,6 +232,7 @@ static int __nf_conncount_add(struct net *net,
230232
nf_ct_put(found_ct);
231233
}
232234
list->last_gc = (u32)jiffies;
235+
list->last_gc_count = list->count;
233236

234237
add_new_node:
235238
if (WARN_ON_ONCE(list->count > INT_MAX)) {
@@ -277,6 +280,7 @@ void nf_conncount_list_init(struct nf_conncount_list *list)
277280
spin_lock_init(&list->list_lock);
278281
INIT_LIST_HEAD(&list->head);
279282
list->count = 0;
283+
list->last_gc_count = 0;
280284
list->last_gc = (u32)jiffies;
281285
}
282286
EXPORT_SYMBOL_GPL(nf_conncount_list_init);
@@ -316,13 +320,14 @@ static bool __nf_conncount_gc_list(struct net *net,
316320
}
317321

318322
nf_ct_put(found_ct);
319-
if (collected > CONNCOUNT_GC_MAX_NODES)
323+
if (collected > CONNCOUNT_GC_MAX_COLLECT)
320324
break;
321325
}
322326

323327
if (!list->count)
324328
ret = true;
325329
list->last_gc = (u32)jiffies;
330+
list->last_gc_count = list->count;
326331

327332
return ret;
328333
}

0 commit comments

Comments
 (0)