diff mbox series

[v5,net-next,11/16] net: propagate errors from dev_get_stats

Message ID 20210108163159.358043-12-olteanv@gmail.com (mailing list archive)
State Superseded
Delegated to: Netdev Maintainers
Headers show
Series Make .ndo_get_stats64 sleepable | expand

Checks

Context Check Description
netdev/cover_letter success Link
netdev/fixes_present success Link
netdev/patch_count fail Series longer than 15 patches
netdev/tree_selection success Clearly marked for net-next
netdev/subject_prefix success Link
netdev/cc_maintainers warning 23 maintainers not CCed: sfr@canb.auug.org.au christian.brauner@ubuntu.com roopa@cumulusnetworks.com atenart@kernel.org pabeni@redhat.com tobias@waldekranz.com colin.king@canonical.com laniel_francis@privacyrequired.com deller@gmx.de James.Bottomley@HansenPartnership.com abelits@marvell.com balbi@kernel.org ast@kernel.org alexanderduyck@fb.com akpm@linux-foundation.org linux-usb@vger.kernel.org linux-parisc@vger.kernel.org jwi@linux.ibm.com toke@redhat.com gregkh@linuxfoundation.org adobriyan@gmail.com zhudi21@huawei.com vladimir.oltean@nxp.com
netdev/source_inline success Was 0 now: 0
netdev/verify_signedoff success Link
netdev/module_param success Was 0 now: 0
netdev/build_32bit success Errors and warnings before: 7 this patch: 6
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/verify_fixes success Link
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 306 lines checked
netdev/build_allmodconfig_warn success Errors and warnings before: 7 this patch: 6
netdev/header_inline success Link
netdev/stable success Stable not CCed

Commit Message

Vladimir Oltean Jan. 8, 2021, 4:31 p.m. UTC
From: Vladimir Oltean <vladimir.oltean@nxp.com>

dev_get_stats can now return error codes. Take the remaining call sites
where those errors can be propagated, which are all trivial, and convert
them to look at that error code and stop processing.

The effects of simulating a kernel error (returning -ENOMEM) upon
existing programs or kernel interfaces:

- cat /proc/net/dev prints up until the interface that failed, and there
  it returns:
cat: read error: Cannot allocate memory

- ifstat simply returns this and prints nothing:
Error: Buffer too small for object.
Dump terminated

- ip -s -s link show behaves the same as ifstat.

- ifconfig prints only the info for the interfaces whose statistics did
  not fail.

Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Changes in v5:
- Actually propagate errors from bonding and net_failover from within
  this patch.
- Properly propagating the dev_get_stats() error code from
  rtnl_fill_stats now, and not -EMSGSIZE.

Changes in v4:
Patch is new (Eric's suggestion).

 drivers/net/bonding/bond_main.c     | 24 ++++++++++++++++-----
 drivers/net/net_failover.c          | 33 ++++++++++++++++++++++-------
 drivers/parisc/led.c                |  7 +++++-
 drivers/usb/gadget/function/rndis.c |  4 +++-
 net/8021q/vlanproc.c                |  7 ++++--
 net/core/net-procfs.c               | 16 ++++++++++----
 net/core/net-sysfs.c                |  4 +++-
 net/core/rtnetlink.c                | 15 +++++++++----
 8 files changed, 84 insertions(+), 26 deletions(-)

Comments

Vladimir Oltean Jan. 8, 2021, 5:22 p.m. UTC | #1
On Fri, Jan 08, 2021 at 06:31:54PM +0200, Vladimir Oltean wrote:
> From: Vladimir Oltean <vladimir.oltean@nxp.com>
> 
> dev_get_stats can now return error codes. Take the remaining call sites
> where those errors can be propagated, which are all trivial, and convert
> them to look at that error code and stop processing.
> 
> The effects of simulating a kernel error (returning -ENOMEM) upon
> existing programs or kernel interfaces:
> 
> - cat /proc/net/dev prints up until the interface that failed, and there
>   it returns:
> cat: read error: Cannot allocate memory
> 
> - ifstat simply returns this and prints nothing:
> Error: Buffer too small for object.
> Dump terminated
> 
> - ip -s -s link show behaves the same as ifstat.

Note that at first I did not understand why ifstat and "ip -s -s link
show" return this message. But in the meantime I figured that it was due
to rtnetlink still returning -EMSGSIZE. That is fixed in this patch
series, but I forgot to update the commit message to reflect it. The
current output from these two commands is:

$ ifstat
RTNETLINK answers: Cannot allocate memory
Dump terminated
$ ip -s -s link show
RTNETLINK answers: Cannot allocate memory
Dump terminated

> 
> - ifconfig prints only the info for the interfaces whose statistics did
>   not fail.
> 
> Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
> ---
> Changes in v5:
> - Actually propagate errors from bonding and net_failover from within
>   this patch.
> - Properly propagating the dev_get_stats() error code from
>   rtnl_fill_stats now, and not -EMSGSIZE.
> 
> Changes in v4:
> Patch is new (Eric's suggestion).
Dan Carpenter Jan. 11, 2021, 10:55 a.m. UTC | #2
Hi Vladimir,

I love your patch! Perhaps something to improve:

[auto build test WARNING on net-next/master]

url:    https://github.com/0day-ci/linux/commits/Vladimir-Oltean/Make-ndo_get_stats64-sleepable/20210109-003617
base:   https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git 58334e7537278793c86baa88b70c48b0d50b00ae
config: i386-randconfig-m021-20210108 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-15) 9.3.0

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>

New smatch warnings:
net/core/rtnetlink.c:1821 rtnl_fill_ifinfo() warn: missing error code 'err'

vim +/err +1821 net/core/rtnetlink.c

79e1ad148c844f5c Jiri Benc            2017-11-02  1704  static int rtnl_fill_ifinfo(struct sk_buff *skb,
79e1ad148c844f5c Jiri Benc            2017-11-02  1705  			    struct net_device *dev, struct net *src_net,
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1706  			    int type, u32 pid, u32 seq, u32 change,
3d3ea5af5c0b382b Vlad Yasevich        2017-05-27  1707  			    unsigned int flags, u32 ext_filter_mask,
38e01b30563a5b5a Nicolas Dichtel      2018-01-25  1708  			    u32 event, int *new_nsid, int new_ifindex,
d4e4fdf9e4a27c87 Guillaume Nault      2019-10-23  1709  			    int tgt_netnsid, gfp_t gfp)
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1710  {
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1711  	struct ifinfomsg *ifm;
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1712  	struct nlmsghdr *nlh;
5d346342f59ffa31 Vladimir Oltean      2021-01-08  1713  	int err = -EMSGSIZE;
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1714  
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1715  	ASSERT_RTNL();
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1716  	nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1717  	if (nlh == NULL)
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1718  		return -EMSGSIZE;
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1719  
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1720  	ifm = nlmsg_data(nlh);
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1721  	ifm->ifi_family = AF_UNSPEC;
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1722  	ifm->__ifi_pad = 0;
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1723  	ifm->ifi_type = dev->type;
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1724  	ifm->ifi_index = dev->ifindex;
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1725  	ifm->ifi_flags = dev_get_flags(dev);
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1726  	ifm->ifi_change = change;
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1727  
7e4a8d5a93f649a1 Christian Brauner    2018-09-04  1728  	if (tgt_netnsid >= 0 && nla_put_s32(skb, IFLA_TARGET_NETNSID, tgt_netnsid))
79e1ad148c844f5c Jiri Benc            2017-11-02  1729  		goto nla_put_failure;
79e1ad148c844f5c Jiri Benc            2017-11-02  1730  
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1731  	if (nla_put_string(skb, IFLA_IFNAME, dev->name) ||
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1732  	    nla_put_u32(skb, IFLA_TXQLEN, dev->tx_queue_len) ||
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1733  	    nla_put_u8(skb, IFLA_OPERSTATE,
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1734  		       netif_running(dev) ? dev->operstate : IF_OPER_DOWN) ||
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1735  	    nla_put_u8(skb, IFLA_LINKMODE, dev->link_mode) ||
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1736  	    nla_put_u32(skb, IFLA_MTU, dev->mtu) ||
3e7a50ceb11ea75c Stephen Hemminger    2018-07-27  1737  	    nla_put_u32(skb, IFLA_MIN_MTU, dev->min_mtu) ||
3e7a50ceb11ea75c Stephen Hemminger    2018-07-27  1738  	    nla_put_u32(skb, IFLA_MAX_MTU, dev->max_mtu) ||
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1739  	    nla_put_u32(skb, IFLA_GROUP, dev->group) ||
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1740  	    nla_put_u32(skb, IFLA_PROMISCUITY, dev->promiscuity) ||
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1741  	    nla_put_u32(skb, IFLA_NUM_TX_QUEUES, dev->num_tx_queues) ||
c70ce028e834f8e5 Eric Dumazet         2016-03-21  1742  	    nla_put_u32(skb, IFLA_GSO_MAX_SEGS, dev->gso_max_segs) ||
c70ce028e834f8e5 Eric Dumazet         2016-03-21  1743  	    nla_put_u32(skb, IFLA_GSO_MAX_SIZE, dev->gso_max_size) ||
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1744  #ifdef CONFIG_RPS
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1745  	    nla_put_u32(skb, IFLA_NUM_RX_QUEUES, dev->num_rx_queues) ||
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1746  #endif
79110a0426d8179a Florian Westphal     2017-09-26  1747  	    put_master_ifindex(skb, dev) ||
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1748  	    nla_put_u8(skb, IFLA_CARRIER, netif_carrier_ok(dev)) ||
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1749  	    (dev->qdisc &&
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1750  	     nla_put_string(skb, IFLA_QDISC, dev->qdisc->ops->id)) ||
6c5570016b972d9b Florian Westphal     2017-10-02  1751  	    nla_put_ifalias(skb, dev) ||
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1752  	    nla_put_u32(skb, IFLA_CARRIER_CHANGES,
b2d3bcfa26a7a8de David Decotigny      2018-01-18  1753  			atomic_read(&dev->carrier_up_count) +
b2d3bcfa26a7a8de David Decotigny      2018-01-18  1754  			atomic_read(&dev->carrier_down_count)) ||
b2d3bcfa26a7a8de David Decotigny      2018-01-18  1755  	    nla_put_u32(skb, IFLA_CARRIER_UP_COUNT,
b2d3bcfa26a7a8de David Decotigny      2018-01-18  1756  			atomic_read(&dev->carrier_up_count)) ||
b2d3bcfa26a7a8de David Decotigny      2018-01-18  1757  	    nla_put_u32(skb, IFLA_CARRIER_DOWN_COUNT,
b2d3bcfa26a7a8de David Decotigny      2018-01-18  1758  			atomic_read(&dev->carrier_down_count)))
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1759  		goto nla_put_failure;
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1760  
829eb208e80d6db9 Roopa Prabhu         2020-07-31  1761  	if (rtnl_fill_proto_down(skb, dev))
829eb208e80d6db9 Roopa Prabhu         2020-07-31  1762  		goto nla_put_failure;
829eb208e80d6db9 Roopa Prabhu         2020-07-31  1763  
3d3ea5af5c0b382b Vlad Yasevich        2017-05-27  1764  	if (event != IFLA_EVENT_NONE) {
3d3ea5af5c0b382b Vlad Yasevich        2017-05-27  1765  		if (nla_put_u32(skb, IFLA_EVENT, event))
3d3ea5af5c0b382b Vlad Yasevich        2017-05-27  1766  			goto nla_put_failure;
3d3ea5af5c0b382b Vlad Yasevich        2017-05-27  1767  	}
3d3ea5af5c0b382b Vlad Yasevich        2017-05-27  1768  
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1769  	if (rtnl_fill_link_ifmap(skb, dev))
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1770  		goto nla_put_failure;
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1771  
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1772  	if (dev->addr_len) {
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1773  		if (nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr) ||
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1774  		    nla_put(skb, IFLA_BROADCAST, dev->addr_len, dev->broadcast))
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1775  			goto nla_put_failure;
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1776  	}
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1777  
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1778  	if (rtnl_phys_port_id_fill(skb, dev))
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1779  		goto nla_put_failure;
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1780  
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1781  	if (rtnl_phys_port_name_fill(skb, dev))
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1782  		goto nla_put_failure;
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1783  
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1784  	if (rtnl_phys_switch_id_fill(skb, dev))
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1785  		goto nla_put_failure;
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1786  
5d346342f59ffa31 Vladimir Oltean      2021-01-08  1787  	err = rtnl_fill_stats(skb, dev);
5d346342f59ffa31 Vladimir Oltean      2021-01-08  1788  	if (err)
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1789  		goto nla_put_failure;
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1790  
250fc3dfdbd3e8b5 Florian Westphal     2017-09-26  1791  	if (rtnl_fill_vf(skb, dev, ext_filter_mask))
b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1792  		goto nla_put_failure;

No error codes any more on the rest of the gotos in this function.

b22b941b2c253a20 Hannes Frederic Sowa 2015-11-17  1793  
c53864fd60227de0 David Gibson         2014-04-24  1794  	if (rtnl_port_fill(skb, dev, ext_filter_mask))
57b610805ce92dbd Scott Feldman        2010-05-17  1795  		goto nla_put_failure;
57b610805ce92dbd Scott Feldman        2010-05-17  1796  
d1fdd9138682e0f2 Brenden Blanco       2016-07-19  1797  	if (rtnl_xdp_fill(skb, dev))
d1fdd9138682e0f2 Brenden Blanco       2016-07-19  1798  		goto nla_put_failure;
d1fdd9138682e0f2 Brenden Blanco       2016-07-19  1799  
ba7d49b1f0f8e5f2 Jiri Pirko           2014-01-22  1800  	if (dev->rtnl_link_ops || rtnl_have_link_slave_info(dev)) {
38f7b870d4a6a5d3 Patrick McHardy      2007-06-13  1801  		if (rtnl_link_fill(skb, dev) < 0)
38f7b870d4a6a5d3 Patrick McHardy      2007-06-13  1802  			goto nla_put_failure;
38f7b870d4a6a5d3 Patrick McHardy      2007-06-13  1803  	}
38f7b870d4a6a5d3 Patrick McHardy      2007-06-13  1804  
d4e4fdf9e4a27c87 Guillaume Nault      2019-10-23  1805  	if (rtnl_fill_link_netnsid(skb, dev, src_net, gfp))
d37512a277dfb2ce Nicolas Dichtel      2015-01-15  1806  		goto nla_put_failure;
d37512a277dfb2ce Nicolas Dichtel      2015-01-15  1807  
6621dd29eb9b5e67 Nicolas Dichtel      2017-10-03  1808  	if (new_nsid &&
6621dd29eb9b5e67 Nicolas Dichtel      2017-10-03  1809  	    nla_put_s32(skb, IFLA_NEW_NETNSID, *new_nsid) < 0)
6621dd29eb9b5e67 Nicolas Dichtel      2017-10-03  1810  		goto nla_put_failure;
38e01b30563a5b5a Nicolas Dichtel      2018-01-25  1811  	if (new_ifindex &&
38e01b30563a5b5a Nicolas Dichtel      2018-01-25  1812  	    nla_put_s32(skb, IFLA_NEW_IFINDEX, new_ifindex) < 0)
38e01b30563a5b5a Nicolas Dichtel      2018-01-25  1813  		goto nla_put_failure;
38e01b30563a5b5a Nicolas Dichtel      2018-01-25  1814  
f74877a5457d34d6 Michal Kubecek       2019-12-11  1815  	if (memchr_inv(dev->perm_addr, '\0', dev->addr_len) &&
f74877a5457d34d6 Michal Kubecek       2019-12-11  1816  	    nla_put(skb, IFLA_PERM_ADDRESS, dev->addr_len, dev->perm_addr))
f74877a5457d34d6 Michal Kubecek       2019-12-11  1817  		goto nla_put_failure;
6621dd29eb9b5e67 Nicolas Dichtel      2017-10-03  1818  
5fa85a09390c4a52 Florian Westphal     2017-10-16  1819  	rcu_read_lock();
070cbf5be7774dcf Florian Westphal     2017-10-16  1820  	if (rtnl_fill_link_af(skb, dev, ext_filter_mask))
5fa85a09390c4a52 Florian Westphal     2017-10-16 @1821  		goto nla_put_failure_rcu;
5fa85a09390c4a52 Florian Westphal     2017-10-16  1822  	rcu_read_unlock();
f8ff182c716c6f11 Thomas Graf          2010-11-16  1823  
88f4fb0c7496a13b Jiri Pirko           2019-09-30  1824  	if (rtnl_fill_prop_list(skb, dev))
88f4fb0c7496a13b Jiri Pirko           2019-09-30  1825  		goto nla_put_failure;
88f4fb0c7496a13b Jiri Pirko           2019-09-30  1826  
053c095a82cf7730 Johannes Berg        2015-01-16  1827  	nlmsg_end(skb, nlh);
053c095a82cf7730 Johannes Berg        2015-01-16  1828  	return 0;
b60c5115f4abf0b9 Thomas Graf          2006-08-04  1829  
5fa85a09390c4a52 Florian Westphal     2017-10-16  1830  nla_put_failure_rcu:
5fa85a09390c4a52 Florian Westphal     2017-10-16  1831  	rcu_read_unlock();
b60c5115f4abf0b9 Thomas Graf          2006-08-04  1832  nla_put_failure:
26932566a42d46ae Patrick McHardy      2007-01-31  1833  	nlmsg_cancel(skb, nlh);
5d346342f59ffa31 Vladimir Oltean      2021-01-08  1834  	return err;
^1da177e4c3f4152 Linus Torvalds       2005-04-16  1835  }
^1da177e4c3f4152 Linus Torvalds       2005-04-16  1836  

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
Vladimir Oltean Jan. 11, 2021, 11:03 a.m. UTC | #3
Hi Dan,

On Mon, Jan 11, 2021 at 01:55:16PM +0300, Dan Carpenter wrote:
> Hi Vladimir,
>
> New smatch warnings:
> net/core/rtnetlink.c:1821 rtnl_fill_ifinfo() warn: missing error code 'err'
>
> vim +/err +1821 net/core/rtnetlink.c
>
> static int rtnl_fill_ifinfo(struct sk_buff *skb,
> 			    struct net_device *dev, struct net *src_net,
> 			    int type, u32 pid, u32 seq, u32 change,
> 			    unsigned int flags, u32 ext_filter_mask,
> 			    u32 event, int *new_nsid, int new_ifindex,
> 			    int tgt_netnsid, gfp_t gfp)
> {
> 	struct ifinfomsg *ifm;
> 	struct nlmsghdr *nlh;
> 	int err = -EMSGSIZE;
>
...
>
> 	err = rtnl_fill_stats(skb, dev);
> 	if (err)
> 		goto nla_put_failure;
>
> 	if (rtnl_fill_vf(skb, dev, ext_filter_mask))
> 		goto nla_put_failure;
>
> No error codes any more on the rest of the gotos in this function.
>
>
> 	if (rtnl_port_fill(skb, dev, ext_filter_mask))
> 		goto nla_put_failure;
>
> 	if (rtnl_xdp_fill(skb, dev))
> 		goto nla_put_failure;
>
...
>
> 	nlmsg_end(skb, nlh);
> 	return 0;
>
> nla_put_failure_rcu:
> 	rcu_read_unlock();
> nla_put_failure:
> 	nlmsg_cancel(skb, nlh);
> 	return err;
> }

Thank you for this report. It is a valid issue. It has also been fixed
in v6:
https://patchwork.kernel.org/project/netdevbpf/patch/20210109172624.2028156-12-olteanv@gmail.com/
From the changelog:

Changes in v6:
- Fixed rtnetlink incorrectly returning 0 in rtnl_fill_ifinfo on
  nla_put_failure and causing "ip a" to not show any interfaces.
diff mbox series

Patch

diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 5a3178b3dba3..2352ef64486b 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1757,7 +1757,12 @@  int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
 
 	slave_dev->priv_flags |= IFF_BONDING;
 	/* initialize slave stats */
-	dev_get_stats(new_slave->dev, &new_slave->slave_stats);
+	res = dev_get_stats(new_slave->dev, &new_slave->slave_stats);
+	if (res) {
+		slave_err(bond_dev, slave_dev, "dev_get_stats returned %d\n",
+			  res);
+		goto err_close;
+	}
 
 	if (bond_is_lb(bond)) {
 		/* bond_alb_init_slave() must be called before all other stages since
@@ -2094,7 +2099,13 @@  static int __bond_release_one(struct net_device *bond_dev,
 	bond_sysfs_slave_del(slave);
 
 	/* recompute stats just before removing the slave */
-	bond_get_stats(bond->dev, &bond->bond_stats);
+	err = bond_get_stats(bond->dev, &bond->bond_stats);
+	if (err) {
+		slave_info(bond_dev, slave_dev, "dev_get_stats returned %d\n",
+			   err);
+		unblock_netpoll_tx();
+		return err;
+	}
 
 	bond_upper_dev_unlink(bond, slave);
 	/* unregister rx_handler early so bond_handle_frame wouldn't be called
@@ -3743,7 +3754,7 @@  static int bond_get_stats(struct net_device *bond_dev,
 	struct list_head *iter;
 	struct slave *slave;
 	int nest_level = 0;
-
+	int res = 0;
 
 	rcu_read_lock();
 #ifdef CONFIG_LOCKDEP
@@ -3754,7 +3765,9 @@  static int bond_get_stats(struct net_device *bond_dev,
 	memcpy(stats, &bond->bond_stats, sizeof(*stats));
 
 	bond_for_each_slave_rcu(bond, slave, iter) {
-		dev_get_stats(slave->dev, &temp);
+		res = dev_get_stats(slave->dev, &temp);
+		if (res)
+			goto out;
 
 		bond_fold_stats(stats, &temp, &slave->slave_stats);
 
@@ -3763,10 +3776,11 @@  static int bond_get_stats(struct net_device *bond_dev,
 	}
 
 	memcpy(&bond->bond_stats, stats, sizeof(*stats));
+out:
 	spin_unlock(&bond->stats_lock);
 	rcu_read_unlock();
 
-	return 0;
+	return res;
 }
 
 static int bond_do_ioctl(struct net_device *bond_dev, struct ifreq *ifr, int cmd)
diff --git a/drivers/net/net_failover.c b/drivers/net/net_failover.c
index e032ad1c5e22..7f70555e68d1 100644
--- a/drivers/net/net_failover.c
+++ b/drivers/net/net_failover.c
@@ -185,6 +185,7 @@  static int net_failover_get_stats(struct net_device *dev,
 	struct net_failover_info *nfo_info = netdev_priv(dev);
 	struct rtnl_link_stats64 temp;
 	struct net_device *slave_dev;
+	int err = 0;
 
 	spin_lock(&nfo_info->stats_lock);
 	memcpy(stats, &nfo_info->failover_stats, sizeof(*stats));
@@ -193,24 +194,29 @@  static int net_failover_get_stats(struct net_device *dev,
 
 	slave_dev = rcu_dereference(nfo_info->primary_dev);
 	if (slave_dev) {
-		dev_get_stats(slave_dev, &temp);
+		err = dev_get_stats(slave_dev, &temp);
+		if (err)
+			goto out;
 		net_failover_fold_stats(stats, &temp, &nfo_info->primary_stats);
 		memcpy(&nfo_info->primary_stats, &temp, sizeof(temp));
 	}
 
 	slave_dev = rcu_dereference(nfo_info->standby_dev);
 	if (slave_dev) {
-		dev_get_stats(slave_dev, &temp);
+		err = dev_get_stats(slave_dev, &temp);
+		if (err)
+			goto out;
 		net_failover_fold_stats(stats, &temp, &nfo_info->standby_stats);
 		memcpy(&nfo_info->standby_stats, &temp, sizeof(temp));
 	}
 
+out:
 	rcu_read_unlock();
 
 	memcpy(&nfo_info->failover_stats, stats, sizeof(*stats));
 	spin_unlock(&nfo_info->stats_lock);
 
-	return 0;
+	return err;
 }
 
 static int net_failover_change_mtu(struct net_device *dev, int new_mtu)
@@ -545,11 +551,15 @@  static int net_failover_slave_register(struct net_device *slave_dev,
 	if (slave_is_standby) {
 		rcu_assign_pointer(nfo_info->standby_dev, slave_dev);
 		standby_dev = slave_dev;
-		dev_get_stats(standby_dev, &nfo_info->standby_stats);
+		err = dev_get_stats(standby_dev, &nfo_info->standby_stats);
+		if (err)
+			goto err_stats_get;
 	} else {
 		rcu_assign_pointer(nfo_info->primary_dev, slave_dev);
 		primary_dev = slave_dev;
-		dev_get_stats(primary_dev, &nfo_info->primary_stats);
+		err = dev_get_stats(primary_dev, &nfo_info->primary_stats);
+		if (err)
+			goto err_stats_get;
 		failover_dev->min_mtu = slave_dev->min_mtu;
 		failover_dev->max_mtu = slave_dev->max_mtu;
 	}
@@ -564,6 +574,8 @@  static int net_failover_slave_register(struct net_device *slave_dev,
 
 	return 0;
 
+err_stats_get:
+	vlan_vids_del_by_dev(slave_dev, failover_dev);
 err_vlan_add:
 	dev_uc_unsync(slave_dev, failover_dev);
 	dev_mc_unsync(slave_dev, failover_dev);
@@ -597,6 +609,7 @@  static int net_failover_slave_unregister(struct net_device *slave_dev,
 	struct net_device *standby_dev, *primary_dev;
 	struct net_failover_info *nfo_info;
 	bool slave_is_standby;
+	int err;
 
 	nfo_info = netdev_priv(failover_dev);
 	primary_dev = rtnl_dereference(nfo_info->primary_dev);
@@ -611,7 +624,8 @@  static int net_failover_slave_unregister(struct net_device *slave_dev,
 	dev_close(slave_dev);
 
 	nfo_info = netdev_priv(failover_dev);
-	dev_get_stats(failover_dev, &nfo_info->failover_stats);
+	/* Proceed with the deregistration anyway */
+	err = dev_get_stats(failover_dev, &nfo_info->failover_stats);
 
 	slave_is_standby = slave_dev->dev.parent == failover_dev->dev.parent;
 	if (slave_is_standby) {
@@ -631,7 +645,7 @@  static int net_failover_slave_unregister(struct net_device *slave_dev,
 	netdev_info(failover_dev, "failover %s slave:%s unregistered\n",
 		    slave_is_standby ? "standby" : "primary", slave_dev->name);
 
-	return 0;
+	return err;
 }
 
 static int net_failover_slave_link_change(struct net_device *slave_dev,
@@ -639,6 +653,7 @@  static int net_failover_slave_link_change(struct net_device *slave_dev,
 {
 	struct net_device *primary_dev, *standby_dev;
 	struct net_failover_info *nfo_info;
+	int err;
 
 	nfo_info = netdev_priv(failover_dev);
 
@@ -653,7 +668,9 @@  static int net_failover_slave_link_change(struct net_device *slave_dev,
 		netif_carrier_on(failover_dev);
 		netif_tx_wake_all_queues(failover_dev);
 	} else {
-		dev_get_stats(failover_dev, &nfo_info->failover_stats);
+		err = dev_get_stats(failover_dev, &nfo_info->failover_stats);
+		if (err)
+			return err;
 		netif_carrier_off(failover_dev);
 		netif_tx_stop_all_queues(failover_dev);
 	}
diff --git a/drivers/parisc/led.c b/drivers/parisc/led.c
index cc6108785323..d17d0fbf878d 100644
--- a/drivers/parisc/led.c
+++ b/drivers/parisc/led.c
@@ -370,7 +370,12 @@  static __inline__ int led_get_net_activity(void)
 
 		in_dev_put(in_dev);
 
-		dev_get_stats(dev, &stats);
+		retval = dev_get_stats(dev, &stats);
+		if (retval) {
+			netif_lists_unlock(&init_net);
+			return retval;
+		}
+
 		rx_total += stats.rx_packets;
 		tx_total += stats.tx_packets;
 	}
diff --git a/drivers/usb/gadget/function/rndis.c b/drivers/usb/gadget/function/rndis.c
index 7ec29e007ae9..bec474819c3d 100644
--- a/drivers/usb/gadget/function/rndis.c
+++ b/drivers/usb/gadget/function/rndis.c
@@ -198,7 +198,9 @@  static int gen_ndis_query_resp(struct rndis_params *params, u32 OID, u8 *buf,
 	resp->InformationBufferOffset = cpu_to_le32(16);
 
 	net = params->dev;
-	dev_get_stats(net, &stats);
+	retval = dev_get_stats(net, &stats);
+	if (retval)
+		return retval;
 
 	switch (OID) {
 
diff --git a/net/8021q/vlanproc.c b/net/8021q/vlanproc.c
index 3a6682d79630..d89b75804834 100644
--- a/net/8021q/vlanproc.c
+++ b/net/8021q/vlanproc.c
@@ -244,12 +244,15 @@  static int vlandev_seq_show(struct seq_file *seq, void *offset)
 	const struct vlan_dev_priv *vlan = vlan_dev_priv(vlandev);
 	static const char fmt64[] = "%30s %12llu\n";
 	struct rtnl_link_stats64 stats;
-	int i;
+	int err, i;
 
 	if (!is_vlan_dev(vlandev))
 		return 0;
 
-	dev_get_stats(vlandev, &stats);
+	err = dev_get_stats(vlandev, &stats);
+	if (err)
+		return err;
+
 	seq_printf(seq,
 		   "%s  VID: %d	 REORDER_HDR: %i  dev->priv_flags: %hx\n",
 		   vlandev->name, vlan->vlan_id,
diff --git a/net/core/net-procfs.c b/net/core/net-procfs.c
index 64666ba7ccab..ee19c35f6e00 100644
--- a/net/core/net-procfs.c
+++ b/net/core/net-procfs.c
@@ -78,11 +78,14 @@  static void dev_seq_stop(struct seq_file *seq, void *v)
 	netif_lists_unlock(net);
 }
 
-static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
+static int dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
 {
 	struct rtnl_link_stats64 stats;
+	int err;
 
-	dev_get_stats(dev, &stats);
+	err = dev_get_stats(dev, &stats);
+	if (err)
+		return err;
 
 	seq_printf(seq, "%6s: %7llu %7llu %4llu %4llu %4llu %5llu %10llu %9llu "
 		   "%8llu %7llu %4llu %4llu %4llu %5llu %7llu %10llu\n",
@@ -101,6 +104,8 @@  static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
 		    stats.tx_window_errors +
 		    stats.tx_heartbeat_errors,
 		   stats.tx_compressed);
+
+	return 0;
 }
 
 /*
@@ -109,6 +114,8 @@  static void dev_seq_printf_stats(struct seq_file *seq, struct net_device *dev)
  */
 static int dev_seq_show(struct seq_file *seq, void *v)
 {
+	int err = 0;
+
 	if (v == SEQ_START_TOKEN)
 		seq_puts(seq, "Inter-|   Receive                            "
 			      "                    |  Transmit\n"
@@ -116,8 +123,9 @@  static int dev_seq_show(struct seq_file *seq, void *v)
 			      "compressed multicast|bytes    packets errs "
 			      "drop fifo colls carrier compressed\n");
 	else
-		dev_seq_printf_stats(seq, v);
-	return 0;
+		err = dev_seq_printf_stats(seq, v);
+
+	return err;
 }
 
 static u32 softnet_backlog_len(struct softnet_data *sd)
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c
index 5d89c85b42d4..6f789e178e92 100644
--- a/net/core/net-sysfs.c
+++ b/net/core/net-sysfs.c
@@ -588,7 +588,9 @@  static ssize_t netstat_show(const struct device *d,
 	if (dev_isalive(dev)) {
 		struct rtnl_link_stats64 stats;
 
-		dev_get_stats(dev, &stats);
+		ret = dev_get_stats(dev, &stats);
+		if (ret)
+			return ret;
 
 		ret = sprintf(buf, fmt_u64, *(u64 *)(((u8 *)&stats) + offset));
 	}
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index bb0596c41b3e..656c482befac 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1201,6 +1201,7 @@  static noinline_for_stack int rtnl_fill_stats(struct sk_buff *skb,
 {
 	struct rtnl_link_stats64 *sp;
 	struct nlattr *attr;
+	int err;
 
 	attr = nla_reserve_64bit(skb, IFLA_STATS64,
 				 sizeof(struct rtnl_link_stats64), IFLA_PAD);
@@ -1208,7 +1209,9 @@  static noinline_for_stack int rtnl_fill_stats(struct sk_buff *skb,
 		return -EMSGSIZE;
 
 	sp = nla_data(attr);
-	dev_get_stats(dev, sp);
+	err = dev_get_stats(dev, sp);
+	if (err)
+		return err;
 
 	attr = nla_reserve(skb, IFLA_STATS,
 			   sizeof(struct rtnl_link_stats));
@@ -1707,6 +1710,7 @@  static int rtnl_fill_ifinfo(struct sk_buff *skb,
 {
 	struct ifinfomsg *ifm;
 	struct nlmsghdr *nlh;
+	int err = -EMSGSIZE;
 
 	ASSERT_RTNL();
 	nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
@@ -1780,7 +1784,8 @@  static int rtnl_fill_ifinfo(struct sk_buff *skb,
 	if (rtnl_phys_switch_id_fill(skb, dev))
 		goto nla_put_failure;
 
-	if (rtnl_fill_stats(skb, dev))
+	err = rtnl_fill_stats(skb, dev);
+	if (err)
 		goto nla_put_failure;
 
 	if (rtnl_fill_vf(skb, dev, ext_filter_mask))
@@ -1826,7 +1831,7 @@  static int rtnl_fill_ifinfo(struct sk_buff *skb,
 	rcu_read_unlock();
 nla_put_failure:
 	nlmsg_cancel(skb, nlh);
-	return -EMSGSIZE;
+	return err;
 }
 
 static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
@@ -5135,7 +5140,9 @@  static int rtnl_fill_statsinfo(struct sk_buff *skb, struct net_device *dev,
 			goto nla_put_failure;
 
 		sp = nla_data(attr);
-		dev_get_stats(dev, sp);
+		err = dev_get_stats(dev, sp);
+		if (err)
+			goto nla_put_failure;
 	}
 
 	if (stats_attr_valid(filter_mask, IFLA_STATS_LINK_XSTATS, *idxattr)) {