Skip to content

Commit 226a85a

Browse files
committed
e1000e: Fix real-time violations on link up
Author: Gerhard Engleder <eg@keba.com> Link down and up triggers update of MTA table. This update executes many PCIe writes and a final flush. Thus, PCIe will be blocked until all writes are flushed. As a result, DMA transfers of other targets suffer from delay in the range of 50us. This results in timing violations on real-time systems during link down and up of e1000e in combination with an Intel i3-2310E Sandy Bridge CPU. The i3-2310E is quite old. Launched 2011 by Intel but still in use as robot controller. The exact root cause of the problem is unclear and this situation won't change as Intel support for this CPU has ended years ago. Our experience is that the number of posted PCIe writes needs to be limited at least for real-time systems. With posted PCIe writes a much higher throughput can be generated than with PCIe reads which cannot be posted. Thus, the load on the interconnect is much higher. Additionally, a PCIe read waits until all posted PCIe writes are done. Therefore, the PCIe read can block the CPU for much more than 10us if a lot of PCIe writes were posted before. Both issues are the reason why we are limiting the number of posted PCIe writes in row in general for our real-time systems, not only for this driver. A flush after a low enough number of posted PCIe writes eliminates the delay but also increases the time needed for MTA table update. The following measurements were done on i3-2310E with e1000e for 128 MTA table entries: Single flush after all writes: 106us Flush after every write: 429us Flush after every 2nd write: 266us Flush after every 4th write: 180us Flush after every 8th write: 141us Flush after every 16th write: 121us A flush after every 8th write delays the link up by 35us and the negative impact to DMA transfers of other targets is still tolerable. Execute a flush after every 8th write. This prevents overloading the interconnect with posted writes. Signed-off-by: Gerhard Engleder <eg@keba.com> Link: https://lore.kernel.org/netdev/f8fe665a-5e6c-4f95-b47a-2f3281aa0e6c@lunn.ch/T/ CC: Vitaly Lifshits <vitaly.lifshits@intel.com> Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com> Tested-by: Avigail Dahan <avigailx.dahan@intel.com> Reviewed-by: Vitaly Lifshits <vitaly.lifshits@intel.com> Reviewed-by: Simon Horman <horms@kernel.org> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> (cherry picked from commit 13e2297) JIRA: https://issues.redhat.com/browse/RHEL-99399 Signed-off-by: Corinna Vinschen <vinschen@redhat.com>
1 parent f8cde5a commit 226a85a

File tree

1 file changed

+14
-1
lines changed
  • drivers/net/ethernet/intel/e1000e

1 file changed

+14
-1
lines changed

drivers/net/ethernet/intel/e1000e/mac.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -331,8 +331,21 @@ void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
331331
}
332332

333333
/* replace the entire MTA table */
334-
for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
334+
for (i = hw->mac.mta_reg_count - 1; i >= 0; i--) {
335335
E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]);
336+
337+
if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
338+
/*
339+
* Do not queue up too many posted writes to prevent
340+
* increased latency for other devices on the
341+
* interconnect. Flush after each 8th posted write,
342+
* to keep additional execution time low while still
343+
* preventing increased latency.
344+
*/
345+
if (!(i % 8) && i)
346+
e1e_flush();
347+
}
348+
}
336349
e1e_flush();
337350
}
338351

0 commit comments

Comments
 (0)