• Stephane Eranian's avatar
    perf_events: Fix bogus context time tracking · c530ccd9
    Stephane Eranian authored
    You can only call update_context_time() when the context
    is active, i.e., the thread it is attached to is still running.
    
    However, perf_event_read() can be called even when the context
    is inactive, e.g., user read() the counters. The call to
    update_context_time() must be conditioned on the status of
    the context, otherwise, bogus time_enabled, time_running may
    be returned. Here is an example on AMD64. The task program
    is an example from libpfm4. The -p prints deltas every 1s.
    
    $ task -p -e cpu_clk_unhalted sleep 5
        2,266,610 cpu_clk_unhalted (0.00% scaling, ena=2,158,982, run=2,158,982)
    	    0 cpu_clk_unhalted (0.00% scaling, ena=2,158,982, run=2,158,982)
    	    0 cpu_clk_unhalted (0.00% scaling, ena=2,158,982, run=2,158,982)
    	    0 cpu_clk_unhalted (0.00% scaling, ena=2,158,982, run=2,158,982)
    	    0 cpu_clk_unhalted (0.00% scaling, ena=2,158,982, run=2,158,982)
    5,242,358,071 cpu_clk_unhalted (99.95% scaling, ena=5,000,359,984, run=2,319,270)
    
    Whereas if you don't read deltas, e.g., no call to perf_event_read() until
    the process terminates:
    
    $ task -e cpu_clk_unhalted sleep 5
        2,497,783 cpu_clk_unhalted (0.00% scaling, ena=2,376,899, run=2,376,899)
    
    Notice that time_enable, time_running are bogus in the first example
    causing bogus scaling.
    
    This patch fixes the problem, by conditionally calling update_context_time()
    in perf_event_read().
    Signed-off-by: default avatarStephane Eranian <eranian@google.com>
    Signed-off-by: default avatarPeter Zijlstra <a.p.zijlstra@chello.nl>
    Cc: stable@kernel.org
    LKML-Reference: <4cb856dc.51edd80a.5ae0.38fb@mx.google.com>
    Signed-off-by: default avatarIngo Molnar <mingo@elte.hu>
    c530ccd9
perf_event.c 143 KB