Skip to contentSkip to conversation

i40e/i40evf: Split container ITR into current_itr and target_itr

PATCH New Alice Michael 2 participants 2 messages Dec 29, 2017 – Jan 5, 2018

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

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
index 0212f6c..bfaeb77 100644
@@ -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
index c810e9d..6380d03 100644
@@ -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
index d226c7c..59acc25 100644
@@ -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
index f1c5ef7..5a6012b 100644
@@ -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
index f5d3725..aded3ad 100644
@@ -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
index f648e5e..3bf6a12 100644
@@ -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
#1 lore raw

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 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.

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(-)