Re: [PATCHv3 linux-next] hrtimer: Add notifier when clock_was_setwas called

From: Thomas Gleixner
Date: Thu Sep 12 2013 - 15:38:00 EST


On Thu, 12 Sep 2013, David Miller wrote:
> From: Thomas Gleixner <tglx@xxxxxxxxxxxxx>
> Date: Thu, 12 Sep 2013 16:43:37 +0200 (CEST)
>
> > So what about going back to timer_list timers and simply utilize
> > register_pm_notifier(), which will tell you that the system resumed?
>
> The thing to understand is that there are two timeouts for an IPSEC
> rule, a soft and a hard timeout.
>
> There is a gap between these two exactly so that we can negotiate a
> new encapsulation with the IPSEC gateway before communication ceases
> to be possible over the IPSEC protected path.
>
> So the idea is that the soft timeout triggers the re-negotiation,
> and after a hard timeout the IPSEC path is no longer usable and
> all communication will fail.
>
> Simply triggering a re-negoation after every suspend/resume makes
> no sense at all. Spurious re-negotiations are undesirable.
>
> What we want are real timers. We want that rather than a "we
> suspended so just assume all timers expired" event which is not very
> useful for this kind of application.

Your argumentation makes no sense at all. Where is the difference
between the "real timer" plus a clock was set notification and a timer
list timer and a resume notification?

In both cases you need to walk through the timers and reevaluate
them. Just in the clock was set notification case you need to deal
with NTP/settimeofday/PPS and whatever cases which are completely
irrelevant to the life time management.

So what's wrong with:

now = get_seconds();
x->timeout = now + x->soft_timeout;
x->timeout_active = SOFT;
start_timer(x->timer, jiffies + sec_to_jiffies(x->soft_timeout));

In the timer handler:

switch (x->timeout_active) {
case SOFT:
trigger_renegotiation();
hts = x->hard_timeout - x->soft_timeout;
x->timeout += hts;
x->timeout_active = HARD;
start_timer(x->timer, jiffies + sec_to_jiffies(hts));
break;
case HARD:
stop_connection();
break:
}

If the negotiation succeeds:

now = get_seconds();
x->t_timeout = now + x->soft_timeout;
x->timeout_active = SOFT;
mod_timer(x->timer, jiffies + sec_to_jiffies(x->soft_timeout));

Now in the resume notification you walk the active timers and do for
each timer:

now = get_seconds();

switch (x->timeout_active) {
case SOFT:
if (now >= x->timeout) {
hts = x->hard_timeout - x->soft_timeout;
x->timeout += hts;
if (now >= x->timeout) {
del_timer(x->timeout);
stop_connection();
break:
}
trigger_renegotiation();
x->timeout_active = HARD;
mod_timer(x->timer, jiffies + sec_to_jiffies(hts));
break;
}
delta = x->timeout - now;
mod_timer(x->timer, jiffies + sec_to_jiffies(delta));
break;

case HARD:
if (now >= x->timeout) {
del_timer(x->timeout);
stop_connection();
}
delta = x->timeout - now;
mod_timer(x->timer, jiffies + sec_to_jiffies(delta));
break;
}

That's what you have to do with a clock was set notification as
well. And what's worse is that you need to figure out whether the
clock change was due to a suspend/resume cycle or just because
NTP/settimeofday/PPS or whatever decided to fiddle with the wall
time. And you need to do that to avoid the spurious renegotiations
which you are afraid of.


Thanks,

tglx

--
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/