net: add __rcu annotation to sk_filter
Eric Dumazet [Mon, 25 Oct 2010 03:47:05 +0000 (03:47 +0000)]
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 73a4f97..c7a7362 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 7adf503..7beaec3 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 11db436..3eed542 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 b3f7e8c..28cb2d7 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 45e6efb..86c3952 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 c84dad4..91def93 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;
        }