summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2023-10-26 16:14:46 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-11-20 13:06:46 +0300
commit9954a7f3808b22b9e7d9e16c8547eb58784a7357 (patch)
treea0ec1a4bef0374c523ca61472459fcf766ab56f1
parente897dcbd5fbcf8f6d9bc62406c04ca9459ab4092 (diff)
downloadlinux-9954a7f3808b22b9e7d9e16c8547eb58784a7357.tar.xz
ipvlan: properly track tx_errors
[ Upstream commit ff672b9ffeb3f82135488ac16c5c5eb4b992999b ] Both ipvlan_process_v4_outbound() and ipvlan_process_v6_outbound() increment dev->stats.tx_errors in case of errors. Unfortunately there are two issues : 1) ipvlan_get_stats64() does not propagate dev->stats.tx_errors to user. 2) Increments are not atomic. KCSAN would complain eventually. Use DEV_STATS_INC() to not miss an update, and change ipvlan_get_stats64() to copy the value back to user. Fixes: 2ad7bf363841 ("ipvlan: Initial check-in of the IPVLAN driver.") Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Mahesh Bandewar <maheshb@google.com> Link: https://lore.kernel.org/r/20231026131446.3933175-1-edumazet@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r--drivers/net/ipvlan/ipvlan_core.c8
-rw-r--r--drivers/net/ipvlan/ipvlan_main.c1
2 files changed, 5 insertions, 4 deletions
diff --git a/drivers/net/ipvlan/ipvlan_core.c b/drivers/net/ipvlan/ipvlan_core.c
index ab09d110760e..b5a61b16a7ea 100644
--- a/drivers/net/ipvlan/ipvlan_core.c
+++ b/drivers/net/ipvlan/ipvlan_core.c
@@ -442,12 +442,12 @@ static int ipvlan_process_v4_outbound(struct sk_buff *skb)
err = ip_local_out(net, skb->sk, skb);
if (unlikely(net_xmit_eval(err)))
- dev->stats.tx_errors++;
+ DEV_STATS_INC(dev, tx_errors);
else
ret = NET_XMIT_SUCCESS;
goto out;
err:
- dev->stats.tx_errors++;
+ DEV_STATS_INC(dev, tx_errors);
kfree_skb(skb);
out:
return ret;
@@ -483,12 +483,12 @@ static int ipvlan_process_v6_outbound(struct sk_buff *skb)
err = ip6_local_out(net, skb->sk, skb);
if (unlikely(net_xmit_eval(err)))
- dev->stats.tx_errors++;
+ DEV_STATS_INC(dev, tx_errors);
else
ret = NET_XMIT_SUCCESS;
goto out;
err:
- dev->stats.tx_errors++;
+ DEV_STATS_INC(dev, tx_errors);
kfree_skb(skb);
out:
return ret;
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index 93be7dd571fc..f59ef2e2a614 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -322,6 +322,7 @@ static void ipvlan_get_stats64(struct net_device *dev,
s->rx_dropped = rx_errs;
s->tx_dropped = tx_drps;
}
+ s->tx_errors = DEV_STATS_READ(dev, tx_errors);
}
static int ipvlan_vlan_rx_add_vid(struct net_device *dev, __be16 proto, u16 vid)