• Peter Zijlstra's avatar
    cputimer: Cure lock inversion · bcd5cff7
    Peter Zijlstra authored
    There's a lock inversion between the cputimer->lock and rq->lock;
    notably the two callchains involved are:
    
     update_rlimit_cpu()
       sighand->siglock
       set_process_cpu_timer()
         cpu_timer_sample_group()
           thread_group_cputimer()
             cputimer->lock
             thread_group_cputime()
               task_sched_runtime()
                 ->pi_lock
                 rq->lock
    
     scheduler_tick()
       rq->lock
       task_tick_fair()
         update_curr()
           account_group_exec()
             cputimer->lock
    
    Where the first one is enabling a CLOCK_PROCESS_CPUTIME_ID timer, and
    the second one is keeping up-to-date.
    
    This problem was introduced by e8abccb7 ("posix-cpu-timers: Cure
    SMP accounting oddities").
    
    Cure the problem by removing the cputimer->lock and rq->lock nesting,
    this leaves concurrent enablers doing duplicate work, but the time
    wasted should be on the same order otherwise wasted spinning on the
    lock and the greater-than assignment filter should ensure we preserve
    monotonicity.
    Reported-by: default avatarDave Jones <davej@redhat.com>
    Reported-by: default avatarSimon Kirby <sim@hostway.ca>
    Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
    Cc: stable@kernel.org
    Cc: Linus Torvalds <torvalds@linux-foundation.org>
    Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
    Link: http://lkml.kernel.org/r/1318928713.21167.4.camel@twinsSigned-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
    bcd5cff7
posix-cpu-timers.c 42.5 KB