hw/sbe-p9: Better handle SBE timer rate-limiting
SBE timer messages are rate-limited so as not to flood the SBE. 2 timer
updates are permitted before the next timer interrupt. The problem with
this is that any subsequent sooner timers will not reprogram the
interrupt earlier so will be arbitrarily delayed.
Change this code to allow 3 updates, and have the 3rd update program
the SBE to the minimum expiry time, which gives rate-limiting without
compromising timer accuracy.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: Reza Arbab <arbab@linux.ibm.com>
diff --git a/hw/sbe-p9.c b/hw/sbe-p9.c
index ec2ad3d..bc9a635 100644
--- a/hw/sbe-p9.c
+++ b/hw/sbe-p9.c
@@ -96,7 +96,7 @@
* We can update inflight timer if new timer request is lesser than inflight
* one. Limit such updates so that SBE gets time to handle FIFO side requests.
*/
-#define SBE_TIMER_UPDATE_MAX 2
+#define SBE_TIMER_UPDATE_MAX 3
static uint32_t timer_update_cnt = 0;
/* Timer control message */
@@ -805,6 +805,10 @@
u32 tick_us = SBE_TIMER_DEFAULT_US;
u64 tb_cnt, now = mftb();
+ /* Stop sending timer update chipop until inflight timer expires */
+ if (timer_update_cnt == SBE_TIMER_UPDATE_MAX)
+ return;
+
if (sbe_timer_in_progress) {
if (sbe_timer_target >= sbe_last_gen_stamp)
return;
@@ -817,12 +821,8 @@
return;
}
- /* Stop sending timer update chipop until inflight timer expires */
- if (timer_update_cnt > SBE_TIMER_UPDATE_MAX)
- return;
timer_update_cnt++;
-
- if (now < sbe_timer_target) {
+ if (timer_update_cnt < SBE_TIMER_UPDATE_MAX && now < sbe_timer_target) {
/* Calculate how many microseconds from now, rounded up */
if ((sbe_timer_target - now) > sbe_timer_def_tb) {
tb_cnt = sbe_timer_target - now + usecs_to_tb(1) - 1;