Skip to content

Commit 23be707

Browse files
jbrandebanguy11
authored andcommitted
ice: fix software generating extra interrupts
The driver tried to work around missing completion events that occurred while interrupts are disabled, by triggering a software interrupt whenever we exit polling (but we had to have polled at least once). This was causing a *lot* of extra interrupts for some workloads like NVMe over TCP, which resulted in regressions in performance. It was also visible when polling didn't prevent interrupts when busy_poll was enabled. Fix the extra interrupts by utilizing our previously unused 3rd ITR (interrupt throttle) index and set it to 20K interrupts per second, and then trigger a software interrupt within that rate limit. While here, slightly refactor the code to avoid an overwrite of a local variable in the case of wb_en = true. Fixes: b7306b4 ("ice: manage interrupts during poll exit") Signed-off-by: Jesse Brandeburg <[email protected]> Tested-by: Gurucharan G <[email protected]> Signed-off-by: Tony Nguyen <[email protected]>
1 parent d16a4f4 commit 23be707

File tree

2 files changed

+16
-11
lines changed

2 files changed

+16
-11
lines changed

drivers/net/ethernet/intel/ice/ice_hw_autogen.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@
182182
#define GLINT_DYN_CTL_INTERVAL_S 5
183183
#define GLINT_DYN_CTL_INTERVAL_M ICE_M(0xFFF, 5)
184184
#define GLINT_DYN_CTL_SW_ITR_INDX_ENA_M BIT(24)
185+
#define GLINT_DYN_CTL_SW_ITR_INDX_S 25
185186
#define GLINT_DYN_CTL_SW_ITR_INDX_M ICE_M(0x3, 25)
186187
#define GLINT_DYN_CTL_WB_ON_ITR_M BIT(30)
187188
#define GLINT_DYN_CTL_INTENA_MSK_M BIT(31)

drivers/net/ethernet/intel/ice/ice_txrx.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,21 +1361,25 @@ static void ice_enable_interrupt(struct ice_q_vector *q_vector)
13611361
if (test_bit(ICE_DOWN, vsi->state))
13621362
return;
13631363

1364-
/* When exiting WB_ON_ITR, let ITR resume its normal
1365-
* interrupts-enabled path.
1364+
/* trigger an ITR delayed software interrupt when exiting busy poll, to
1365+
* make sure to catch any pending cleanups that might have been missed
1366+
* due to interrupt state transition. If busy poll or poll isn't
1367+
* enabled, then don't update ITR, and just enable the interrupt.
13661368
*/
1367-
if (wb_en)
1369+
if (!wb_en) {
1370+
itr_val = ice_buildreg_itr(ICE_ITR_NONE, 0);
1371+
} else {
13681372
q_vector->wb_on_itr = false;
13691373

1370-
itr_val = ice_buildreg_itr(ICE_ITR_NONE, 0);
1371-
/* trigger an immediate software interrupt when exiting
1372-
* busy poll, to make sure to catch any pending cleanups
1373-
* that might have been missed due to interrupt state
1374-
* transition.
1375-
*/
1376-
if (wb_en) {
1374+
/* do two things here with a single write. Set up the third ITR
1375+
* index to be used for software interrupt moderation, and then
1376+
* trigger a software interrupt with a rate limit of 20K on
1377+
* software interrupts, this will help avoid high interrupt
1378+
* loads due to frequently polling and exiting polling.
1379+
*/
1380+
itr_val = ice_buildreg_itr(ICE_IDX_ITR2, ICE_ITR_20K);
13771381
itr_val |= GLINT_DYN_CTL_SWINT_TRIG_M |
1378-
GLINT_DYN_CTL_SW_ITR_INDX_M |
1382+
ICE_IDX_ITR2 << GLINT_DYN_CTL_SW_ITR_INDX_S |
13791383
GLINT_DYN_CTL_SW_ITR_INDX_ENA_M;
13801384
}
13811385
wr32(&vsi->back->hw, GLINT_DYN_CTL(q_vector->reg_idx), itr_val);

0 commit comments

Comments
 (0)