• Shay Agroskin's avatar
    net: ena: Prevent reset after device destruction · 63d4a4c1
    Shay Agroskin authored
    The reset work is scheduled by the timer routine whenever it
    detects that a device reset is required (e.g. when a keep_alive signal
    is missing).
    When releasing device resources in ena_destroy_device() the driver
    cancels the scheduling of the timer routine without destroying the reset
    work explicitly.
    
    This creates the following bug:
        The driver is suspended and the ena_suspend() function is called
    	-> This function calls ena_destroy_device() to free the net device
    	   resources
    	    -> The driver waits for the timer routine to finish
    	    its execution and then cancels it, thus preventing from it
    	    to be called again.
    
        If, in its final execution, the timer routine schedules a reset,
        the reset routine might be called afterwards,and a redundant call to
        ena_restore_device() would be made.
    
    By changing the reset routine we allow it to read the device's state
    accurately.
    This is achieved by checking whether ENA_FLAG_TRIGGER_RESET flag is set
    before resetting the device and making both the destruction function and
    the flag check are under rtnl lock.
    The ENA_FLAG_TRIGGER_RESET is cleared at the end of the destruction
    routine. Also surround the flag check with 'likely' because
    we expect that the reset routine would be called only when
    ENA_FLAG_TRIGGER_RESET flag is set.
    
    The destruction of the timer and reset services in __ena_shutoff() have to
    stay, even though the timer routine is destroyed in ena_destroy_device().
    This is to avoid a case in which the reset routine is scheduled after
    free_netdev() in __ena_shutoff(), which would create an access to freed
    memory in adapter->flags.
    
    Fixes: 8c5c7abd ("net: ena: add power management ops to the ENA driver")
    Signed-off-by: default avatarShay Agroskin <shayagr@amazon.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    63d4a4c1
ena_netdev.c 123 KB