Message ID | c7c8ebcd9ed88bb09d76059c745a1fafb48314e7.1427959032.git.viresh.kumar@linaro.org |
---|---|
State | New |
Headers | show |
On 2 April 2015 at 19:17, Peter Zijlstra <peterz@infradead.org> wrote: > On Thu, Apr 02, 2015 at 04:21:21PM +0530, Viresh Kumar wrote: >> 'active_bases' indicates which clock-base have active timers. While it >> is updated (almost) correctly, it is hardly used. Next commit will start >> using it to make code more efficient, but before that we need to fix a >> problem. >> >> While removing hrtimers, in __remove_hrtimer(): >> - We first remove the hrtimer from the queue. >> - Then reprogram clockevent device if required >> (hrtimer_force_reprogram()). >> - And then finally clear 'active_bases', if no more timers are pending >> on the current clock base (from which we are removing the hrtimer). >> >> hrtimer_force_reprogram() needs to loop over all active clock bases to >> find the next expiry event, and while doing so it will use >> 'active_bases' (after next commit). And it will find the current base >> active, as we haven't cleared it until now, even if current clock base >> has no more hrtimers queued. >> >> To fix this issue, clear active_bases before calling >> hrtimer_force_reprogram(). > > This is a small inefficiency right? Not an actual bug or anything. So, what's explained in this patch is a BUG, which isn't harming us today. But overall both patches combined are about improving on the small inefficiency :) Sorry for the political answer :) -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
On 2 April 2015 at 19:46, Peter Zijlstra <peterz@infradead.org> wrote: > So then I'm not seeing how its a bug. Sure __hrtimer_get_next_event() > will iterate all the bases again, and it will not skip the just empty > one. But I don't see how that is anything but an inefficiency. By virtue > of the base being empty it cannot find an event there, so its a > pointless check. > > What am I missing? Hmm. It was a bug for me because I was doing this unconditionally: timer = container_of(timerqueue_getnext(&base->active), + struct hrtimer, node); And this will give a container-of over NULL, as timerqueue_getnext() can return NULL.. And so it will crash in my case. But I understand your point, its inefficiency only :( -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
diff --git a/kernel/time/hrtimer.c b/kernel/time/hrtimer.c index bee0c1f78091..3152f327c988 100644 --- a/kernel/time/hrtimer.c +++ b/kernel/time/hrtimer.c @@ -879,6 +879,9 @@ static void __remove_hrtimer(struct hrtimer *timer, next_timer = timerqueue_getnext(&base->active); timerqueue_del(&base->active, &timer->node); + if (!timerqueue_getnext(&base->active)) + base->cpu_base->active_bases &= ~(1 << base->index); + if (&timer->node == next_timer) { #ifdef CONFIG_HIGH_RES_TIMERS /* Reprogram the clock event device. if enabled */ @@ -892,8 +895,6 @@ static void __remove_hrtimer(struct hrtimer *timer, } #endif } - if (!timerqueue_getnext(&base->active)) - base->cpu_base->active_bases &= ~(1 << base->index); out: timer->state = newstate; }