• Frederic Weisbecker's avatar
    x86: Fixup wrong irq frame link in stacktraces · af2d8289
    Frederic Weisbecker authored
    When we enter in irq, two things can happen to preserve the link
    to the previous frame pointer:
    
    - If we were in an irq already, we don't switch to the irq stack
      as we are inside. We just need to save the previous frame
      pointer and to link the new one to the previous.
    
    - Otherwise we need another level of indirection. We enter the irq with
      the previous stack. We save the previous bp inside and make bp
      pointing to its saved address. Then we switch to the irq stack and
      push bp another time but to the new stack. This makes two levels to
      dereference instead of one.
    
    In the second case, the current stacktrace code omits the second level
    and loses the frame pointer accuracy. The stack that follows will then
    be considered as unreliable.
    
    Handling that makes the perf callchain happier.
    Before:
    
    43.94%  [k] _raw_read_lock
                |
                --- _read_lock
                   |
                   |--60.53%-- send_sigio
                   |          __kill_fasync
                   |          kill_fasync
                   |          evdev_pass_event
                   |          evdev_event
                   |          input_pass_event
                   |          input_handle_event
                   |          input_event
                   |          synaptics_process_byte
                   |          psmouse_handle_byte
                   |          psmouse_interrupt
                   |          serio_interrupt
                   |          i8042_interrupt
                   |          handle_IRQ_event
                   |          handle_edge_irq
                   |          handle_irq
                   |          __irqentry_text_start
                   |          ret_from_intr
                   |          |
                   |          |--30.43%-- __select
                   |          |
                   |          |--17.39%-- 0x454f15
                   |          |
                   |          |--13.04%-- __read
                   |          |
                   |          |--13.04%-- vread_hpet
                   |          |
                   |          |--13.04%-- _xcb_lock_io
                   |          |
                   |           --13.04%-- 0x7f630878ce8
    
    After:
    
        50.00%  [k] _raw_read_lock
                |
                --- _read_lock
                   |
                   |--98.97%-- send_sigio
                   |          __kill_fasync
                   |          kill_fasync
                   |          evdev_pass_event
                   |          evdev_event
                   |          input_pass_event
                   |          input_handle_event
                   |          input_event
                   |          |
                   |          |--96.88%-- synaptics_process_byte
                   |          |          psmouse_handle_byte
                   |          |          psmouse_interrupt
                   |          |          serio_interrupt
                   |          |          i8042_interrupt
                   |          |          handle_IRQ_event
                   |          |          handle_edge_irq
                   |          |          handle_irq
                   |          |          __irqentry_text_start
                   |          |          ret_from_intr
                   |          |          |
                   |          |          |--39.78%-- __const_udelay
                   |          |          |          |
                   |          |          |          |--91.89%-- ath5k_hw_register_timeout
                   |          |          |          |          ath5k_hw_noise_floor_calibration
                   |          |          |          |          ath5k_hw_reset
                   |          |          |          |          ath5k_reset
                   |          |          |          |          ath5k_config
                   |          |          |          |          ieee80211_hw_config
                   |          |          |          |          |
                   |          |          |          |          |--88.24%-- ieee80211_scan_work
                   |          |          |          |          |          worker_thread
                   |          |          |          |          |          kthread
                   |          |          |          |          |          child_rip
                   |          |          |          |          |
                   |          |          |          |           --11.76%-- ieee80211_scan_completed
                   |          |          |          |                     ieee80211_scan_work
                   |          |          |          |                     worker_thread
                   |          |          |          |                     kthread
                   |          |          |          |                     child_rip
                   |          |          |          |
                   |          |          |           --8.11%-- ath5k_hw_noise_floor_calibration
                   |          |          |                     ath5k_hw_reset
                   |          |          |                     ath5k_reset
                   |          |          |                     ath5k_config
    
    Note: This does not only affect perf events but also x86-64
    stacktraces. They were considered as unreliable once we quit
    the irq stack frame.
    Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
    Cc: Peter Zijlstra <peterz@infradead.org>
    Cc: Paul Mackerras <paulus@samba.org>
    Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
    Cc: "K. Prasad" <prasad@linux.vnet.ibm.com>
    Cc: Thomas Gleixner <tglx@linutronix.de>
    Cc: "H. Peter Anvin" <hpa@zytor.com>
    af2d8289
dumpstack_64.c 8.21 KB