Commit 654d1f8a019dfa06df8355248e1ce222f303b88d
Committed by
David S. Miller
1 parent
1178f66eae
Exists in
master
and in
7 other branches
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; |