[PATCH v4 net-next 13/18] net: terminate errors from dev_get_stats
From: Vladimir Oltean <olteanv@gmail.com>
Date: 2021-01-08 00:21:54
Subsystem:
applied micro (apm) x-gene soc ethernet driver, hisilicon network subsystem driver, intel ethernet drivers, led subsystem, networking drivers, s390 architecture, the rest · Maintainers:
Iyappan Subramanian, Keyur Chudgar, Quan Nguyen, Jian Shen, Jijie Shao, Tony Nguyen, Przemek Kitszel, Lee Jones, Pavel Machek, Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Heiko Carstens, Vasily Gorbik, Alexander Gordeev, Linus Torvalds
From: Vladimir Oltean <vladimir.oltean@nxp.com> dev_get_stats can now return errors. Some call sites are coming from a context that returns void (ethtool stats, workqueue context). So since we can't report to the upper layer, do the next best thing: shout. Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com> --- Changes in v4: Patch is new (Eric's suggestion). arch/s390/appldata/appldata_net_sum.c | 10 ++++++++-- drivers/leds/trigger/ledtrig-netdev.c | 9 ++++++++- drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c | 9 +++++++-- drivers/net/ethernet/hisilicon/hns/hns_ethtool.c | 7 ++++++- drivers/net/ethernet/intel/e1000e/ethtool.c | 9 +++++++-- drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c | 9 +++++++-- drivers/net/ethernet/intel/ixgbevf/ethtool.c | 9 +++++++-- 7 files changed, 50 insertions(+), 12 deletions(-)
diff --git a/arch/s390/appldata/appldata_net_sum.c b/arch/s390/appldata/appldata_net_sum.c
index 6146606ac9a3..72cb5344e488 100644
--- a/arch/s390/appldata/appldata_net_sum.c
+++ b/arch/s390/appldata/appldata_net_sum.c@@ -58,11 +58,11 @@ struct appldata_net_sum_data { */ static void appldata_get_net_sum_data(void *data) { - int i; struct appldata_net_sum_data *net_data; struct net_device *dev; unsigned long rx_packets, tx_packets, rx_bytes, tx_bytes, rx_errors, tx_errors, rx_dropped, tx_dropped, collisions; + int ret, i; net_data = data; net_data->sync_count_1++;
@@ -83,7 +83,13 @@ static void appldata_get_net_sum_data(void *data) for_each_netdev(&init_net, dev) { struct rtnl_link_stats64 stats; - dev_get_stats(dev, &stats); + ret = dev_get_stats(dev, &stats); + if (ret) { + netif_lists_unlock(&init_net); + netdev_err(dev, "dev_get_stats returned %d\n", ret); + return; + } + rx_packets += stats.rx_packets; tx_packets += stats.tx_packets; rx_bytes += stats.rx_bytes;
diff --git a/drivers/leds/trigger/ledtrig-netdev.c b/drivers/leds/trigger/ledtrig-netdev.c
index 4382ee278309..c717b7e7dd81 100644
--- a/drivers/leds/trigger/ledtrig-netdev.c
+++ b/drivers/leds/trigger/ledtrig-netdev.c@@ -351,6 +351,7 @@ static void netdev_trig_work(struct work_struct *work) unsigned int new_activity; unsigned long interval; int invert; + int err; /* If we dont have a device, insure we are off */ if (!trigger_data->net_dev) {
@@ -363,7 +364,13 @@ static void netdev_trig_work(struct work_struct *work) !test_bit(NETDEV_LED_RX, &trigger_data->mode)) return; - dev_get_stats(trigger_data->net_dev, &dev_stats); + err = dev_get_stats(trigger_data->net_dev, &dev_stats); + if (err) { + netdev_err(trigger_data->net_dev, + "dev_get_stats returned %d\n", err); + return; + } + new_activity = (test_bit(NETDEV_LED_TX, &trigger_data->mode) ? dev_stats.tx_packets : 0) +
diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c b/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c
index ada70425b48c..aab6a81f0438 100644
--- a/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c
+++ b/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c@@ -266,9 +266,14 @@ static void xgene_get_ethtool_stats(struct net_device *ndev, { struct xgene_enet_pdata *pdata = netdev_priv(ndev); struct rtnl_link_stats64 stats; - int i; + int err, i; + + err = dev_get_stats(ndev, &stats); + if (err) { + netdev_err(ndev, "dev_get_stats returned %d\n", err); + return; + } - dev_get_stats(ndev, &stats); for (i = 0; i < XGENE_STATS_LEN; i++) data[i] = *(u64 *)((char *)&stats + gstrings_stats[i].offset);
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
index ee2172011051..d05fa7b3f6e0 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_ethtool.c@@ -840,6 +840,7 @@ static void hns_get_ethtool_stats(struct net_device *netdev, struct hns_nic_priv *priv = netdev_priv(netdev); struct hnae_handle *h = priv->ae_handle; struct rtnl_link_stats64 net_stats; + int err; if (!h->dev->ops->get_stats || !h->dev->ops->update_stats) { netdev_err(netdev, "get_stats or update_stats is null!\n");
@@ -848,7 +849,11 @@ static void hns_get_ethtool_stats(struct net_device *netdev, h->dev->ops->update_stats(h, &netdev->stats); - dev_get_stats(netdev, &net_stats); + err = dev_get_stats(netdev, &net_stats); + if (err) { + netdev_err(netdev, "dev_get_stats returned %d\n", err); + return; + } /* get netdev statistics */ p[0] = net_stats.rx_packets;
diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c
index 06442e6bef73..41bd3e0598ce 100644
--- a/drivers/net/ethernet/intel/e1000e/ethtool.c
+++ b/drivers/net/ethernet/intel/e1000e/ethtool.c@@ -2060,15 +2060,20 @@ static void e1000_get_ethtool_stats(struct net_device *netdev, { struct e1000_adapter *adapter = netdev_priv(netdev); struct rtnl_link_stats64 net_stats; - int i; char *p = NULL; + int err, i; pm_runtime_get_sync(netdev->dev.parent); - dev_get_stats(netdev, &net_stats); + err = dev_get_stats(netdev, &net_stats); pm_runtime_put_sync(netdev->dev.parent); + if (err) { + netdev_err(netdev, "dev_get_stats returned %d\n", err); + return; + } + for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { switch (e1000_gstrings_stats[i].type) { case NETDEV_STATS:
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
index 2b8084664403..a647e2774f76 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ethtool.c@@ -1298,11 +1298,16 @@ static void ixgbe_get_ethtool_stats(struct net_device *netdev, struct rtnl_link_stats64 net_stats; unsigned int start; struct ixgbe_ring *ring; - int i, j; char *p = NULL; + int err, i, j; ixgbe_update_stats(adapter); - dev_get_stats(netdev, &net_stats); + err = dev_get_stats(netdev, &net_stats); + if (err) { + netdev_err(netdev, "dev_get_stats returned %d\n", err); + return; + } + for (i = 0; i < IXGBE_GLOBAL_STATS_LEN; i++) { switch (ixgbe_gstrings_stats[i].type) { case NETDEV_STATS:
diff --git a/drivers/net/ethernet/intel/ixgbevf/ethtool.c b/drivers/net/ethernet/intel/ixgbevf/ethtool.c
index 3b9b7e5c2998..665e39301092 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ethtool.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ethtool.c@@ -423,11 +423,16 @@ static void ixgbevf_get_ethtool_stats(struct net_device *netdev, struct rtnl_link_stats64 net_stats; unsigned int start; struct ixgbevf_ring *ring; - int i, j; + int err, i, j; char *p; ixgbevf_update_stats(adapter); - dev_get_stats(netdev, &net_stats); + err = dev_get_stats(netdev, &net_stats); + if (err) { + netdev_err(netdev, "dev_get_stats returned %d\n", err); + return; + } + for (i = 0; i < IXGBEVF_GLOBAL_STATS_LEN; i++) { switch (ixgbevf_gstrings_stats[i].type) { case NETDEV_STATS:
--
2.25.1