[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20241203202814.56140-1-gerhard@engleder-embedded.com>
Date: Tue, 3 Dec 2024 21:28:14 +0100
From: Gerhard Engleder <gerhard@...leder-embedded.com>
To: netdev@...r.kernel.org
Cc: anthony.l.nguyen@...el.com,
przemyslaw.kitszel@...el.com,
andrew+netdev@...n.ch,
davem@...emloft.net,
kuba@...nel.org,
edumazet@...gle.com,
pabeni@...hat.com,
Gerhard Engleder <eg@...a.com>
Subject: [PATCH net-next] e1000e: Fix real-time violations on link up
From: Gerhard Engleder <eg@...a.com>
From: Gerhard Engleder <eg@...a.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.
A flush after a low enough number of 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. As this also increases the time spent for
MTA table update considerable this change is limited to PREEMPT_RT.
Signed-off-by: Gerhard Engleder <eg@...a.com>
---
drivers/net/ethernet/intel/e1000e/mac.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/e1000e/mac.c b/drivers/net/ethernet/intel/e1000e/mac.c
index d7df2a0ed629..7a2c10a4ecc5 100644
--- a/drivers/net/ethernet/intel/e1000e/mac.c
+++ b/drivers/net/ethernet/intel/e1000e/mac.c
@@ -331,8 +331,14 @@ void e1000e_update_mc_addr_list_generic(struct e1000_hw *hw,
}
/* replace the entire MTA table */
- for (i = hw->mac.mta_reg_count - 1; i >= 0; i--)
+ for (i = hw->mac.mta_reg_count - 1; i >= 0; i--) {
E1000_WRITE_REG_ARRAY(hw, E1000_MTA, i, hw->mac.mta_shadow[i]);
+ if (IS_ENABLED(CONFIG_PREEMPT_RT)) {
+ /* do not queue up too many writes */
+ if ((i % 8) == 0 && i != 0)
+ e1e_flush();
+ }
+ }
e1e_flush();
}
--
2.39.2
Powered by blists - more mailing lists