Skip to contentSkip to conversation

e1000e: Set HTHRESH when PTHRESH is used

PATCH New Matt Turner 3 participants 12 messages Nov 7, 2017 – Nov 29, 2017

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

PATCH 1/3 e1000e: Set HTHRESH when PTHRESH is used

From: Matt Turner <[email protected]>

According to section 12.0.3.4.13 "Receive Descriptor Control - RXDCTL" of the Intel? 82579 Gigabit Ethernet PHY Datasheet v2.1:

"HTHRESH should be given a non zero value when ever PTHRESH is
used."

In RXDCTL(0), PTHRESH lives at bits 5:0, and HTHREST lives at bits 13:8. Set only bit 8 of HTHREST as is done in e1000_flush_rx_ring(). Found by inspection.

---
 drivers/net/ethernet/intel/e1000e/netdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/intel/e1000e/netdev.c +1 -1
index 2dcb5463d9b8..286d0277284e 100644
@@ -3285,7 +3285,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
 		if (adapter->flags & FLAG_IS_ICH) {
 			u32 rxdctl = er32(RXDCTL(0));
 
-			ew32(RXDCTL(0), rxdctl | 0x3);
+			ew32(RXDCTL(0), rxdctl | 0x3 | BIT(8));
 		}
 
 		pm_qos_update_request(&adapter->pm_qos_req, lat);
Signature · 1 line
2.13.6
#1 lore raw

PATCH 2/3 e1000e: Alert the user that C-states will be disabled by enabling jumbo frames

From: Matt Turner <[email protected]>

I personally spent a long time trying to decypher why my CPU would not reach deeper C-states. Let's just tell the next user what's going on.

---
 drivers/net/ethernet/intel/e1000e/netdev.c | 3 +++
 1 file changed, 3 insertions(+)
drivers/net/ethernet/intel/e1000e/netdev.c +3 -0
index 286d0277284e..4dcff481c4b4 100644
@@ -3288,6 +3288,9 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
 			ew32(RXDCTL(0), rxdctl | 0x3 | BIT(8));
 		}
 
+		dev_info(&adapter->pdev->dev,
+			 "Some CPU C-states have been disabled in order to "
+			 "enable jumbo frames\n");
 		pm_qos_update_request(&adapter->pm_qos_req, lat);
 	} else {
 		pm_qos_update_request(&adapter->pm_qos_req,
Signature · 1 line
2.13.6
#2 lore raw

PATCH 2/3 e1000e: Alert the user that C-states will be disabled by enabling jumbo frames

Quoted 15 lines · Matt Turner

From: Matt Turner <[email protected]>

I personally spent a long time trying to decypher why my CPU would not reach deeper C-states. Let's just tell the next user what's going on.

---
  drivers/net/ethernet/intel/e1000e/netdev.c | 3 +++
  1 file changed, 3 insertions(+)
drivers/net/ethernet/intel/e1000e/netdev.c +0 -0
index 286d0277284e..4dcff481c4b4 100644

drivers/net/ethernet/intel/e1000e/netdev.c static void e1000_configure_rx(struct e1000_adapter *adapter) · line 3296

Quoted 9 lines
drivers/net/ethernet/intel/e1000e/netdev.c +3 -0
@@ -3288,6 +3288,9 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
  			ew32(RXDCTL(0), rxdctl | 0x3 | BIT(8));
  		}
 
+		dev_info(&adapter->pdev->dev,
+			 "Some CPU C-states have been disabled in order to "
+			 "enable jumbo frames\n");
  		pm_qos_update_request(&adapter->pm_qos_req, lat);
  	} else {
  		pm_qos_update_request(&adapter->pm_qos_req,

Ack. Let's accept this comments.

#3 lore raw

PATCH 2/3 e1000e: Alert the user that C-states will be disabled by enabling jumbo frames

Quoted 20 lines · Sasha
Quoted 19 lines · Matt Turner

From: Matt Turner <[email protected]>

I personally spent a long time trying to decypher why my CPU would not reach deeper C-states. Let's just tell the next user what's going on.

---
? drivers/net/ethernet/intel/e1000e/netdev.c | 3 +++ ? 1 file changed, 3 insertions(+)

drivers/net/ethernet/intel/e1000e/netdev.c +0 -0
index 286d0277284e..4dcff481c4b4 100644
@@ -3288,6 +3288,9 @@ static void e1000_configure_rx(struct 
 e1000_adapter *adapter)
 ????????????? ew32(RXDCTL(0), rxdctl | 0x3 | BIT(8));
 ????????? }
Quoted 8 lines

drivers/net/ethernet/intel/e1000e/netdev.c static void e1000_configure_rx(struct · line 3296

Quoted 6 lines
drivers/net/ethernet/intel/e1000e/netdev.c +3 -0
+??????? dev_info(&adapter->pdev->dev,
+???????????? "Some CPU C-states have been disabled in order to "
+???????????? "enable jumbo frames\n");
 ????????? pm_qos_update_request(&adapter->pm_qos_req, lat);
 ????? } else {
 ????????? pm_qos_update_request(&adapter->pm_qos_req,

Ack. Let's accept this comments.

But let's make that a single string, not split between lines. sln

Quoted 5 lines

_______________________________________________
Intel-wired-lan mailing list
Intel-wired-lan at osuosl.org
https://lists.osuosl.org/mailman/listinfo/intel-wired-lan

#4 lore raw

PATCH 2/3 e1000e: Alert the user that C-states will be disabled by enabling jumbo frames

In reply to Matt Turner

From: Matt Turner <[email protected]>

I personally spent a long time trying to decypher why my CPU would not reach deeper C-states. Let's just tell the next user what's going on.

---
v2: Per Shannon, put string on one line for easier grepping

 drivers/net/ethernet/intel/e1000e/netdev.c | 2 ++
 1 file changed, 2 insertions(+)
drivers/net/ethernet/intel/e1000e/netdev.c +2 -0
index 286d0277284e..31577dad22cb 100644
@@ -3288,6 +3288,8 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
 			ew32(RXDCTL(0), rxdctl | 0x3 | BIT(8));
 		}
 
+		dev_info(&adapter->pdev->dev,
+			 "Some CPU C-states have been disabled in order to enable jumbo frames\n");
 		pm_qos_update_request(&adapter->pm_qos_req, lat);
 	} else {
 		pm_qos_update_request(&adapter->pm_qos_req,
Signature · 1 line
2.13.6
#5 lore raw

PATCH 2/3 e1000e: Alert the user that C-states will be disabled by enabling jumbo frames

Quoted 8 lines · Matt Turner

From: Matt Turner <[email protected]>

I personally spent a long time trying to decypher why my CPU would not reach deeper C-states. Let's just tell the next user what's going on.

---
v2: Per Shannon, put string on one line for easier grepping

Quoted 18 lines
  drivers/net/ethernet/intel/e1000e/netdev.c | 2 ++
  1 file changed, 2 insertions(+)
drivers/net/ethernet/intel/e1000e/netdev.c +2 -0
index 286d0277284e..31577dad22cb 100644
@@ -3288,6 +3288,8 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
  			ew32(RXDCTL(0), rxdctl | 0x3 | BIT(8));
  		}
 
+		dev_info(&adapter->pdev->dev,
+			 "Some CPU C-states have been disabled in order to enable jumbo frames\n");
  		pm_qos_update_request(&adapter->pm_qos_req, lat);
  	} else {
  		pm_qos_update_request(&adapter->pm_qos_req,
#6 lore raw

PATCH 2/3 e1000e: Alert the user that C-states will be disabled by enabling jumbo frames

In reply to Matt Turner
Quoted 13 lines

From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On Behalf Of Matt Turner
Sent: Tuesday, November 14, 2017 3:52 PM
To: intel-wired-lan at lists.osuosl.org
Cc: Turner, Matt <[email protected]>
Subject: [Intel-wired-lan] [PATCH 2/3] e1000e: Alert the user that C-states will be disabled by enabling jumbo frames

From: Matt Turner <[email protected]>

I personally spent a long time trying to decypher why my CPU would not reach deeper C-states. Let's just tell the next user what's going on.

Quoted 6 lines

---
v2: Per Shannon, put string on one line for easier grepping

 drivers/net/ethernet/intel/e1000e/netdev.c | 2 ++
 1 file changed, 2 insertions(+)
#7 lore raw

PATCH 3/3 e1000e: Disable jumbo receive workaround on Lynx Point and newer

In reply to Matt Turner

From: Matt Turner <[email protected]>

Commit 3e35d9918cbb ("e1000e: adjust PM QoS request") expanded the application of what is evidently a hardware workaround to apply to all e1000e devices. Prior to the commit, it applied only to e1000_pch2lan (Sandy Bridge era) and the commit message notes that other earlier parts such as ICH9 and ICH10 suffer from the problem as well.

The workaround works by preventing the CPU from entering deep sleep states, which increases energy consumption significantly. My Skylake CPU reaches the C10 state the PC8 package state with the MTU for its I219-LM set to 1500. At an MTU of 9000, it can only reach the C1E state and no low power package state at all. With this patch, the CPU again reaches the C10 state and (only) the PC2 package state. Not ideal, but an improvement nonetheless.

---
This patch is speculative -- I'm an Intel employee (not in the networking division), but I have no idea where to find documentation about the hardware bug in question. I'm hoping that someone more in the know can check if the hardware was fixed in subsequent generations and this workaround can be disabled. I have chosen the pch2 cut off only because nothing further is mentioned about the bug in git history.

 drivers/net/ethernet/intel/e1000e/netdev.c | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)
drivers/net/ethernet/intel/e1000e/netdev.c +9 -8
index 4dcff481c4b4..553f8bd45eea 100644
@@ -3277,7 +3277,8 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
 	/* With jumbo frames, excessive C-state transition latencies result
 	 * in dropped transactions.
 	 */
-	if (adapter->netdev->mtu > ETH_DATA_LEN) {
+	if (adapter->hw.mac.type <= e1000_pch2lan &&
+	    adapter->netdev->mtu > ETH_DATA_LEN) {
 		u32 lat =
 		    ((er32(PBA) & E1000_PBA_RXA_MASK) * 1024 -
 		     adapter->max_frame_size) * 8 / 1000;
@@ -3292,9 +3293,6 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
 			 "Some CPU C-states have been disabled in order to "
 			 "enable jumbo frames\n");
 		pm_qos_update_request(&adapter->pm_qos_req, lat);
-	} else {
-		pm_qos_update_request(&adapter->pm_qos_req,
-				      PM_QOS_DEFAULT_VALUE);
 	}
 
 	/* Enable Receives */
@@ -4625,8 +4623,9 @@ int e1000e_open(struct net_device *netdev)
 		e1000_update_mng_vlan(adapter);
 
 	/* DMA latency requirement to workaround jumbo issue */
-	pm_qos_add_request(&adapter->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
-			   PM_QOS_DEFAULT_VALUE);
+	if (adapter->hw.mac.type <= e1000_pch2lan)
+		pm_qos_add_request(&adapter->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
+				   PM_QOS_DEFAULT_VALUE);
 
 	/* before we allocate an interrupt, we must be ready to handle it.
 	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
@@ -4669,7 +4668,8 @@ int e1000e_open(struct net_device *netdev)
 	return 0;
 
 err_req_irq:
-	pm_qos_remove_request(&adapter->pm_qos_req);
+	if (adapter->hw.mac.type <= e1000_pch2lan)
+		pm_qos_remove_request(&adapter->pm_qos_req);
 	e1000e_release_hw_control(adapter);
 	e1000_power_down_phy(adapter);
 	e1000e_free_rx_resources(adapter->rx_ring);
@@ -4733,7 +4733,8 @@ int e1000e_close(struct net_device *netdev)
 	    !test_bit(__E1000_TESTING, &adapter->state))
 		e1000e_release_hw_control(adapter);
 
-	pm_qos_remove_request(&adapter->pm_qos_req);
+	if (adapter->hw.mac.type <= e1000_pch2lan)
+		pm_qos_remove_request(&adapter->pm_qos_req);
 
 	pm_runtime_put_sync(&pdev->dev);
 
Signature · 1 line
2.13.6
#8 lore raw

PATCH 3/3 e1000e: Disable jumbo receive workaround on Lynx Point and newer

Quoted 75 lines · Matt Turner

From: Matt Turner <[email protected]>

Commit 3e35d9918cbb ("e1000e: adjust PM QoS request") expanded the application of what is evidently a hardware workaround to apply to all e1000e devices. Prior to the commit, it applied only to e1000_pch2lan (Sandy Bridge era) and the commit message notes that other earlier parts such as ICH9 and ICH10 suffer from the problem as well.

The workaround works by preventing the CPU from entering deep sleep states, which increases energy consumption significantly. My Skylake CPU reaches the C10 state the PC8 package state with the MTU for its I219-LM set to 1500. At an MTU of 9000, it can only reach the C1E state and no low power package state at all. With this patch, the CPU again reaches the C10 state and (only) the PC2 package state. Not ideal, but an improvement nonetheless.

---
This patch is speculative -- I'm an Intel employee (not in the networking division), but I have no idea where to find documentation about the hardware bug in question. I'm hoping that someone more in the know can check if the hardware was fixed in subsequent generations and this workaround can be disabled. I have chosen the pch2 cut off only because nothing further is mentioned about the bug in git history.

  drivers/net/ethernet/intel/e1000e/netdev.c | 17 +++++++++--------
  1 file changed, 9 insertions(+), 8 deletions(-)
drivers/net/ethernet/intel/e1000e/netdev.c +7 -7
index 4dcff481c4b4..553f8bd45eea 100644
@@ -3277,7 +3277,8 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
  	/* With jumbo frames, excessive C-state transition latencies result
  	 * in dropped transactions.
  	 */
-	if (adapter->netdev->mtu > ETH_DATA_LEN) {
+	if (adapter->hw.mac.type <= e1000_pch2lan &&
+	    adapter->netdev->mtu > ETH_DATA_LEN) {
  		u32 lat =
  		    ((er32(PBA) & E1000_PBA_RXA_MASK) * 1024 -
  		     adapter->max_frame_size) * 8 / 1000;
@@ -3292,9 +3293,6 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
  			 "Some CPU C-states have been disabled in order to "
  			 "enable jumbo frames\n");
  		pm_qos_update_request(&adapter->pm_qos_req, lat);
-	} else {
-		pm_qos_update_request(&adapter->pm_qos_req,
-				      PM_QOS_DEFAULT_VALUE);
  	}
 
  	/* Enable Receives */
@@ -4625,8 +4623,9 @@ int e1000e_open(struct net_device *netdev)
  		e1000_update_mng_vlan(adapter);
 
  	/* DMA latency requirement to workaround jumbo issue */
-	pm_qos_add_request(&adapter->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
-			   PM_QOS_DEFAULT_VALUE);
+	if (adapter->hw.mac.type <= e1000_pch2lan)
+		pm_qos_add_request(&adapter->pm_qos_req, PM_QOS_CPU_DMA_LATENCY,
+				   PM_QOS_DEFAULT_VALUE);
 
  	/* before we allocate an interrupt, we must be ready to handle it.
  	 * Setting DEBUG_SHIRQ in the kernel makes it fire an interrupt
@@ -4669,7 +4668,8 @@ int e1000e_open(struct net_device *netdev)
  	return 0;
 
  err_req_irq:
-	pm_qos_remove_request(&adapter->pm_qos_req);
+	if (adapter->hw.mac.type <= e1000_pch2lan)
+		pm_qos_remove_request(&adapter->pm_qos_req);
  	e1000e_release_hw_control(adapter);
  	e1000_power_down_phy(adapter);
  	e1000e_free_rx_resources(adapter->rx_ring);

drivers/net/ethernet/intel/e1000e/netdev.c int e1000e_close(struct net_device *netdev) · line 4740

Quoted 9 lines
drivers/net/ethernet/intel/e1000e/netdev.c +2 -1
@@ -4733,7 +4733,8 @@ int e1000e_close(struct net_device *netdev)
  	    !test_bit(__E1000_TESTING, &adapter->state))
  		e1000e_release_hw_control(adapter);
 
-	pm_qos_remove_request(&adapter->pm_qos_req);
+	if (adapter->hw.mac.type <= e1000_pch2lan)
+		pm_qos_remove_request(&adapter->pm_qos_req);
 
  	pm_runtime_put_sync(&pdev->dev);
 

This patch should be rejected. The original patch 3e35d9918cbb ("e1000e:
adjust PM QoS request") is from 2013, before Lynx Point and later devices were introduced. However, nothing was changed in this regard in the later devices and same limitation still apply. Enabling deep CPU Cx states with jumbo frame can lead to packet loss, which is worse than extra power consumption. Therefore we suggest to reject this patch. Note that on modern systems, the effect of jumbo frames on performance is negligible, as near-wire speed can be reached with standard MTU size.

#9 lore raw

PATCH 3/3 e1000e: Disable jumbo receive workaround on Lynx Point and newer

Quoted 4 lines · Sasha

This patch should be rejected. The original patch 3e35d9918cbb ("e1000e:
adjust PM QoS request") is from 2013, before Lynx Point and later devices were introduced. However, nothing was changed in this regard in the later devices and same limitation still apply.

Dang, that's unfortunate. Thanks for checking.

#10 lore raw

PATCH 1/3 e1000e: Set HTHRESH when PTHRESH is used

In reply to Matt Turner
Quoted 22 lines · Matt Turner

From: Matt Turner <[email protected]>

According to section 12.0.3.4.13 "Receive Descriptor Control - RXDCTL" of the Intel? 82579 Gigabit Ethernet PHY Datasheet v2.1:

"HTHRESH should be given a non zero value when ever PTHRESH is
used."

In RXDCTL(0), PTHRESH lives at bits 5:0, and HTHREST lives at bits 13:8. Set only bit 8 of HTHREST as is done in e1000_flush_rx_ring(). Found by inspection.

---
  drivers/net/ethernet/intel/e1000e/netdev.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/intel/e1000e/netdev.c +0 -0
index 2dcb5463d9b8..286d0277284e 100644

drivers/net/ethernet/intel/e1000e/netdev.c static void e1000_configure_rx(struct e1000_adapter *adapter) · line 3291

Quoted 8 lines
drivers/net/ethernet/intel/e1000e/netdev.c +1 -1
@@ -3285,7 +3285,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
  		if (adapter->flags & FLAG_IS_ICH) {
  			u32 rxdctl = er32(RXDCTL(0));
 
-			ew32(RXDCTL(0), rxdctl | 0x3);
+			ew32(RXDCTL(0), rxdctl | 0x3 | BIT(8));
  		}
 
  		pm_qos_update_request(&adapter->pm_qos_req, lat);

Ack. Good point.

#11 lore raw

PATCH 1/3 e1000e: Set HTHRESH when PTHRESH is used

In reply to Matt Turner
Quoted 16 lines

From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On Behalf Of Matt Turner
Sent: Tuesday, November 7, 2017 2:14 PM
To: intel-wired-lan at lists.osuosl.org
Cc: Turner, Matt <[email protected]>
Subject: [Intel-wired-lan] [PATCH 1/3] e1000e: Set HTHRESH when PTHRESH is used

From: Matt Turner <[email protected]>

According to section 12.0.3.4.13 "Receive Descriptor Control - RXDCTL" of the Intel? 82579 Gigabit Ethernet PHY Datasheet v2.1:

"HTHRESH should be given a non zero value when ever PTHRESH is
used."

Quoted 8 lines

In RXDCTL(0), PTHRESH lives at bits 5:0, and HTHREST lives at bits 13:8. Set only bit 8 of HTHREST as is done in e1000_flush_rx_ring(). Found by inspection.

---
 drivers/net/ethernet/intel/e1000e/netdev.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)