[Skiboot] [PATCH 2/2] timer: Reschedule timer if OPAL receives early timer interrupt
Vasant Hegde
hegdevasant at linux.vnet.ibm.com
Fri May 4 21:07:39 AEST 2018
On 05/04/2018 02:33 AM, Benjamin Herrenschmidt wrote:
> On Thu, 2018-05-03 at 18:51 +0530, Vasant Hegde wrote:
>> If we receive timer interrupt before timer expiry, we are not rescheduling
>> timer again. Lets fix this by rescheduling timer.
>
> Doesn't that mean we'll reschedule every time we call check timer in a
> loop ?
update_timer_expiry() compares with previously scheduled timer value. I thought
that's enough.
> I'd be keen on only doing that from an actual timer interrupt
Ok. I can add that check.
> and only if we haven't already rescheduled (we could cache the
> scheduled time, and clear it on interrupt entry, so we reschedule at
> most once per interrupt).
Sorry. I don't understand why we should cache schedule time.
- I will add check to make sure we reschedule only in interrupt path.
- So we will be rescheduling only when we get early response from SBE.
And once we reschedule we will not enter this path until we get next
interrupt from SBE.
something like below works ?
commit dbf2f5e2fa465433b0ee54162d69179bd1148032
Author: Vasant Hegde <hegdevasant at linux.vnet.ibm.com>
Date: Thu Apr 19 11:32:01 2018 +0530
timer: Reschedule timer if OPAL receives early timer interrupt
If we receive timer interrupt before timer expiry, we are not rescheduling
timer again. Lets fix this by rescheduling timer.
Suggested-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
Signed-off-by: Vasant Hegde <hegdevasant at linux.vnet.ibm.com>
diff --git a/core/timer.c b/core/timer.c
index 1c5395178..d7f9dae00 100644
--- a/core/timer.c
+++ b/core/timer.c
@@ -196,17 +196,23 @@ static void __check_poll_timers(uint64_t now)
timer_in_poll = false;
}
-static void __check_timers(uint64_t now)
+static void __check_timers(bool from_interrupt, uint64_t now)
{
struct timer *t;
for (;;) {
t = list_top(&timer_list, struct timer, link);
- /* Top of list not expired ? that's it ... */
- if (!t || t->target > now)
+ if (!t)
break;
+ /* Top of list not expired ? re-schedule timer */
+ if (t->target > now) {
+ if (from_interrupt)
+ update_timer_expiry(t->target);
+ break;
+ }
+
/* Top of list still running, we have to delay handling
* it. For now just skip until the next poll, when we have
* SLW interrupts, we'll probably want to trip another one
@@ -252,7 +258,7 @@ void check_timers(bool from_interrupt)
lock(&timer_lock);
if (!from_interrupt)
__check_poll_timers(now);
- __check_timers(now);
+ __check_timers(from_interrupt, now);
unlock(&timer_lock);
}
-Vasant
More information about the Skiboot
mailing list