Skip to content

Commit 8dcf2c2

Browse files
shifty91anguy11
authored andcommitted
igc: 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 igc 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. [1] - https://git.kernel.org/pub/scm/linux/kernel/git/tglx/history.git/commit/?id=3be507547e6177e5c808544bd6a2efa2c7f1d436 Reviewed-by: Sebastian Andrzej Siewior <[email protected]> Acked-by: Vinicius Costa Gomes <[email protected]> Acked-by: Maciej Fijalkowski <[email protected]> Signed-off-by: Kurt Kanzenbach <[email protected]> Reviewed-by: Simon Horman <[email protected]> Tested-by: Mor Bar-Gabay <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent 9f32975 commit 8dcf2c2

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

drivers/net/ethernet/intel/igc/igc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,7 @@ enum igc_ring_flags_t {
687687
IGC_RING_FLAG_TX_DETECT_HANG,
688688
IGC_RING_FLAG_AF_XDP_ZC,
689689
IGC_RING_FLAG_TX_HWTSTAMP,
690+
IGC_RING_FLAG_RX_ALLOC_FAILED,
690691
};
691692

692693
#define ring_uses_large_buffer(ring) \

drivers/net/ethernet/intel/igc/igc_main.c

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2191,6 +2191,7 @@ static bool igc_alloc_mapped_page(struct igc_ring *rx_ring,
21912191
page = dev_alloc_pages(igc_rx_pg_order(rx_ring));
21922192
if (unlikely(!page)) {
21932193
rx_ring->rx_stats.alloc_failed++;
2194+
set_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags);
21942195
return false;
21952196
}
21962197

@@ -2207,6 +2208,7 @@ static bool igc_alloc_mapped_page(struct igc_ring *rx_ring,
22072208
__free_page(page);
22082209

22092210
rx_ring->rx_stats.alloc_failed++;
2211+
set_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags);
22102212
return false;
22112213
}
22122214

@@ -2658,6 +2660,7 @@ static int igc_clean_rx_irq(struct igc_q_vector *q_vector, const int budget)
26582660
if (!skb) {
26592661
rx_ring->rx_stats.alloc_failed++;
26602662
rx_buffer->pagecnt_bias++;
2663+
set_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags);
26612664
break;
26622665
}
26632666

@@ -2738,6 +2741,7 @@ static void igc_dispatch_skb_zc(struct igc_q_vector *q_vector,
27382741
skb = igc_construct_skb_zc(ring, xdp);
27392742
if (!skb) {
27402743
ring->rx_stats.alloc_failed++;
2744+
set_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &ring->flags);
27412745
return;
27422746
}
27432747

@@ -5807,11 +5811,29 @@ static void igc_watchdog_task(struct work_struct *work)
58075811
if (adapter->flags & IGC_FLAG_HAS_MSIX) {
58085812
u32 eics = 0;
58095813

5810-
for (i = 0; i < adapter->num_q_vectors; i++)
5811-
eics |= adapter->q_vector[i]->eims_value;
5812-
wr32(IGC_EICS, eics);
5814+
for (i = 0; i < adapter->num_q_vectors; i++) {
5815+
struct igc_q_vector *q_vector = adapter->q_vector[i];
5816+
struct igc_ring *rx_ring;
5817+
5818+
if (!q_vector->rx.ring)
5819+
continue;
5820+
5821+
rx_ring = adapter->rx_ring[q_vector->rx.ring->queue_index];
5822+
5823+
if (test_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags)) {
5824+
eics |= q_vector->eims_value;
5825+
clear_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags);
5826+
}
5827+
}
5828+
if (eics)
5829+
wr32(IGC_EICS, eics);
58135830
} else {
5814-
wr32(IGC_ICS, IGC_ICS_RXDMT0);
5831+
struct igc_ring *rx_ring = adapter->rx_ring[0];
5832+
5833+
if (test_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags)) {
5834+
clear_bit(IGC_RING_FLAG_RX_ALLOC_FAILED, &rx_ring->flags);
5835+
wr32(IGC_ICS, IGC_ICS_RXDMT0);
5836+
}
58155837
}
58165838

58175839
igc_ptp_tx_hang(adapter);

0 commit comments

Comments
 (0)