Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Mike Marciniszyn and committed by
Jason Gunthorpe
e5cce44a 5f8f55b9

+12 -2
+12 -2
drivers/infiniband/hw/hfi1/ipoib_main.c
··· 22 22 int ret; 23 23 24 24 dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats); 25 + if (!dev->tstats) 26 + return -ENOMEM; 25 27 26 28 ret = priv->netdev_ops->ndo_init(dev); 27 29 if (ret) 28 - return ret; 30 + goto out_ret; 29 31 30 32 ret = hfi1_netdev_add_data(priv->dd, 31 33 qpn_from_mac(priv->netdev->dev_addr), 32 34 dev); 33 35 if (ret < 0) { 34 36 priv->netdev_ops->ndo_uninit(dev); 35 - return ret; 37 + goto out_ret; 36 38 } 37 39 38 40 return 0; 41 + out_ret: 42 + free_percpu(dev->tstats); 43 + dev->tstats = NULL; 44 + return ret; 39 45 } 40 46 41 47 static void hfi1_ipoib_dev_uninit(struct net_device *dev) 42 48 { 43 49 struct hfi1_ipoib_dev_priv *priv = hfi1_ipoib_priv(dev); 50 + 51 + free_percpu(dev->tstats); 52 + dev->tstats = NULL; 44 53 45 54 hfi1_netdev_remove_data(priv->dd, qpn_from_mac(priv->netdev->dev_addr)); 46 55 ··· 175 166 hfi1_ipoib_rxq_deinit(priv->netdev); 176 167 177 168 free_percpu(dev->tstats); 169 + dev->tstats = NULL; 178 170 } 179 171 180 172 static void hfi1_ipoib_set_id(struct net_device *dev, int id)