| Submitter | Eric Dumazet |
|---|---|
| Date | Sept. 27, 2010, 4:07 p.m. |
| Message ID | <1285603650.3017.57.camel@edumazet-laptop> |
| Download | mbox | patch |
| Permalink | /patch/65879/ |
| State | Accepted |
| Delegated to: | David Miller |
| Headers | show |
Comments
From: Eric Dumazet <eric.dumazet@gmail.com> Date: Mon, 27 Sep 2010 18:07:30 +0200 > Le lundi 27 septembre 2010 à 17:57 +0200, Eric Dumazet a écrit : >> sk_attach_filter() is run with socket locked. >> >> Use the appropriate rcu_dereference_protected() instead of blocking BH, >> and rcu_dereference_bh(). >> There is no point adding BH prevention and memory barrier. > > Hmm, same thing can be done in sk_detach_filter, here is a v2. > > Thanks > > [PATCH net-next-2.6 v2] net: sk_{detach|attach}_filter() rcu fixes > > sk_attach_filter() and sk_detach_filter() are run with socket locked. > > Use the appropriate rcu_dereference_protected() instead of blocking BH, > and rcu_dereference_bh(). > There is no point adding BH prevention and memory barrier. > > Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com> Applied. -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Patch
diff --git a/net/core/filter.c b/net/core/filter.c index 52b051f..7adf503 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -638,10 +638,9 @@ int sk_attach_filter(struct sock_fprog *fprog, struct sock *sk) return err; } - rcu_read_lock_bh(); - old_fp = rcu_dereference_bh(sk->sk_filter); + old_fp = rcu_dereference_protected(sk->sk_filter, + sock_owned_by_user(sk)); rcu_assign_pointer(sk->sk_filter, fp); - rcu_read_unlock_bh(); if (old_fp) sk_filter_delayed_uncharge(sk, old_fp); @@ -654,14 +653,13 @@ int sk_detach_filter(struct sock *sk) int ret = -ENOENT; struct sk_filter *filter; - rcu_read_lock_bh(); - filter = rcu_dereference_bh(sk->sk_filter); + filter = rcu_dereference_protected(sk->sk_filter, + sock_owned_by_user(sk)); if (filter) { rcu_assign_pointer(sk->sk_filter, NULL); sk_filter_delayed_uncharge(sk, filter); ret = 0; } - rcu_read_unlock_bh(); return ret; } EXPORT_SYMBOL_GPL(sk_detach_filter);