aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2014-03-20 06:53:39 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2014-04-03 17:52:13 -0400
commite00b437b3d6d4d26ecd95108b575ee1bcfcb478f (patch)
tree39436424c7559b1ce55e49e7ca6b7d36d3d4d57b
parente5ac6eafba887821044c65b6fe59d9eb8b7c7f61 (diff)
netfilter: connlimit: move lock array out of struct connlimit_data
Eric points out that the locks can be global. Moreover, both Jesper and Eric note that using only 32 locks increases false sharing as only two cache lines are used. This increases locks to 256 (16 cache lines assuming 64byte cacheline and 4 bytes per spinlock). Suggested-by: Jesper Dangaard Brouer <brouer@redhat.com> Suggested-by: Eric Dumazet <eric.dumazet@gmail.com> Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--net/netfilter/xt_connlimit.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c
index a6e129eb3aa0..fbc66bb250d5 100644
--- a/net/netfilter/xt_connlimit.c
+++ b/net/netfilter/xt_connlimit.c
@@ -32,8 +32,14 @@
32#include <net/netfilter/nf_conntrack_tuple.h> 32#include <net/netfilter/nf_conntrack_tuple.h>
33#include <net/netfilter/nf_conntrack_zones.h> 33#include <net/netfilter/nf_conntrack_zones.h>
34 34
35#define CONNLIMIT_SLOTS 32 35#define CONNLIMIT_SLOTS 256U
36#define CONNLIMIT_LOCK_SLOTS 32 36
37#ifdef CONFIG_LOCKDEP
38#define CONNLIMIT_LOCK_SLOTS 8U
39#else
40#define CONNLIMIT_LOCK_SLOTS 256U
41#endif
42
37#define CONNLIMIT_GC_MAX_NODES 8 43#define CONNLIMIT_GC_MAX_NODES 8
38 44
39/* we will save the tuples of all connections we care about */ 45/* we will save the tuples of all connections we care about */
@@ -49,10 +55,11 @@ struct xt_connlimit_rb {
49 union nf_inet_addr addr; /* search key */ 55 union nf_inet_addr addr; /* search key */
50}; 56};
51 57
58static spinlock_t xt_connlimit_locks[CONNLIMIT_LOCK_SLOTS] __cacheline_aligned_in_smp;
59
52struct xt_connlimit_data { 60struct xt_connlimit_data {
53 struct rb_root climit_root4[CONNLIMIT_SLOTS]; 61 struct rb_root climit_root4[CONNLIMIT_SLOTS];
54 struct rb_root climit_root6[CONNLIMIT_SLOTS]; 62 struct rb_root climit_root6[CONNLIMIT_SLOTS];
55 spinlock_t locks[CONNLIMIT_LOCK_SLOTS];
56}; 63};
57 64
58static u_int32_t connlimit_rnd __read_mostly; 65static u_int32_t connlimit_rnd __read_mostly;
@@ -297,11 +304,11 @@ static int count_them(struct net *net,
297 root = &data->climit_root4[hash]; 304 root = &data->climit_root4[hash];
298 } 305 }
299 306
300 spin_lock_bh(&data->locks[hash % CONNLIMIT_LOCK_SLOTS]); 307 spin_lock_bh(&xt_connlimit_locks[hash % CONNLIMIT_LOCK_SLOTS]);
301 308
302 count = count_tree(net, root, tuple, addr, mask, family); 309 count = count_tree(net, root, tuple, addr, mask, family);
303 310
304 spin_unlock_bh(&data->locks[hash % CONNLIMIT_LOCK_SLOTS]); 311 spin_unlock_bh(&xt_connlimit_locks[hash % CONNLIMIT_LOCK_SLOTS]);
305 312
306 return count; 313 return count;
307} 314}
@@ -377,9 +384,6 @@ static int connlimit_mt_check(const struct xt_mtchk_param *par)
377 return -ENOMEM; 384 return -ENOMEM;
378 } 385 }
379 386
380 for (i = 0; i < CONNLIMIT_LOCK_SLOTS; ++i)
381 spin_lock_init(&info->data->locks[i]);
382
383 for (i = 0; i < ARRAY_SIZE(info->data->climit_root4); ++i) 387 for (i = 0; i < ARRAY_SIZE(info->data->climit_root4); ++i)
384 info->data->climit_root4[i] = RB_ROOT; 388 info->data->climit_root4[i] = RB_ROOT;
385 for (i = 0; i < ARRAY_SIZE(info->data->climit_root6); ++i) 389 for (i = 0; i < ARRAY_SIZE(info->data->climit_root6); ++i)
@@ -435,11 +439,14 @@ static struct xt_match connlimit_mt_reg __read_mostly = {
435 439
436static int __init connlimit_mt_init(void) 440static int __init connlimit_mt_init(void)
437{ 441{
438 int ret; 442 int ret, i;
439 443
440 BUILD_BUG_ON(CONNLIMIT_LOCK_SLOTS > CONNLIMIT_SLOTS); 444 BUILD_BUG_ON(CONNLIMIT_LOCK_SLOTS > CONNLIMIT_SLOTS);
441 BUILD_BUG_ON((CONNLIMIT_SLOTS % CONNLIMIT_LOCK_SLOTS) != 0); 445 BUILD_BUG_ON((CONNLIMIT_SLOTS % CONNLIMIT_LOCK_SLOTS) != 0);
442 446
447 for (i = 0; i < CONNLIMIT_LOCK_SLOTS; ++i)
448 spin_lock_init(&xt_connlimit_locks[i]);
449
443 connlimit_conn_cachep = kmem_cache_create("xt_connlimit_conn", 450 connlimit_conn_cachep = kmem_cache_create("xt_connlimit_conn",
444 sizeof(struct xt_connlimit_conn), 451 sizeof(struct xt_connlimit_conn),
445 0, 0, NULL); 452 0, 0, NULL);