Re: [PATCH v2 0/3] Deferrable timers support for timerfd API

From: Alexey Perevalov
Date: Tue Feb 18 2014 - 14:48:45 EST


On 02/16/2014 07:39 PM, Thomas Gleixner wrote:
On Sun, 16 Feb 2014, Alexey Perevalov wrote:
As I understand main idea in hrtimer.c was do not decrement expires_next in
case of DEFERRABLE timers type.
Such small average delay could be explained: it's due higher resolution, and
cpu is not in idle when we in hrtimer_interrupt,
with timer_list decrementing process not so often.
In this case it's hard to me to explain such small "time delta", it occurs
almost every time we have larger delay.
Well, the point of deferrable timers is that they get executed, when
the cpu is not idle, i.e. running some other timers as well

I did not test my patch and I have no idea whether it really does what
it should do, but tracing should tell you rather fast.

So w/o instrumenting the kernel you can't tell why a timer is
expired. Just looking at random numbers does not help. You need to
create a proper test scenario which makes sure that the system goes
into an extended nohz idle and then check whether the timers are
deferred over that idle time.

Thanks,

tglx




Dear Thomas,

I figured out with deviation, I described before.

It was due expires and especially softexpires is fixed (don't base on delay).

For example if we have a timer like this:
hrtimer_expire_entry: hrtimer=ffffffffa056f280 function=timerfd_tmrproc [hrtimers_mod] now=191450988244 expires=191400000000 softexpires=191400000000
It was fired at 191450988244, but softexpire is 191400000000, 50ms delay, if I'm not wrong.
Next trigger time is 191700000000, (hrtimer_start: hrtimer=ffffffffa056f280 function=timerfd_tmrproc [hrtimers_mod] expires=191700000000 softexpires=191700000000)
and if there is no cpu idle at next time, we'll get 250ms interval for such timer. But we want 300ms or more for DEFERRABLE timer.

Thomas what do you think about moving format expire/softexpire to _!now!_ in run_hrtimer, right before we
invoke callback function? The prolongation of hrtimer usually comes from user timer functions by
invoking hrtimer_forward, which moves expires/softexpires forward.


+static void __run_hrtimer(struct hrtimer *timer, ktime_t *now, int deferrable)
{
struct hrtimer_clock_base *base = timer->base;
struct hrtimer_cpu_base *cpu_base = base->cpu_base;
@@ -1286,8 +1286,13 @@ static void __run_hrtimer(struct hrtimer *timer, ktime_t *now)
* the timer base.
*/
raw_spin_unlock(&cpu_base->lock);
- trace_hrtimer_expire_entry(timer, now);
+ trace_hrtimer_expire_entry(timer, now, 0);
+
+ if (deferrable)
+ hrtimer_set_expires(timer, *now);
restart = fn(timer);


I got expected results (timer interval is 300ms):
[ 247.251609] time delta 315563612
[ 247.652398] time delta 400788785
[ 248.000169] time delta 347764697
[ 248.372070] time delta 371900444
[ 248.800175] time delta 428105238
[ 249.144178] time delta 344002733
[ 249.455920] time delta 311748775
[ 249.804166] time delta 348245676
[ 250.136165] time delta 331999061
[ 250.458606] time delta 322441758
[ 250.804184] time delta 345571829

Also I tried move just _softexpire, but timer function in this case wasn't called at all.


--
Best regards,
Alexey Perevalov
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/