octeontx2-pf: Fix interface down flag on error
[ Upstream commit69f0aeb13b] In the existing code while changing the number of TX/RX queues using ethtool the PF/VF interface resources are freed and reallocated (otx2_stop and otx2_open is called) if the device is in running state. If any resource allocation fails in otx2_open, driver free already allocated resources and return. But again, when the number of queues changes as the device state still running oxt2_stop is called. In which we try to free already freed resources leading to driver crash. This patch fixes the issue by setting the INTF_DOWN flag on error and free the resources in otx2_stop only if the flag is not set. Fixes:50fe6c02e5("octeontx2-pf: Register and handle link notifications") Signed-off-by: Geetha sowjanya <gakula@marvell.com> Signed-off-by: Sunil Kovvuri Goutham <Sunil.Goutham@cavium.com> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
4951ffa3fa
commit
51b751fc06
@@ -230,15 +230,14 @@ static int otx2_set_channels(struct net_device *dev,
|
|||||||
err = otx2_set_real_num_queues(dev, channel->tx_count,
|
err = otx2_set_real_num_queues(dev, channel->tx_count,
|
||||||
channel->rx_count);
|
channel->rx_count);
|
||||||
if (err)
|
if (err)
|
||||||
goto fail;
|
return err;
|
||||||
|
|
||||||
pfvf->hw.rx_queues = channel->rx_count;
|
pfvf->hw.rx_queues = channel->rx_count;
|
||||||
pfvf->hw.tx_queues = channel->tx_count;
|
pfvf->hw.tx_queues = channel->tx_count;
|
||||||
pfvf->qset.cq_cnt = pfvf->hw.tx_queues + pfvf->hw.rx_queues;
|
pfvf->qset.cq_cnt = pfvf->hw.tx_queues + pfvf->hw.rx_queues;
|
||||||
|
|
||||||
fail:
|
|
||||||
if (if_up)
|
if (if_up)
|
||||||
dev->netdev_ops->ndo_open(dev);
|
err = dev->netdev_ops->ndo_open(dev);
|
||||||
|
|
||||||
netdev_info(dev, "Setting num Tx rings to %d, Rx rings to %d success\n",
|
netdev_info(dev, "Setting num Tx rings to %d, Rx rings to %d success\n",
|
||||||
pfvf->hw.tx_queues, pfvf->hw.rx_queues);
|
pfvf->hw.tx_queues, pfvf->hw.rx_queues);
|
||||||
@@ -342,7 +341,7 @@ static int otx2_set_ringparam(struct net_device *netdev,
|
|||||||
qs->rqe_cnt = rx_count;
|
qs->rqe_cnt = rx_count;
|
||||||
|
|
||||||
if (if_up)
|
if (if_up)
|
||||||
netdev->netdev_ops->ndo_open(netdev);
|
return netdev->netdev_ops->ndo_open(netdev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1592,6 +1592,7 @@ int otx2_open(struct net_device *netdev)
|
|||||||
err_tx_stop_queues:
|
err_tx_stop_queues:
|
||||||
netif_tx_stop_all_queues(netdev);
|
netif_tx_stop_all_queues(netdev);
|
||||||
netif_carrier_off(netdev);
|
netif_carrier_off(netdev);
|
||||||
|
pf->flags |= OTX2_FLAG_INTF_DOWN;
|
||||||
err_free_cints:
|
err_free_cints:
|
||||||
otx2_free_cints(pf, qidx);
|
otx2_free_cints(pf, qidx);
|
||||||
vec = pci_irq_vector(pf->pdev,
|
vec = pci_irq_vector(pf->pdev,
|
||||||
@@ -1619,6 +1620,10 @@ int otx2_stop(struct net_device *netdev)
|
|||||||
struct otx2_rss_info *rss;
|
struct otx2_rss_info *rss;
|
||||||
int qidx, vec, wrk;
|
int qidx, vec, wrk;
|
||||||
|
|
||||||
|
/* If the DOWN flag is set resources are already freed */
|
||||||
|
if (pf->flags & OTX2_FLAG_INTF_DOWN)
|
||||||
|
return 0;
|
||||||
|
|
||||||
netif_carrier_off(netdev);
|
netif_carrier_off(netdev);
|
||||||
netif_tx_stop_all_queues(netdev);
|
netif_tx_stop_all_queues(netdev);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user