diff --git a/include/net/sock.h b/include/net/sock.h index 453c79d0915ba00ca8b33ff160ba64cb7c58a521..b9cfe125c9e68e56ed4768552280e71cb894ba16 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -922,14 +922,18 @@ static inline void sk_filter_rcu_free(struct rcu_head *rcu) * Remove a filter from a socket and release its resources. */ -static inline void sk_filter_release(struct sock *sk, struct sk_filter *fp) +static inline void sk_filter_release(struct sk_filter *fp) +{ + if (atomic_dec_and_test(&fp->refcnt)) + call_rcu_bh(&fp->rcu, sk_filter_rcu_free); +} + +static inline void sk_filter_uncharge(struct sock *sk, struct sk_filter *fp) { unsigned int size = sk_filter_len(fp); atomic_sub(size, &sk->sk_omem_alloc); - - if (atomic_dec_and_test(&fp->refcnt)) - call_rcu_bh(&fp->rcu, sk_filter_rcu_free); + sk_filter_release(fp); } static inline void sk_filter_charge(struct sock *sk, struct sk_filter *fp) diff --git a/net/core/filter.c b/net/core/filter.c index fd607581ab503bb69043cbbc154265c3799baf05..2be1830d3c35183d033ecc9108f98ae58d204c0a 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -429,7 +429,7 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) } if (fp) - sk_filter_release(sk, fp); + sk_filter_uncharge(sk, fp); return err; } @@ -442,7 +442,7 @@ int sk_detach_filter(struct sock *sk) filter = rcu_dereference(sk->sk_filter); if (filter) { rcu_assign_pointer(sk->sk_filter, NULL); - sk_filter_release(sk, filter); + sk_filter_uncharge(sk, filter); ret = 0; } rcu_read_unlock_bh(); diff --git a/net/core/sock.c b/net/core/sock.c index 07101381b8b78df697987325a421d37dd308537f..d292b4113d6e240829c48cbd84e24ab5da660764 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -915,7 +915,7 @@ void sk_free(struct sock *sk) filter = rcu_dereference(sk->sk_filter); if (filter) { - sk_filter_release(sk, filter); + sk_filter_uncharge(sk, filter); rcu_assign_pointer(sk->sk_filter, NULL); }