• Paul Mackerras's avatar
    perf_counter: Don't swap contexts containing locked mutex · ad3a37de
    Paul Mackerras authored
    Peter Zijlstra pointed out that under some circumstances, we can take
    the mutex in a context or a counter and then swap that context or
    counter to another task, potentially leading to lock order inversions
    or the mutexes not protecting what they are supposed to protect.
    
    This fixes the problem by making sure that we never take a mutex in a
    context or counter which could get swapped to another task.  Most of
    the cases where we take a mutex is on a top-level counter or context,
    i.e. a counter which has an fd associated with it or a context that
    contains such a counter.  This adds WARN_ON_ONCE statements to verify
    that.
    
    The two cases where we need to take the mutex on a context that is a
    clone of another are in perf_counter_exit_task and
    perf_counter_init_task.  The perf_counter_exit_task case is solved by
    uncloning the context before starting to remove the counters from it.
    The perf_counter_init_task is a little trickier; we temporarily
    disable context swapping for the parent (forking) task by setting its
    ctx->parent_gen to the all-1s value after locking the context, if it
    is a cloned context, and restore the ctx->parent_gen value at the end
    if the context didn't get uncloned in the meantime.
    
    This also moves the increment of the context generation count to be
    within the same critical section, protected by the context mutex, that
    adds the new counter to the context.  That way, taking the mutex is
    sufficient to ensure that both the counter list and the generation
    count are stable.
    
    [ Impact: fix hangs, races with inherited and PID counters ]
    Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
    Acked-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
    LKML-Reference: <18975.31580.520676.619896@drongo.ozlabs.ibm.com>
    Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
    ad3a37de
perf_counter.c 92.2 KB