packet: less dev_put() calls
Subsystems (3)
PATCH 1/1 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 <[email protected]>
--- net/packet/af_packet.c | 22 ++++++++++++---------- 1 files changed, 12 insertions(+), 10 deletions(-)
net/packet/af_packet.c +12 -10
@@ -437,7 +437,8 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock,*/ saddr->spkt_device[13 ] =0 ; - dev =dev_get_by_name (sock_net (sk), saddr->spkt_device); +rcu_read_lock (); + dev =dev_get_by_name_rcu (sock_net (sk), saddr->spkt_device); err = -ENODEV ;if (dev ==NULL ) goto out_unlock;
@@ -500,14 +501,13 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock,*/ dev_queue_xmit (skb); -dev_put (dev); +rcu_read_unlock ();return len; out_free:kfree_skb (skb); out_unlock: -if (dev) -dev_put (dev); +rcu_read_unlock ();return err; }
@@ -1518,12 +1518,13 @@ static int packet_getname_spkt(struct socket *sock, struct sockaddr *uaddr,return -EOPNOTSUPP ; uaddr->sa_family =AF_PACKET ; - dev =dev_get_by_index (sock_net (sk),pkt_sk (sk)->ifindex); -if (dev) { +rcu_read_lock (); + dev =dev_get_by_index_rcu (sock_net (sk),pkt_sk (sk)->ifindex); +if (dev)strlcpy (uaddr->sa_data, dev->name,15 ); -dev_put (dev); - }else +else memset (uaddr->sa_data,0 ,14 ); +rcu_read_unlock (); *uaddr_len =sizeof (*uaddr);return 0 ;
@@ -1543,16 +1544,17 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr, sll->sll_family =AF_PACKET ; sll->sll_ifindex = po->ifindex; sll->sll_protocol = po->num; - dev =dev_get_by_index (sock_net (sk), po->ifindex); +rcu_read_lock (); + dev =dev_get_by_index_rcu (sock_net (sk), po->ifindex);if (dev) { sll->sll_hatype = dev->type; sll->sll_halen = dev->addr_len;memcpy (sll->sll_addr, dev->dev_addr, dev->addr_len); -dev_put (dev); }else { sll->sll_hatype =0 ;/* Bad: we have no ARPHRD_UNSPEC */ sll->sll_halen =0 ; } +rcu_read_unlock (); *uaddr_len = offsetof(struct sockaddr_ll , sll_addr) + sll->sll_halen;return 0 ;
From: Eric Dumazet <[email protected]>
Date: Mon, 02 Nov 2009 10:43:32 +0100
Quoted 9 lines
-
packet_sendmsg_spkt()can usedev_get_by_name_rcu()to avoid touching device refcount.-
packet_getname_spkt()&packet_getname()can usedev_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 <[email protected]>
You're unstoppable :-)
Applied.