Commit 654d1f8a019dfa06df8355248e1ce222f303b88d

Authored by Eric Dumazet
Committed by David S. Miller
1 parent 1178f66eae

packet: less dev_put() calls

- packet_sendmsg_spkt() can use dev_get_by_name_rcu() to avoid touching device refcount.

- packet_getname_spkt() & packet_getname() can use dev_get_by_index_rcu() to
  avoid touching device refcount too.

tpacket_snd() & packet_snd() can not use RCU yet because they can sleep when
allocating skb.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 1 changed file with 12 additions and 10 deletions Side-by-side Diff

net/packet/af_packet.c
... ... @@ -437,7 +437,8 @@
437 437 */
438 438  
439 439 saddr->spkt_device[13] = 0;
440   - dev = dev_get_by_name(sock_net(sk), saddr->spkt_device);
  440 + rcu_read_lock();
  441 + dev = dev_get_by_name_rcu(sock_net(sk), saddr->spkt_device);
441 442 err = -ENODEV;
442 443 if (dev == NULL)
443 444 goto out_unlock;
444 445  
... ... @@ -500,14 +501,13 @@
500 501 */
501 502  
502 503 dev_queue_xmit(skb);
503   - dev_put(dev);
  504 + rcu_read_unlock();
504 505 return len;
505 506  
506 507 out_free:
507 508 kfree_skb(skb);
508 509 out_unlock:
509   - if (dev)
510   - dev_put(dev);
  510 + rcu_read_unlock();
511 511 return err;
512 512 }
513 513  
514 514  
515 515  
... ... @@ -1518,12 +1518,13 @@
1518 1518 return -EOPNOTSUPP;
1519 1519  
1520 1520 uaddr->sa_family = AF_PACKET;
1521   - dev = dev_get_by_index(sock_net(sk), pkt_sk(sk)->ifindex);
1522   - if (dev) {
  1521 + rcu_read_lock();
  1522 + dev = dev_get_by_index_rcu(sock_net(sk), pkt_sk(sk)->ifindex);
  1523 + if (dev)
1523 1524 strlcpy(uaddr->sa_data, dev->name, 15);
1524   - dev_put(dev);
1525   - } else
  1525 + else
1526 1526 memset(uaddr->sa_data, 0, 14);
  1527 + rcu_read_unlock();
1527 1528 *uaddr_len = sizeof(*uaddr);
1528 1529  
1529 1530 return 0;
1530 1531  
1531 1532  
... ... @@ -1543,16 +1544,17 @@
1543 1544 sll->sll_family = AF_PACKET;
1544 1545 sll->sll_ifindex = po->ifindex;
1545 1546 sll->sll_protocol = po->num;
1546   - dev = dev_get_by_index(sock_net(sk), po->ifindex);
  1547 + rcu_read_lock();
  1548 + dev = dev_get_by_index_rcu(sock_net(sk), po->ifindex);
1547 1549 if (dev) {
1548 1550 sll->sll_hatype = dev->type;
1549 1551 sll->sll_halen = dev->addr_len;
1550 1552 memcpy(sll->sll_addr, dev->dev_addr, dev->addr_len);
1551   - dev_put(dev);
1552 1553 } else {
1553 1554 sll->sll_hatype = 0; /* Bad: we have no ARPHRD_UNSPEC */
1554 1555 sll->sll_halen = 0;
1555 1556 }
  1557 + rcu_read_unlock();
1556 1558 *uaddr_len = offsetof(struct sockaddr_ll, sll_addr) + sll->sll_halen;
1557 1559  
1558 1560 return 0;