From: Jagadeesh <jagadeesh.yalapa...@einfochips.com> Replace direct schedule_work() usage with queue_delayed_work() to allow better timing control for the watchdog task. This resolves potential race conditions during interface reset operations.
- Added watchdog_wq workqueue_struct and watchdog_dq delayed_work - Updated e1000_watchdog() to use queue_delayed_work() - Removed obsolete TODO comment about delayed workqueue Tested in Qemu : / # for i in {1..1000}; do > echo 1 > /sys/class/net/eth0/device/reset > sleep 0.1 > done [ 726.357499] e1000e 0000:00:02.0: resetting [ 726.390737] e1000e 0000:00:02.0: reset done Signed-off-by: Jagadeesh <jagadeesh.yalapa...@einfochips.com> --- drivers/net/ethernet/intel/e1000e/e1000.h | 2 ++ drivers/net/ethernet/intel/e1000e/netdev.c | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h index ba9c19e6994c..1e7b365c4f31 100644 --- a/drivers/net/ethernet/intel/e1000e/e1000.h +++ b/drivers/net/ethernet/intel/e1000e/e1000.h @@ -194,6 +194,8 @@ struct e1000_adapter { struct timer_list blink_timer; struct work_struct reset_task; + struct workqueue_struct *watchdog_wq; + struct delayed_work watchdog_dq; struct work_struct watchdog_task; const struct e1000_info *ei; diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 8ebcb6a7d608..87a915d09f4e 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c @@ -5178,9 +5178,8 @@ static void e1000_watchdog(struct timer_list *t) struct e1000_adapter *adapter = from_timer(adapter, t, watchdog_timer); /* Do the rest outside of interrupt context */ - schedule_work(&adapter->watchdog_task); + queue_delayed_work(adapter->watchdog_wq, &adapter->watchdog_dq, 0); - /* TODO: make this use queue_delayed_work() */ } static void e1000_watchdog_task(struct work_struct *work) -- 2.43.0