Commit cfa324a5 authored by Netanel Belgazal's avatar Netanel Belgazal Committed by David S. Miller

net: ena: fix device destruction to gracefully free resources

When ena_destroy_device() is called from ena_suspend(), the device is
still reachable from the driver. Therefore, the driver can send a command
to the device to free all resources.
However, in all other cases of calling ena_destroy_device(), the device is
potentially in an error state and unreachable from the driver. In these
cases the driver must not send commands to the device.

The current implementation does not request resource freeing from the
device even when possible. We add the graceful parameter to
ena_destroy_device() to enable resource freeing when possible, and
use it in ena_suspend().
Signed-off-by: default avatarNetanel Belgazal <netanel@amazon.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ef5b0771
...@@ -76,7 +76,7 @@ MODULE_DEVICE_TABLE(pci, ena_pci_tbl); ...@@ -76,7 +76,7 @@ MODULE_DEVICE_TABLE(pci, ena_pci_tbl);
static int ena_rss_init_default(struct ena_adapter *adapter); static int ena_rss_init_default(struct ena_adapter *adapter);
static void check_for_admin_com_state(struct ena_adapter *adapter); static void check_for_admin_com_state(struct ena_adapter *adapter);
static void ena_destroy_device(struct ena_adapter *adapter); static void ena_destroy_device(struct ena_adapter *adapter, bool graceful);
static int ena_restore_device(struct ena_adapter *adapter); static int ena_restore_device(struct ena_adapter *adapter);
static void ena_tx_timeout(struct net_device *dev) static void ena_tx_timeout(struct net_device *dev)
...@@ -1900,7 +1900,7 @@ static int ena_close(struct net_device *netdev) ...@@ -1900,7 +1900,7 @@ static int ena_close(struct net_device *netdev)
"Destroy failure, restarting device\n"); "Destroy failure, restarting device\n");
ena_dump_stats_to_dmesg(adapter); ena_dump_stats_to_dmesg(adapter);
/* rtnl lock already obtained in dev_ioctl() layer */ /* rtnl lock already obtained in dev_ioctl() layer */
ena_destroy_device(adapter); ena_destroy_device(adapter, false);
ena_restore_device(adapter); ena_restore_device(adapter);
} }
...@@ -2550,7 +2550,7 @@ static int ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *adapter, ...@@ -2550,7 +2550,7 @@ static int ena_enable_msix_and_set_admin_interrupts(struct ena_adapter *adapter,
return rc; return rc;
} }
static void ena_destroy_device(struct ena_adapter *adapter) static void ena_destroy_device(struct ena_adapter *adapter, bool graceful)
{ {
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
struct ena_com_dev *ena_dev = adapter->ena_dev; struct ena_com_dev *ena_dev = adapter->ena_dev;
...@@ -2563,7 +2563,8 @@ static void ena_destroy_device(struct ena_adapter *adapter) ...@@ -2563,7 +2563,8 @@ static void ena_destroy_device(struct ena_adapter *adapter)
dev_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags); dev_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags);
adapter->dev_up_before_reset = dev_up; adapter->dev_up_before_reset = dev_up;
ena_com_set_admin_running_state(ena_dev, false); if (!graceful)
ena_com_set_admin_running_state(ena_dev, false);
if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags)) if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags))
ena_down(adapter); ena_down(adapter);
...@@ -2665,7 +2666,7 @@ static void ena_fw_reset_device(struct work_struct *work) ...@@ -2665,7 +2666,7 @@ static void ena_fw_reset_device(struct work_struct *work)
return; return;
} }
rtnl_lock(); rtnl_lock();
ena_destroy_device(adapter); ena_destroy_device(adapter, false);
ena_restore_device(adapter); ena_restore_device(adapter);
rtnl_unlock(); rtnl_unlock();
} }
...@@ -3467,7 +3468,7 @@ static int ena_suspend(struct pci_dev *pdev, pm_message_t state) ...@@ -3467,7 +3468,7 @@ static int ena_suspend(struct pci_dev *pdev, pm_message_t state)
"ignoring device reset request as the device is being suspended\n"); "ignoring device reset request as the device is being suspended\n");
clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); clear_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags);
} }
ena_destroy_device(adapter); ena_destroy_device(adapter, true);
rtnl_unlock(); rtnl_unlock();
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment