net: wangxun: replace busy-wait reset flag with kernel mutex

Replace the busy-wait loop using test_and_set_bit(WX_STATE_RESETTING)
with a proper per-device mutex to serialize reset operations.

The reset flag is reserved for other code paths (like watchdog), which
need tocheck if a reset is in process.

Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
Link: https://patch.msgid.link/20260407025616.33652-5-jiawenwu@trustnetic.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Jiawen Wu 2026-04-07 10:56:11 +08:00 committed by Jakub Kicinski
parent 9bc29a87fb
commit d48df7e7c3
6 changed files with 15 additions and 30 deletions

View File

@ -2513,6 +2513,7 @@ int wx_sw_init(struct wx *wx)
return -ENOMEM;
}
mutex_init(&wx->reset_lock);
bitmap_zero(wx->state, WX_STATE_NBITS);
bitmap_zero(wx->flags, WX_PF_FLAGS_NBITS);
wx->misc_irq_domain = false;

View File

@ -1400,6 +1400,7 @@ struct wx {
struct timer_list service_timer;
struct work_struct service_task;
struct mutex reset_lock; /* mutex for reset */
};
#define WX_INTR_ALL (~0ULL)
@ -1478,21 +1479,6 @@ static inline struct wx *phylink_to_wx(struct phylink_config *config)
return container_of(config, struct wx, phylink_config);
}
static inline int wx_set_state_reset(struct wx *wx)
{
u8 timeout = 50;
while (test_and_set_bit(WX_STATE_RESETTING, wx->state)) {
timeout--;
if (!timeout)
return -EBUSY;
usleep_range(1000, 2000);
}
return 0;
}
static inline unsigned int wx_rx_pg_order(struct wx_ring *ring)
{
#if (PAGE_SIZE < 8192)

View File

@ -339,14 +339,16 @@ static void wxvf_down(struct wx *wx)
static void wxvf_reinit_locked(struct wx *wx)
{
while (test_and_set_bit(WX_STATE_RESETTING, wx->state))
usleep_range(1000, 2000);
mutex_lock(&wx->reset_lock);
set_bit(WX_STATE_RESETTING, wx->state);
wxvf_down(wx);
wx_free_irq(wx);
wx_configure_vf(wx);
wx_request_msix_irqs_vf(wx);
wxvf_up_complete(wx);
clear_bit(WX_STATE_RESETTING, wx->state);
mutex_unlock(&wx->reset_lock);
}
static void wxvf_reset_subtask(struct wx *wx)

View File

@ -32,9 +32,8 @@ static int ngbe_set_ringparam(struct net_device *netdev,
new_rx_count == wx->rx_ring_count)
return 0;
err = wx_set_state_reset(wx);
if (err)
return err;
mutex_lock(&wx->reset_lock);
set_bit(WX_STATE_RESETTING, wx->state);
if (!netif_running(wx->netdev)) {
for (i = 0; i < wx->num_tx_queues; i++)
@ -65,6 +64,7 @@ static int ngbe_set_ringparam(struct net_device *netdev,
clear_reset:
clear_bit(WX_STATE_RESETTING, wx->state);
mutex_unlock(&wx->reset_lock);
return err;
}

View File

@ -56,9 +56,8 @@ static int txgbe_set_ringparam(struct net_device *netdev,
new_rx_count == wx->rx_ring_count)
return 0;
err = wx_set_state_reset(wx);
if (err)
return err;
mutex_lock(&wx->reset_lock);
set_bit(WX_STATE_RESETTING, wx->state);
if (!netif_running(wx->netdev)) {
for (i = 0; i < wx->num_tx_queues; i++)
@ -88,6 +87,7 @@ static int txgbe_set_ringparam(struct net_device *netdev,
clear_reset:
clear_bit(WX_STATE_RESETTING, wx->state);
mutex_unlock(&wx->reset_lock);
return err;
}

View File

@ -598,20 +598,16 @@ int txgbe_setup_tc(struct net_device *dev, u8 tc)
static void txgbe_reinit_locked(struct wx *wx)
{
int err = 0;
netif_trans_update(wx->netdev);
err = wx_set_state_reset(wx);
if (err) {
wx_err(wx, "wait device reset timeout\n");
return;
}
mutex_lock(&wx->reset_lock);
set_bit(WX_STATE_RESETTING, wx->state);
txgbe_down(wx);
txgbe_up(wx);
clear_bit(WX_STATE_RESETTING, wx->state);
mutex_unlock(&wx->reset_lock);
}
void txgbe_do_reset(struct net_device *netdev)