aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2023-07-05 14:30:54 +0100
committerMichael Brown <mcb30@ipxe.org>2023-07-05 14:30:54 +0100
commit6701d91c5033a3804a3bb5d49a8f9f2212b901b4 (patch)
tree0a5e950f56f174bf4f27d0d06a5b2df2e6e8f9c6
parentb5b60ea33dc48a297515f95ac19cca20bb39edd1 (diff)
downloadipxe-6701d91c5033a3804a3bb5d49a8f9f2212b901b4.zip
ipxe-6701d91c5033a3804a3bb5d49a8f9f2212b901b4.tar.gz
ipxe-6701d91c5033a3804a3bb5d49a8f9f2212b901b4.tar.bz2
[netdevice] Stop link block timer when device is closed
A running link block timer holds a reference to the network device and will prevent it from being freed until the timer expires. It is impossible for free_netdev() to be called while the timer is still running: the call to stop_timer() therein is therefore a no-op. Stop the link block timer when the device is closed, to allow a link-blocked device to be freed immediately upon unregistration of the device. (Since link block state is updated in response to received packets, the state is effectively undefined for a closed device: there is therefore no reason to leave the timer running.) Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r--src/net/netdevice.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/src/net/netdevice.c b/src/net/netdevice.c
index 07961bf..9151782 100644
--- a/src/net/netdevice.c
+++ b/src/net/netdevice.c
@@ -656,7 +656,7 @@ static void free_netdev ( struct refcnt *refcnt ) {
struct net_device *netdev =
container_of ( refcnt, struct net_device, refcnt );
- stop_timer ( &netdev->link_block );
+ assert ( ! timer_running ( &netdev->link_block ) );
netdev_tx_flush ( netdev );
netdev_rx_flush ( netdev );
clear_settings ( netdev_settings ( netdev ) );
@@ -879,6 +879,9 @@ void netdev_close ( struct net_device *netdev ) {
/* Close the device */
netdev->op->close ( netdev );
+ /* Stop link block timer */
+ stop_timer ( &netdev->link_block );
+
/* Flush TX and RX queues */
netdev_tx_flush ( netdev );
netdev_rx_flush ( netdev );