Commit 37b12910 authored by Raanan Avargil's avatar Raanan Avargil Committed by Jeff Kirsher

e1000e: Fix tight loop implementation of systime read algorithm

Change the algorithm. Read systimel twice and check for overflow.
If there was no overflow, use the first value.
If there was an overflow, read systimeh again and use the second
systimel value.
Signed-off-by: default avatarRaanan Avargil <raanan.avargil@intel.com>
Tested-by: default avatarAaron Brown <aaron.f.brown@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 2758f9ed
......@@ -4280,18 +4280,29 @@ static cycle_t e1000e_cyclecounter_read(const struct cyclecounter *cc)
struct e1000_adapter *adapter = container_of(cc, struct e1000_adapter,
cc);
struct e1000_hw *hw = &adapter->hw;
u32 systimel_1, systimel_2, systimeh;
cycle_t systim, systim_next;
/* SYSTIMH latching upon SYSTIML read does not work well. To fix that
* we don't want to allow overflow of SYSTIML and a change to SYSTIMH
* to occur between reads, so if we read a vale close to overflow, we
* wait for overflow to occur and read both registers when its safe.
/* SYSTIMH latching upon SYSTIML read does not work well.
* This means that if SYSTIML overflows after we read it but before
* we read SYSTIMH, the value of SYSTIMH has been incremented and we
* will experience a huge non linear increment in the systime value
* to fix that we test for overflow and if true, we re-read systime.
*/
systimel_1 = er32(SYSTIML);
systimeh = er32(SYSTIMH);
systimel_2 = er32(SYSTIML);
/* Check for overflow. If there was no overflow, use the values */
if (systimel_1 < systimel_2) {
systim = (cycle_t)systimel_1;
systim |= (cycle_t)systimeh << 32;
} else {
/* There was an overflow, read again SYSTIMH, and use
* systimel_2
*/
u32 systim_overflow_latch_fix = 0x3FFFFFFF;
do {
systim = (cycle_t)er32(SYSTIML);
} while (systim > systim_overflow_latch_fix);
systim |= (cycle_t)er32(SYSTIMH) << 32;
systimeh = er32(SYSTIMH);
systim = (cycle_t)systimel_2;
systim |= (cycle_t)systimeh << 32;
}
if ((hw->mac.type == e1000_82574) || (hw->mac.type == e1000_82583)) {
u64 incvalue, time_delta, rem, temp;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment