i40e/i40evf: Split container ITR into current_itr and target_itr
Subsystems (2)
PATCH 13/14 i40e/i40evf: Split container ITR into current_itr and target_itr
From: Alexander Duyck <[email protected]>
This patch is mostly prep-work for replacing the current approach to programming the dynamic aka adaptive ITR. Specifically here what we are doing is splitting the Tx and Rx ITR each into two separate values.
The first value current_itr represents the current value of the register.
The second value target_itr represents the desired value of the register.
The general plan by doing this is to allow for deferring the update of the ITR value under certain circumstances. For now we will work with what we have, but in the future I hope to change the behavior so that we always only update one ITR at a time using some simple logic to determine which ITR requires an update.
--- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 13 +++-- drivers/net/ethernet/intel/i40e/i40e_main.c | 22 ++++--- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 68 +++++++++++++--------- drivers/net/ethernet/intel/i40e/i40e_txrx.h | 5 +- drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 68 +++++++++++++--------- drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 5 +- drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c | 14 ++--- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 10 ++-- 8 files changed, 117 insertions(+), 88 deletions(-)
drivers/net/ethernet/intel/i40e/i40e_ethtool.c +7 -6
@@ -2329,14 +2329,15 @@ static void i40e_set_itr_per_queue(struct i40e_vsi *vsi, tx_ring->itr_setting &= ~I40E_ITR_DYNAMIC ; q_vector = rx_ring->q_vector; - q_vector->rx.itr =ITR_TO_REG (rx_ring->itr_setting); -wr32 (hw,I40E_PFINT_ITRN (I40E_RX_ITR , q_vector->reg_idx), - q_vector->rx.itr); + q_vector->rx.target_itr =ITR_TO_REG (rx_ring->itr_setting); q_vector = tx_ring->q_vector; - q_vector->tx.itr =ITR_TO_REG (tx_ring->itr_setting); -wr32 (hw,I40E_PFINT_ITRN (I40E_TX_ITR , q_vector->reg_idx), - q_vector->tx.itr); + q_vector->tx.target_itr =ITR_TO_REG (tx_ring->itr_setting); + +/* The interrupt handler itself will take care of programming +* the Tx and Rx ITR values based on the values we have entered +* into the q_vector, no need to write the values now. +*/ wr32 (hw,I40E_PFINT_RATEN (q_vector->reg_idx), intrl);i40e_flush (hw);
drivers/net/ethernet/intel/i40e/i40e_main.c +14 -8
@@ -3434,14 +3434,18 @@ static void i40e_vsi_configure_msix(struct i40e_vsi *vsi)struct i40e_q_vector *q_vector = vsi->q_vectors[i]; q_vector->itr_countdown =ITR_COUNTDOWN_START ; - q_vector->rx.itr =ITR_TO_REG (vsi->rx_rings[i]->itr_setting); + q_vector->rx.target_itr = +ITR_TO_REG (vsi->rx_rings[i]->itr_setting); q_vector->rx.latency_range =I40E_LOW_LATENCY ;wr32 (hw,I40E_PFINT_ITRN (I40E_RX_ITR , vector -1 ), - q_vector->rx.itr); - q_vector->tx.itr =ITR_TO_REG (vsi->tx_rings[i]->itr_setting); + q_vector->rx.target_itr); + q_vector->rx.current_itr = q_vector->rx.target_itr; + q_vector->tx.target_itr = +ITR_TO_REG (vsi->tx_rings[i]->itr_setting); q_vector->tx.latency_range =I40E_LOW_LATENCY ;wr32 (hw,I40E_PFINT_ITRN (I40E_TX_ITR , vector -1 ), - q_vector->tx.itr); + q_vector->tx.target_itr); + q_vector->tx.current_itr = q_vector->tx.target_itr;wr32 (hw,I40E_PFINT_RATEN (vector -1 ),i40e_intrl_usec_to_reg (vsi->int_rate_limit));
@@ -3543,12 +3547,14 @@ static void i40e_configure_msi_and_legacy(struct i40e_vsi *vsi)/* set the ITR configuration */ q_vector->itr_countdown =ITR_COUNTDOWN_START ; - q_vector->rx.itr =ITR_TO_REG (vsi->rx_rings[0 ]->itr_setting); + q_vector->rx.target_itr =ITR_TO_REG (vsi->rx_rings[0 ]->itr_setting); q_vector->rx.latency_range =I40E_LOW_LATENCY ; -wr32 (hw,I40E_PFINT_ITR0 (I40E_RX_ITR ), q_vector->rx.itr); - q_vector->tx.itr =ITR_TO_REG (vsi->tx_rings[0 ]->itr_setting); +wr32 (hw,I40E_PFINT_ITR0 (I40E_RX_ITR ), q_vector->rx.target_itr); + q_vector->rx.current_itr = q_vector->rx.target_itr; + q_vector->tx.target_itr =ITR_TO_REG (vsi->tx_rings[0 ]->itr_setting); q_vector->tx.latency_range =I40E_LOW_LATENCY ; -wr32 (hw,I40E_PFINT_ITR0 (I40E_TX_ITR ), q_vector->tx.itr); +wr32 (hw,I40E_PFINT_ITR0 (I40E_TX_ITR ), q_vector->tx.target_itr); + q_vector->tx.current_itr = q_vector->tx.target_itr;i40e_enable_misc_int_causes (pf);
drivers/net/ethernet/intel/i40e/i40e_txrx.c +39 -29
121 lines not on this page · raw message
drivers/net/ethernet/intel/i40e/i40e_txrx.h +3 -2
@@ -32,7 +32,7 @@/* The datasheet for the X710 and XL710 indicate that the maximum value for * the ITR is 8160usec which is then called out as 0xFF0 with a 2usec -* resoltion. 8160 is 0x1FE0 when written out in hex. So instead of storing +* resolution. 8160 is 0x1FE0 when written out in hex. So instead of storing * the register value which is divided by 2 lets use the actual values and * avoid an excessive amount of translation. */
@@ -474,7 +474,8 @@ struct i40e_ring_container {unsigned long last_itr_update;/* jiffies of last ITR update */ u16 count;enum i40e_latency_range latency_range; -u16 itr; +u16 target_itr;/* target ITR setting for ring(s) */ +u16 current_itr;/* current ITR setting for ring(s) */ };/* iterator for handling rings in ring container */
drivers/net/ethernet/intel/i40evf/i40e_txrx.c +39 -29
115 lines not on this page · raw message
drivers/net/ethernet/intel/i40evf/i40e_txrx.h +3 -2
@@ -32,7 +32,7 @@/* The datasheet for the X710 and XL710 indicate that the maximum value for * the ITR is 8160usec which is then called out as 0xFF0 with a 2usec -* resoltion. 8160 is 0x1FE0 when written out in hex. So instead of storing +* resolution. 8160 is 0x1FE0 when written out in hex. So instead of storing * the register value which is divided by 2 lets use the actual values and * avoid an excessive amount of translation. */
@@ -442,7 +442,8 @@ struct i40e_ring_container {unsigned long last_itr_update;/* jiffies of last ITR update */ u16 count;enum i40e_latency_range latency_range; -u16 itr; +u16 target_itr;/* target ITR setting for ring(s) */ +u16 current_itr;/* current ITR setting for ring(s) */ };/* iterator for handling rings in ring container */
drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c +6 -8
@@ -514,7 +514,6 @@ static void i40evf_set_itr_per_queue(struct i40evf_adapter *adapter, {struct i40e_ring *rx_ring = &adapter->rx_rings[queue];struct i40e_ring *tx_ring = &adapter->tx_rings[queue]; -struct i40e_hw *hw = &adapter->hw;struct i40e_q_vector *q_vector; rx_ring->itr_setting =ITR_REG_ALIGN (ec->rx_coalesce_usecs);
@@ -529,16 +528,15 @@ static void i40evf_set_itr_per_queue(struct i40evf_adapter *adapter, tx_ring->itr_setting ^=I40E_ITR_DYNAMIC ; q_vector = rx_ring->q_vector; - q_vector->rx.itr =ITR_TO_REG (rx_ring->itr_setting); -wr32 (hw,I40E_VFINT_ITRN1 (I40E_RX_ITR , q_vector->reg_idx), - q_vector->rx.itr); + q_vector->rx.target_itr =ITR_TO_REG (rx_ring->itr_setting); q_vector = tx_ring->q_vector; - q_vector->tx.itr =ITR_TO_REG (tx_ring->itr_setting); -wr32 (hw,I40E_VFINT_ITRN1 (I40E_TX_ITR , q_vector->reg_idx), - q_vector->tx.itr); + q_vector->tx.target_itr =ITR_TO_REG (tx_ring->itr_setting); -i40e_flush (hw); +/* The interrupt handler itself will take care of programming +* the Tx and Rx ITR values based on the values we have entered +* into the q_vector, no need to write the values now. +*/ }/**
drivers/net/ethernet/intel/i40evf/i40evf_main.c +6 -4
@@ -354,11 +354,12 @@ i40evf_map_vector_to_rxq(struct i40evf_adapter *adapter, int v_idx, int r_idx) q_vector->rx.ring = rx_ring; q_vector->rx.count++; q_vector->rx.latency_range =I40E_LOW_LATENCY ; - q_vector->rx.itr =ITR_TO_REG (rx_ring->itr_setting); + q_vector->rx.target_itr =ITR_TO_REG (rx_ring->itr_setting); q_vector->ring_mask |=BIT (r_idx); q_vector->itr_countdown =ITR_COUNTDOWN_START ;wr32 (hw,I40E_VFINT_ITRN1 (I40E_RX_ITR , q_vector->reg_idx), - q_vector->rx.itr); + q_vector->rx.current_itr); + q_vector->rx.current_itr = q_vector->rx.target_itr; }/**
@@ -380,11 +381,12 @@ i40evf_map_vector_to_txq(struct i40evf_adapter *adapter, int v_idx, int t_idx) q_vector->tx.ring = tx_ring; q_vector->tx.count++; q_vector->tx.latency_range =I40E_LOW_LATENCY ; - q_vector->tx.itr =ITR_TO_REG (tx_ring->itr_setting); + q_vector->tx.target_itr =ITR_TO_REG (tx_ring->itr_setting); q_vector->itr_countdown =ITR_COUNTDOWN_START ; q_vector->num_ringpairs++;wr32 (hw,I40E_VFINT_ITRN1 (I40E_TX_ITR , q_vector->reg_idx), - q_vector->tx.itr); + q_vector->tx.target_itr); + q_vector->tx.current_itr = q_vector->tx.target_itr; }/**
Signature · 1 line
2.9.5
Bowers
PATCH 13/14 i40e/i40evf: Split container ITR into current_itr and target_itr
Quoted 26 lines
-----Original Message-----
From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On Behalf Of Alice Michael
Sent: Friday, December 29, 2017 5:51 AM
To: Michael, Alice <[email protected]>; intel-wired- lan at lists.osuosl.org
Subject: [Intel-wired-lan] [next PATCH S85-V1 13/14] i40e/i40evf: Split container ITR intocurrent_itrandtarget_itrFrom: Alexander Duyck <[email protected]>
This patch is mostly prep-work for replacing the current approach to programming the dynamic aka adaptive ITR. Specifically here what we are doing is splitting the Tx and Rx ITR each into two separate values.
The first value
current_itrrepresents the current value of the register.The second value
target_itrrepresents the desired value of the register.The general plan by doing this is to allow for deferring the update of the ITR value under certain circumstances. For now we will work with what we have, but in the future I hope to change the behavior so that we always only update one ITR at a time using some simple logic to determine which ITR requires an update.
Signed-off-by Alexander Duyck <[email protected]>
Quoted 11 lines
--- drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 13 +++-- drivers/net/ethernet/intel/i40e/i40e_main.c | 22 ++++--- drivers/net/ethernet/intel/i40e/i40e_txrx.c | 68 +++++++++++++--------- drivers/net/ethernet/intel/i40e/i40e_txrx.h | 5 +- drivers/net/ethernet/intel/i40evf/i40e_txrx.c | 68 +++++++++++++------- -- drivers/net/ethernet/intel/i40evf/i40e_txrx.h | 5 +- drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c | 14 ++--- drivers/net/ethernet/intel/i40evf/i40evf_main.c | 10 ++-- 8 files changed, 117 insertions(+), 88 deletions(-)