• Chris Phlipot's avatar
    perf callchain: Fix incorrect ordering of entries · 9919a65e
    Chris Phlipot authored
    The existing implementation of thread__resolve_callchain, under certain
    circumstances, can assemble callchain entries in the incorrect order.
    
    The callchain entries are resolved incorrectly for a sample when all of
    the following conditions are met:
    
    1. callchain_param.order is set to ORDER_CALLER
    
    2. thread__resolve_callchain_sample is able to resolve callchain entries
       for the sample.
    
    3. unwind__get_entries is also able to resolve callchain entries for the
       sample.
    
    The fix is accomplished by reversing the order in which
    thread__resolve_callchain_sample and unwind__get_entries are called when
    callchain_param.order is set to ORDER_CALLER.
    
    Unwind specific code from thread__resolve_callchain is also moved into a
    new static function to improve readability of the fix.
    
    How to Reproduce the Existing Bug:
    
    Modifying perf script to print call trees in the opposite order or
    applying the remaining patches from this series and comparing the
    results output from export-to-postgtresql.py are the easiest ways to see
    the bug, however it can still be seen in current builds using perf
    report.
    
    Here is how i can reproduce the bug using perf report:
    
      # perf record --call-graph=dwarf stress -c 1 -t 5
    
    when i run this command:
    
      # perf report --call-graph=flat,0,0,callee
    
    This callchain, containing kernel (handle_irq_event, etc) and userspace
    samples (__libc_start_main, etc) is contained in the output, which looks
    correct (callee order):
    
                    gen8_irq_handler
                    handle_irq_event_percpu
                    handle_irq_event
                    handle_edge_irq
                    handle_irq
                    do_IRQ
                    ret_from_intr
                    __random
                    rand
                    0x558f2a04dded
                    0x558f2a04c774
                    __libc_start_main
                    0x558f2a04dcd9
    
    Now run this command using caller order:
    
      # perf report --call-graph=flat,0,0,caller
    
    It is expected to see the exact reverse of the above when using caller
    order (with "0x558f2a04dcd9" at the top and "gen8_irq_handler" at the
    bottom) in the output, but it is nowhere to be found.
    
    instead you see this:
    
                    ret_from_intr
                    do_IRQ
                    handle_irq
                    handle_edge_irq
                    handle_irq_event
                    handle_irq_event_percpu
                    gen8_irq_handler
                    0x558f2a04dcd9
                    __libc_start_main
                    0x558f2a04c774
                    0x558f2a04dded
                    rand
                    __random
    
    Notice how internally the kernel symbols are reversed and the user space
    symbols are reversed, but the kernel symbols still appear above the user
    space symbols.
    
    if this patch is applied and perf script is re-run, you will see the
    expected output (with "0x558f2a04dcd9" at the top and "gen8_irq_handler"
    at the bottom):
    
                    0x558f2a04dcd9
                    __libc_start_main
                    0x558f2a04c774
                    0x558f2a04dded
                    rand
                    __random
                    ret_from_intr
                    do_IRQ
                    handle_irq
                    handle_edge_irq
                    handle_irq_event
                    handle_irq_event_percpu
                    gen8_irq_handler
    Signed-off-by: default avatarChris Phlipot <cphlipot0@gmail.com>
    Tested-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
    Acked-by: default avatarJiri Olsa <jolsa@kernel.org>
    Cc: Adrian Hunter <adrian.hunter@intel.com>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Link: http://lkml.kernel.org/r/1461831551-12213-2-git-send-email-cphlipot0@gmail.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
    9919a65e
machine.c 51.1 KB