diff options
author | Greg Kroah-Hartman <gregkh@suse.de> | 2006-08-18 11:02:52 -0700 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2006-08-18 11:02:52 -0700 |
commit | ef7d1b244fa6c94fb76d5f787b8629df64ea4046 (patch) | |
tree | eb6b35bb250f46d75853764bd9309c75e4f03c72 /net/ipv6 | |
parent | ed0da6fc9d3096f54c4a76737eeae57ac81418cf (diff) | |
parent | 78eb887733ec8ff5d6e6c69e3c32a187a9303622 (diff) | |
download | blackbird-op-linux-ef7d1b244fa6c94fb76d5f787b8629df64ea4046.tar.gz blackbird-op-linux-ef7d1b244fa6c94fb76d5f787b8629df64ea4046.zip |
Merge gregkh@master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/icmp.c | 13 | ||||
-rw-r--r-- | net/ipv6/mcast.c | 10 |
2 files changed, 19 insertions, 4 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index 1044b6fce0d5..3d6e9a351150 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -712,6 +712,11 @@ discard_it: return 0; } +/* + * Special lock-class for __icmpv6_socket: + */ +static struct lock_class_key icmpv6_socket_sk_dst_lock_key; + int __init icmpv6_init(struct net_proto_family *ops) { struct sock *sk; @@ -730,6 +735,14 @@ int __init icmpv6_init(struct net_proto_family *ops) sk = per_cpu(__icmpv6_socket, i)->sk; sk->sk_allocation = GFP_ATOMIC; + /* + * Split off their lock-class, because sk->sk_dst_lock + * gets used from softirqs, which is safe for + * __icmpv6_socket (because those never get directly used + * via userspace syscalls), but unsafe for normal sockets. + */ + lockdep_set_class(&sk->sk_dst_lock, + &icmpv6_socket_sk_dst_lock_key); /* Enough space for 2 64K ICMP packets, including * sk_buff struct overhead. diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c index 9d697d4dcffc..639eb20c9f1f 100644 --- a/net/ipv6/mcast.c +++ b/net/ipv6/mcast.c @@ -268,13 +268,14 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, struct in6_addr *addr) if ((dev = dev_get_by_index(mc_lst->ifindex)) != NULL) { struct inet6_dev *idev = in6_dev_get(dev); + (void) ip6_mc_leave_src(sk, mc_lst, idev); if (idev) { - (void) ip6_mc_leave_src(sk,mc_lst,idev); __ipv6_dev_mc_dec(idev, &mc_lst->addr); in6_dev_put(idev); } dev_put(dev); - } + } else + (void) ip6_mc_leave_src(sk, mc_lst, NULL); sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); return 0; } @@ -334,13 +335,14 @@ void ipv6_sock_mc_close(struct sock *sk) if (dev) { struct inet6_dev *idev = in6_dev_get(dev); + (void) ip6_mc_leave_src(sk, mc_lst, idev); if (idev) { - (void) ip6_mc_leave_src(sk, mc_lst, idev); __ipv6_dev_mc_dec(idev, &mc_lst->addr); in6_dev_put(idev); } dev_put(dev); - } + } else + (void) ip6_mc_leave_src(sk, mc_lst, NULL); sock_kfree_s(sk, mc_lst, sizeof(*mc_lst)); |