net: add __rcu annotation to sk_filter
authorEric Dumazet <eric.dumazet@gmail.com>
Mon, 25 Oct 2010 03:47:05 +0000 (03:47 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 25 Oct 2010 21:18:28 +0000 (14:18 -0700)
Add __rcu annotation to :
        (struct sock)->sk_filter

And use appropriate rcu primitives to reduce sparse warnings if
CONFIG_SPARSE_RCU_POINTER=y

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/sock.h
net/core/filter.c
net/core/sock.c
net/ipv4/udp.c
net/ipv6/raw.c
net/ipv6/udp.c

index 73a4f9702a65c816c3701ab7fa9777fdbcaa2c72..c7a736228ca2dcab930f7f4a9f07d5fda2858c7c 100644 (file)
@@ -301,7 +301,7 @@ struct sock {
        const struct cred       *sk_peer_cred;
        long                    sk_rcvtimeo;
        long                    sk_sndtimeo;
-       struct sk_filter        *sk_filter;
+       struct sk_filter __rcu  *sk_filter;
        void                    *sk_protinfo;
        struct timer_list       sk_timer;
        ktime_t                 sk_stamp;
index 7adf50352918713af197b55283faf6b105087f4e..7beaec36b541274bcd1d62c9fe8376b368ab3386 100644 (file)
@@ -89,8 +89,8 @@ int sk_filter(struct sock *sk, struct sk_buff *skb)
        rcu_read_lock_bh();
        filter = rcu_dereference_bh(sk->sk_filter);
        if (filter) {
-               unsigned int pkt_len = sk_run_filter(skb, filter->insns,
-                               filter->len);
+               unsigned int pkt_len = sk_run_filter(skb, filter->insns, filter->len);
+
                err = pkt_len ? pskb_trim(skb, pkt_len) : -EPERM;
        }
        rcu_read_unlock_bh();
index 11db43632df8712576b4ff8f6c8eed7a8fdfd21d..3eed5424e659a1ab130324d16bfe3c0af4ab2feb 100644 (file)
@@ -1225,7 +1225,7 @@ struct sock *sk_clone(const struct sock *sk, const gfp_t priority)
                sock_reset_flag(newsk, SOCK_DONE);
                skb_queue_head_init(&newsk->sk_error_queue);
 
-               filter = newsk->sk_filter;
+               filter = rcu_dereference_protected(newsk->sk_filter, 1);
                if (filter != NULL)
                        sk_filter_charge(newsk, filter);
 
index b3f7e8cf18ac4227d298c7d4d659a7d19c50a244..28cb2d733a3cf6a9dd8e65a8dd2de0b44caae782 100644 (file)
@@ -1413,7 +1413,7 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
                }
        }
 
-       if (sk->sk_filter) {
+       if (rcu_dereference_raw(sk->sk_filter)) {
                if (udp_lib_checksum_complete(skb))
                        goto drop;
        }
index 45e6efb7f17120554bb963d983d74028a2001342..86c39526ba5ecb581e197d245855c9edabb53e99 100644 (file)
@@ -373,7 +373,7 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
 
 static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb)
 {
-       if ((raw6_sk(sk)->checksum || sk->sk_filter) &&
+       if ((raw6_sk(sk)->checksum || rcu_dereference_raw(sk->sk_filter)) &&
            skb_checksum_complete(skb)) {
                atomic_inc(&sk->sk_drops);
                kfree_skb(skb);
index c84dad432114ef0d885b29244bf9df0854f750e2..91def93bec85060e7571218c20439cabd4ec824f 100644 (file)
@@ -527,7 +527,7 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
                }
        }
 
-       if (sk->sk_filter) {
+       if (rcu_dereference_raw(sk->sk_filter)) {
                if (udp_lib_checksum_complete(skb))
                        goto drop;
        }