Skip to content

Commit a22ed15

Browse files
shifty91anguy11
authored andcommitted
igb: Get rid of spurious interrupts
When running the igc with XDP/ZC in busy polling mode with deferral of hard interrupts, interrupts still happen from time to time. That is caused by the igb task watchdog which triggers Rx interrupts periodically. That mechanism has been introduced to overcome skb/memory allocation failures [1]. So the Rx clean functions stop processing the Rx ring in case of such failure. The task watchdog triggers Rx interrupts periodically in the hope that memory became available in the mean time. The current behavior is undesirable for real time applications, because the driver induced Rx interrupts trigger also the softirq processing. However, all real time packets should be processed by the application which uses the busy polling method. Therefore, only trigger the Rx interrupts in case of real allocation failures. Introduce a new flag for signaling that condition. Follow the same logic as in commit 8dcf2c2 ("igc: Get rid of spurious interrupts"). [1] - https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/commit/?id=3be507547e6177e5c808544bd6a2efa2c7f1d436 Reviewed-by: Joe Damato <jdamato@fastly.com> Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com> Tested-by: Sweta Kumari <sweta.kumari@intel.com> Signed-off-by: Kurt Kanzenbach <kurt@linutronix.de> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
1 parent fc0fb1f commit a22ed15

File tree

3 files changed

+28
-5
lines changed

3 files changed

+28
-5
lines changed

drivers/net/ethernet/intel/igb/igb.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,8 @@ enum e1000_ring_flags_t {
391391
IGB_RING_FLAG_RX_LB_VLAN_BSWAP,
392392
IGB_RING_FLAG_TX_CTX_IDX,
393393
IGB_RING_FLAG_TX_DETECT_HANG,
394-
IGB_RING_FLAG_TX_DISABLED
394+
IGB_RING_FLAG_TX_DISABLED,
395+
IGB_RING_FLAG_RX_ALLOC_FAILED,
395396
};
396397

397398
#define ring_uses_large_buffer(ring) \

drivers/net/ethernet/intel/igb/igb_main.c

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5755,11 +5755,29 @@ static void igb_watchdog_task(struct work_struct *work)
57555755
if (adapter->flags & IGB_FLAG_HAS_MSIX) {
57565756
u32 eics = 0;
57575757

5758-
for (i = 0; i < adapter->num_q_vectors; i++)
5759-
eics |= adapter->q_vector[i]->eims_value;
5760-
wr32(E1000_EICS, eics);
5758+
for (i = 0; i < adapter->num_q_vectors; i++) {
5759+
struct igb_q_vector *q_vector = adapter->q_vector[i];
5760+
struct igb_ring *rx_ring;
5761+
5762+
if (!q_vector->rx.ring)
5763+
continue;
5764+
5765+
rx_ring = adapter->rx_ring[q_vector->rx.ring->queue_index];
5766+
5767+
if (test_bit(IGB_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags)) {
5768+
eics |= q_vector->eims_value;
5769+
clear_bit(IGB_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags);
5770+
}
5771+
}
5772+
if (eics)
5773+
wr32(E1000_EICS, eics);
57615774
} else {
5762-
wr32(E1000_ICS, E1000_ICS_RXDMT0);
5775+
struct igb_ring *rx_ring = adapter->rx_ring[0];
5776+
5777+
if (test_bit(IGB_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags)) {
5778+
clear_bit(IGB_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags);
5779+
wr32(E1000_ICS, E1000_ICS_RXDMT0);
5780+
}
57635781
}
57645782

57655783
igb_spoof_check(adapter);
@@ -9090,6 +9108,7 @@ static int igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
90909108
if (!xdp_res && !skb) {
90919109
rx_ring->rx_stats.alloc_failed++;
90929110
rx_buffer->pagecnt_bias++;
9111+
set_bit(IGB_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags);
90939112
break;
90949113
}
90959114

@@ -9149,6 +9168,7 @@ static bool igb_alloc_mapped_page(struct igb_ring *rx_ring,
91499168
page = dev_alloc_pages(igb_rx_pg_order(rx_ring));
91509169
if (unlikely(!page)) {
91519170
rx_ring->rx_stats.alloc_failed++;
9171+
set_bit(IGB_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags);
91529172
return false;
91539173
}
91549174

@@ -9165,6 +9185,7 @@ static bool igb_alloc_mapped_page(struct igb_ring *rx_ring,
91659185
__free_pages(page, igb_rx_pg_order(rx_ring));
91669186

91679187
rx_ring->rx_stats.alloc_failed++;
9188+
set_bit(IGB_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags);
91689189
return false;
91699190
}
91709191

drivers/net/ethernet/intel/igb/igb_xsk.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,7 @@ int igb_clean_rx_irq_zc(struct igb_q_vector *q_vector,
415415
/* exit if we failed to retrieve a buffer */
416416
if (!skb) {
417417
rx_ring->rx_stats.alloc_failed++;
418+
set_bit(IGB_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags);
418419
break;
419420
}
420421

0 commit comments

Comments
 (0)