* [PATCH net] iavf: fix deadlock in reset handling
@ 2026-02-02 8:48 Petr Oros
2026-02-02 9:06 ` [Intel-wired-lan] " Loktionov, Aleksandr
` (3 more replies)
0 siblings, 4 replies; 17+ messages in thread
From: Petr Oros @ 2026-02-02 8:48 UTC (permalink / raw)
To: netdev
Cc: ivecera, mschmidt, Petr Oros, Tony Nguyen, Przemek Kitszel,
Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski,
Paolo Abeni, Stanislav Fomichev, intel-wired-lan, linux-kernel
Three driver callbacks schedule a reset and wait for its completion:
ndo_change_mtu(), ethtool set_ringparam(), and ethtool set_channels().
Waiting for reset in ndo_change_mtu() and set_ringparam() was added by
commit c2ed2403f12c74 ("iavf: Wait for reset in callbacks which trigger
it") to fix a race condition where adding an interface to bonding
immediately after MTU or ring parameter change failed because the
interface was still in __RESETTING state. The same commit also added
waiting in iavf_set_priv_flags(), which was later removed by commit
53844673d55529 ("iavf: kill "legacy-rx" for good").
Waiting in set_channels() was introduced earlier by commit 4e5e6b5d9d13
("iavf: Fix return of set the new channel count") to ensure the PF has
enough time to complete the VF reset when changing channel count, and to
return correct error codes to userspace.
Commit ef490bbb226702 ("iavf: Add net_shaper_ops support") added
net_shaper_ops to iavf, which required reset_task to use _locked NAPI
variants (napi_enable_locked, napi_disable_locked) that need the netdev
instance lock.
Later, commit 7e4d784f5810 ("net: hold netdev instance lock during
rtnetlink operations") and commit 2bcf4772e45adb ("net: ethtool: try to
protect all callback with netdev instance lock") started holding the
netdev instance lock during ndo and ethtool callbacks for drivers with
net_shaper_ops.
The combination of waiting for reset and the new locking requirements
creates a deadlock: the callback holds the lock and waits for reset_task,
but reset_task is blocked waiting for the same lock:
Thread 1 (callback) Thread 2 (reset_task)
------------------- ---------------------
netdev_lock()
ndo_change_mtu() or ethtool op
iavf_schedule_reset()
iavf_wait_for_reset() iavf_reset_task()
waiting... netdev_lock() <- DEADLOCK
Reproducer:
# echo 16 > /sys/class/net/$PF/device/sriov_numvfs
# ip link set $VF up
# ip link set $VF mtu 5000
RTNETLINK answers: Device or resource busy
# dmesg | tail -1
iavf: MTU change interrupted waiting for reset
Fix this by temporarily releasing the lock while waiting for reset to
complete. This follows the pattern used elsewhere in the kernel (e.g.,
do_set_master() releases rtnl_lock before calling ndo_add_slave()).
Fixes: 7e4d784f5810 ("net: hold netdev instance lock during rtnetlink operations")
Signed-off-by: Petr Oros <poros@redhat.com>
---
drivers/net/ethernet/intel/iavf/iavf_main.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c
index 8aa6e92c16431f..d7738fb8fa60bc 100644
--- a/drivers/net/ethernet/intel/iavf/iavf_main.c
+++ b/drivers/net/ethernet/intel/iavf/iavf_main.c
@@ -189,13 +189,22 @@ static bool iavf_is_reset_in_progress(struct iavf_adapter *adapter)
* iavf_wait_for_reset - Wait for reset to finish.
* @adapter: board private structure
*
+ * The iavf driver selects NET_SHAPER, so callbacks that trigger reset are
+ * always called with netdev instance lock held, while reset_task also needs
+ * this lock. Release the lock while waiting to avoid deadlock.
+ *
* Returns 0 if reset finished successfully, negative on timeout or interrupt.
*/
int iavf_wait_for_reset(struct iavf_adapter *adapter)
{
- int ret = wait_event_interruptible_timeout(adapter->reset_waitqueue,
- !iavf_is_reset_in_progress(adapter),
- msecs_to_jiffies(5000));
+ struct net_device *netdev = adapter->netdev;
+ int ret;
+
+ netdev_unlock(netdev);
+ ret = wait_event_interruptible_timeout(adapter->reset_waitqueue,
+ !iavf_is_reset_in_progress(adapter),
+ msecs_to_jiffies(5000));
+ netdev_lock(netdev);
/* If ret < 0 then it means wait was interrupted.
* If ret == 0 then it means we got a timeout while waiting
--
2.52.0
^ permalink raw reply related [flat|nested] 17+ messages in thread* RE: [Intel-wired-lan] [PATCH net] iavf: fix deadlock in reset handling 2026-02-02 8:48 [PATCH net] iavf: fix deadlock in reset handling Petr Oros @ 2026-02-02 9:06 ` Loktionov, Aleksandr 2026-02-02 10:53 ` Jijie Shao ` (2 subsequent siblings) 3 siblings, 0 replies; 17+ messages in thread From: Loktionov, Aleksandr @ 2026-02-02 9:06 UTC (permalink / raw) To: Oros, Petr, netdev@vger.kernel.org Cc: Vecera, Ivan, Kitszel, Przemyslaw, Eric Dumazet, linux-kernel@vger.kernel.org, Andrew Lunn, Stanislav Fomichev, Nguyen, Anthony L, intel-wired-lan@lists.osuosl.org, Jakub Kicinski, Paolo Abeni, David S. Miller > -----Original Message----- > From: Intel-wired-lan <intel-wired-lan-bounces@osuosl.org> On Behalf > Of Petr Oros > Sent: Monday, February 2, 2026 9:48 AM > To: netdev@vger.kernel.org > Cc: Vecera, Ivan <ivecera@redhat.com>; Kitszel, Przemyslaw > <przemyslaw.kitszel@intel.com>; Eric Dumazet <edumazet@google.com>; > linux-kernel@vger.kernel.org; Andrew Lunn <andrew+netdev@lunn.ch>; > Stanislav Fomichev <sdf@fomichev.me>; Nguyen, Anthony L > <anthony.l.nguyen@intel.com>; intel-wired-lan@lists.osuosl.org; > Jakub Kicinski <kuba@kernel.org>; Paolo Abeni <pabeni@redhat.com>; > David S. Miller <davem@davemloft.net> > Subject: [Intel-wired-lan] [PATCH net] iavf: fix deadlock in reset > handling > > Three driver callbacks schedule a reset and wait for its completion: > ndo_change_mtu(), ethtool set_ringparam(), and ethtool > set_channels(). > > Waiting for reset in ndo_change_mtu() and set_ringparam() was added > by commit c2ed2403f12c74 ("iavf: Wait for reset in callbacks which > trigger > it") to fix a race condition where adding an interface to bonding > immediately after MTU or ring parameter change failed because the > interface was still in __RESETTING state. The same commit also added > waiting in iavf_set_priv_flags(), which was later removed by commit > 53844673d55529 ("iavf: kill "legacy-rx" for good"). > > Waiting in set_channels() was introduced earlier by commit > 4e5e6b5d9d13 > ("iavf: Fix return of set the new channel count") to ensure the PF > has enough time to complete the VF reset when changing channel > count, and to return correct error codes to userspace. > > Commit ef490bbb226702 ("iavf: Add net_shaper_ops support") added > net_shaper_ops to iavf, which required reset_task to use _locked > NAPI variants (napi_enable_locked, napi_disable_locked) that need > the netdev instance lock. > > Later, commit 7e4d784f5810 ("net: hold netdev instance lock during > rtnetlink operations") and commit 2bcf4772e45adb ("net: ethtool: try > to protect all callback with netdev instance lock") started holding > the netdev instance lock during ndo and ethtool callbacks for > drivers with net_shaper_ops. > > The combination of waiting for reset and the new locking > requirements creates a deadlock: the callback holds the lock and > waits for reset_task, but reset_task is blocked waiting for the same > lock: > > Thread 1 (callback) Thread 2 (reset_task) > ------------------- --------------------- > netdev_lock() > ndo_change_mtu() or ethtool op > iavf_schedule_reset() > iavf_wait_for_reset() iavf_reset_task() > waiting... netdev_lock() <- DEADLOCK > > Reproducer: > > # echo 16 > /sys/class/net/$PF/device/sriov_numvfs > # ip link set $VF up > # ip link set $VF mtu 5000 > RTNETLINK answers: Device or resource busy > > # dmesg | tail -1 > iavf: MTU change interrupted waiting for reset > > Fix this by temporarily releasing the lock while waiting for reset > to complete. This follows the pattern used elsewhere in the kernel > (e.g., > do_set_master() releases rtnl_lock before calling ndo_add_slave()). > > Fixes: 7e4d784f5810 ("net: hold netdev instance lock during > rtnetlink operations") > Signed-off-by: Petr Oros <poros@redhat.com> > --- > drivers/net/ethernet/intel/iavf/iavf_main.c | 15 ++++++++++++--- > 1 file changed, 12 insertions(+), 3 deletions(-) > > diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c > b/drivers/net/ethernet/intel/iavf/iavf_main.c > index 8aa6e92c16431f..d7738fb8fa60bc 100644 > --- a/drivers/net/ethernet/intel/iavf/iavf_main.c > +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c > @@ -189,13 +189,22 @@ static bool iavf_is_reset_in_progress(struct > iavf_adapter *adapter) > * iavf_wait_for_reset - Wait for reset to finish. > * @adapter: board private structure > * > + * The iavf driver selects NET_SHAPER, so callbacks that trigger > reset > + are > + * always called with netdev instance lock held, while reset_task > also > + needs > + * this lock. Release the lock while waiting to avoid deadlock. > + * > * Returns 0 if reset finished successfully, negative on timeout or > interrupt. > */ > int iavf_wait_for_reset(struct iavf_adapter *adapter) { > - int ret = wait_event_interruptible_timeout(adapter- > >reset_waitqueue, > - > !iavf_is_reset_in_progress(adapter), > - msecs_to_jiffies(5000)); > + struct net_device *netdev = adapter->netdev; > + int ret; > + > + netdev_unlock(netdev); > + ret = wait_event_interruptible_timeout(adapter- > >reset_waitqueue, > + > !iavf_is_reset_in_progress(adapter), > + msecs_to_jiffies(5000)); > + netdev_lock(netdev); > > /* If ret < 0 then it means wait was interrupted. > * If ret == 0 then it means we got a timeout while waiting > -- > 2.52.0 Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH net] iavf: fix deadlock in reset handling 2026-02-02 8:48 [PATCH net] iavf: fix deadlock in reset handling Petr Oros 2026-02-02 9:06 ` [Intel-wired-lan] " Loktionov, Aleksandr @ 2026-02-02 10:53 ` Jijie Shao 2026-02-02 13:30 ` Ivan Vecera 2026-02-02 23:58 ` Jakub Kicinski 3 siblings, 0 replies; 17+ messages in thread From: Jijie Shao @ 2026-02-02 10:53 UTC (permalink / raw) To: Petr Oros, netdev Cc: shaojijie, ivecera, mschmidt, Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Stanislav Fomichev, intel-wired-lan, linux-kernel on 2026/2/2 16:48, Petr Oros wrote: > Three driver callbacks schedule a reset and wait for its completion: > ndo_change_mtu(), ethtool set_ringparam(), and ethtool set_channels(). > > Waiting for reset in ndo_change_mtu() and set_ringparam() was added by > commit c2ed2403f12c74 ("iavf: Wait for reset in callbacks which trigger > it") to fix a race condition where adding an interface to bonding > immediately after MTU or ring parameter change failed because the > interface was still in __RESETTING state. The same commit also added > waiting in iavf_set_priv_flags(), which was later removed by commit > 53844673d55529 ("iavf: kill "legacy-rx" for good"). > > Waiting in set_channels() was introduced earlier by commit 4e5e6b5d9d13 > ("iavf: Fix return of set the new channel count") to ensure the PF has > enough time to complete the VF reset when changing channel count, and to > return correct error codes to userspace. > > Commit ef490bbb226702 ("iavf: Add net_shaper_ops support") added > net_shaper_ops to iavf, which required reset_task to use _locked NAPI > variants (napi_enable_locked, napi_disable_locked) that need the netdev > instance lock. > > Later, commit 7e4d784f5810 ("net: hold netdev instance lock during > rtnetlink operations") and commit 2bcf4772e45adb ("net: ethtool: try to > protect all callback with netdev instance lock") started holding the > netdev instance lock during ndo and ethtool callbacks for drivers with > net_shaper_ops. > > The combination of waiting for reset and the new locking requirements > creates a deadlock: the callback holds the lock and waits for reset_task, > but reset_task is blocked waiting for the same lock: > > Thread 1 (callback) Thread 2 (reset_task) > ------------------- --------------------- > netdev_lock() > ndo_change_mtu() or ethtool op > iavf_schedule_reset() > iavf_wait_for_reset() iavf_reset_task() > waiting... netdev_lock() <- DEADLOCK > > Reproducer: > > # echo 16 > /sys/class/net/$PF/device/sriov_numvfs > # ip link set $VF up > # ip link set $VF mtu 5000 > RTNETLINK answers: Device or resource busy > > # dmesg | tail -1 > iavf: MTU change interrupted waiting for reset > > Fix this by temporarily releasing the lock while waiting for reset to > complete. This follows the pattern used elsewhere in the kernel (e.g., > do_set_master() releases rtnl_lock before calling ndo_add_slave()). > > Fixes: 7e4d784f5810 ("net: hold netdev instance lock during rtnetlink operations") > Signed-off-by: Petr Oros <poros@redhat.com> Reviewed-by: Jijie Shao <shaojijie@huawei.com> > --- > drivers/net/ethernet/intel/iavf/iavf_main.c | 15 ++++++++++++--- > 1 file changed, 12 insertions(+), 3 deletions(-) > > diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c > index 8aa6e92c16431f..d7738fb8fa60bc 100644 > --- a/drivers/net/ethernet/intel/iavf/iavf_main.c > +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c > @@ -189,13 +189,22 @@ static bool iavf_is_reset_in_progress(struct iavf_adapter *adapter) > * iavf_wait_for_reset - Wait for reset to finish. > * @adapter: board private structure > * > + * The iavf driver selects NET_SHAPER, so callbacks that trigger reset are > + * always called with netdev instance lock held, while reset_task also needs > + * this lock. Release the lock while waiting to avoid deadlock. > + * > * Returns 0 if reset finished successfully, negative on timeout or interrupt. > */ > int iavf_wait_for_reset(struct iavf_adapter *adapter) > { > - int ret = wait_event_interruptible_timeout(adapter->reset_waitqueue, > - !iavf_is_reset_in_progress(adapter), > - msecs_to_jiffies(5000)); > + struct net_device *netdev = adapter->netdev; > + int ret; > + > + netdev_unlock(netdev); > + ret = wait_event_interruptible_timeout(adapter->reset_waitqueue, > + !iavf_is_reset_in_progress(adapter), > + msecs_to_jiffies(5000)); > + netdev_lock(netdev); > > /* If ret < 0 then it means wait was interrupted. > * If ret == 0 then it means we got a timeout while waiting ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH net] iavf: fix deadlock in reset handling 2026-02-02 8:48 [PATCH net] iavf: fix deadlock in reset handling Petr Oros 2026-02-02 9:06 ` [Intel-wired-lan] " Loktionov, Aleksandr 2026-02-02 10:53 ` Jijie Shao @ 2026-02-02 13:30 ` Ivan Vecera 2026-02-02 23:58 ` Jakub Kicinski 3 siblings, 0 replies; 17+ messages in thread From: Ivan Vecera @ 2026-02-02 13:30 UTC (permalink / raw) To: Petr Oros, netdev Cc: mschmidt, Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Stanislav Fomichev, intel-wired-lan, linux-kernel On 2/2/26 9:48 AM, Petr Oros wrote: > Three driver callbacks schedule a reset and wait for its completion: > ndo_change_mtu(), ethtool set_ringparam(), and ethtool set_channels(). > > Waiting for reset in ndo_change_mtu() and set_ringparam() was added by > commit c2ed2403f12c74 ("iavf: Wait for reset in callbacks which trigger > it") to fix a race condition where adding an interface to bonding > immediately after MTU or ring parameter change failed because the > interface was still in __RESETTING state. The same commit also added > waiting in iavf_set_priv_flags(), which was later removed by commit > 53844673d55529 ("iavf: kill "legacy-rx" for good"). > > Waiting in set_channels() was introduced earlier by commit 4e5e6b5d9d13 > ("iavf: Fix return of set the new channel count") to ensure the PF has > enough time to complete the VF reset when changing channel count, and to > return correct error codes to userspace. > > Commit ef490bbb226702 ("iavf: Add net_shaper_ops support") added > net_shaper_ops to iavf, which required reset_task to use _locked NAPI > variants (napi_enable_locked, napi_disable_locked) that need the netdev > instance lock. > > Later, commit 7e4d784f5810 ("net: hold netdev instance lock during > rtnetlink operations") and commit 2bcf4772e45adb ("net: ethtool: try to > protect all callback with netdev instance lock") started holding the > netdev instance lock during ndo and ethtool callbacks for drivers with > net_shaper_ops. > > The combination of waiting for reset and the new locking requirements > creates a deadlock: the callback holds the lock and waits for reset_task, > but reset_task is blocked waiting for the same lock: > > Thread 1 (callback) Thread 2 (reset_task) > ------------------- --------------------- > netdev_lock() > ndo_change_mtu() or ethtool op > iavf_schedule_reset() > iavf_wait_for_reset() iavf_reset_task() > waiting... netdev_lock() <- DEADLOCK > > Reproducer: > > # echo 16 > /sys/class/net/$PF/device/sriov_numvfs > # ip link set $VF up > # ip link set $VF mtu 5000 > RTNETLINK answers: Device or resource busy > > # dmesg | tail -1 > iavf: MTU change interrupted waiting for reset > > Fix this by temporarily releasing the lock while waiting for reset to > complete. This follows the pattern used elsewhere in the kernel (e.g., > do_set_master() releases rtnl_lock before calling ndo_add_slave()). > > Fixes: 7e4d784f5810 ("net: hold netdev instance lock during rtnetlink operations") > Signed-off-by: Petr Oros <poros@redhat.com> > --- > drivers/net/ethernet/intel/iavf/iavf_main.c | 15 ++++++++++++--- > 1 file changed, 12 insertions(+), 3 deletions(-) > > diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c > index 8aa6e92c16431f..d7738fb8fa60bc 100644 > --- a/drivers/net/ethernet/intel/iavf/iavf_main.c > +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c > @@ -189,13 +189,22 @@ static bool iavf_is_reset_in_progress(struct iavf_adapter *adapter) > * iavf_wait_for_reset - Wait for reset to finish. > * @adapter: board private structure > * > + * The iavf driver selects NET_SHAPER, so callbacks that trigger reset are > + * always called with netdev instance lock held, while reset_task also needs > + * this lock. Release the lock while waiting to avoid deadlock. > + * > * Returns 0 if reset finished successfully, negative on timeout or interrupt. > */ > int iavf_wait_for_reset(struct iavf_adapter *adapter) > { > - int ret = wait_event_interruptible_timeout(adapter->reset_waitqueue, > - !iavf_is_reset_in_progress(adapter), > - msecs_to_jiffies(5000)); > + struct net_device *netdev = adapter->netdev; > + int ret; > + > + netdev_unlock(netdev); > + ret = wait_event_interruptible_timeout(adapter->reset_waitqueue, > + !iavf_is_reset_in_progress(adapter), > + msecs_to_jiffies(5000)); > + netdev_lock(netdev); > > /* If ret < 0 then it means wait was interrupted. > * If ret == 0 then it means we got a timeout while waiting Reviewed-by: Ivan Vecera <ivecera@redhat.com> ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH net] iavf: fix deadlock in reset handling 2026-02-02 8:48 [PATCH net] iavf: fix deadlock in reset handling Petr Oros ` (2 preceding siblings ...) 2026-02-02 13:30 ` Ivan Vecera @ 2026-02-02 23:58 ` Jakub Kicinski 2026-02-03 1:00 ` [Intel-wired-lan] " Jacob Keller 3 siblings, 1 reply; 17+ messages in thread From: Jakub Kicinski @ 2026-02-02 23:58 UTC (permalink / raw) To: Petr Oros Cc: netdev, ivecera, mschmidt, Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet, Paolo Abeni, Stanislav Fomichev, intel-wired-lan, linux-kernel On Mon, 2 Feb 2026 09:48:20 +0100 Petr Oros wrote: > + netdev_unlock(netdev); > + ret = wait_event_interruptible_timeout(adapter->reset_waitqueue, > + !iavf_is_reset_in_progress(adapter), > + msecs_to_jiffies(5000)); > + netdev_lock(netdev); Dropping locks taken by the core around the driver callback is obviously unacceptable. SMH. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Intel-wired-lan] [PATCH net] iavf: fix deadlock in reset handling 2026-02-02 23:58 ` Jakub Kicinski @ 2026-02-03 1:00 ` Jacob Keller 2026-02-03 8:44 ` Petr Oros 0 siblings, 1 reply; 17+ messages in thread From: Jacob Keller @ 2026-02-03 1:00 UTC (permalink / raw) To: Jakub Kicinski, Petr Oros Cc: ivecera, netdev, linux-kernel, Andrew Lunn, Eric Dumazet, Stanislav Fomichev, Tony Nguyen, Przemek Kitszel, intel-wired-lan, Paolo Abeni, David S. Miller On 2/2/2026 3:58 PM, Jakub Kicinski wrote: > On Mon, 2 Feb 2026 09:48:20 +0100 Petr Oros wrote: >> + netdev_unlock(netdev); >> + ret = wait_event_interruptible_timeout(adapter->reset_waitqueue, >> + !iavf_is_reset_in_progress(adapter), >> + msecs_to_jiffies(5000)); >> + netdev_lock(netdev); > > Dropping locks taken by the core around the driver callback > is obviously unacceptable. SMH. Right. It seems like the correct fix is to either a) have reset take and hold the netdev lock (now that its distinct from the global RTNL lock) or b) refactor reset so that it can defer any of the netdev related stuff somehow. ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Intel-wired-lan] [PATCH net] iavf: fix deadlock in reset handling 2026-02-03 1:00 ` [Intel-wired-lan] " Jacob Keller @ 2026-02-03 8:44 ` Petr Oros 2026-02-03 10:19 ` Przemek Kitszel 0 siblings, 1 reply; 17+ messages in thread From: Petr Oros @ 2026-02-03 8:44 UTC (permalink / raw) To: Jacob Keller, Jakub Kicinski Cc: ivecera, netdev, linux-kernel, Andrew Lunn, Eric Dumazet, Stanislav Fomichev, Tony Nguyen, Przemek Kitszel, intel-wired-lan, Paolo Abeni, David S. Miller On 2/3/26 02:00, Jacob Keller wrote: > > > On 2/2/2026 3:58 PM, Jakub Kicinski wrote: >> On Mon, 2 Feb 2026 09:48:20 +0100 Petr Oros wrote: >>> + netdev_unlock(netdev); >>> + ret = wait_event_interruptible_timeout(adapter->reset_waitqueue, >>> + !iavf_is_reset_in_progress(adapter), >>> + msecs_to_jiffies(5000)); >>> + netdev_lock(netdev); >> >> Dropping locks taken by the core around the driver callback >> is obviously unacceptable. SMH. > > Right. It seems like the correct fix is to either a) have reset take > and hold the netdev lock (now that its distinct from the global RTNL > lock) or b) refactor reset so that it can defer any of the netdev > related stuff somehow. > I modeled this after the existing pattern in iavf_close() (ndo_stop), which also temporarily releases the netdev instance lock taken by the core to wait for an async operation to complete: static int iavf_close(struct net_device *netdev) { netdev_assert_locked(netdev); ... iavf_down(adapter); iavf_change_state(adapter, __IAVF_DOWN_PENDING); iavf_free_traffic_irqs(adapter); netdev_unlock(netdev); status = wait_event_timeout(adapter->down_waitqueue, adapter->state == __IAVF_DOWN, msecs_to_jiffies(500)); if (!status) netdev_warn(netdev, "Device resources not yet released\n"); netdev_lock(netdev); ... } This was introduced by commit 120f28a6f314fe ("iavf: get rid of the crit lock"), and ndo_stop is called with netdev instance lock held by the core just like ndo_change_mtu is. Could you clarify why the unlock-wait-lock pattern is acceptable in ndo_stop but not here? ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Intel-wired-lan] [PATCH net] iavf: fix deadlock in reset handling 2026-02-03 8:44 ` Petr Oros @ 2026-02-03 10:19 ` Przemek Kitszel 2026-02-03 11:32 ` Petr Oros 0 siblings, 1 reply; 17+ messages in thread From: Przemek Kitszel @ 2026-02-03 10:19 UTC (permalink / raw) To: Petr Oros, Jacob Keller, Jakub Kicinski Cc: ivecera, netdev, linux-kernel, Andrew Lunn, Eric Dumazet, Stanislav Fomichev, Tony Nguyen, intel-wired-lan, Paolo Abeni, David S. Miller On 2/3/26 09:44, Petr Oros wrote: > > On 2/3/26 02:00, Jacob Keller wrote: >> >> >> On 2/2/2026 3:58 PM, Jakub Kicinski wrote: >>> On Mon, 2 Feb 2026 09:48:20 +0100 Petr Oros wrote: >>>> + netdev_unlock(netdev); >>>> + ret = wait_event_interruptible_timeout(adapter->reset_waitqueue, >>>> + !iavf_is_reset_in_progress(adapter), >>>> + msecs_to_jiffies(5000)); >>>> + netdev_lock(netdev); >>> >>> Dropping locks taken by the core around the driver callback >>> is obviously unacceptable. SMH. >> >> Right. It seems like the correct fix is to either a) have reset take >> and hold the netdev lock (now that its distinct from the global RTNL >> lock) or b) refactor reset so that it can defer any of the netdev >> related stuff somehow. >> > I modeled this after the existing pattern in iavf_close() (ndo_stop), > which also temporarily releases the netdev instance lock taken by the > core to wait for an async operation to complete: First of all, thank you for working on that, I was hit by the very same problem (no series yet), but my local fix is the same as of now. I don't see an easy fix (w/o substantial driver refactor). > > static int iavf_close(struct net_device *netdev) > { > netdev_assert_locked(netdev); > ... > iavf_down(adapter); > iavf_change_state(adapter, __IAVF_DOWN_PENDING); > iavf_free_traffic_irqs(adapter); > > netdev_unlock(netdev); > > status = wait_event_timeout(adapter->down_waitqueue, > adapter->state == __IAVF_DOWN, > msecs_to_jiffies(500)); > if (!status) > netdev_warn(netdev, "Device resources not yet > released\n"); > netdev_lock(netdev); > ... > } > > This was introduced by commit 120f28a6f314fe ("iavf: get rid of the crit > lock"), and ndo_stop is called with netdev instance lock held by the > core just like ndo_change_mtu is. technically it was introduced by commmit afc664987ab3 ("eth: iavf: extend the netdev_lock usage") > Could you clarify why the unlock-wait- > lock pattern is acceptable in ndo_stop but not here? > perhaps just closing netdev is a special kind of operation Other thing is that the lock was added to allow further NAPI development, and one silly driver should not stop that effort. Sadly, we have not managed to re-design the driver yet. I would like to do so personally, but have much work accumulated/pending to free my time ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Intel-wired-lan] [PATCH net] iavf: fix deadlock in reset handling 2026-02-03 10:19 ` Przemek Kitszel @ 2026-02-03 11:32 ` Petr Oros 2026-02-03 23:47 ` Jacob Keller 0 siblings, 1 reply; 17+ messages in thread From: Petr Oros @ 2026-02-03 11:32 UTC (permalink / raw) To: Przemek Kitszel, Jacob Keller, Jakub Kicinski Cc: ivecera, netdev, linux-kernel, Andrew Lunn, Eric Dumazet, Stanislav Fomichev, Tony Nguyen, intel-wired-lan, Paolo Abeni, David S. Miller On 2/3/26 11:19, Przemek Kitszel wrote: > On 2/3/26 09:44, Petr Oros wrote: >> >> On 2/3/26 02:00, Jacob Keller wrote: >>> >>> >>> On 2/2/2026 3:58 PM, Jakub Kicinski wrote: >>>> On Mon, 2 Feb 2026 09:48:20 +0100 Petr Oros wrote: >>>>> + netdev_unlock(netdev); >>>>> + ret = wait_event_interruptible_timeout(adapter->reset_waitqueue, >>>>> + !iavf_is_reset_in_progress(adapter), >>>>> + msecs_to_jiffies(5000)); >>>>> + netdev_lock(netdev); >>>> >>>> Dropping locks taken by the core around the driver callback >>>> is obviously unacceptable. SMH. >>> >>> Right. It seems like the correct fix is to either a) have reset take >>> and hold the netdev lock (now that its distinct from the global RTNL >>> lock) or b) refactor reset so that it can defer any of the netdev >>> related stuff somehow. >>> >> I modeled this after the existing pattern in iavf_close() (ndo_stop), >> which also temporarily releases the netdev instance lock taken by the >> core to wait for an async operation to complete: > > First of all, thank you for working on that, I was hit by the very same > problem (no series yet), but my local fix is the same as of now. > > I don't see an easy fix (w/o substantial driver refactor). > >> >> static int iavf_close(struct net_device *netdev) >> { >> netdev_assert_locked(netdev); >> ... >> iavf_down(adapter); >> iavf_change_state(adapter, __IAVF_DOWN_PENDING); >> iavf_free_traffic_irqs(adapter); >> >> netdev_unlock(netdev); >> >> status = wait_event_timeout(adapter->down_waitqueue, >> adapter->state == __IAVF_DOWN, >> msecs_to_jiffies(500)); >> if (!status) >> netdev_warn(netdev, "Device resources not yet >> released\n"); >> netdev_lock(netdev); >> ... >> } >> >> This was introduced by commit 120f28a6f314fe ("iavf: get rid of the >> crit lock"), and ndo_stop is called with netdev instance lock held by >> the core just like ndo_change_mtu is. > > technically it was introduced by commmit afc664987ab3 ("eth: iavf: > extend the netdev_lock usage") > >> Could you clarify why the unlock-wait- lock pattern is acceptable in >> ndo_stop but not here? >> > > perhaps just closing netdev is a special kind of operation > > Other thing is that the lock was added to allow further NAPI > development, and one silly driver should not stop that effort. > Sadly, we have not managed to re-design the driver yet. I would like to > do so personally, but have much work accumulated/pending to free my time > I agree, the unlock-wait-lock pattern is fundamentally flawed (I now understand why it is unacceptable) and should be avoided. What can we do now? * Eliminating the wait is not an option: As noted in the description of commit c2ed2403f12c, this wait was originally added to fix a race condition where adding an interface to bonding failed because the device remained in __RESETTING state after the callback returned. * Passing the lock into reset is impractical: The reset path is triggered from numerous contexts, many of which are not under the netdev_lock, making this even more complex than a full refactor. If dropping the lock is a no-go, the only viable path forward is to split the reset_task so that the waiting portion is decoupled from the netdev_lock critical section. The fact remains that MTU configuration and ring parameter changes are currently broken in iavf. Changing the MTU on a Virtual Function is a fundamental configuration not an obscure edge case that can remain non-functional. I would appreciate any further guidance on how you would prefer... ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Intel-wired-lan] [PATCH net] iavf: fix deadlock in reset handling 2026-02-03 11:32 ` Petr Oros @ 2026-02-03 23:47 ` Jacob Keller 2026-02-04 6:12 ` Przemek Kitszel 0 siblings, 1 reply; 17+ messages in thread From: Jacob Keller @ 2026-02-03 23:47 UTC (permalink / raw) To: Petr Oros, Przemek Kitszel, Jakub Kicinski Cc: ivecera, netdev, linux-kernel, Andrew Lunn, Eric Dumazet, Stanislav Fomichev, Tony Nguyen, intel-wired-lan, Paolo Abeni, David S. Miller On 2/3/2026 3:32 AM, Petr Oros wrote: > > On 2/3/26 11:19, Przemek Kitszel wrote: >> On 2/3/26 09:44, Petr Oros wrote: >>> >>> On 2/3/26 02:00, Jacob Keller wrote: >>>> >>>> >>>> On 2/2/2026 3:58 PM, Jakub Kicinski wrote: >>>>> On Mon, 2 Feb 2026 09:48:20 +0100 Petr Oros wrote: >>>>>> + netdev_unlock(netdev); >>>>>> + ret = wait_event_interruptible_timeout(adapter->reset_waitqueue, >>>>>> + !iavf_is_reset_in_progress(adapter), >>>>>> + msecs_to_jiffies(5000)); >>>>>> + netdev_lock(netdev); >>>>> >>>>> Dropping locks taken by the core around the driver callback >>>>> is obviously unacceptable. SMH. >>>> >>>> Right. It seems like the correct fix is to either a) have reset take >>>> and hold the netdev lock (now that its distinct from the global RTNL >>>> lock) or b) refactor reset so that it can defer any of the netdev >>>> related stuff somehow. >>>> >>> I modeled this after the existing pattern in iavf_close() (ndo_stop), >>> which also temporarily releases the netdev instance lock taken by the >>> core to wait for an async operation to complete: >> >> First of all, thank you for working on that, I was hit by the very same >> problem (no series yet), but my local fix is the same as of now. >> >> I don't see an easy fix (w/o substantial driver refactor). >> >>> >>> static int iavf_close(struct net_device *netdev) >>> { >>> netdev_assert_locked(netdev); >>> ... >>> iavf_down(adapter); >>> iavf_change_state(adapter, __IAVF_DOWN_PENDING); >>> iavf_free_traffic_irqs(adapter); >>> >>> netdev_unlock(netdev); >>> >>> status = wait_event_timeout(adapter->down_waitqueue, >>> adapter->state == __IAVF_DOWN, >>> msecs_to_jiffies(500)); >>> if (!status) >>> netdev_warn(netdev, "Device resources not yet >>> released\n"); >>> netdev_lock(netdev); >>> ... >>> } >>> >>> This was introduced by commit 120f28a6f314fe ("iavf: get rid of the >>> crit lock"), and ndo_stop is called with netdev instance lock held by >>> the core just like ndo_change_mtu is. >> >> technically it was introduced by commmit afc664987ab3 ("eth: iavf: >> extend the netdev_lock usage") >> >>> Could you clarify why the unlock-wait- lock pattern is acceptable in >>> ndo_stop but not here? >>> It may simply be that no one spotted it in ndo_stop. >> >> perhaps just closing netdev is a special kind of operation >> >> Other thing is that the lock was added to allow further NAPI >> development, and one silly driver should not stop that effort. >> Sadly, we have not managed to re-design the driver yet. I would like to >> do so personally, but have much work accumulated/pending to free my time >> > I agree, the unlock-wait-lock pattern is fundamentally flawed (I now > understand > why it is unacceptable) and should be avoided. > > What can we do now? > > * Eliminating the wait is not an option: As noted in the description of > commit > c2ed2403f12c, this wait was originally added to fix a race condition where > adding an interface to bonding failed because the device remained in > __RESETTING state after the callback returned. > * Passing the lock into reset is impractical: The reset path is > triggered from > numerous contexts, many of which are not under the netdev_lock, making this > even more complex than a full refactor. Hm. I was thinking we could just hold the netdev lock for the reset, but... we already take the netdev lock there as of commit ef490bbb2267 ("iavf: Add net_shaper_ops support"). That's actually what causes the deadlock: prior to that change reset didn't hold the netdev lock for the duration. This is what gets us stuck. We are waiting for reset to finish while holding the lock that blocks the reset. But I am not really sure how to fix this: We want change MTU to only return once reset is complete.. but reset is dependent on the very lock that we're holding. And there's no way to communicate this fact to the reset handler... > > If dropping the lock is a no-go, the only viable path forward is to > split the > reset_task so that the waiting portion is decoupled from the netdev_lock > critical section. > We used to do this back before the netdev shaper ops. We didn't acquire either netdev lock or RTNL during reset. I thought we had some code in the past that would handle netdev stuff outside of reset.. but I don't really know and git blame is not making it easy to find this information. Perhaps we don't actually need to hold the netdev lock over the reset task.. except Przemek's refactor to remove the critical lock now makes us fully dependent on the netdev lock in this case for reset :( > The fact remains that MTU configuration and ring parameter changes are > currently broken in iavf. Changing the MTU on a Virtual Function is a > fundamental configuration not an obscure edge case that can remain non- > functional. > Agreed. This needs a resolution. It is just very tricky to figure out what the solution should be. We need to hold the netdev lock during reset, and we need to have our handlers wait for reset to complete in order to be certain their task is done... but reset is a separate thread so we can't really communicate to it that we're holding the lock, and attempts to do that would be a huge problem. We don't want to go back to the critical lock and all of its horrible problems either. The commit that removed it is here: 120f28a6f314 ("iavf: get rid of the crit lock") > I would appreciate any further guidance on how you would prefer... > I wish I had some better ideas.. Bad ideas I've thought about so far: 1) this patch with its drop lock and wait, which we discussed as problematic before. It creates a lot of issues since it means the operations are no longer atomic and we could potentially get stuck with some other operation in the event of another thread starting some core netdev task. No good. 2) not holding netdev_lock in reset, which is now a nogo since we removed the crit_lock, and apparently we held netdev_lock prior to that too anyways... 3) we could maybe do some sort of ref counting dance where we take some reference in threads that queue a reset, and the reset task would know if that reference was non-zero then another driver thread is holding netdev_lock so its safe to go into reset without locking... but this feels extremely ugly and error prone to me... 4) convert reset handling to a separate function that depends on the netdev_lock, and call that directly from within the threads that currently "wait for reset" while holding the netdev lock. Thus, we basically move this entire call chain into the thread already holding the lock, and call it from the context of the function like the MTU change, etc. This feels like its also a huge issue, and could potentially lead to some sort of issue where we need to still block the reset thread from going if we reset at the end of the netdev_lock thread.. I don't really like any of these solutions, even if (3) and (4) aren't fully ruled out as completely broken... they probably have all kinds of issues... ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Intel-wired-lan] [PATCH net] iavf: fix deadlock in reset handling 2026-02-03 23:47 ` Jacob Keller @ 2026-02-04 6:12 ` Przemek Kitszel 2026-02-04 19:25 ` Jacob Keller 0 siblings, 1 reply; 17+ messages in thread From: Przemek Kitszel @ 2026-02-04 6:12 UTC (permalink / raw) To: Jacob Keller, Petr Oros, Jakub Kicinski Cc: ivecera, netdev, linux-kernel, Andrew Lunn, Eric Dumazet, Stanislav Fomichev, Tony Nguyen, intel-wired-lan, Paolo Abeni, David S. Miller [...] >> If dropping the lock is a no-go, the only viable path forward is to >> split the >> reset_task so that the waiting portion is decoupled from the netdev_lock >> critical section. >> > We used to do this back before the netdev shaper ops. We didn't acquire > either netdev lock or RTNL during reset. > > I thought we had some code in the past that would handle netdev stuff > outside of reset.. but I don't really know and git blame is not making > it easy to find this information. IIRC it was iavf_config_task that is used to complete stuff requested under RTNL but later > > Perhaps we don't actually need to hold the netdev lock over the reset > task.. except Przemek's refactor to remove the critical lock now makes > us fully dependent on the netdev lock in this case for reset :( > >> The fact remains that MTU configuration and ring parameter changes are >> currently broken in iavf. Changing the MTU on a Virtual Function is a >> fundamental configuration not an obscure edge case that can remain >> non- functional. >> > > Agreed. This needs a resolution. It is just very tricky to figure out > what the solution should be. > > We need to hold the netdev lock during reset, and we need to have our > handlers wait for reset to complete in order to be certain their task is > done... but reset is a separate thread so we can't really communicate to > it that we're holding the lock, and attempts to do that would be a huge > problem. > > We don't want to go back to the critical lock and all of its horrible > problems either. The commit that removed it is here: 120f28a6f314 > ("iavf: get rid of the crit lock") > >> I would appreciate any further guidance on how you would prefer... >> > > I wish I had some better ideas.. > > Bad ideas I've thought about so far: > > 1) this patch with its drop lock and wait, which we discussed as > problematic before. It creates a lot of issues since it means the > operations are no longer atomic and we could potentially get stuck with > some other operation in the event of another thread starting some core > netdev task. No good. > > 2) not holding netdev_lock in reset, which is now a nogo since we > removed the crit_lock, and apparently we held netdev_lock prior to that > too anyways... > > 3) we could maybe do some sort of ref counting dance where we take some > reference in threads that queue a reset, and the reset task would know > if that reference was non-zero then another driver thread is holding > netdev_lock so its safe to go into reset without locking... but this > feels extremely ugly and error prone to me... > > 4) convert reset handling to a separate function that depends on the > netdev_lock, and call that directly from within the threads that > currently "wait for reset" while holding the netdev lock. Thus, we > basically move this entire call chain into the thread already holding > the lock, and call it from the context of the function like the MTU > change, etc. reset_thread() { while (!stopped) { netdev_lock(); reset_step(); netdev_unlock(); } } looks cool, IIRC I did something similar with the "after crit lock removal refactor continuation", but I've put it on hold https://github.com/pkitszel/linux/commits/undeadlock/ The linked code went even further and merged all of our admin-worker threads into one and the whole was protected by the netdev_lock :) This feels like its also a huge issue, and could > potentially lead to some sort of issue where we need to still block the > reset thread from going if we reset at the end of the netdev_lock thread.. that should queue on the "do later stuff queue", which we don't have right now (and keep some of such stuff in the state machine), but would be useful for many other actions too (like virtchnl messages, for which we have queue-of-1 right now > > I don't really like any of these solutions, even if (3) and (4) aren't > fully ruled out as completely broken... they probably have all kinds of > issues... ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Intel-wired-lan] [PATCH net] iavf: fix deadlock in reset handling 2026-02-04 6:12 ` Przemek Kitszel @ 2026-02-04 19:25 ` Jacob Keller 2026-02-05 12:24 ` Petr Oros 0 siblings, 1 reply; 17+ messages in thread From: Jacob Keller @ 2026-02-04 19:25 UTC (permalink / raw) To: Przemek Kitszel, Petr Oros, Jakub Kicinski Cc: ivecera, netdev, linux-kernel, Andrew Lunn, Eric Dumazet, Stanislav Fomichev, Tony Nguyen, intel-wired-lan, Paolo Abeni, David S. Miller On 2/3/2026 10:12 PM, Przemek Kitszel wrote: > > [...] > >>> If dropping the lock is a no-go, the only viable path forward is to >>> split the >>> reset_task so that the waiting portion is decoupled from the netdev_lock >>> critical section. >>> >> We used to do this back before the netdev shaper ops. We didn't >> acquire either netdev lock or RTNL during reset. >> >> I thought we had some code in the past that would handle netdev stuff >> outside of reset.. but I don't really know and git blame is not making >> it easy to find this information. > > IIRC it was iavf_config_task that is used to complete stuff requested > under RTNL but later > >> >> Perhaps we don't actually need to hold the netdev lock over the reset >> task.. except Przemek's refactor to remove the critical lock now makes >> us fully dependent on the netdev lock in this case for reset :( >> >>> The fact remains that MTU configuration and ring parameter changes are >>> currently broken in iavf. Changing the MTU on a Virtual Function is a >>> fundamental configuration not an obscure edge case that can remain >>> non- functional. >>> >> >> Agreed. This needs a resolution. It is just very tricky to figure out >> what the solution should be. >> >> We need to hold the netdev lock during reset, and we need to have our >> handlers wait for reset to complete in order to be certain their task >> is done... but reset is a separate thread so we can't really >> communicate to it that we're holding the lock, and attempts to do that >> would be a huge problem. >> >> We don't want to go back to the critical lock and all of its horrible >> problems either. The commit that removed it is here: 120f28a6f314 >> ("iavf: get rid of the crit lock") >> >>> I would appreciate any further guidance on how you would prefer... >>> >> >> I wish I had some better ideas.. >> >> Bad ideas I've thought about so far: >> >> 1) this patch with its drop lock and wait, which we discussed as >> problematic before. It creates a lot of issues since it means the >> operations are no longer atomic and we could potentially get stuck >> with some other operation in the event of another thread starting some >> core netdev task. No good. >> >> 2) not holding netdev_lock in reset, which is now a nogo since we >> removed the crit_lock, and apparently we held netdev_lock prior to >> that too anyways... >> >> 3) we could maybe do some sort of ref counting dance where we take >> some reference in threads that queue a reset, and the reset task would >> know if that reference was non-zero then another driver thread is >> holding netdev_lock so its safe to go into reset without locking... >> but this feels extremely ugly and error prone to me... >> >> 4) convert reset handling to a separate function that depends on the >> netdev_lock, and call that directly from within the threads that >> currently "wait for reset" while holding the netdev lock. Thus, we >> basically move this entire call chain into the thread already holding >> the lock, and call it from the context of the function like the MTU >> change, etc. > > reset_thread() { > while (!stopped) { > netdev_lock(); > reset_step(); > netdev_unlock(); > } > } > > looks cool, IIRC I did something similar with the "after crit lock > removal refactor continuation", but I've put it on hold > https://github.com/pkitszel/linux/commits/undeadlock/ > The linked code went even further and merged all of our admin-worker > threads into one and the whole was protected by the netdev_lock :) > That is a lot of patches and doesn't feel like a minimal fix. > This feels like its also a huge issue, and could >> potentially lead to some sort of issue where we need to still block >> the reset thread from going if we reset at the end of the netdev_lock >> thread.. > > that should queue on the "do later stuff queue", which we don't have > right now (and keep some of such stuff in the state machine), but would > be useful for many other actions too (like virtchnl messages, for which > we have queue-of-1 right now > I think we need to lay out what we need and maybe that will help figure out a solution. 1) several NDO operations need to perform tasks that require AVF hardware to reset, and which need to be certain that happens before they return. 2) reset is handled by a separate workqueue task 3) reset also requires the netdev lock We can't make the ndo operations avoid the netdev lock We pretty much can't make reset not require the netdev lock, especially since we are now using it as effectively the main driver lock now. I am not certain we can move all of the reset code to work from the ndo thread context, as we still also have to wait for hardware notification that reset happened, which seems like a pretty massive refactor to get right. We can't drop the waiting in the ndo operation because we need to be sure that the operation applied properly, otherwise we get errors elsewhere. So that leaves me without any solution so far, certainly not one that can be completed quickly... which means we're stuck with a guaranteed deadlock anytime the MTU is changed? >> >> I don't really like any of these solutions, even if (3) and (4) aren't >> fully ruled out as completely broken... they probably have all kinds >> of issues... ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Intel-wired-lan] [PATCH net] iavf: fix deadlock in reset handling 2026-02-04 19:25 ` Jacob Keller @ 2026-02-05 12:24 ` Petr Oros 2026-02-05 23:37 ` Jacob Keller 0 siblings, 1 reply; 17+ messages in thread From: Petr Oros @ 2026-02-05 12:24 UTC (permalink / raw) To: Jacob Keller, Przemek Kitszel, Jakub Kicinski Cc: ivecera, netdev, linux-kernel, Andrew Lunn, Eric Dumazet, Stanislav Fomichev, Tony Nguyen, intel-wired-lan, Paolo Abeni, David S. Miller On 2/4/26 20:25, Jacob Keller wrote: > > > On 2/3/2026 10:12 PM, Przemek Kitszel wrote: >> >> [...] >> >>>> If dropping the lock is a no-go, the only viable path forward is to >>>> split the >>>> reset_task so that the waiting portion is decoupled from the >>>> netdev_lock >>>> critical section. >>>> >>> We used to do this back before the netdev shaper ops. We didn't >>> acquire either netdev lock or RTNL during reset. >>> >>> I thought we had some code in the past that would handle netdev >>> stuff outside of reset.. but I don't really know and git blame is >>> not making it easy to find this information. >> >> IIRC it was iavf_config_task that is used to complete stuff requested >> under RTNL but later >> >>> >>> Perhaps we don't actually need to hold the netdev lock over the >>> reset task.. except Przemek's refactor to remove the critical lock >>> now makes us fully dependent on the netdev lock in this case for >>> reset :( >>> >>>> The fact remains that MTU configuration and ring parameter changes are >>>> currently broken in iavf. Changing the MTU on a Virtual Function is a >>>> fundamental configuration not an obscure edge case that can remain >>>> non- functional. >>>> >>> >>> Agreed. This needs a resolution. It is just very tricky to figure >>> out what the solution should be. >>> >>> We need to hold the netdev lock during reset, and we need to have >>> our handlers wait for reset to complete in order to be certain their >>> task is done... but reset is a separate thread so we can't really >>> communicate to it that we're holding the lock, and attempts to do >>> that would be a huge problem. >>> >>> We don't want to go back to the critical lock and all of its >>> horrible problems either. The commit that removed it is here: >>> 120f28a6f314 ("iavf: get rid of the crit lock") >>> >>>> I would appreciate any further guidance on how you would prefer... >>>> >>> >>> I wish I had some better ideas.. >>> >>> Bad ideas I've thought about so far: >>> >>> 1) this patch with its drop lock and wait, which we discussed as >>> problematic before. It creates a lot of issues since it means the >>> operations are no longer atomic and we could potentially get stuck >>> with some other operation in the event of another thread starting >>> some core netdev task. No good. >>> >>> 2) not holding netdev_lock in reset, which is now a nogo since we >>> removed the crit_lock, and apparently we held netdev_lock prior to >>> that too anyways... >>> >>> 3) we could maybe do some sort of ref counting dance where we take >>> some reference in threads that queue a reset, and the reset task >>> would know if that reference was non-zero then another driver thread >>> is holding netdev_lock so its safe to go into reset without >>> locking... but this feels extremely ugly and error prone to me... >>> >>> 4) convert reset handling to a separate function that depends on the >>> netdev_lock, and call that directly from within the threads that >>> currently "wait for reset" while holding the netdev lock. Thus, we >>> basically move this entire call chain into the thread already >>> holding the lock, and call it from the context of the function like >>> the MTU change, etc. >> >> reset_thread() { >> while (!stopped) { >> netdev_lock(); >> reset_step(); >> netdev_unlock(); >> } >> } >> >> looks cool, IIRC I did something similar with the "after crit lock >> removal refactor continuation", but I've put it on hold >> https://github.com/pkitszel/linux/commits/undeadlock/ >> The linked code went even further and merged all of our admin-worker >> threads into one and the whole was protected by the netdev_lock :) >> > > That is a lot of patches and doesn't feel like a minimal fix. > >> This feels like its also a huge issue, and could >>> potentially lead to some sort of issue where we need to still block >>> the reset thread from going if we reset at the end of the >>> netdev_lock thread.. >> >> that should queue on the "do later stuff queue", which we don't have >> right now (and keep some of such stuff in the state machine), but would >> be useful for many other actions too (like virtchnl messages, for which >> we have queue-of-1 right now >> > > I think we need to lay out what we need and maybe that will help > figure out a solution. > > > 1) several NDO operations need to perform tasks that require AVF > hardware to reset, and which need to be certain that happens before > they return. > > 2) reset is handled by a separate workqueue task > > 3) reset also requires the netdev lock > > > We can't make the ndo operations avoid the netdev lock > > We pretty much can't make reset not require the netdev lock, > especially since we are now using it as effectively the main driver > lock now. > > I am not certain we can move all of the reset code to work from the > ndo thread context, as we still also have to wait for hardware > notification that reset happened, which seems like a pretty massive > refactor to get right. > > We can't drop the waiting in the ndo operation because we need to be > sure that the operation applied properly, otherwise we get errors > elsewhere. > > So that leaves me without any solution so far, certainly not one that > can be completed quickly... which means we're stuck with a guaranteed > deadlock anytime the MTU is changed? I’ve been looking at the code on GitHub, and in my opinion, the fastest and most straightforward solution is to use a slightly modified approach based on patch 8c90ca2 ("iavf: split out body of reset task"). Since that patch refactors iavf_reset_task into iavf_reset_step and removes all netdev_lock acquisitions from its internal logic, we can resolve the deadlock by calling it directly. In places where we currently wait (MTU, channels, ringparam), we should replace the asynchronous scheduling and waiting with a synchronous call. This avoids the deadlock by executing the reset in the thread that already holds the netdev_lock: if (netif_running(netdev)) { - iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); - ret = iavf_wait_for_reset(adapter); - if (ret < 0) - netdev_warn(netdev, "MTU change interrupted waiting for reset"); - else if (ret) - netdev_warn(netdev, "MTU change timed out waiting for reset"); + adapter->flags |= IAVF_FLAG_RESET_NEEDED; + iavf_reset_step(adapter); } What do you think about this? > >>> >>> I don't really like any of these solutions, even if (3) and (4) >>> aren't fully ruled out as completely broken... they probably have >>> all kinds of issues... > ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [Intel-wired-lan] [PATCH net] iavf: fix deadlock in reset handling 2026-02-05 12:24 ` Petr Oros @ 2026-02-05 23:37 ` Jacob Keller 2026-02-06 10:04 ` Petr Oros 0 siblings, 1 reply; 17+ messages in thread From: Jacob Keller @ 2026-02-05 23:37 UTC (permalink / raw) To: Petr Oros, Przemek Kitszel, Jakub Kicinski Cc: ivecera, netdev, linux-kernel, Andrew Lunn, Eric Dumazet, Stanislav Fomichev, Tony Nguyen, intel-wired-lan, Paolo Abeni, David S. Miller On 2/5/2026 4:24 AM, Petr Oros wrote: > > On 2/4/26 20:25, Jacob Keller wrote: >> >> >> On 2/3/2026 10:12 PM, Przemek Kitszel wrote: >>> >>> [...] >>> >>>>> If dropping the lock is a no-go, the only viable path forward is to >>>>> split the >>>>> reset_task so that the waiting portion is decoupled from the >>>>> netdev_lock >>>>> critical section. >>>>> >>>> We used to do this back before the netdev shaper ops. We didn't >>>> acquire either netdev lock or RTNL during reset. >>>> >>>> I thought we had some code in the past that would handle netdev >>>> stuff outside of reset.. but I don't really know and git blame is >>>> not making it easy to find this information. >>> >>> IIRC it was iavf_config_task that is used to complete stuff requested >>> under RTNL but later >>> >>>> >>>> Perhaps we don't actually need to hold the netdev lock over the >>>> reset task.. except Przemek's refactor to remove the critical lock >>>> now makes us fully dependent on the netdev lock in this case for >>>> reset :( >>>> >>>>> The fact remains that MTU configuration and ring parameter changes are >>>>> currently broken in iavf. Changing the MTU on a Virtual Function is a >>>>> fundamental configuration not an obscure edge case that can remain >>>>> non- functional. >>>>> >>>> >>>> Agreed. This needs a resolution. It is just very tricky to figure >>>> out what the solution should be. >>>> >>>> We need to hold the netdev lock during reset, and we need to have >>>> our handlers wait for reset to complete in order to be certain their >>>> task is done... but reset is a separate thread so we can't really >>>> communicate to it that we're holding the lock, and attempts to do >>>> that would be a huge problem. >>>> >>>> We don't want to go back to the critical lock and all of its >>>> horrible problems either. The commit that removed it is here: >>>> 120f28a6f314 ("iavf: get rid of the crit lock") >>>> >>>>> I would appreciate any further guidance on how you would prefer... >>>>> >>>> >>>> I wish I had some better ideas.. >>>> >>>> Bad ideas I've thought about so far: >>>> >>>> 1) this patch with its drop lock and wait, which we discussed as >>>> problematic before. It creates a lot of issues since it means the >>>> operations are no longer atomic and we could potentially get stuck >>>> with some other operation in the event of another thread starting >>>> some core netdev task. No good. >>>> >>>> 2) not holding netdev_lock in reset, which is now a nogo since we >>>> removed the crit_lock, and apparently we held netdev_lock prior to >>>> that too anyways... >>>> >>>> 3) we could maybe do some sort of ref counting dance where we take >>>> some reference in threads that queue a reset, and the reset task >>>> would know if that reference was non-zero then another driver thread >>>> is holding netdev_lock so its safe to go into reset without >>>> locking... but this feels extremely ugly and error prone to me... >>>> >>>> 4) convert reset handling to a separate function that depends on the >>>> netdev_lock, and call that directly from within the threads that >>>> currently "wait for reset" while holding the netdev lock. Thus, we >>>> basically move this entire call chain into the thread already >>>> holding the lock, and call it from the context of the function like >>>> the MTU change, etc. >>> >>> reset_thread() { >>> while (!stopped) { >>> netdev_lock(); >>> reset_step(); >>> netdev_unlock(); >>> } >>> } >>> >>> looks cool, IIRC I did something similar with the "after crit lock >>> removal refactor continuation", but I've put it on hold >>> https://github.com/pkitszel/linux/commits/undeadlock/ >>> The linked code went even further and merged all of our admin-worker >>> threads into one and the whole was protected by the netdev_lock :) >>> >> >> That is a lot of patches and doesn't feel like a minimal fix. >> >>> This feels like its also a huge issue, and could >>>> potentially lead to some sort of issue where we need to still block >>>> the reset thread from going if we reset at the end of the >>>> netdev_lock thread.. >>> >>> that should queue on the "do later stuff queue", which we don't have >>> right now (and keep some of such stuff in the state machine), but would >>> be useful for many other actions too (like virtchnl messages, for which >>> we have queue-of-1 right now >>> >> >> I think we need to lay out what we need and maybe that will help >> figure out a solution. >> >> >> 1) several NDO operations need to perform tasks that require AVF >> hardware to reset, and which need to be certain that happens before >> they return. >> >> 2) reset is handled by a separate workqueue task >> >> 3) reset also requires the netdev lock >> >> >> We can't make the ndo operations avoid the netdev lock >> >> We pretty much can't make reset not require the netdev lock, >> especially since we are now using it as effectively the main driver >> lock now. >> >> I am not certain we can move all of the reset code to work from the >> ndo thread context, as we still also have to wait for hardware >> notification that reset happened, which seems like a pretty massive >> refactor to get right. >> >> We can't drop the waiting in the ndo operation because we need to be >> sure that the operation applied properly, otherwise we get errors >> elsewhere. >> >> So that leaves me without any solution so far, certainly not one that >> can be completed quickly... which means we're stuck with a guaranteed >> deadlock anytime the MTU is changed? > > I’ve been looking at the code on GitHub, and in my opinion, the fastest > and most straightforward solution is to use a slightly modified approach > based on patch 8c90ca2 ("iavf: split out body of reset task"). > > Since that patch refactors iavf_reset_task into iavf_reset_step and > removes all netdev_lock acquisitions from its internal logic, we can > resolve the deadlock by calling it directly. > > In places where we currently wait (MTU, channels, ringparam), we should > replace the asynchronous scheduling and waiting with a synchronous call. > This avoids the deadlock by executing the reset in the thread that > already holds the netdev_lock: > > if (netif_running(netdev)) { > - iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); > - ret = iavf_wait_for_reset(adapter); > - if (ret < 0) > - netdev_warn(netdev, "MTU change interrupted > waiting for reset"); > - else if (ret) > - netdev_warn(netdev, "MTU change timed out > waiting for reset"); > + adapter->flags |= IAVF_FLAG_RESET_NEEDED; > + iavf_reset_step(adapter); > } > What do you think about this? > I think this works. The netdev lock itself will provide synchronization between threads that need to reset, (since we take the netdev lock around reset and we hold it here). This is more or less one of my ideas earlier, but I didn't look closely enough to see how easy it is to implement. We will need to do some double checking to make sure that nothing else checks the reset flags without holding the netdev lock, but I think since Przemek's cleanups that is true. Good idea! Hopefully its not too much work to pull out just that part of the refactor and get it cleaned up. I'm currently working on setting my system up to reproduce the deadlock. ^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH net] iavf: fix deadlock in reset handling 2026-02-05 23:37 ` Jacob Keller @ 2026-02-06 10:04 ` Petr Oros 2026-02-07 1:00 ` Jacob Keller 2026-02-07 3:01 ` Jakub Kicinski 0 siblings, 2 replies; 17+ messages in thread From: Petr Oros @ 2026-02-06 10:04 UTC (permalink / raw) To: jacob.e.keller Cc: Petr Oros, Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Stanislav Fomichev, intel-wired-lan, netdev, linux-kernel description... Fixes: 120f28a6f314 ("iavf: get rid of the crit lock") Signed-off-by: Petr Oros <poros@redhat.com> --- drivers/net/ethernet/intel/iavf/iavf.h | 2 +- .../net/ethernet/intel/iavf/iavf_ethtool.c | 21 +++--- drivers/net/ethernet/intel/iavf/iavf_main.c | 72 +++++++------------ 3 files changed, 33 insertions(+), 62 deletions(-) diff --git a/drivers/net/ethernet/intel/iavf/iavf.h b/drivers/net/ethernet/intel/iavf/iavf.h index d552f912e8a947..0c3844b3ff1c86 100644 --- a/drivers/net/ethernet/intel/iavf/iavf.h +++ b/drivers/net/ethernet/intel/iavf/iavf.h @@ -625,5 +625,5 @@ void iavf_add_adv_rss_cfg(struct iavf_adapter *adapter); void iavf_del_adv_rss_cfg(struct iavf_adapter *adapter); struct iavf_mac_filter *iavf_add_filter(struct iavf_adapter *adapter, const u8 *macaddr); -int iavf_wait_for_reset(struct iavf_adapter *adapter); +void iavf_reset_step(struct iavf_adapter *adapter); #endif /* _IAVF_H_ */ diff --git a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c index 2cc21289a70779..9b0f47f9340942 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_ethtool.c +++ b/drivers/net/ethernet/intel/iavf/iavf_ethtool.c @@ -492,7 +492,6 @@ static int iavf_set_ringparam(struct net_device *netdev, { struct iavf_adapter *adapter = netdev_priv(netdev); u32 new_rx_count, new_tx_count; - int ret = 0; if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) return -EINVAL; @@ -537,13 +536,11 @@ static int iavf_set_ringparam(struct net_device *netdev, } if (netif_running(netdev)) { - iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); - ret = iavf_wait_for_reset(adapter); - if (ret) - netdev_warn(netdev, "Changing ring parameters timeout or interrupted waiting for reset"); + adapter->flags |= IAVF_FLAG_RESET_NEEDED; + iavf_reset_step(adapter); } - return ret; + return 0; } /** @@ -1723,7 +1720,6 @@ static int iavf_set_channels(struct net_device *netdev, { struct iavf_adapter *adapter = netdev_priv(netdev); u32 num_req = ch->combined_count; - int ret = 0; if ((adapter->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADQ) && adapter->num_tc) { @@ -1745,13 +1741,12 @@ static int iavf_set_channels(struct net_device *netdev, adapter->num_req_queues = num_req; adapter->flags |= IAVF_FLAG_REINIT_ITR_NEEDED; - iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); - - ret = iavf_wait_for_reset(adapter); - if (ret) - netdev_warn(netdev, "Changing channel count timeout or interrupted waiting for reset"); + if (netif_running(netdev)) { + adapter->flags |= IAVF_FLAG_RESET_NEEDED; + iavf_reset_step(adapter); + } - return ret; + return 0; } /** diff --git a/drivers/net/ethernet/intel/iavf/iavf_main.c b/drivers/net/ethernet/intel/iavf/iavf_main.c index 8aa6e92c16431f..9c8d6125106f5a 100644 --- a/drivers/net/ethernet/intel/iavf/iavf_main.c +++ b/drivers/net/ethernet/intel/iavf/iavf_main.c @@ -185,31 +185,6 @@ static bool iavf_is_reset_in_progress(struct iavf_adapter *adapter) return false; } -/** - * iavf_wait_for_reset - Wait for reset to finish. - * @adapter: board private structure - * - * Returns 0 if reset finished successfully, negative on timeout or interrupt. - */ -int iavf_wait_for_reset(struct iavf_adapter *adapter) -{ - int ret = wait_event_interruptible_timeout(adapter->reset_waitqueue, - !iavf_is_reset_in_progress(adapter), - msecs_to_jiffies(5000)); - - /* If ret < 0 then it means wait was interrupted. - * If ret == 0 then it means we got a timeout while waiting - * for reset to finish. - * If ret > 0 it means reset has finished. - */ - if (ret > 0) - return 0; - else if (ret < 0) - return -EINTR; - else - return -EBUSY; -} - /** * iavf_allocate_dma_mem_d - OS specific memory alloc for shared code * @hw: pointer to the HW structure @@ -3100,18 +3075,16 @@ static void iavf_reconfig_qs_bw(struct iavf_adapter *adapter) } /** - * iavf_reset_task - Call-back task to handle hardware reset - * @work: pointer to work_struct + * iavf_reset_step - Perform the VF reset sequence + * @adapter: board private structure * - * During reset we need to shut down and reinitialize the admin queue - * before we can use it to communicate with the PF again. We also clear - * and reinit the rings because that context is lost as well. - **/ -static void iavf_reset_task(struct work_struct *work) + * Requests a reset from PF, polls for completion, and reconfigures + * the driver. Caller must hold the netdev instance lock. + * + * This can sleep for several seconds while polling HW registers. + */ +void iavf_reset_step(struct iavf_adapter *adapter) { - struct iavf_adapter *adapter = container_of(work, - struct iavf_adapter, - reset_task); struct virtchnl_vf_resource *vfres = adapter->vf_res; struct net_device *netdev = adapter->netdev; struct iavf_hw *hw = &adapter->hw; @@ -3122,7 +3095,7 @@ static void iavf_reset_task(struct work_struct *work) int i = 0, err; bool running; - netdev_lock(netdev); + netdev_assert_locked(netdev); iavf_misc_irq_disable(adapter); if (adapter->flags & IAVF_FLAG_RESET_NEEDED) { @@ -3167,7 +3140,6 @@ static void iavf_reset_task(struct work_struct *work) dev_err(&adapter->pdev->dev, "Reset never finished (%x)\n", reg_val); iavf_disable_vf(adapter); - netdev_unlock(netdev); return; /* Do not attempt to reinit. It's dead, Jim. */ } @@ -3179,7 +3151,6 @@ static void iavf_reset_task(struct work_struct *work) iavf_startup(adapter); queue_delayed_work(adapter->wq, &adapter->watchdog_task, msecs_to_jiffies(30)); - netdev_unlock(netdev); return; } @@ -3321,7 +3292,6 @@ static void iavf_reset_task(struct work_struct *work) adapter->flags &= ~IAVF_FLAG_REINIT_ITR_NEEDED; wake_up(&adapter->reset_waitqueue); - netdev_unlock(netdev); return; reset_err: @@ -3331,10 +3301,21 @@ static void iavf_reset_task(struct work_struct *work) } iavf_disable_vf(adapter); - netdev_unlock(netdev); dev_err(&adapter->pdev->dev, "failed to allocate resources during reinit\n"); } +static void iavf_reset_task(struct work_struct *work) +{ + struct iavf_adapter *adapter = container_of(work, + struct iavf_adapter, + reset_task); + struct net_device *netdev = adapter->netdev; + + netdev_lock(netdev); + iavf_reset_step(adapter); + netdev_unlock(netdev); +} + /** * iavf_adminq_task - worker thread to clean the admin queue * @work: pointer to work_struct containing our data @@ -4600,22 +4581,17 @@ static int iavf_close(struct net_device *netdev) static int iavf_change_mtu(struct net_device *netdev, int new_mtu) { struct iavf_adapter *adapter = netdev_priv(netdev); - int ret = 0; netdev_dbg(netdev, "changing MTU from %d to %d\n", netdev->mtu, new_mtu); WRITE_ONCE(netdev->mtu, new_mtu); if (netif_running(netdev)) { - iavf_schedule_reset(adapter, IAVF_FLAG_RESET_NEEDED); - ret = iavf_wait_for_reset(adapter); - if (ret < 0) - netdev_warn(netdev, "MTU change interrupted waiting for reset"); - else if (ret) - netdev_warn(netdev, "MTU change timed out waiting for reset"); + adapter->flags |= IAVF_FLAG_RESET_NEEDED; + iavf_reset_step(adapter); } - return ret; + return 0; } /** -- 2.52.0 ^ permalink raw reply related [flat|nested] 17+ messages in thread
* Re: [PATCH net] iavf: fix deadlock in reset handling 2026-02-06 10:04 ` Petr Oros @ 2026-02-07 1:00 ` Jacob Keller 2026-02-07 3:01 ` Jakub Kicinski 1 sibling, 0 replies; 17+ messages in thread From: Jacob Keller @ 2026-02-07 1:00 UTC (permalink / raw) To: Petr Oros, Anthony Nguyen Cc: Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, Stanislav Fomichev, intel-wired-lan, netdev, linux-kernel On 2/6/2026 2:04 AM, Petr Oros wrote: > description... > > Fixes: 120f28a6f314 ("iavf: get rid of the crit lock") > Signed-off-by: Petr Oros <poros@redhat.com> > --- Code changes look correct to me. Description obviously needs to get written, but... I loaded both the net as of ee9241524b46 ("amd-xgbe: do not select NET_SELFTESTS when INET is disabled") and tested it with and without this fix applied. Before the fix, changing MTU till timeout after a few seconds with the complaint, after which the reset will happen and MTU will be applied late (the timeout in the wait event prevents a permanent deadlock). With the fix the command completes quickly with no errors and the MTU change applies immediately. Tested-by: Jacob Keller <jacob.e.keller@intel.com> Additionally, for a version with a proper commit message, please feel free to add: Reviewed-by: Jacob Keller <jacob.e.keller@intel.com> Thanks for working on this, Petr! Regards, Jake ^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH net] iavf: fix deadlock in reset handling 2026-02-06 10:04 ` Petr Oros 2026-02-07 1:00 ` Jacob Keller @ 2026-02-07 3:01 ` Jakub Kicinski 1 sibling, 0 replies; 17+ messages in thread From: Jakub Kicinski @ 2026-02-07 3:01 UTC (permalink / raw) To: Petr Oros Cc: jacob.e.keller, Tony Nguyen, Przemek Kitszel, Andrew Lunn, David S. Miller, Eric Dumazet, Paolo Abeni, Stanislav Fomichev, intel-wired-lan, netdev, linux-kernel On Fri, 6 Feb 2026 11:04:26 +0100 Petr Oros wrote: > Fixes: 120f28a6f314 ("iavf: get rid of the crit lock") This is so much better 👍️ ^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2026-02-07 3:01 UTC | newest] Thread overview: 17+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-02-02 8:48 [PATCH net] iavf: fix deadlock in reset handling Petr Oros 2026-02-02 9:06 ` [Intel-wired-lan] " Loktionov, Aleksandr 2026-02-02 10:53 ` Jijie Shao 2026-02-02 13:30 ` Ivan Vecera 2026-02-02 23:58 ` Jakub Kicinski 2026-02-03 1:00 ` [Intel-wired-lan] " Jacob Keller 2026-02-03 8:44 ` Petr Oros 2026-02-03 10:19 ` Przemek Kitszel 2026-02-03 11:32 ` Petr Oros 2026-02-03 23:47 ` Jacob Keller 2026-02-04 6:12 ` Przemek Kitszel 2026-02-04 19:25 ` Jacob Keller 2026-02-05 12:24 ` Petr Oros 2026-02-05 23:37 ` Jacob Keller 2026-02-06 10:04 ` Petr Oros 2026-02-07 1:00 ` Jacob Keller 2026-02-07 3:01 ` Jakub Kicinski
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox