• Peter Zijlstra's avatar
    sched,perf: Fix periodic timers · 4cfafd30
    Peter Zijlstra authored
    In the below two commits (see Fixes) we have periodic timers that can
    stop themselves when they're no longer required, but need to be
    (re)-started when their idle condition changes.
    
    Further complications is that we want the timer handler to always do
    the forward such that it will always correctly deal with the overruns,
    and we do not want to race such that the handler has already decided
    to stop, but the (external) restart sees the timer still active and we
    end up with a 'lost' timer.
    
    The problem with the current code is that the re-start can come before
    the callback does the forward, at which point the forward from the
    callback will WARN about forwarding an enqueued timer.
    
    Now, conceptually its easy to detect if you're before or after the fwd
    by comparing the expiration time against the current time. Of course,
    that's expensive (and racy) because we don't have the current time.
    
    Alternatively one could cache this state inside the timer, but then
    everybody pays the overhead of maintaining this extra state, and that
    is undesired.
    
    The only other option that I could see is the external timer_active
    variable, which I tried to kill before. I would love a nicer interface
    for this seemingly simple 'problem' but alas.
    
    Fixes: 272325c4 ("perf: Fix mux_interval hrtimer wreckage")
    Fixes: 77a4d1a1 ("sched: Cleanup bandwidth timers")
    Cc: pjt@google.com
    Cc: tglx@linutronix.de
    Cc: klamm@yandex-team.ru
    Cc: mingo@kernel.org
    Cc: bsegall@google.com
    Cc: hpa@zytor.com
    Cc: Sasha Levin <sasha.levin@oracle.com>
    Signed-off-by: default avatarPeter Zijlstra (Intel) <peterz@infradead.org>
    Link: http://lkml.kernel.org/r/20150514102311.GX21418@twins.programming.kicks-ass.net
    4cfafd30
fair.c 215 KB