aboutsummaryrefslogtreecommitdiffstats
path: root/net/packet/af_packet.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-12-19 06:22:11 -0500
committerTakashi Iwai <tiwai@suse.de>2013-12-19 06:22:11 -0500
commit356f402da0f989b16e4b6849e88dba5df0e25944 (patch)
treed1d41d07abf30bdd7fe1498f6eb239eaced6d9b3 /net/packet/af_packet.c
parent3a6c5d8ad0a9253aafb76df3577edcb68c09b939 (diff)
parent96b7fe0119b932ad25451d2b6357e727bbe6a309 (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.c65
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 {
237static void __fanout_unlink(struct sock *sk, struct packet_sock *po); 237static void __fanout_unlink(struct sock *sk, struct packet_sock *po);
238static void __fanout_link(struct sock *sk, struct packet_sock *po); 238static void __fanout_link(struct sock *sk, struct packet_sock *po);
239 239
240static 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
253static 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
259static 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
2062static 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
2075static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) 2083static 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);