diff mbox series

[net-next,2/4] ionic: recover from ringsize change failure

Message ID 20200725002326.41407-3-snelson@pensando.io
State Changes Requested
Delegated to: David Miller
Headers show
Series ionic txrx updates | expand

Commit Message

Shannon Nelson July 25, 2020, 12:23 a.m. UTC
If the ringsize change fails, try restoring the previous setting.

Signed-off-by: Shannon Nelson <snelson@pensando.io>
---
 .../ethernet/pensando/ionic/ionic_ethtool.c   | 23 ++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

Comments

David Miller July 25, 2020, 2:44 a.m. UTC | #1
From: Shannon Nelson <snelson@pensando.io>
Date: Fri, 24 Jul 2020 17:23:24 -0700

> If the ringsize change fails, try restoring the previous setting.
> 
> Signed-off-by: Shannon Nelson <snelson@pensando.io>

You really can't recover properly, or reliably, with the way all of this
is structured in the ionic driver.  This is at best a half attempt at
error recovery.

Doing a full ionic_open() call abstracts things too heavily.

What you need to do is save away the current queue memory and object,
without freeing them, and only release them when you can successfully
setup the new queues.

This is the only way you can properly recover from errors in this
operation, with a proper check/commit sequence.

I'd rather not merge half solutions to this problem, sorry.
Shannon Nelson July 27, 2020, 4:42 p.m. UTC | #2
On 7/24/20 7:44 PM, David Miller wrote:
> From: Shannon Nelson <snelson@pensando.io>
> Date: Fri, 24 Jul 2020 17:23:24 -0700
>
>> If the ringsize change fails, try restoring the previous setting.
>>
>> Signed-off-by: Shannon Nelson <snelson@pensando.io>
> You really can't recover properly, or reliably, with the way all of this
> is structured in the ionic driver.  This is at best a half attempt at
> error recovery.
>
> Doing a full ionic_open() call abstracts things too heavily.
>
> What you need to do is save away the current queue memory and object,
> without freeing them, and only release them when you can successfully
> setup the new queues.
>
> This is the only way you can properly recover from errors in this
> operation, with a proper check/commit sequence.
>
> I'd rather not merge half solutions to this problem, sorry.

Sure, thanks anyway.
sln
diff mbox series

Patch

diff --git a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
index e03ea9b18f95..b48f0e46584b 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_ethtool.c
@@ -480,6 +480,8 @@  static int ionic_set_ringparam(struct net_device *netdev,
 			       struct ethtool_ringparam *ring)
 {
 	struct ionic_lif *lif = netdev_priv(netdev);
+	int tx_start, rx_start;
+	int err;
 
 	if (ring->rx_mini_pending || ring->rx_jumbo_pending) {
 		netdev_info(netdev, "Changing jumbo or mini descriptors not supported\n");
@@ -497,7 +499,26 @@  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);
+	tx_start = lif->ntxq_descs;
+	rx_start = lif->nrxq_descs;
+
+	err = ionic_reset_queues(lif, ionic_set_ringsize, ring);
+
+	if (err) {
+		int my_err;
+
+		netdev_warn(netdev, "Ringsize change failed, restoring ring sizes\n");
+		ring->tx_pending = tx_start;
+		ring->rx_pending = rx_start;
+		my_err = ionic_reset_queues(lif, ionic_set_ringsize, ring);
+
+		if (my_err) {
+			netdev_err(netdev, "Ringsize restore failed\n");
+			err = my_err;
+		}
+	}
+
+	return err;
 }
 
 static void ionic_get_channels(struct net_device *netdev,