diff options
author | Daniel Borkmann <dborkman@redhat.com> | 2014-03-28 13:58:20 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-03-31 00:45:09 -0400 |
commit | fbc907f0b1386c02e00516aa78a0fa6b0454fd0b (patch) | |
tree | a747b5bb1dec44ce93e0924e4ea2de3411417b2c /net/core | |
parent | a3ea269b8bcdbb0c5fa2fd449a436e7987446975 (diff) |
net: filter: move filter accounting to filter core
This patch basically does two things, i) removes the extern keyword
from the include/linux/filter.h file to be more consistent with the
rest of Joe's changes, and ii) moves filter accounting into the filter
core framework.
Filter accounting mainly done through sk_filter_{un,}charge() take
care of the case when sockets are being cloned through sk_clone_lock()
so that removal of the filter on one socket won't result in eviction
as it's still referenced by the other.
These functions actually belong to net/core/filter.c and not
include/net/sock.h as we want to keep all that in a central place.
It's also not in fast-path so uninlining them is fine and even allows
us to get rd of sk_filter_release_rcu()'s EXPORT_SYMBOL and a forward
declaration.
Joint work with Alexei Starovoitov.
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>
Cc: Pavel Emelyanov <xemul@parallels.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/filter.c | 27 |
1 files changed, 25 insertions, 2 deletions
diff --git a/net/core/filter.c b/net/core/filter.c index 9730e7fe4770..5b3427aaeca5 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -664,14 +664,37 @@ static void sk_release_orig_filter(struct sk_filter *fp) | |||
664 | * sk_filter_release_rcu - Release a socket filter by rcu_head | 664 | * sk_filter_release_rcu - Release a socket filter by rcu_head |
665 | * @rcu: rcu_head that contains the sk_filter to free | 665 | * @rcu: rcu_head that contains the sk_filter to free |
666 | */ | 666 | */ |
667 | void sk_filter_release_rcu(struct rcu_head *rcu) | 667 | static void sk_filter_release_rcu(struct rcu_head *rcu) |
668 | { | 668 | { |
669 | struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); | 669 | struct sk_filter *fp = container_of(rcu, struct sk_filter, rcu); |
670 | 670 | ||
671 | sk_release_orig_filter(fp); | 671 | sk_release_orig_filter(fp); |
672 | bpf_jit_free(fp); | 672 | bpf_jit_free(fp); |
673 | } | 673 | } |
674 | EXPORT_SYMBOL(sk_filter_release_rcu); | 674 | |
675 | /** | ||
676 | * sk_filter_release - release a socket filter | ||
677 | * @fp: filter to remove | ||
678 | * | ||
679 | * Remove a filter from a socket and release its resources. | ||
680 | */ | ||
681 | static void sk_filter_release(struct sk_filter *fp) | ||
682 | { | ||
683 | if (atomic_dec_and_test(&fp->refcnt)) | ||
684 | call_rcu(&fp->rcu, sk_filter_release_rcu); | ||
685 | } | ||
686 | |||
687 | void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp) | ||
688 | { | ||
689 | atomic_sub(sk_filter_size(fp->len), &sk->sk_omem_alloc); | ||
690 | sk_filter_release(fp); | ||
691 | } | ||
692 | |||
693 | void sk_filter_charge(struct sock *sk, struct sk_filter *fp) | ||
694 | { | ||
695 | atomic_inc(&fp->refcnt); | ||
696 | atomic_add(sk_filter_size(fp->len), &sk->sk_omem_alloc); | ||
697 | } | ||
675 | 698 | ||
676 | static int __sk_prepare_filter(struct sk_filter *fp) | 699 | static int __sk_prepare_filter(struct sk_filter *fp) |
677 | { | 700 | { |