diff options
author | Shannon Nelson <snelson@pensando.io> | 2020-08-27 16:00:28 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2020-08-28 08:01:30 -0700 |
commit | a34e25ab977ced1c3366fc69c0595bb3fde63fad (patch) | |
tree | 791eff1b9f42b1645ed3ddabed931aed76a4daa8 /drivers/net/ethernet/pensando/ionic/ionic_ethtool.c | |
parent | ionic: change mtu without full queue rebuild (diff) | |
download | linux-dev-a34e25ab977ced1c3366fc69c0595bb3fde63fad.tar.xz linux-dev-a34e25ab977ced1c3366fc69c0595bb3fde63fad.zip |
ionic: change the descriptor ring length without full reset
The original way of changing ring length was to completely
tear down the lif's queue structure and then rebuild it, while
running the risk of allocations that might fail in the middle
and leave us with a broken driver.
Instead, we can set up all the new queue and descriptor
allocations first, then swap them out and delete the old
allocations. If the new allocations fail, we report the error,
stay with the old setup and continue running. This gives us
a safer path, and a smaller window of time where we're not
processing traffic.
Signed-off-by: Shannon Nelson <snelson@pensando.io>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ethernet/pensando/ionic/ionic_ethtool.c')
-rw-r--r-- | drivers/net/ethernet/pensando/ionic/ionic_ethtool.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c index 73af0ecc5495..adaefa5fe883 100644 --- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c +++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c @@ -493,18 +493,14 @@ static void ionic_get_ringparam(struct net_device *netdev, ring->rx_pending = lif->nrxq_descs; } -static void ionic_set_ringsize(struct ionic_lif *lif, void *arg) -{ - struct ethtool_ringparam *ring = arg; - - lif->ntxq_descs = ring->tx_pending; - lif->nrxq_descs = ring->rx_pending; -} - static int ionic_set_ringparam(struct net_device *netdev, struct ethtool_ringparam *ring) { struct ionic_lif *lif = netdev_priv(netdev); + struct ionic_queue_params qparam; + int err; + + ionic_init_queue_params(lif, &qparam); if (ring->rx_mini_pending || ring->rx_jumbo_pending) { netdev_info(netdev, "Changing jumbo or mini descriptors not supported\n"); @@ -522,7 +518,28 @@ static int ionic_set_ringparam(struct net_device *netdev, ring->rx_pending == lif->nrxq_descs) return 0; - return ionic_reset_queues(lif, ionic_set_ringsize, ring); + if (ring->tx_pending != lif->ntxq_descs) + netdev_info(netdev, "Changing Tx ring size from %d to %d\n", + lif->ntxq_descs, ring->tx_pending); + + if (ring->rx_pending != lif->nrxq_descs) + netdev_info(netdev, "Changing Rx ring size from %d to %d\n", + lif->nrxq_descs, ring->rx_pending); + + /* if we're not running, just set the values and return */ + if (!netif_running(lif->netdev)) { + lif->ntxq_descs = ring->tx_pending; + lif->nrxq_descs = ring->rx_pending; + return 0; + } + + qparam.ntxq_descs = ring->tx_pending; + qparam.nrxq_descs = ring->rx_pending; + err = ionic_reconfigure_queues(lif, &qparam); + if (err) + netdev_info(netdev, "Ring reconfiguration failed, changes canceled: %d\n", err); + + return err; } static void ionic_get_channels(struct net_device *netdev, |