ipv6: tunnels: use DEV_STATS_INC()
authorEric Dumazet <edumazet@google.com>
Tue, 15 Nov 2022 08:53:57 +0000 (08:53 +0000)
committerDavid S. Miller <davem@davemloft.net>
Wed, 16 Nov 2022 12:48:44 +0000 (12:48 +0000)
Most of code paths in tunnels are lockless (eg NETIF_F_LLTX in tx).

Adopt SMP safe DEV_STATS_{INC|ADD}() to update dev->stats fields.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/ipv6/ip6_gre.c
net/ipv6/ip6_tunnel.c
net/ipv6/ip6_vti.c
net/ipv6/ip6mr.c

index 7673e1d..89f5f0f 100644 (file)
@@ -895,7 +895,6 @@ static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *skb,
        struct net_device *dev)
 {
        struct ip6_tnl *t = netdev_priv(dev);
-       struct net_device_stats *stats = &t->dev->stats;
        __be16 payload_protocol;
        int ret;
 
@@ -925,8 +924,8 @@ static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *skb,
 
 tx_err:
        if (!t->parms.collect_md || !IS_ERR(skb_tunnel_info_txcheck(skb)))
-               stats->tx_errors++;
-       stats->tx_dropped++;
+               DEV_STATS_INC(dev, tx_errors);
+       DEV_STATS_INC(dev, tx_dropped);
        kfree_skb(skb);
        return NETDEV_TX_OK;
 }
@@ -937,7 +936,6 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
        struct ip_tunnel_info *tun_info = NULL;
        struct ip6_tnl *t = netdev_priv(dev);
        struct dst_entry *dst = skb_dst(skb);
-       struct net_device_stats *stats;
        bool truncate = false;
        int encap_limit = -1;
        __u8 dsfield = false;
@@ -1086,10 +1084,9 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
        return NETDEV_TX_OK;
 
 tx_err:
-       stats = &t->dev->stats;
        if (!IS_ERR(tun_info))
-               stats->tx_errors++;
-       stats->tx_dropped++;
+               DEV_STATS_INC(dev, tx_errors);
+       DEV_STATS_INC(dev, tx_dropped);
        kfree_skb(skb);
        return NETDEV_TX_OK;
 }
index 2fb4c6a..47b6607 100644 (file)
@@ -803,8 +803,8 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
             (tunnel->parms.i_flags & TUNNEL_CSUM)) ||
            ((tpi->flags & TUNNEL_CSUM) &&
             !(tunnel->parms.i_flags & TUNNEL_CSUM))) {
-               tunnel->dev->stats.rx_crc_errors++;
-               tunnel->dev->stats.rx_errors++;
+               DEV_STATS_INC(tunnel->dev, rx_crc_errors);
+               DEV_STATS_INC(tunnel->dev, rx_errors);
                goto drop;
        }
 
@@ -812,8 +812,8 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
                if (!(tpi->flags & TUNNEL_SEQ) ||
                    (tunnel->i_seqno &&
                     (s32)(ntohl(tpi->seq) - tunnel->i_seqno) < 0)) {
-                       tunnel->dev->stats.rx_fifo_errors++;
-                       tunnel->dev->stats.rx_errors++;
+                       DEV_STATS_INC(tunnel->dev, rx_fifo_errors);
+                       DEV_STATS_INC(tunnel->dev, rx_errors);
                        goto drop;
                }
                tunnel->i_seqno = ntohl(tpi->seq) + 1;
@@ -824,8 +824,8 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
        /* Warning: All skb pointers will be invalidated! */
        if (tunnel->dev->type == ARPHRD_ETHER) {
                if (!pskb_may_pull(skb, ETH_HLEN)) {
-                       tunnel->dev->stats.rx_length_errors++;
-                       tunnel->dev->stats.rx_errors++;
+                       DEV_STATS_INC(tunnel->dev, rx_length_errors);
+                       DEV_STATS_INC(tunnel->dev, rx_errors);
                        goto drop;
                }
 
@@ -849,8 +849,8 @@ static int __ip6_tnl_rcv(struct ip6_tnl *tunnel, struct sk_buff *skb,
                                             &ipv6h->saddr,
                                             ipv6_get_dsfield(ipv6h));
                if (err > 1) {
-                       ++tunnel->dev->stats.rx_frame_errors;
-                       ++tunnel->dev->stats.rx_errors;
+                       DEV_STATS_INC(tunnel->dev, rx_frame_errors);
+                       DEV_STATS_INC(tunnel->dev, rx_errors);
                        goto drop;
                }
        }
@@ -1071,7 +1071,6 @@ int ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev, __u8 dsfield,
 {
        struct ip6_tnl *t = netdev_priv(dev);
        struct net *net = t->net;
-       struct net_device_stats *stats = &t->dev->stats;
        struct ipv6hdr *ipv6h;
        struct ipv6_tel_txoption opt;
        struct dst_entry *dst = NULL, *ndst = NULL;
@@ -1166,7 +1165,7 @@ route_lookup:
        tdev = dst->dev;
 
        if (tdev == dev) {
-               stats->collisions++;
+               DEV_STATS_INC(dev, collisions);
                net_warn_ratelimited("%s: Local routing loop detected!\n",
                                     t->parms.name);
                goto tx_err_dst_release;
@@ -1265,7 +1264,7 @@ route_lookup:
        ip6tunnel_xmit(NULL, skb, dev);
        return 0;
 tx_err_link_failure:
-       stats->tx_carrier_errors++;
+       DEV_STATS_INC(dev, tx_carrier_errors);
        dst_link_failure(skb);
 tx_err_dst_release:
        dst_release(dst);
@@ -1408,7 +1407,6 @@ static netdev_tx_t
 ip6_tnl_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct ip6_tnl *t = netdev_priv(dev);
-       struct net_device_stats *stats = &t->dev->stats;
        u8 ipproto;
        int ret;
 
@@ -1438,8 +1436,8 @@ ip6_tnl_start_xmit(struct sk_buff *skb, struct net_device *dev)
        return NETDEV_TX_OK;
 
 tx_err:
-       stats->tx_errors++;
-       stats->tx_dropped++;
+       DEV_STATS_INC(dev, tx_errors);
+       DEV_STATS_INC(dev, tx_dropped);
        kfree_skb(skb);
        return NETDEV_TX_OK;
 }
index 151337d..10b2228 100644 (file)
@@ -317,7 +317,7 @@ static int vti6_input_proto(struct sk_buff *skb, int nexthdr, __be32 spi,
 
                ipv6h = ipv6_hdr(skb);
                if (!ip6_tnl_rcv_ctl(t, &ipv6h->daddr, &ipv6h->saddr)) {
-                       t->dev->stats.rx_dropped++;
+                       DEV_STATS_INC(t->dev, rx_dropped);
                        rcu_read_unlock();
                        goto discard;
                }
@@ -359,8 +359,8 @@ static int vti6_rcv_cb(struct sk_buff *skb, int err)
        dev = t->dev;
 
        if (err) {
-               dev->stats.rx_errors++;
-               dev->stats.rx_dropped++;
+               DEV_STATS_INC(dev, rx_errors);
+               DEV_STATS_INC(dev, rx_dropped);
 
                return 0;
        }
@@ -446,7 +446,6 @@ static int
 vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
 {
        struct ip6_tnl *t = netdev_priv(dev);
-       struct net_device_stats *stats = &t->dev->stats;
        struct dst_entry *dst = skb_dst(skb);
        struct net_device *tdev;
        struct xfrm_state *x;
@@ -506,7 +505,7 @@ vti6_xmit(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
        tdev = dst->dev;
 
        if (tdev == dev) {
-               stats->collisions++;
+               DEV_STATS_INC(dev, collisions);
                net_warn_ratelimited("%s: Local routing loop detected!\n",
                                     t->parms.name);
                goto tx_err_dst_release;
@@ -544,7 +543,7 @@ xmit:
 
        return 0;
 tx_err_link_failure:
-       stats->tx_carrier_errors++;
+       DEV_STATS_INC(dev, tx_carrier_errors);
        dst_link_failure(skb);
 tx_err_dst_release:
        dst_release(dst);
@@ -555,7 +554,6 @@ static netdev_tx_t
 vti6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct ip6_tnl *t = netdev_priv(dev);
-       struct net_device_stats *stats = &t->dev->stats;
        struct flowi fl;
        int ret;
 
@@ -591,8 +589,8 @@ vti6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
        return NETDEV_TX_OK;
 
 tx_err:
-       stats->tx_errors++;
-       stats->tx_dropped++;
+       DEV_STATS_INC(dev, tx_errors);
+       DEV_STATS_INC(dev, tx_dropped);
        kfree_skb(skb);
        return NETDEV_TX_OK;
 }
index facdc78..23e7665 100644 (file)
@@ -608,8 +608,8 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb,
        if (ip6mr_fib_lookup(net, &fl6, &mrt) < 0)
                goto tx_err;
 
-       dev->stats.tx_bytes += skb->len;
-       dev->stats.tx_packets++;
+       DEV_STATS_ADD(dev, tx_bytes, skb->len);
+       DEV_STATS_INC(dev, tx_packets);
        rcu_read_lock();
        ip6mr_cache_report(mrt, skb, READ_ONCE(mrt->mroute_reg_vif_num),
                           MRT6MSG_WHOLEPKT);
@@ -618,7 +618,7 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb,
        return NETDEV_TX_OK;
 
 tx_err:
-       dev->stats.tx_errors++;
+       DEV_STATS_INC(dev, tx_errors);
        kfree_skb(skb);
        return NETDEV_TX_OK;
 }
@@ -2044,8 +2044,8 @@ static int ip6mr_forward2(struct net *net, struct mr_table *mrt,
        if (vif->flags & MIFF_REGISTER) {
                WRITE_ONCE(vif->pkt_out, vif->pkt_out + 1);
                WRITE_ONCE(vif->bytes_out, vif->bytes_out + skb->len);
-               vif_dev->stats.tx_bytes += skb->len;
-               vif_dev->stats.tx_packets++;
+               DEV_STATS_ADD(vif_dev, tx_bytes, skb->len);
+               DEV_STATS_INC(vif_dev, tx_packets);
                ip6mr_cache_report(mrt, skb, vifi, MRT6MSG_WHOLEPKT);
                goto out_free;
        }