On Thu, 12 Sep 2013, David Miller wrote:
> From: Thomas Gleixner <t...@linutronix.de>
> 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 majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to