mirror of
https://github.com/torvalds/linux.git
synced 2026-05-28 17:13:52 +02:00
net: wangxun: schedule hardware stats update in watchdog
Hardware statistics should be updated periodically in the watchdog to prevent 32-bit registers from overflowing. This is also required for the upcoming pause frame accounting logic, which relies on regular statistics sampling. Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com> Link: https://patch.msgid.link/20260407025616.33652-8-jiawenwu@trustnetic.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
58f6303572
commit
dc33e52b8c
|
|
@ -2513,6 +2513,7 @@ int wx_sw_init(struct wx *wx)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
spin_lock_init(&wx->hw_stats_lock);
|
||||
mutex_init(&wx->reset_lock);
|
||||
bitmap_zero(wx->state, WX_STATE_NBITS);
|
||||
bitmap_zero(wx->flags, WX_PF_FLAGS_NBITS);
|
||||
|
|
@ -2845,6 +2846,12 @@ void wx_update_stats(struct wx *wx)
|
|||
u64 restart_queue = 0, tx_busy = 0;
|
||||
u32 i;
|
||||
|
||||
if (!netif_running(wx->netdev) ||
|
||||
test_bit(WX_STATE_RESETTING, wx->state))
|
||||
return;
|
||||
|
||||
spin_lock(&wx->hw_stats_lock);
|
||||
|
||||
/* gather some stats to the wx struct that are per queue */
|
||||
for (i = 0; i < wx->num_rx_queues; i++) {
|
||||
struct wx_ring *rx_ring = wx->rx_ring[i];
|
||||
|
|
@ -2913,6 +2920,8 @@ void wx_update_stats(struct wx *wx)
|
|||
for (i = wx->num_vfs * wx->num_rx_queues_per_pool;
|
||||
i < wx->mac.max_rx_queues; i++)
|
||||
hwstats->qmprc += rd32(wx, WX_PX_MPRC(i));
|
||||
|
||||
spin_unlock(&wx->hw_stats_lock);
|
||||
}
|
||||
EXPORT_SYMBOL(wx_update_stats);
|
||||
|
||||
|
|
|
|||
|
|
@ -1354,6 +1354,7 @@ struct wx {
|
|||
bool default_up;
|
||||
|
||||
struct wx_hw_stats stats;
|
||||
spinlock_t hw_stats_lock; /* spinlock for accessing to hw stats */
|
||||
u64 tx_busy;
|
||||
u64 non_eop_descs;
|
||||
u64 restart_queue;
|
||||
|
|
|
|||
|
|
@ -138,6 +138,26 @@ static int ngbe_sw_init(struct wx *wx)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* ngbe_service_task - manages and runs subtasks
|
||||
* @work: pointer to work_struct containing our data
|
||||
**/
|
||||
static void ngbe_service_task(struct work_struct *work)
|
||||
{
|
||||
struct wx *wx = container_of(work, struct wx, service_task);
|
||||
|
||||
wx_update_stats(wx);
|
||||
|
||||
wx_service_event_complete(wx);
|
||||
}
|
||||
|
||||
static void ngbe_init_service(struct wx *wx)
|
||||
{
|
||||
timer_setup(&wx->service_timer, wx_service_timer, 0);
|
||||
INIT_WORK(&wx->service_task, ngbe_service_task);
|
||||
clear_bit(WX_STATE_SERVICE_SCHED, wx->state);
|
||||
}
|
||||
|
||||
/**
|
||||
* ngbe_irq_enable - Enable default interrupt generation settings
|
||||
* @wx: board private structure
|
||||
|
|
@ -368,6 +388,10 @@ static void ngbe_disable_device(struct wx *wx)
|
|||
wx_napi_disable_all(wx);
|
||||
netif_tx_stop_all_queues(netdev);
|
||||
netif_tx_disable(netdev);
|
||||
|
||||
timer_delete_sync(&wx->service_timer);
|
||||
cancel_work_sync(&wx->service_task);
|
||||
|
||||
if (wx->gpio_ctrl)
|
||||
ngbe_sfp_modules_txrx_powerctl(wx, false);
|
||||
wx_irq_disable(wx);
|
||||
|
|
@ -407,6 +431,7 @@ void ngbe_up(struct wx *wx)
|
|||
wx_napi_enable_all(wx);
|
||||
/* enable transmits */
|
||||
netif_tx_start_all_queues(wx->netdev);
|
||||
mod_timer(&wx->service_timer, jiffies);
|
||||
|
||||
/* clear any pending interrupts, may auto mask */
|
||||
rd32(wx, WX_PX_IC(0));
|
||||
|
|
@ -770,9 +795,11 @@ static int ngbe_probe(struct pci_dev *pdev,
|
|||
eth_hw_addr_set(netdev, wx->mac.perm_addr);
|
||||
wx_mac_set_default_filter(wx, wx->mac.perm_addr);
|
||||
|
||||
ngbe_init_service(wx);
|
||||
|
||||
err = wx_init_interrupt_scheme(wx);
|
||||
if (err)
|
||||
goto err_free_mac_table;
|
||||
goto err_cancel_service;
|
||||
|
||||
/* phy Interface Configuration */
|
||||
err = ngbe_mdio_init(wx);
|
||||
|
|
@ -792,6 +819,9 @@ static int ngbe_probe(struct pci_dev *pdev,
|
|||
wx_control_hw(wx, false);
|
||||
err_clear_interrupt_scheme:
|
||||
wx_clear_interrupt_scheme(wx);
|
||||
err_cancel_service:
|
||||
timer_delete_sync(&wx->service_timer);
|
||||
cancel_work_sync(&wx->service_task);
|
||||
err_free_mac_table:
|
||||
kfree(wx->rss_key);
|
||||
kfree(wx->mac_table);
|
||||
|
|
@ -820,6 +850,10 @@ static void ngbe_remove(struct pci_dev *pdev)
|
|||
netdev = wx->netdev;
|
||||
wx_disable_sriov(wx);
|
||||
unregister_netdev(netdev);
|
||||
|
||||
timer_shutdown_sync(&wx->service_timer);
|
||||
cancel_work_sync(&wx->service_task);
|
||||
|
||||
phylink_destroy(wx->phylink);
|
||||
pci_release_selected_regions(pdev,
|
||||
pci_select_bars(pdev, IORESOURCE_MEM));
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ static void txgbe_service_task(struct work_struct *work)
|
|||
|
||||
txgbe_module_detection_subtask(wx);
|
||||
txgbe_link_config_subtask(wx);
|
||||
wx_update_stats(wx);
|
||||
|
||||
wx_service_event_complete(wx);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user