diff options
author | Takashi Iwai <tiwai@suse.de> | 2013-12-19 06:22:11 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2013-12-19 06:22:11 -0500 |
commit | 356f402da0f989b16e4b6849e88dba5df0e25944 (patch) | |
tree | d1d41d07abf30bdd7fe1498f6eb239eaced6d9b3 /net/packet/af_packet.c | |
parent | 3a6c5d8ad0a9253aafb76df3577edcb68c09b939 (diff) | |
parent | 96b7fe0119b932ad25451d2b6357e727bbe6a309 (diff) |
Merge tag 'asoc-v3.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound into for-linus
ASoC: Fixes for v3.13
The fixes here are all driver specific ones, none of which particularly
stand out but all of which are useful to users of those drivers.
Diffstat (limited to 'net/packet/af_packet.c')
-rw-r--r-- | net/packet/af_packet.c | 65 |
1 files changed, 40 insertions, 25 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index ba2548bd85bf..88cfbc189558 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -237,6 +237,30 @@ struct packet_skb_cb { | |||
237 | static void __fanout_unlink(struct sock *sk, struct packet_sock *po); | 237 | static void __fanout_unlink(struct sock *sk, struct packet_sock *po); |
238 | static void __fanout_link(struct sock *sk, struct packet_sock *po); | 238 | static void __fanout_link(struct sock *sk, struct packet_sock *po); |
239 | 239 | ||
240 | static struct net_device *packet_cached_dev_get(struct packet_sock *po) | ||
241 | { | ||
242 | struct net_device *dev; | ||
243 | |||
244 | rcu_read_lock(); | ||
245 | dev = rcu_dereference(po->cached_dev); | ||
246 | if (likely(dev)) | ||
247 | dev_hold(dev); | ||
248 | rcu_read_unlock(); | ||
249 | |||
250 | return dev; | ||
251 | } | ||
252 | |||
253 | static void packet_cached_dev_assign(struct packet_sock *po, | ||
254 | struct net_device *dev) | ||
255 | { | ||
256 | rcu_assign_pointer(po->cached_dev, dev); | ||
257 | } | ||
258 | |||
259 | static void packet_cached_dev_reset(struct packet_sock *po) | ||
260 | { | ||
261 | RCU_INIT_POINTER(po->cached_dev, NULL); | ||
262 | } | ||
263 | |||
240 | /* register_prot_hook must be invoked with the po->bind_lock held, | 264 | /* register_prot_hook must be invoked with the po->bind_lock held, |
241 | * or from a context in which asynchronous accesses to the packet | 265 | * or from a context in which asynchronous accesses to the packet |
242 | * socket is not possible (packet_create()). | 266 | * socket is not possible (packet_create()). |
@@ -246,12 +270,10 @@ static void register_prot_hook(struct sock *sk) | |||
246 | struct packet_sock *po = pkt_sk(sk); | 270 | struct packet_sock *po = pkt_sk(sk); |
247 | 271 | ||
248 | if (!po->running) { | 272 | if (!po->running) { |
249 | if (po->fanout) { | 273 | if (po->fanout) |
250 | __fanout_link(sk, po); | 274 | __fanout_link(sk, po); |
251 | } else { | 275 | else |
252 | dev_add_pack(&po->prot_hook); | 276 | dev_add_pack(&po->prot_hook); |
253 | rcu_assign_pointer(po->cached_dev, po->prot_hook.dev); | ||
254 | } | ||
255 | 277 | ||
256 | sock_hold(sk); | 278 | sock_hold(sk); |
257 | po->running = 1; | 279 | po->running = 1; |
@@ -270,12 +292,11 @@ static void __unregister_prot_hook(struct sock *sk, bool sync) | |||
270 | struct packet_sock *po = pkt_sk(sk); | 292 | struct packet_sock *po = pkt_sk(sk); |
271 | 293 | ||
272 | po->running = 0; | 294 | po->running = 0; |
273 | if (po->fanout) { | 295 | |
296 | if (po->fanout) | ||
274 | __fanout_unlink(sk, po); | 297 | __fanout_unlink(sk, po); |
275 | } else { | 298 | else |
276 | __dev_remove_pack(&po->prot_hook); | 299 | __dev_remove_pack(&po->prot_hook); |
277 | RCU_INIT_POINTER(po->cached_dev, NULL); | ||
278 | } | ||
279 | 300 | ||
280 | __sock_put(sk); | 301 | __sock_put(sk); |
281 | 302 | ||
@@ -2059,19 +2080,6 @@ static int tpacket_fill_skb(struct packet_sock *po, struct sk_buff *skb, | |||
2059 | return tp_len; | 2080 | return tp_len; |
2060 | } | 2081 | } |
2061 | 2082 | ||
2062 | static struct net_device *packet_cached_dev_get(struct packet_sock *po) | ||
2063 | { | ||
2064 | struct net_device *dev; | ||
2065 | |||
2066 | rcu_read_lock(); | ||
2067 | dev = rcu_dereference(po->cached_dev); | ||
2068 | if (dev) | ||
2069 | dev_hold(dev); | ||
2070 | rcu_read_unlock(); | ||
2071 | |||
2072 | return dev; | ||
2073 | } | ||
2074 | |||
2075 | static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | 2083 | static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) |
2076 | { | 2084 | { |
2077 | struct sk_buff *skb; | 2085 | struct sk_buff *skb; |
@@ -2088,7 +2096,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | |||
2088 | 2096 | ||
2089 | mutex_lock(&po->pg_vec_lock); | 2097 | mutex_lock(&po->pg_vec_lock); |
2090 | 2098 | ||
2091 | if (saddr == NULL) { | 2099 | if (likely(saddr == NULL)) { |
2092 | dev = packet_cached_dev_get(po); | 2100 | dev = packet_cached_dev_get(po); |
2093 | proto = po->num; | 2101 | proto = po->num; |
2094 | addr = NULL; | 2102 | addr = NULL; |
@@ -2242,7 +2250,7 @@ static int packet_snd(struct socket *sock, | |||
2242 | * Get and verify the address. | 2250 | * Get and verify the address. |
2243 | */ | 2251 | */ |
2244 | 2252 | ||
2245 | if (saddr == NULL) { | 2253 | if (likely(saddr == NULL)) { |
2246 | dev = packet_cached_dev_get(po); | 2254 | dev = packet_cached_dev_get(po); |
2247 | proto = po->num; | 2255 | proto = po->num; |
2248 | addr = NULL; | 2256 | addr = NULL; |
@@ -2451,6 +2459,8 @@ static int packet_release(struct socket *sock) | |||
2451 | 2459 | ||
2452 | spin_lock(&po->bind_lock); | 2460 | spin_lock(&po->bind_lock); |
2453 | unregister_prot_hook(sk, false); | 2461 | unregister_prot_hook(sk, false); |
2462 | packet_cached_dev_reset(po); | ||
2463 | |||
2454 | if (po->prot_hook.dev) { | 2464 | if (po->prot_hook.dev) { |
2455 | dev_put(po->prot_hook.dev); | 2465 | dev_put(po->prot_hook.dev); |
2456 | po->prot_hook.dev = NULL; | 2466 | po->prot_hook.dev = NULL; |
@@ -2506,14 +2516,17 @@ static int packet_do_bind(struct sock *sk, struct net_device *dev, __be16 protoc | |||
2506 | 2516 | ||
2507 | spin_lock(&po->bind_lock); | 2517 | spin_lock(&po->bind_lock); |
2508 | unregister_prot_hook(sk, true); | 2518 | unregister_prot_hook(sk, true); |
2519 | |||
2509 | po->num = protocol; | 2520 | po->num = protocol; |
2510 | po->prot_hook.type = protocol; | 2521 | po->prot_hook.type = protocol; |
2511 | if (po->prot_hook.dev) | 2522 | if (po->prot_hook.dev) |
2512 | dev_put(po->prot_hook.dev); | 2523 | dev_put(po->prot_hook.dev); |
2513 | po->prot_hook.dev = dev; | ||
2514 | 2524 | ||
2525 | po->prot_hook.dev = dev; | ||
2515 | po->ifindex = dev ? dev->ifindex : 0; | 2526 | po->ifindex = dev ? dev->ifindex : 0; |
2516 | 2527 | ||
2528 | packet_cached_dev_assign(po, dev); | ||
2529 | |||
2517 | if (protocol == 0) | 2530 | if (protocol == 0) |
2518 | goto out_unlock; | 2531 | goto out_unlock; |
2519 | 2532 | ||
@@ -2626,7 +2639,8 @@ static int packet_create(struct net *net, struct socket *sock, int protocol, | |||
2626 | po = pkt_sk(sk); | 2639 | po = pkt_sk(sk); |
2627 | sk->sk_family = PF_PACKET; | 2640 | sk->sk_family = PF_PACKET; |
2628 | po->num = proto; | 2641 | po->num = proto; |
2629 | RCU_INIT_POINTER(po->cached_dev, NULL); | 2642 | |
2643 | packet_cached_dev_reset(po); | ||
2630 | 2644 | ||
2631 | sk->sk_destruct = packet_sock_destruct; | 2645 | sk->sk_destruct = packet_sock_destruct; |
2632 | sk_refcnt_debug_inc(sk); | 2646 | sk_refcnt_debug_inc(sk); |
@@ -3337,6 +3351,7 @@ static int packet_notifier(struct notifier_block *this, | |||
3337 | sk->sk_error_report(sk); | 3351 | sk->sk_error_report(sk); |
3338 | } | 3352 | } |
3339 | if (msg == NETDEV_UNREGISTER) { | 3353 | if (msg == NETDEV_UNREGISTER) { |
3354 | packet_cached_dev_reset(po); | ||
3340 | po->ifindex = -1; | 3355 | po->ifindex = -1; |
3341 | if (po->prot_hook.dev) | 3356 | if (po->prot_hook.dev) |
3342 | dev_put(po->prot_hook.dev); | 3357 | dev_put(po->prot_hook.dev); |