]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
net: ena: fix race between link up and device initalization
authorArthur Kiyanovski <akiyano@amazon.com>
Wed, 20 Feb 2019 16:55:58 +0000 (08:55 -0800)
committerKhalid Elmously <khalid.elmously@canonical.com>
Mon, 4 Mar 2019 01:59:06 +0000 (20:59 -0500)
BugLink: http://bugs.launchpad.net/bugs/1816806
Fix race condition between ena_update_on_link_change() and
ena_restore_device().

This race can occur if link notification arrives while the driver
is performing a reset sequence. In this case link can be set up,
enabling the device, before it is fully restored. If packets are
sent at this time, the driver might access uninitialized data
structures, causing kernel crash.

Move the clearing of ENA_FLAG_ONGOING_RESET and netif_carrier_on()
after ena_up() to ensure the device is ready when link is set up.

Fixes: d18e4f683445 ("net: ena: fix race condition between device reset and link up setup")
Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
(cherry picked from commit e1f1bd9bfbedcfce428ee7e1b82a6ec12d4c3863)
Signed-off-by: Kamal Mostafa <kamal@canonical.com>
Acked-by: You-Sheng Yang <vicamo.yang@canonical.com>
Acked-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
Signed-off-by: Khalid Elmously <khalid.elmously@canonical.com>
drivers/net/ethernet/amazon/ena/ena_netdev.c

index 08a05f3d41eb2f3377f94b8f655f935602ae0f80..c86e554317d66cd1a8bce23b6db09483ef39df06 100644 (file)
@@ -2663,11 +2663,6 @@ static int ena_restore_device(struct ena_adapter *adapter)
                goto err_device_destroy;
        }
 
-       clear_bit(ENA_FLAG_ONGOING_RESET, &adapter->flags);
-       /* Make sure we don't have a race with AENQ Links state handler */
-       if (test_bit(ENA_FLAG_LINK_UP, &adapter->flags))
-               netif_carrier_on(adapter->netdev);
-
        rc = ena_enable_msix_and_set_admin_interrupts(adapter,
                                                      adapter->num_queues);
        if (rc) {
@@ -2684,6 +2679,11 @@ static int ena_restore_device(struct ena_adapter *adapter)
        }
 
        set_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags);
+
+       clear_bit(ENA_FLAG_ONGOING_RESET, &adapter->flags);
+       if (test_bit(ENA_FLAG_LINK_UP, &adapter->flags))
+               netif_carrier_on(adapter->netdev);
+
        mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ));
        dev_err(&pdev->dev,
                "Device reset completed successfully, Driver info: %s\n",