diff options
author | Liping Zhang <zlpnobody@gmail.com> | 2017-03-11 14:08:09 +0800 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2017-03-13 19:30:31 +0100 |
commit | 2cb4bbd75bdf9d423b9f6c629f81eb66ee312fac (patch) | |
tree | 1a9561302ba75b1483f6ea5954d62478f82d35dd /net/netfilter/nft_limit.c | |
parent | fc09e4a75a12552b9374a5b0c5f5815aecf8c37a (diff) | |
download | op-kernel-dev-2cb4bbd75bdf9d423b9f6c629f81eb66ee312fac.zip op-kernel-dev-2cb4bbd75bdf9d423b9f6c629f81eb66ee312fac.tar.gz |
netfilter: limit: use per-rule spinlock to improve the scalability
The limit token is independent between each rules, so there's no
need to use a global spinlock.
Signed-off-by: Liping Zhang <zlpnobody@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter/nft_limit.c')
-rw-r--r-- | net/netfilter/nft_limit.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c index c6baf41..18dd57a 100644 --- a/net/netfilter/nft_limit.c +++ b/net/netfilter/nft_limit.c @@ -17,9 +17,8 @@ #include <linux/netfilter/nf_tables.h> #include <net/netfilter/nf_tables.h> -static DEFINE_SPINLOCK(limit_lock); - struct nft_limit { + spinlock_t lock; u64 last; u64 tokens; u64 tokens_max; @@ -34,7 +33,7 @@ static inline bool nft_limit_eval(struct nft_limit *limit, u64 cost) u64 now, tokens; s64 delta; - spin_lock_bh(&limit_lock); + spin_lock_bh(&limit->lock); now = ktime_get_ns(); tokens = limit->tokens + now - limit->last; if (tokens > limit->tokens_max) @@ -44,11 +43,11 @@ static inline bool nft_limit_eval(struct nft_limit *limit, u64 cost) delta = tokens - cost; if (delta >= 0) { limit->tokens = delta; - spin_unlock_bh(&limit_lock); + spin_unlock_bh(&limit->lock); return limit->invert; } limit->tokens = tokens; - spin_unlock_bh(&limit_lock); + spin_unlock_bh(&limit->lock); return !limit->invert; } @@ -86,6 +85,7 @@ static int nft_limit_init(struct nft_limit *limit, limit->invert = true; } limit->last = ktime_get_ns(); + spin_lock_init(&limit->lock); return 0; } |