amd-xgbe: schedule NAPI on Rx Buffer Unavailable (RBU)

Under heavy load, Rx Buffer Unavailable (RBU) can occur if Rx processing
is slower than network. When an RBU is signaled, try to schedule NAPI to
help recover from such situation (including cases where an IRQ may be
missed or such)

Signed-off-by: Raju Rangoju <Raju.Rangoju@amd.com>
Link: https://patch.msgid.link/20251129175016.3034185-3-Raju.Rangoju@amd.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
Raju Rangoju 2025-11-29 23:20:16 +05:30 committed by Jakub Kicinski
parent c3b744fd20
commit ab96af7004
1 changed files with 15 additions and 4 deletions

View File

@ -410,15 +410,29 @@ static void xgbe_isr_bh_work(struct work_struct *work)
* Decide which NAPI to use and whether to schedule: * Decide which NAPI to use and whether to schedule:
* - When not using per-channel IRQs: schedule on global NAPI * - When not using per-channel IRQs: schedule on global NAPI
* if TI or RI are set. * if TI or RI are set.
* - RBU should also trigger NAPI (either per-channel or global)
* to allow refill.
*/ */
if (!per_ch_irq && (ti || ri)) if (!per_ch_irq && (ti || ri))
schedule_napi = true; schedule_napi = true;
if (rbu) {
schedule_napi = true;
pdata->ext_stats.rx_buffer_unavailable++;
}
napi = per_ch_irq ? &channel->napi : &pdata->napi; napi = per_ch_irq ? &channel->napi : &pdata->napi;
if (schedule_napi && napi_schedule_prep(napi)) { if (schedule_napi && napi_schedule_prep(napi)) {
/* Disable interrupts appropriately before polling */ /* Disable interrupts appropriately before polling */
xgbe_disable_rx_tx_ints(pdata); if (per_ch_irq) {
if (pdata->channel_irq_mode)
xgbe_disable_rx_tx_int(pdata, channel);
else
disable_irq_nosync(channel->dma_irq);
} else {
xgbe_disable_rx_tx_ints(pdata);
}
/* Turn on polling */ /* Turn on polling */
__napi_schedule(napi); __napi_schedule(napi);
@ -436,9 +450,6 @@ static void xgbe_isr_bh_work(struct work_struct *work)
XGMAC_SET_BITS(dma_ch_isr, DMA_CH_SR, RI, 0); XGMAC_SET_BITS(dma_ch_isr, DMA_CH_SR, RI, 0);
} }
if (rbu)
pdata->ext_stats.rx_buffer_unavailable++;
/* Restart the device on a Fatal Bus Error */ /* Restart the device on a Fatal Bus Error */
if (fbe) if (fbe)
schedule_work(&pdata->restart_work); schedule_work(&pdata->restart_work);