提交 8d317b0a 编写于 作者: M Miroslav Lichvar 提交者: Greg Kroah-Hartman

mlx5: update timecounter at least twice per counter overflow

[ Upstream commit 5d8678365c90b9ce1fd2243ff5ea562609f6cec1 ]

The timecounter needs to be updated at least once in half of the
cyclecounter interval to prevent timecounter_cyc2time() interpreting a
new timestamp as an old value and causing a backward jump.

This would be an issue if the timecounter multiplier was so small that
the update interval would not be limited by the 64-bit overflow in
multiplication.

Shorten the calculated interval to make sure the timecounter is updated
in time even when the system clock is slowed down by up to 10%, the
multiplier is increased by up to 10%, and the scheduled overflow check
is late by 15%.

Cc: Richard Cochran <richardcochran@gmail.com>
Cc: Ariel Levkovich <lariel@mellanox.com>
Cc: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: NMiroslav Lichvar <mlichvar@redhat.com>
Signed-off-by: NSaeed Mahameed <saeedm@mellanox.com>
Signed-off-by: NSasha Levin <sashal@kernel.org>
上级 49f182e6
...@@ -511,14 +511,14 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev) ...@@ -511,14 +511,14 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev)
ktime_to_ns(ktime_get_real())); ktime_to_ns(ktime_get_real()));
/* Calculate period in seconds to call the overflow watchdog - to make /* Calculate period in seconds to call the overflow watchdog - to make
* sure counter is checked at least once every wrap around. * sure counter is checked at least twice every wrap around.
* The period is calculated as the minimum between max HW cycles count * The period is calculated as the minimum between max HW cycles count
* (The clock source mask) and max amount of cycles that can be * (The clock source mask) and max amount of cycles that can be
* multiplied by clock multiplier where the result doesn't exceed * multiplied by clock multiplier where the result doesn't exceed
* 64bits. * 64bits.
*/ */
overflow_cycles = div64_u64(~0ULL >> 1, clock->cycles.mult); overflow_cycles = div64_u64(~0ULL >> 1, clock->cycles.mult);
overflow_cycles = min(overflow_cycles, clock->cycles.mask >> 1); overflow_cycles = min(overflow_cycles, div_u64(clock->cycles.mask, 3));
ns = cyclecounter_cyc2ns(&clock->cycles, overflow_cycles, ns = cyclecounter_cyc2ns(&clock->cycles, overflow_cycles,
frac, &frac); frac, &frac);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册