diff options
author | Vasant Hegde <hegdevasant@linux.vnet.ibm.com> | 2020-12-17 12:29:29 +0530 |
---|---|---|
committer | Vasant Hegde <hegdevasant@linux.vnet.ibm.com> | 2021-01-06 16:58:10 +0530 |
commit | 2866f9dccdc6a39845d07424800e10b042005615 (patch) | |
tree | fd5c907c121a6e6321d65dcc148d56edd204d57b /hw/sbe-p9.c | |
parent | 7dfd20f37e0f1f0090ef54b0fd5a1bf601baf741 (diff) | |
download | skiboot-2866f9dccdc6a39845d07424800e10b042005615.zip skiboot-2866f9dccdc6a39845d07424800e10b042005615.tar.gz skiboot-2866f9dccdc6a39845d07424800e10b042005615.tar.bz2 |
SBE: Rate limit timer requests
[ Upstream commit 2e654443050acdd4deffdbb44723a847ca11e6b2 ]
We schedule timer and wait for `timer expiry` interrupt from SBE.
If we get new timer request which is lesser than inflight timer
expiry value we can update timer (essentially sending new timer chip-op
and SBE takes care of stoping inflight timer and scheduling new one).
SBE runs at much slower speed than host CPU. If we do continuous timer
update like below then SBE will be busy with handling PSU side timer
message and will not get time to handle FIFO side requests.
send timer chip-op -> Got ACK -> send timer chip-op
Hence this patch limits number of continuous timer update and we will
restart sending timer request as soon as we get timer expiry interrupt.
Rate limit value (2) is suggested by SBE team.
With this patch:
If our timer requests are : 2ms, 1500us, 1000us and 800us
(and requests are coming after sending each message)
We will schedule timer for 2ms and then update timer for 1500us and 1000us
(These update happens after getting ACK interrupt from SBE)
We will not send 800us request.
At 1000us we get `timer expiry` and we are good to send next timer requests
(At this stage both 1000us and 800us timeout happens. We will schedule
next timer request with timeout value 500us (1500-1000)).
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
Diffstat (limited to 'hw/sbe-p9.c')
-rw-r--r-- | hw/sbe-p9.c | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/hw/sbe-p9.c b/hw/sbe-p9.c index 75dc37a..63ff3cc 100644 --- a/hw/sbe-p9.c +++ b/hw/sbe-p9.c @@ -91,6 +91,14 @@ static struct lock sbe_timer_lock; #define SBE_TIMER_DEFAULT_US 500 static uint64_t sbe_timer_def_tb; +/* + * Rate limit continuous timer update. + * 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 +static uint32_t timer_update_cnt = 0; + /* Timer control message */ static struct p9_sbe_msg *timer_ctrl_msg; @@ -530,6 +538,15 @@ static void p9_sbe_timer_response(struct p9_sbe *sbe) sbe_timer_in_progress = false; /* Drop lock and call timers */ unlock(&sbe->lock); + + lock(&sbe_timer_lock); + /* + * Once we get timer expiry interrupt (even if its suprious interrupt) + * we can schedule next timer request. + */ + timer_update_cnt = 0; + unlock(&sbe_timer_lock); + check_timers(true); lock(&sbe->lock); } @@ -791,6 +808,11 @@ static void p9_sbe_timer_schedule(void) 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) { /* Calculate how many microseconds from now, rounded up */ if ((sbe_timer_target - now) > sbe_timer_def_tb) { |