diff options
author | Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com> | 2022-01-16 00:02:36 +0100 |
---|---|---|
committer | Jason Gunthorpe <jgg@nvidia.com> | 2022-01-28 16:12:15 +0100 |
commit | e5cce44aff3be9ad2cd52f63f35edbd706181d50 (patch) | |
tree | 56750baac5498441f569e29d77f18bf7f75cd9da /drivers | |
parent | IB/hfi1: Fix AIP early init panic (diff) | |
download | linux-e5cce44aff3be9ad2cd52f63f35edbd706181d50.tar.xz linux-e5cce44aff3be9ad2cd52f63f35edbd706181d50.zip |
IB/hfi1: Fix tstats alloc and dealloc
The tstats allocation is done in the accelerated ndo_init function but the
allocation is not tested to succeed.
The deallocation is not done in the accelerated ndo_uninit function.
Resolve issues by testing for an allocation failure and adding the
free_percpu in the uninit function.
Fixes: aa0616a9bd52 ("IB/hfi1: switch to core handling of rx/tx byte/packet counters")
Link: https://lore.kernel.org/r/1642287756-182313-5-git-send-email-mike.marciniszyn@cornelisnetworks.com
Reviewed-by: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
Signed-off-by: Mike Marciniszyn <mike.marciniszyn@cornelisnetworks.com>
Signed-off-by: Jason Gunthorpe <jgg@nvidia.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/infiniband/hw/hfi1/ipoib_main.c | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/infiniband/hw/hfi1/ipoib_main.c b/drivers/infiniband/hw/hfi1/ipoib_main.c index 8306ed5c1b80..5d814afdf7f3 100644 --- a/drivers/infiniband/hw/hfi1/ipoib_main.c +++ b/drivers/infiniband/hw/hfi1/ipoib_main.c @@ -22,26 +22,35 @@ static int hfi1_ipoib_dev_init(struct net_device *dev) int ret; dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); + if (!dev->tstats) + return -ENOMEM; ret = priv->netdev_ops->ndo_init(dev); if (ret) - return ret; + goto out_ret; ret = hfi1_netdev_add_data(priv->dd, qpn_from_mac(priv->netdev->dev_addr), dev); if (ret < 0) { priv->netdev_ops->ndo_uninit(dev); - return ret; + goto out_ret; } return 0; +out_ret: + free_percpu(dev->tstats); + dev->tstats = NULL; + return ret; } static void hfi1_ipoib_dev_uninit(struct net_device *dev) { struct hfi1_ipoib_dev_priv *priv = hfi1_ipoib_priv(dev); + free_percpu(dev->tstats); + dev->tstats = NULL; + hfi1_netdev_remove_data(priv->dd, qpn_from_mac(priv->netdev->dev_addr)); priv->netdev_ops->ndo_uninit(dev); @@ -166,6 +175,7 @@ static void hfi1_ipoib_netdev_dtor(struct net_device *dev) hfi1_ipoib_rxq_deinit(priv->netdev); free_percpu(dev->tstats); + dev->tstats = NULL; } static void hfi1_ipoib_set_id(struct net_device *dev, int id) |