Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1273315 > unrolled thread

[GIT PULL 00/37] perf/core improvements and fixes

Started byArnaldo Carvalho de Melo <acme@kernel.org>
First post2015-11-19 19:00 +0100
Last post2015-11-23 09:20 +0100
Articles 20 on this page of 45 — 7 participants

Back to article view | Back to linux.kernel


Contents

  [GIT PULL 00/37] perf/core improvements and fixes Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:00 +0100
    [PATCH 31/37] perf callchain: Add count fields to struct callchain_node Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:00 +0100
      Re: [PATCH 31/37] perf callchain: Add count fields to struct  callchain_node Frederic Weisbecker <fweisbec@gmail.com> - 2015-11-23 15:40 +0100
        Re: [PATCH 31/37] perf callchain: Add count fields to struct  callchain_node Namhyung Kim <namhyung@kernel.org> - 2015-11-24 06:20 +0100
    [PATCH 27/37] perf tools: Fix machine__create_kernel_maps to put kernel dso refcount Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:00 +0100
    [PATCH 06/37] perf bpf: Add BPF_PROLOGUE config options for further patches Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:00 +0100
    [PATCH 17/37] perf test: Print result for each LLVM subtest Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:00 +0100
    [PATCH 30/37] perf callchain: Abstract callchain print function Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:00 +0100
    [PATCH 10/37] perf bpf: Allow BPF program config probing options Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:00 +0100
    [PATCH 35/37] perf hists browser: Support folded callchains Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:00 +0100
    [PATCH 37/37] perf ui/gtk: Support folded callchains Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:00 +0100
    [PATCH 36/37] perf ui/gtk: Support flat callchains Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:00 +0100
    [PATCH 34/37] perf hists browser: Support flat callchains Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:00 +0100
      Re: [PATCH 34/37] perf hists browser: Support flat callchains Frederic Weisbecker <fweisbec@gmail.com> - 2015-11-23 16:20 +0100
        Re: [PATCH 34/37] perf hists browser: Support flat callchains Namhyung Kim <namhyung@kernel.org> - 2015-11-24 06:30 +0100
          Re: [PATCH 34/37] perf hists browser: Support flat callchains Arnaldo Carvalho de Melo <arnaldo.melo@gmail.com> - 2015-11-24 15:50 +0100
            Re: [PATCH 34/37] perf hists browser: Support flat callchains Namhyung Kim <namhyung@kernel.org> - 2015-11-25 02:30 +0100
              Re: [PATCH 34/37] perf hists browser: Support flat callchains Arnaldo Carvalho de Melo <arnaldo.melo@gmail.com> - 2015-11-25 02:40 +0100
                Re: [PATCH 34/37] perf hists browser: Support flat callchains Arnaldo Carvalho de Melo <arnaldo.melo@gmail.com> - 2015-11-25 03:20 +0100
                  Re: [PATCH 34/37] perf hists browser: Support flat callchains Namhyung Kim <namhyung@kernel.org> - 2015-11-25 22:10 +0100
    [PATCH 03/37] tools: Adopt memdup() from tools/perf, moving it to tools/lib/string.c Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:00 +0100
    [PATCH 02/37] tools: Fix selftests_install Makefile rule Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:00 +0100
    [PATCH 33/37] perf hists browser: Factor out hist_browser__show_callchain_list() Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:00 +0100
    [PATCH 32/37] perf report: Add callchain value option Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:00 +0100
    [PATCH 08/37] perf bpf: Allow BPF program attach to uprobe events Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:10 +0100
    [PATCH 21/37] perf machine: Fix machine__findnew_module_map to put registered map Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:10 +0100
    [PATCH 14/37] perf test: Fix 'perf test BPF' when it fails to find a suitable vmlinux Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:10 +0100
    [PATCH 13/37] perf test: Test the BPF prologue adding infrastructure Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:10 +0100
    [PATCH 16/37] perf tests: Pass the subtest index to each test routine Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:10 +0100
    [PATCH 18/37] perf test: Print result for each BPF subtest Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:10 +0100
    [PATCH 11/37] perf bpf: Add prologue for BPF programs for fetching arguments Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:10 +0100
    [PATCH 19/37] perf test: Mute test cases error messages if verbose == 0 Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:10 +0100
    [PATCH 22/37] perf machine: Fix machine__destroy_kernel_maps to drop vmlinux_maps references Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:10 +0100
    [PATCH 12/37] perf bpf: Generate prologue for BPF programs Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:10 +0100
    [PATCH 20/37] perf probe: Fix to free temporal Dwarf_Frame Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:10 +0100
    [PATCH 25/37] perf tools: Fix to put new map after inserting to map_groups in dso__load_sym Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:10 +0100
    [PATCH 28/37] perf machine: Fix machine__findnew_module_map to put dso Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:10 +0100
    [PATCH 26/37] perf tools: Fix __dsos__addnew to put dso after adding it to the list Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:10 +0100
    [PATCH 04/37] tools: Clone the kernel's strtobool function Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:10 +0100
    [PATCH 23/37] perf machine: Fix to destroy kernel maps when machine exits Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:10 +0100
    [PATCH 05/37] bpf tools: Load a program with different instances using preprocessor Arnaldo Carvalho de Melo <acme@kernel.org> - 2015-11-19 19:10 +0100
    RE: [GIT PULL 00/37] perf/core improvements and fixes 平松雅巳 / HIRAMATU,MASAMI   <masami.hiramatsu.pt@hitachi.com> - 2015-11-20 11:10 +0100
      Re: [GIT PULL 00/37] perf/core improvements and fixes 'Arnaldo Carvalho de Melo' <acme@kernel.org> - 2015-11-20 13:10 +0100
        RE: [GIT PULL 00/37] perf/core improvements and fixes 平松雅巳 / HIRAMATU,MASAMI   <masami.hiramatsu.pt@hitachi.com> - 2015-11-20 18:00 +0100
    Re: [GIT PULL 00/37] perf/core improvements and fixes Ingo Molnar <mingo@kernel.org> - 2015-11-23 09:20 +0100

Page 1 of 3  [1] 2 3  Next page →


#1273315 — [GIT PULL 00/37] perf/core improvements and fixes

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-11-19 19:00 +0100
Subject[GIT PULL 00/37] perf/core improvements and fixes
Message-ID<qwBEZ-44P-3@gated-at.bofh.it>
Hi Ingo,

	Please consider pulling, this was based on tip/perf/urgent and I did a
test merge of tip/perf/core with tip/perf/urgent and then with this branch,
haven't noticed problems,

Best regards,

- Arnaldo

The following changes since commit e15bf88a44d1fcb685754b2868b1cd28927af3aa:

  Merge tag 'perf-urgent-for-mingo' of git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux into perf/urgent (2015-11-18 06:56:48 +0100)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/acme/linux.git tags/perf-core-for-mingo

for you to fetch changes up to 2c6caff2b26fde8f3f87183f8c97f2cebfdbcb98:

  perf ui/gtk: Support folded callchains (2015-11-19 13:19:26 -0300)

----------------------------------------------------------------
perf/core improvements and fixes:

User visible:

- Allows BPF scriptlets specify arguments to be fetched using
  DWARF info, using a prologue generated at compile/build time (He Kuang, Wang Nan)

- Allow attaching BPF scriptlets to module symbols (Wang Nan)

- Allow attaching BPF scriptlets to userspace code using uprobe (Wang Nan)

- BPF programs now can specify 'perf probe' tunables via its section name,
  separating key=val values using semicolons (Wang Nan)

Testing some of these new BPF features:

Use case: get callchains when receiving SSL packets, filter then in the
          kernel, at arbitrary place.

  # cat ssl.bpf.c
  #define SEC(NAME) __attribute__((section(NAME), used))

  struct pt_regs;

  SEC("func=__inet_lookup_established hnum")
  int func(struct pt_regs *ctx, int err, unsigned short port)
  {
          return err == 0 && port == 443;
  }

  char _license[] SEC("license") = "GPL";
  int  _version   SEC("version") = LINUX_VERSION_CODE;
  #
  # perf record -a -g -e ssl.bpf.c
  ^C[ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 0.787 MB perf.data (3 samples) ]
  # perf script | head -30
  swapper     0 [000] 58783.268118: perf_bpf_probe:func: (ffffffff816a0f60) hnum=0x1bb
	 8a0f61 __inet_lookup_established (/lib/modules/4.3.0+/build/vmlinux)
	 896def ip_rcv_finish (/lib/modules/4.3.0+/build/vmlinux)
	 8976c2 ip_rcv (/lib/modules/4.3.0+/build/vmlinux)
	 855eba __netif_receive_skb_core (/lib/modules/4.3.0+/build/vmlinux)
	 8565d8 __netif_receive_skb (/lib/modules/4.3.0+/build/vmlinux)
	 8572a8 process_backlog (/lib/modules/4.3.0+/build/vmlinux)
	 856b11 net_rx_action (/lib/modules/4.3.0+/build/vmlinux)
	 2a284b __do_softirq (/lib/modules/4.3.0+/build/vmlinux)
	 2a2ba3 irq_exit (/lib/modules/4.3.0+/build/vmlinux)
	 96b7a4 do_IRQ (/lib/modules/4.3.0+/build/vmlinux)
	 969807 ret_from_intr (/lib/modules/4.3.0+/build/vmlinux)
	 2dede5 cpu_startup_entry (/lib/modules/4.3.0+/build/vmlinux)
	 95d5bc rest_init (/lib/modules/4.3.0+/build/vmlinux)
	1163ffa start_kernel ([kernel.vmlinux].init.text)
	11634d7 x86_64_start_reservations ([kernel.vmlinux].init.text)
	1163623 x86_64_start_kernel ([kernel.vmlinux].init.text)

  qemu-system-x86  9178 [003] 58785.792417: perf_bpf_probe:func: (ffffffff816a0f60) hnum=0x1bb
	 8a0f61 __inet_lookup_established (/lib/modules/4.3.0+/build/vmlinux)
	 896def ip_rcv_finish (/lib/modules/4.3.0+/build/vmlinux)
	 8976c2 ip_rcv (/lib/modules/4.3.0+/build/vmlinux)
	 855eba __netif_receive_skb_core (/lib/modules/4.3.0+/build/vmlinux)
	 8565d8 __netif_receive_skb (/lib/modules/4.3.0+/build/vmlinux)
	 856660 netif_receive_skb_internal (/lib/modules/4.3.0+/build/vmlinux)
	 8566ec netif_receive_skb_sk (/lib/modules/4.3.0+/build/vmlinux)
	   430a br_handle_frame_finish ([bridge])
	   48bc br_handle_frame ([bridge])
	 855f44 __netif_receive_skb_core (/lib/modules/4.3.0+/build/vmlinux)
	 8565d8 __netif_receive_skb (/lib/modules/4.3.0+/build/vmlinux)
  #

  Use 'perf probe' various options to list functions, see what variables can
  be collected at any given point, experiment first collecting without a filter,
  then filter, use it together with 'perf trace', 'perf top', with or without
  callchains, if it explodes, please tell us!

- Introduce a new callchain mode: "folded", that will list per line
  representations of all callchains for a give histogram entry, facilitating
  'perf report' output processing by other tools, such as Brendan Gregg's
  flamegraph tools (Namhyung Kim)

  E.g:

 # perf report | grep -v ^# | head
    18.37%     0.00%  swapper  [kernel.kallsyms]   [k] cpu_startup_entry
                    |
                    ---cpu_startup_entry
                       |
                       |--12.07%--start_secondary
                       |
                        --6.30%--rest_init
                                  start_kernel
                                  x86_64_start_reservations
                                  x86_64_start_kernel
  #

 Becomes, in "folded" mode:

 # perf report -g folded | grep -v ^# | head -5
     18.37%     0.00%  swapper [kernel.kallsyms]   [k] cpu_startup_entry
   12.07% cpu_startup_entry;start_secondary
    6.30% cpu_startup_entry;rest_init;start_kernel;x86_64_start_reservations;x86_64_start_kernel
     16.90%     0.00%  swapper [kernel.kallsyms]   [k] call_cpuidle
   11.23% call_cpuidle;cpu_startup_entry;start_secondary
    5.67% call_cpuidle;cpu_startup_entry;rest_init;start_kernel;x86_64_start_reservations;x86_64_start_kernel
     16.90%     0.00%  swapper [kernel.kallsyms]   [k] cpuidle_enter
   11.23% cpuidle_enter;call_cpuidle;cpu_startup_entry;start_secondary
    5.67% cpuidle_enter;call_cpuidle;cpu_startup_entry;rest_init;start_kernel;x86_64_start_reservations;x86_64_start_kernel
     15.12%     0.00%  swapper [kernel.kallsyms]   [k] cpuidle_enter_state
  #

   The user can also select one of "count", "period" or "percent" as the first column.

Infrastructure:

- Fix multiple leaks found with valgrind and a refcount
  debugger (Masami Hiramatsu)

- Add further 'perf test' entries for BPF and LLVM (Wang Nan)

- Improve 'perf test' to suport subtests, so that the series of tests
  performed in the LLVM and BPF main tests appear in the default 'perf test'
  output (Wang Nan)

- Move memdup() from tools/perf to tools/lib/string.c (Arnaldo Carvalho de Melo)

- Adopt strtobool() from the kernel into tools/lib/ (Wang Nan)

- Fix selftests_install tools/ Makefile rule (Kevin Hilman)

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

----------------------------------------------------------------
Arnaldo Carvalho de Melo (3):
      perf test: Fix build of BPF and LLVM on older glibc libraries
      tools: Adopt memdup() from tools/perf, moving it to tools/lib/string.c
      perf tests: Pass the subtest index to each test routine

He Kuang (1):
      perf bpf: Add prologue for BPF programs for fetching arguments

Kevin Hilman (1):
      tools: Fix selftests_install Makefile rule

Masami Hiramatsu (9):
      perf probe: Fix to free temporal Dwarf_Frame
      perf machine: Fix machine__findnew_module_map to put registered map
      perf machine: Fix machine__destroy_kernel_maps to drop vmlinux_maps references
      perf machine: Fix to destroy kernel maps when machine exits
      perf tools: Make perf_exec_path() always return malloc'd string
      perf tools: Fix to put new map after inserting to map_groups in dso__load_sym
      perf tools: Fix __dsos__addnew to put dso after adding it to the list
      perf tools: Fix machine__create_kernel_maps to put kernel dso refcount
      perf machine: Fix machine__findnew_module_map to put dso

Namhyung Kim (9):
      perf report: Support folded callchain mode on --stdio
      perf callchain: Abstract callchain print function
      perf callchain: Add count fields to struct callchain_node
      perf report: Add callchain value option
      perf hists browser: Factor out hist_browser__show_callchain_list()
      perf hists browser: Support flat callchains
      perf hists browser: Support folded callchains
      perf ui/gtk: Support flat callchains
      perf ui/gtk: Support folded callchains

Wang Nan (14):
      tools: Clone the kernel's strtobool function
      bpf tools: Load a program with different instances using preprocessor
      perf bpf: Add BPF_PROLOGUE config options for further patches
      perf bpf: Compile dwarf-regs.c if CONFIG_BPF_PROLOGUE is on
      perf bpf: Allow BPF program attach to uprobe events
      perf bpf: Allow attaching BPF programs to modules symbols
      perf bpf: Allow BPF program config probing options
      perf bpf: Generate prologue for BPF programs
      perf test: Test the BPF prologue adding infrastructure
      perf test: Fix 'perf test BPF' when it fails to find a suitable vmlinux
      perf bpf: Use same BPF program if arguments are identical
      perf test: Print result for each LLVM subtest
      perf test: Print result for each BPF subtest
      perf test: Mute test cases error messages if verbose == 0

 tools/Makefile                               |   2 +-
 tools/include/linux/string.h                 |  11 +
 tools/lib/bpf/libbpf.c                       | 146 ++++++++-
 tools/lib/bpf/libbpf.h                       |  64 ++++
 tools/lib/string.c                           |  62 ++++
 tools/perf/Documentation/perf-report.txt     |  14 +-
 tools/perf/MANIFEST                          |   2 +
 tools/perf/arch/x86/include/arch-tests.h     |   8 +-
 tools/perf/arch/x86/tests/insn-x86.c         |   2 +-
 tools/perf/arch/x86/tests/intel-cqm.c        |   2 +-
 tools/perf/arch/x86/tests/perf-time-to-tsc.c |   2 +-
 tools/perf/arch/x86/tests/rdpmc.c            |   2 +-
 tools/perf/arch/x86/util/Build               |   1 +
 tools/perf/builtin-report.c                  |   4 +-
 tools/perf/config/Makefile                   |  12 +
 tools/perf/tests/.gitignore                  |   1 +
 tools/perf/tests/Build                       |   9 +-
 tools/perf/tests/attr.c                      |   2 +-
 tools/perf/tests/bp_signal.c                 |   2 +-
 tools/perf/tests/bp_signal_overflow.c        |   2 +-
 tools/perf/tests/bpf-script-test-prologue.c  |  35 +++
 tools/perf/tests/bpf.c                       |  93 ++++--
 tools/perf/tests/builtin-test.c              | 112 ++++++-
 tools/perf/tests/code-reading.c              |   2 +-
 tools/perf/tests/dso-data.c                  |   6 +-
 tools/perf/tests/dwarf-unwind.c              |   2 +-
 tools/perf/tests/evsel-roundtrip-name.c      |   2 +-
 tools/perf/tests/evsel-tp-sched.c            |   2 +-
 tools/perf/tests/fdarray.c                   |   4 +-
 tools/perf/tests/hists_cumulate.c            |   2 +-
 tools/perf/tests/hists_filter.c              |   2 +-
 tools/perf/tests/hists_link.c                |   2 +-
 tools/perf/tests/hists_output.c              |   2 +-
 tools/perf/tests/keep-tracking.c             |   2 +-
 tools/perf/tests/kmod-path.c                 |   2 +-
 tools/perf/tests/llvm.c                      |  75 +++--
 tools/perf/tests/llvm.h                      |   2 +
 tools/perf/tests/mmap-basic.c                |   2 +-
 tools/perf/tests/mmap-thread-lookup.c        |   2 +-
 tools/perf/tests/openat-syscall-all-cpus.c   |   2 +-
 tools/perf/tests/openat-syscall-tp-fields.c  |   2 +-
 tools/perf/tests/openat-syscall.c            |   2 +-
 tools/perf/tests/parse-events.c              |   2 +-
 tools/perf/tests/parse-no-sample-id-all.c    |   2 +-
 tools/perf/tests/perf-record.c               |   2 +-
 tools/perf/tests/pmu.c                       |   2 +-
 tools/perf/tests/python-use.c                |   3 +-
 tools/perf/tests/sample-parsing.c            |   2 +-
 tools/perf/tests/sw-clock.c                  |   2 +-
 tools/perf/tests/switch-tracking.c           |   2 +-
 tools/perf/tests/task-exit.c                 |   2 +-
 tools/perf/tests/tests.h                     |  89 +++---
 tools/perf/tests/thread-map.c                |   2 +-
 tools/perf/tests/thread-mg-share.c           |   2 +-
 tools/perf/tests/topology.c                  |   2 +-
 tools/perf/tests/vmlinux-kallsyms.c          |   2 +-
 tools/perf/ui/browsers/hists.c               | 315 +++++++++++++++++--
 tools/perf/ui/gtk/hists.c                    | 148 ++++++++-
 tools/perf/ui/stdio/hist.c                   |  94 +++++-
 tools/perf/util/Build                        |   7 +
 tools/perf/util/bpf-loader.c                 | 434 ++++++++++++++++++++++++-
 tools/perf/util/bpf-loader.h                 |   4 +
 tools/perf/util/bpf-prologue.c               | 455 +++++++++++++++++++++++++++
 tools/perf/util/bpf-prologue.h               |  34 ++
 tools/perf/util/callchain.c                  | 135 +++++++-
 tools/perf/util/callchain.h                  |  28 +-
 tools/perf/util/dso.c                        |   2 +
 tools/perf/util/exec_cmd.c                   |  21 +-
 tools/perf/util/exec_cmd.h                   |   5 +-
 tools/perf/util/help.c                       |   6 +-
 tools/perf/util/include/linux/string.h       |   3 -
 tools/perf/util/machine.c                    |  17 +-
 tools/perf/util/probe-event.c                |   7 +-
 tools/perf/util/probe-finder.c               |   9 +-
 tools/perf/util/string.c                     |  16 -
 tools/perf/util/symbol-elf.c                 |   2 +
 tools/perf/util/util.c                       |   3 +-
 77 files changed, 2286 insertions(+), 282 deletions(-)
 create mode 100644 tools/include/linux/string.h
 create mode 100644 tools/lib/string.c
 create mode 100644 tools/perf/tests/bpf-script-test-prologue.c
 create mode 100644 tools/perf/util/bpf-prologue.c
 create mode 100644 tools/perf/util/bpf-prologue.h
 delete mode 100644 tools/perf/util/include/linux/string.h
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [next] | [standalone]


#1273316 — [PATCH 31/37] perf callchain: Add count fields to struct callchain_node

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-11-19 19:00 +0100
Subject[PATCH 31/37] perf callchain: Add count fields to struct callchain_node
Message-ID<qwBF0-44P-19@gated-at.bofh.it>
In reply to#1273315
From: Namhyung Kim <namhyung@kernel.org>

It's to track the count of occurrences of the callchains.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Brendan Gregg <brendan.d.gregg@gmail.com>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1447047946-1691-5-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/callchain.c | 10 ++++++++++
 tools/perf/util/callchain.h |  7 +++++++
 2 files changed, 17 insertions(+)

diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index b948bd068966..e390edd31504 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -437,6 +437,8 @@ add_child(struct callchain_node *parent,
 
 	new->children_hit = 0;
 	new->hit = period;
+	new->children_count = 0;
+	new->count = 1;
 	return new;
 }
 
@@ -484,6 +486,9 @@ split_add_child(struct callchain_node *parent,
 	parent->children_hit = callchain_cumul_hits(new);
 	new->val_nr = parent->val_nr - idx_local;
 	parent->val_nr = idx_local;
+	new->count = parent->count;
+	new->children_count = parent->children_count;
+	parent->children_count = callchain_cumul_counts(new);
 
 	/* create a new child for the new branch if any */
 	if (idx_total < cursor->nr) {
@@ -494,6 +499,8 @@ split_add_child(struct callchain_node *parent,
 
 		parent->hit = 0;
 		parent->children_hit += period;
+		parent->count = 0;
+		parent->children_count += 1;
 
 		node = callchain_cursor_current(cursor);
 		new = add_child(parent, cursor, period);
@@ -516,6 +523,7 @@ split_add_child(struct callchain_node *parent,
 		rb_insert_color(&new->rb_node_in, &parent->rb_root_in);
 	} else {
 		parent->hit = period;
+		parent->count = 1;
 	}
 }
 
@@ -562,6 +570,7 @@ append_chain_children(struct callchain_node *root,
 
 inc_children_hit:
 	root->children_hit += period;
+	root->children_count++;
 }
 
 static int
@@ -614,6 +623,7 @@ append_chain(struct callchain_node *root,
 	/* we match 100% of the path, increment the hit */
 	if (matches == root->val_nr && cursor->pos == cursor->nr) {
 		root->hit += period;
+		root->count++;
 		return 0;
 	}
 
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 060e636e33ab..cdb386d9ba02 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -60,6 +60,8 @@ struct callchain_node {
 	struct rb_root		rb_root_in; /* input tree of children */
 	struct rb_root		rb_root;    /* sorted output tree of children */
 	unsigned int		val_nr;
+	unsigned int		count;
+	unsigned int		children_count;
 	u64			hit;
 	u64			children_hit;
 };
@@ -145,6 +147,11 @@ static inline u64 callchain_cumul_hits(struct callchain_node *node)
 	return node->hit + node->children_hit;
 }
 
+static inline unsigned callchain_cumul_counts(struct callchain_node *node)
+{
+	return node->count + node->children_count;
+}
+
 int callchain_register_param(struct callchain_param *param);
 int callchain_append(struct callchain_root *root,
 		     struct callchain_cursor *cursor,
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1275447 — Re: [PATCH 31/37] perf callchain: Add count fields to struct callchain_node

FromFrederic Weisbecker <fweisbec@gmail.com>
Date2015-11-23 15:40 +0100
SubjectRe: [PATCH 31/37] perf callchain: Add count fields to struct callchain_node
Message-ID<qy0rE-30z-35@gated-at.bofh.it>
In reply to#1273316
Namhyung,

On Thu, Nov 19, 2015 at 02:53:17PM -0300, Arnaldo Carvalho de Melo wrote:
> From: Namhyung Kim <namhyung@kernel.org>
> 
> It's to track the count of occurrences of the callchains.

Please explain why you do something like this in the changelog, even just a single
line to tell which feature is going to use this and why.

No need to resend just for that, it's just for future patches.

Thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1276062 — Re: [PATCH 31/37] perf callchain: Add count fields to struct callchain_node

FromNamhyung Kim <namhyung@kernel.org>
Date2015-11-24 06:20 +0100
SubjectRe: [PATCH 31/37] perf callchain: Add count fields to struct callchain_node
Message-ID<qyebg-3JI-3@gated-at.bofh.it>
In reply to#1275447
Hi Frederic,

On Mon, Nov 23, 2015 at 03:35:30PM +0100, Frederic Weisbecker wrote:
> Namhyung,
> 
> On Thu, Nov 19, 2015 at 02:53:17PM -0300, Arnaldo Carvalho de Melo wrote:
> > From: Namhyung Kim <namhyung@kernel.org>
> > 
> > It's to track the count of occurrences of the callchains.
> 
> Please explain why you do something like this in the changelog, even just a single
> line to tell which feature is going to use this and why.
> 
> No need to resend just for that, it's just for future patches.

OK, I'll keep in mind that.

This patch is a preparation for supporting different callchain value
output style.  Instead of current percent output, it could have period
or count with this change.

Thanks,
Namhyung
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1273317 — [PATCH 27/37] perf tools: Fix machine__create_kernel_maps to put kernel dso refcount

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-11-19 19:00 +0100
Subject[PATCH 27/37] perf tools: Fix machine__create_kernel_maps to put kernel dso refcount
Message-ID<qwBF0-44P-21@gated-at.bofh.it>
In reply to#1273315
From: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>

Fix machine__create_kernel_maps() to put kernel dso because the dso has
been gotten via __machine__create_kernel_maps().

Refcnt debugger shows:
  ==== [0] ====
  Unreclaimed dso: 0x3036ab0
  Refcount +1 => 1 at
    ./perf(dso__new+0x1ff) [0x4a62df]
    ./perf(__dsos__addnew+0x29) [0x4a6e19]
    ./perf(dsos__findnew+0xd1) [0x4a7181]
    ./perf(machine__findnew_kernel+0x27) [0x4a5e17]
    ./perf() [0x4b8cf2]
    ./perf(machine__create_kernel_maps+0x28) [0x4bb428]
    ./perf(machine__new_host+0xfa) [0x4bb74a]
    ./perf(init_probe_symbol_maps+0x93) [0x506613]
    ./perf() [0x455ffa]
    ./perf(cmd_probe+0x6c) [0x4566bc]
    ./perf() [0x47abc5]
    ./perf(main+0x610) [0x421f90]
    /lib64/libc.so.6(__libc_start_main+0xf5) [0x7ffa6809eaf5]
    ./perf() [0x4220a9]
  [snip]
  Refcount +1 => 2 at
    ./perf(dsos__findnew+0x7e) [0x4a712e]
    ./perf(machine__findnew_kernel+0x27) [0x4a5e17]
    ./perf() [0x4b8cf2]
    ./perf(machine__create_kernel_maps+0x28) [0x4bb428]
    ./perf(machine__new_host+0xfa) [0x4bb74a]
    ./perf(init_probe_symbol_maps+0x93) [0x506613]
    ./perf() [0x455ffa]
    ./perf(cmd_probe+0x6c) [0x4566bc]
    ./perf() [0x47abc5]
    ./perf(main+0x610) [0x421f90]
    /lib64/libc.so.6(__libc_start_main+0xf5) [0x7ffa6809eaf5]
    ./perf() [0x4220a9]
  [snip]
  Refcount -1 => 1 at
    ./perf(dso__put+0x2f) [0x4a664f]
    ./perf(machine__delete+0xfe) [0x4b93ee]
    ./perf(exit_probe_symbol_maps+0x28) [0x5066b8]
    ./perf() [0x45628a]
    ./perf(cmd_probe+0x6c) [0x4566bc]
    ./perf() [0x47abc5]
    ./perf(main+0x610) [0x421f90]
    /lib64/libc.so.6(__libc_start_main+0xf5) [0x7ffa6809eaf5]
    ./perf() [0x4220a9]

Actually, dsos__findnew gets the dso before returning it, so the dso
user (in this case machine__create_kernel_maps) has to put the dso after
used.

Signed-off-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/20151118064033.30709.98954.stgit@localhost.localdomain
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/machine.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c
index a358771fe9e3..0b4a05c14204 100644
--- a/tools/perf/util/machine.c
+++ b/tools/perf/util/machine.c
@@ -1088,11 +1088,14 @@ int machine__create_kernel_maps(struct machine *machine)
 	struct dso *kernel = machine__get_kernel(machine);
 	const char *name;
 	u64 addr = machine__get_running_kernel_start(machine, &name);
-	if (!addr)
+	int ret;
+
+	if (!addr || kernel == NULL)
 		return -1;
 
-	if (kernel == NULL ||
-	    __machine__create_kernel_maps(machine, kernel) < 0)
+	ret = __machine__create_kernel_maps(machine, kernel);
+	dso__put(kernel);
+	if (ret < 0)
 		return -1;
 
 	if (symbol_conf.use_modules && machine__create_modules(machine) < 0) {
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1273318 — [PATCH 06/37] perf bpf: Add BPF_PROLOGUE config options for further patches

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-11-19 19:00 +0100
Subject[PATCH 06/37] perf bpf: Add BPF_PROLOGUE config options for further patches
Message-ID<qwBF0-44P-23@gated-at.bofh.it>
In reply to#1273315
From: Wang Nan <wangnan0@huawei.com>

If both LIBBPF and DWARF are detected, it is possible to create prologue
for eBPF programs to help them access kernel data. HAVE_BPF_PROLOGUE and
CONFIG_BPF_PROLOGUE are added as flags for this feature.

PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET is introduced in commit
63ab024a5b6f295ca17a293ad81b7c728f49a89a ("perf tools:
regs_query_register_offset() infrastructure"), which indicates that an
architecture supports converting name of a register to its offset in
'struct pt_regs'. Without this support, BPF_PROLOGUE should be turned
off.

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1447675815-166222-9-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/config/Makefile | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index de89ec574361..6eb9a956a408 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -318,6 +318,18 @@ ifndef NO_LIBELF
       CFLAGS += -DHAVE_LIBBPF_SUPPORT
       $(call detected,CONFIG_LIBBPF)
     endif
+
+    ifndef NO_DWARF
+      ifdef PERF_HAVE_ARCH_REGS_QUERY_REGISTER_OFFSET
+        CFLAGS += -DHAVE_BPF_PROLOGUE
+        $(call detected,CONFIG_BPF_PROLOGUE)
+      else
+        msg := $(warning BPF prologue is not supported by architecture $(ARCH), missing regs_query_register_offset());
+      endif
+    else
+      msg := $(warning DWARF support is off, BPF prologue is disabled);
+    endif
+
   endif # NO_LIBBPF
 endif # NO_LIBELF
 
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1273319 — [PATCH 17/37] perf test: Print result for each LLVM subtest

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-11-19 19:00 +0100
Subject[PATCH 17/37] perf test: Print result for each LLVM subtest
Message-ID<qwBF0-44P-27@gated-at.bofh.it>
In reply to#1273315
From: Wang Nan <wangnan0@huawei.com>

Currently 'perf test llvm' and 'perf test BPF' have multiple sub-tests,
but the result is provided in only one line:

  # perf test LLVM
  35: Test LLVM searching and compiling                        : Ok

This patch introduces sub-tests support, allowing 'perf test' to report
result for each sub-tests:

  # perf test LLVM
  35: Test LLVM searching and compiling                        :
  35.1: Basic BPF llvm compiling test                          : Ok
  35.2: Test kbuild searching                                  : Ok
  35.3: Compile source for BPF prologue generation test        : Ok

When a failure happens:

  # cat ~/.perfconfig
  [llvm]
       clang-path = "/bin/false"
  # perf test LLVM
  35: Test LLVM searching and compiling                        :
  35.1: Basic BPF llvm compiling test                          : FAILED!
  35.2: Test kbuild searching                                  : Skip
  35.3: Compile source for BPF prologue generation test        : Skip

And:

  # rm ~/.perfconfig
  # ./perf test LLVM
  35: Test LLVM searching and compiling                        :
  35.1: Basic BPF llvm compiling test                          : Skip
  35.2: Test kbuild searching                                  : Skip
  35.3: Compile source for BPF prologue generation test        : Skip

Skip by user:

  # ./perf test -s 1,`seq -s , 3 42`
   1: vmlinux symtab matches kallsyms                          : Skip (user override)
   2: detect openat syscall event                              : Ok
  ...
  35: Test LLVM searching and compiling                        : Skip (user override)
  ...

Suggested-and-Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Wang Nan <wangnan0@huawei.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1447749170-175898-4-git-send-email-wangnan0@huawei.com
[ Changed so that func is not on an anonymous union ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/tests/builtin-test.c | 91 ++++++++++++++++++++++++++++++++++-------
 tools/perf/tests/llvm.c         | 65 ++++++++++++++---------------
 tools/perf/tests/tests.h        |  9 ++++
 3 files changed, 115 insertions(+), 50 deletions(-)

diff --git a/tools/perf/tests/builtin-test.c b/tools/perf/tests/builtin-test.c
index 9cf4892c061d..813660976217 100644
--- a/tools/perf/tests/builtin-test.c
+++ b/tools/perf/tests/builtin-test.c
@@ -160,6 +160,11 @@ static struct test generic_tests[] = {
 	{
 		.desc = "Test LLVM searching and compiling",
 		.func = test__llvm,
+		.subtest = {
+			.skip_if_fail	= true,
+			.get_nr		= test__llvm_subtest_get_nr,
+			.get_desc	= test__llvm_subtest_get_desc,
+		},
 	},
 	{
 		.desc = "Test topology in session",
@@ -237,6 +242,40 @@ static int run_test(struct test *test, int subtest)
 	for (j = 0; j < ARRAY_SIZE(tests); j++)	\
 		for (t = &tests[j][0]; t->func; t++)
 
+static int test_and_print(struct test *t, bool force_skip, int subtest)
+{
+	int err;
+
+	if (!force_skip) {
+		pr_debug("\n--- start ---\n");
+		err = run_test(t, subtest);
+		pr_debug("---- end ----\n");
+	} else {
+		pr_debug("\n--- force skipped ---\n");
+		err = TEST_SKIP;
+	}
+
+	if (!t->subtest.get_nr)
+		pr_debug("%s:", t->desc);
+	else
+		pr_debug("%s subtest %d:", t->desc, subtest);
+
+	switch (err) {
+	case TEST_OK:
+		pr_info(" Ok\n");
+		break;
+	case TEST_SKIP:
+		color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip\n");
+		break;
+	case TEST_FAIL:
+	default:
+		color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n");
+		break;
+	}
+
+	return err;
+}
+
 static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
 {
 	struct test *t;
@@ -264,21 +303,43 @@ static int __cmd_test(int argc, const char *argv[], struct intlist *skiplist)
 			continue;
 		}
 
-		pr_debug("\n--- start ---\n");
-		err = run_test(t, i);
-		pr_debug("---- end ----\n%s:", t->desc);
-
-		switch (err) {
-		case TEST_OK:
-			pr_info(" Ok\n");
-			break;
-		case TEST_SKIP:
-			color_fprintf(stderr, PERF_COLOR_YELLOW, " Skip\n");
-			break;
-		case TEST_FAIL:
-		default:
-			color_fprintf(stderr, PERF_COLOR_RED, " FAILED!\n");
-			break;
+		if (!t->subtest.get_nr) {
+			test_and_print(t, false, -1);
+		} else {
+			int subn = t->subtest.get_nr();
+			/*
+			 * minus 2 to align with normal testcases.
+			 * For subtest we print additional '.x' in number.
+			 * for example:
+			 *
+			 * 35: Test LLVM searching and compiling                        :
+			 * 35.1: Basic BPF llvm compiling test                          : Ok
+			 */
+			int subw = width > 2 ? width - 2 : width;
+			bool skip = false;
+			int subi;
+
+			if (subn <= 0) {
+				color_fprintf(stderr, PERF_COLOR_YELLOW,
+					      " Skip (not compiled in)\n");
+				continue;
+			}
+			pr_info("\n");
+
+			for (subi = 0; subi < subn; subi++) {
+				int len = strlen(t->subtest.get_desc(subi));
+
+				if (subw < len)
+					subw = len;
+			}
+
+			for (subi = 0; subi < subn; subi++) {
+				pr_info("%2d.%1d: %-*s:", i, subi + 1, subw,
+					t->subtest.get_desc(subi));
+				err = test_and_print(t, skip, subi);
+				if (err != TEST_OK && t->subtest.skip_if_fail)
+					skip = true;
+			}
 		}
 	}
 
diff --git a/tools/perf/tests/llvm.c b/tools/perf/tests/llvm.c
index 4350c455d06c..06f45c1d4256 100644
--- a/tools/perf/tests/llvm.c
+++ b/tools/perf/tests/llvm.c
@@ -46,7 +46,7 @@ static struct {
 	},
 	[LLVM_TESTCASE_BPF_PROLOGUE] = {
 		.source = test_llvm__bpf_test_prologue_prog,
-		.desc = "Test BPF prologue generation",
+		.desc = "Compile source for BPF prologue generation test",
 	},
 };
 
@@ -131,44 +131,39 @@ out:
 	return ret;
 }
 
-int test__llvm(int subtest __maybe_unused)
+int test__llvm(int subtest)
 {
-	enum test_llvm__testcase i;
+	int ret;
+	void *obj_buf = NULL;
+	size_t obj_buf_sz = 0;
 
-	for (i = 0; i < __LLVM_TESTCASE_MAX; i++) {
-		int ret;
-		void *obj_buf = NULL;
-		size_t obj_buf_sz = 0;
+	if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX))
+		return TEST_FAIL;
 
-		ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz,
-					       i, false);
+	ret = test_llvm__fetch_bpf_obj(&obj_buf, &obj_buf_sz,
+				       subtest, false);
 
-		if (ret == TEST_OK) {
-			ret = test__bpf_parsing(obj_buf, obj_buf_sz);
-			if (ret != TEST_OK)
-				pr_debug("Failed to parse test case '%s'\n",
-					 bpf_source_table[i].desc);
-		}
-		free(obj_buf);
-
-		switch (ret) {
-		case TEST_SKIP:
-			return TEST_SKIP;
-		case TEST_OK:
-			break;
-		default:
-			/*
-			 * Test 0 is the basic LLVM test. If test 0
-			 * fail, the basic LLVM support not functional
-			 * so the whole test should fail. If other test
-			 * case fail, it can be fixed by adjusting
-			 * config so don't report error.
-			 */
-			if (i == 0)
-				return TEST_FAIL;
-			else
-				return TEST_SKIP;
+	if (ret == TEST_OK) {
+		ret = test__bpf_parsing(obj_buf, obj_buf_sz);
+		if (ret != TEST_OK) {
+			pr_debug("Failed to parse test case '%s'\n",
+				 bpf_source_table[subtest].desc);
 		}
 	}
-	return TEST_OK;
+	free(obj_buf);
+
+	return ret;
+}
+
+int test__llvm_subtest_get_nr(void)
+{
+	return __LLVM_TESTCASE_MAX;
+}
+
+const char *test__llvm_subtest_get_desc(int subtest)
+{
+	if ((subtest < 0) || (subtest >= __LLVM_TESTCASE_MAX))
+		return NULL;
+
+	return bpf_source_table[subtest].desc;
 }
diff --git a/tools/perf/tests/tests.h b/tools/perf/tests/tests.h
index 204e4eeadea2..f92af527f080 100644
--- a/tools/perf/tests/tests.h
+++ b/tools/perf/tests/tests.h
@@ -1,6 +1,8 @@
 #ifndef TESTS_H
 #define TESTS_H
 
+#include <stdbool.h>
+
 #define TEST_ASSERT_VAL(text, cond)					 \
 do {									 \
 	if (!(cond)) {							 \
@@ -27,6 +29,11 @@ enum {
 struct test {
 	const char *desc;
 	int (*func)(int subtest);
+	struct {
+		bool skip_if_fail;
+		int (*get_nr)(void);
+		const char *(*get_desc)(int subtest);
+	} subtest;
 };
 
 /* Tests */
@@ -66,6 +73,8 @@ int test__fdarray__add(int subtest);
 int test__kmod_path__parse(int subtest);
 int test__thread_map(int subtest);
 int test__llvm(int subtest);
+const char *test__llvm_subtest_get_desc(int subtest);
+int test__llvm_subtest_get_nr(void);
 int test__bpf(int subtest);
 int test_session_topology(int subtest);
 
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1273320 — [PATCH 30/37] perf callchain: Abstract callchain print function

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-11-19 19:00 +0100
Subject[PATCH 30/37] perf callchain: Abstract callchain print function
Message-ID<qwBF0-44P-33@gated-at.bofh.it>
In reply to#1273315
From: Namhyung Kim <namhyung@kernel.org>

This is a preparation to support for printing other type of callchain
value like count or period.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1447047946-1691-4-git-send-email-namhyung@kernel.org
[ renamed new _sprintf_ operation to _scnprintf_ ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/ui/browsers/hists.c |  8 +++++---
 tools/perf/ui/gtk/hists.c      |  8 ++------
 tools/perf/ui/stdio/hist.c     | 35 +++++++++++++++++------------------
 tools/perf/util/callchain.c    | 29 +++++++++++++++++++++++++++++
 tools/perf/util/callchain.h    |  4 ++++
 5 files changed, 57 insertions(+), 27 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index fa9eb92c9e24..0b18857a36e8 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -592,7 +592,6 @@ static int hist_browser__show_callchain(struct hist_browser *browser,
 	while (node) {
 		struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
 		struct rb_node *next = rb_next(node);
-		u64 cumul = callchain_cumul_hits(child);
 		struct callchain_list *chain;
 		char folded_sign = ' ';
 		int first = true;
@@ -619,9 +618,12 @@ static int hist_browser__show_callchain(struct hist_browser *browser,
 						       browser->show_dso);
 
 			if (was_first && need_percent) {
-				double percent = cumul * 100.0 / total;
+				char buf[64];
 
-				if (asprintf(&alloc_str, "%2.2f%% %s", percent, str) < 0)
+				callchain_node__scnprintf_value(child, buf, sizeof(buf),
+								total);
+
+				if (asprintf(&alloc_str, "%s %s", buf, str) < 0)
 					str = "Not enough memory!";
 				else
 					str = alloc_str;
diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
index 4b3585eed1e8..cff7bb9d9632 100644
--- a/tools/perf/ui/gtk/hists.c
+++ b/tools/perf/ui/gtk/hists.c
@@ -100,14 +100,10 @@ static void perf_gtk__add_callchain(struct rb_root *root, GtkTreeStore *store,
 		struct callchain_list *chain;
 		GtkTreeIter iter, new_parent;
 		bool need_new_parent;
-		double percent;
-		u64 hits, child_total;
+		u64 child_total;
 
 		node = rb_entry(nd, struct callchain_node, rb_node);
 
-		hits = callchain_cumul_hits(node);
-		percent = 100.0 * hits / total;
-
 		new_parent = *parent;
 		need_new_parent = !has_single_node && (node->val_nr > 1);
 
@@ -116,7 +112,7 @@ static void perf_gtk__add_callchain(struct rb_root *root, GtkTreeStore *store,
 
 			gtk_tree_store_append(store, &iter, &new_parent);
 
-			scnprintf(buf, sizeof(buf), "%5.2f%%", percent);
+			callchain_node__scnprintf_value(node, buf, sizeof(buf), total);
 			gtk_tree_store_set(store, &iter, 0, buf, -1);
 
 			callchain_list__sym_name(chain, buf, sizeof(buf), false);
diff --git a/tools/perf/ui/stdio/hist.c b/tools/perf/ui/stdio/hist.c
index ea7984932d9a..f4de055cab9b 100644
--- a/tools/perf/ui/stdio/hist.c
+++ b/tools/perf/ui/stdio/hist.c
@@ -34,10 +34,10 @@ static size_t ipchain__fprintf_graph_line(FILE *fp, int depth, int depth_mask,
 	return ret;
 }
 
-static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
+static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_node *node,
+				     struct callchain_list *chain,
 				     int depth, int depth_mask, int period,
-				     u64 total_samples, u64 hits,
-				     int left_margin)
+				     u64 total_samples, int left_margin)
 {
 	int i;
 	size_t ret = 0;
@@ -50,10 +50,9 @@ static size_t ipchain__fprintf_graph(FILE *fp, struct callchain_list *chain,
 		else
 			ret += fprintf(fp, " ");
 		if (!period && i == depth - 1) {
-			double percent;
-
-			percent = hits * 100.0 / total_samples;
-			ret += percent_color_fprintf(fp, "--%2.2f%%-- ", percent);
+			ret += fprintf(fp, "--");
+			ret += callchain_node__fprintf_value(node, fp, total_samples);
+			ret += fprintf(fp, "--");
 		} else
 			ret += fprintf(fp, "%s", "          ");
 	}
@@ -120,10 +119,9 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root,
 						   left_margin);
 		i = 0;
 		list_for_each_entry(chain, &child->val, list) {
-			ret += ipchain__fprintf_graph(fp, chain, depth,
+			ret += ipchain__fprintf_graph(fp, child, chain, depth,
 						      new_depth_mask, i++,
 						      total_samples,
-						      cumul,
 						      left_margin);
 		}
 
@@ -143,14 +141,17 @@ static size_t __callchain__fprintf_graph(FILE *fp, struct rb_root *root,
 
 	if (callchain_param.mode == CHAIN_GRAPH_REL &&
 		remaining && remaining != total_samples) {
+		struct callchain_node rem_node = {
+			.hit = remaining,
+		};
 
 		if (!rem_sq_bracket)
 			return ret;
 
 		new_depth_mask &= ~(1 << (depth - 1));
-		ret += ipchain__fprintf_graph(fp, &rem_hits, depth,
+		ret += ipchain__fprintf_graph(fp, &rem_node, &rem_hits, depth,
 					      new_depth_mask, 0, total_samples,
-					      remaining, left_margin);
+					      left_margin);
 	}
 
 	return ret;
@@ -243,12 +244,11 @@ static size_t callchain__fprintf_flat(FILE *fp, struct rb_root *tree,
 	struct rb_node *rb_node = rb_first(tree);
 
 	while (rb_node) {
-		double percent;
-
 		chain = rb_entry(rb_node, struct callchain_node, rb_node);
-		percent = chain->hit * 100.0 / total_samples;
 
-		ret = percent_color_fprintf(fp, "           %6.2f%%\n", percent);
+		ret += fprintf(fp, "           ");
+		ret += callchain_node__fprintf_value(chain, fp, total_samples);
+		ret += fprintf(fp, "\n");
 		ret += __callchain__fprintf_flat(fp, chain, total_samples);
 		ret += fprintf(fp, "\n");
 		if (++entries_printed == callchain_param.print_limit)
@@ -295,12 +295,11 @@ static size_t callchain__fprintf_folded(FILE *fp, struct rb_root *tree,
 	struct rb_node *rb_node = rb_first(tree);
 
 	while (rb_node) {
-		double percent;
 
 		chain = rb_entry(rb_node, struct callchain_node, rb_node);
-		percent = chain->hit * 100.0 / total_samples;
 
-		ret += fprintf(fp, "%.2f%% ", percent);
+		ret += callchain_node__fprintf_value(chain, fp, total_samples);
+		ret += fprintf(fp, " ");
 		ret += __callchain__fprintf_folded(fp, chain);
 		ret += fprintf(fp, "\n");
 		if (++entries_printed == callchain_param.print_limit)
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 08cb220ba5ea..b948bd068966 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -805,6 +805,35 @@ char *callchain_list__sym_name(struct callchain_list *cl,
 	return bf;
 }
 
+char *callchain_node__scnprintf_value(struct callchain_node *node,
+				      char *bf, size_t bfsize, u64 total)
+{
+	double percent = 0.0;
+	u64 period = callchain_cumul_hits(node);
+
+	if (callchain_param.mode == CHAIN_FOLDED)
+		period = node->hit;
+	if (total)
+		percent = period * 100.0 / total;
+
+	scnprintf(bf, bfsize, "%.2f%%", percent);
+	return bf;
+}
+
+int callchain_node__fprintf_value(struct callchain_node *node,
+				 FILE *fp, u64 total)
+{
+	double percent = 0.0;
+	u64 period = callchain_cumul_hits(node);
+
+	if (callchain_param.mode == CHAIN_FOLDED)
+		period = node->hit;
+	if (total)
+		percent = period * 100.0 / total;
+
+	return percent_color_fprintf(fp, "%.2f%%", percent);
+}
+
 static void free_callchain_node(struct callchain_node *node)
 {
 	struct callchain_list *list, *tmp;
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 544d99ac169c..060e636e33ab 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -230,6 +230,10 @@ static inline int arch_skip_callchain_idx(struct thread *thread __maybe_unused,
 
 char *callchain_list__sym_name(struct callchain_list *cl,
 			       char *bf, size_t bfsize, bool show_dso);
+char *callchain_node__scnprintf_value(struct callchain_node *node,
+				      char *bf, size_t bfsize, u64 total);
+int callchain_node__fprintf_value(struct callchain_node *node,
+				  FILE *fp, u64 total);
 
 void free_callchain(struct callchain_root *root);
 
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1273321 — [PATCH 10/37] perf bpf: Allow BPF program config probing options

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-11-19 19:00 +0100
Subject[PATCH 10/37] perf bpf: Allow BPF program config probing options
Message-ID<qwBF0-44P-35@gated-at.bofh.it>
In reply to#1273315
From: Wang Nan <wangnan0@huawei.com>

By extending the syntax of BPF object section names, this patch allows users to
config probing options like what they can do in 'perf probe'.

The error message in 'perf probe' is also updated.

Test result:

For following BPF file test_probe_glob.c:

  # cat test_probe_glob.c
  __attribute__((section("inlines=no;func=SyS_dup?"), used))

  int func(void *ctx)
  {
	  return 1;
  }

  char _license[] __attribute__((section("license"), used)) = "GPL";
  int _version __attribute__((section("version"), used)) = 0x40300;
  #
  # ./perf record  -e ./test_probe_glob.c ls /
  ...
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 0.013 MB perf.data ]
  # ./perf evlist
  perf_bpf_probe:func_1
  perf_bpf_probe:func

After changing "inlines=no" to "inlines=yes":

  # ./perf record  -e ./test_probe_glob.c ls /
  ...
  [ perf record: Woken up 2 times to write data ]
  [ perf record: Captured and wrote 0.013 MB perf.data ]
  # ./perf evlist
  perf_bpf_probe:func_3
  perf_bpf_probe:func_2
  perf_bpf_probe:func_1
  perf_bpf_probe:func

Then test 'force':

Use following program:

  # cat test_probe_force.c
  __attribute__((section("func=sys_write"), used))

  int funca(void *ctx)
  {
	  return 1;
  }

  __attribute__((section("force=yes;func=sys_write"), used))

  int funcb(void *ctx)
  {
  	return 1;
  }

  char _license[] __attribute__((section("license"), used)) = "GPL";
  int _version __attribute__((section("version"), used)) = 0x40300;
  #

  # perf record -e ./test_probe_force.c usleep 1
  Error: event "func" already exists.
   Hint: Remove existing event by 'perf probe -d'
       or force duplicates by 'perf probe -f'
       or set 'force=yes' in BPF source.
  event syntax error: './test_probe_force.c'
                       \___ Probe point exist. Try 'perf probe -d "*"' and set 'force=yes'

  (add -v to see detail)
  ...

Then replace 'force=no' to 'force=yes':

  # vim test_probe_force.c
  # perf record -e ./test_probe_force.c usleep 1
  [ perf record: Woken up 1 times to write data ]
  [ perf record: Captured and wrote 0.017 MB perf.data ]
  # perf evlist
  perf_bpf_probe:func_1
  perf_bpf_probe:func
  #

Signed-off-by: Wang Nan <wangnan0@huawei.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
Cc: Zefan Li <lizefan@huawei.com>
Cc: pi3orama@163.com
Link: http://lkml.kernel.org/r/1447675815-166222-7-git-send-email-wangnan0@huawei.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/util/bpf-loader.c  | 53 +++++++++++++++++++++++++++++++++++++++++--
 tools/perf/util/probe-event.c |  7 ++++--
 2 files changed, 56 insertions(+), 4 deletions(-)

diff --git a/tools/perf/util/bpf-loader.c b/tools/perf/util/bpf-loader.c
index d0f02ed93804..98f2e5d1a5be 100644
--- a/tools/perf/util/bpf-loader.c
+++ b/tools/perf/util/bpf-loader.c
@@ -7,6 +7,7 @@
 
 #include <bpf/libbpf.h>
 #include <linux/err.h>
+#include <linux/string.h>
 #include "perf.h"
 #include "debug.h"
 #include "bpf-loader.h"
@@ -129,6 +130,38 @@ config__module(const char *value, struct perf_probe_event *pev)
 	return 0;
 }
 
+static int
+config__bool(const char *value,
+	     bool *pbool, bool invert)
+{
+	int err;
+	bool bool_value;
+
+	if (!pbool)
+		return -EINVAL;
+
+	err = strtobool(value, &bool_value);
+	if (err)
+		return err;
+
+	*pbool = invert ? !bool_value : bool_value;
+	return 0;
+}
+
+static int
+config__inlines(const char *value,
+		struct perf_probe_event *pev __maybe_unused)
+{
+	return config__bool(value, &probe_conf.no_inlines, true);
+}
+
+static int
+config__force(const char *value,
+	      struct perf_probe_event *pev __maybe_unused)
+{
+	return config__bool(value, &probe_conf.force_add, false);
+}
+
 static struct {
 	const char *key;
 	const char *usage;
@@ -146,7 +179,19 @@ static struct {
 		.usage	= "module=<module name>    ",
 		.desc	= "Set kprobe module",
 		.func	= config__module,
-	}
+	},
+	{
+		.key	= "inlines",
+		.usage	= "inlines=[yes|no]        ",
+		.desc	= "Probe at inline symbol",
+		.func	= config__inlines,
+	},
+	{
+		.key	= "force",
+		.usage	= "force=[yes|no]          ",
+		.desc	= "Forcibly add events with existing name",
+		.func	= config__force,
+	},
 };
 
 static int
@@ -240,6 +285,10 @@ config_bpf_program(struct bpf_program *prog)
 	const char *config_str;
 	int err;
 
+	/* Initialize per-program probing setting */
+	probe_conf.no_inlines = false;
+	probe_conf.force_add = false;
+
 	config_str = bpf_program__title(prog, false);
 	if (IS_ERR(config_str)) {
 		pr_debug("bpf: unable to get title for program\n");
@@ -544,7 +593,7 @@ int bpf__strerror_probe(struct bpf_object *obj __maybe_unused,
 		scnprintf(buf, size, "%s (add -v to see detail)", emsg);
 		break;
 	}
-	bpf__strerror_entry(EEXIST, "Probe point exist. Try use 'perf probe -d \"*\"'");
+	bpf__strerror_entry(EEXIST, "Probe point exist. Try 'perf probe -d \"*\"' and set 'force=yes'");
 	bpf__strerror_entry(EACCES, "You need to be root");
 	bpf__strerror_entry(EPERM, "You need to be root, and /proc/sys/kernel/kptr_restrict should be 0");
 	bpf__strerror_entry(ENOENT, "You need to check probing points in BPF file");
diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c
index 03875f9154e7..93996ec4bbe3 100644
--- a/tools/perf/util/probe-event.c
+++ b/tools/perf/util/probe-event.c
@@ -2326,8 +2326,11 @@ static int get_new_event_name(char *buf, size_t len, const char *base,
 		goto out;
 
 	if (!allow_suffix) {
-		pr_warning("Error: event \"%s\" already exists. "
-			   "(Use -f to force duplicates.)\n", buf);
+		pr_warning("Error: event \"%s\" already exists.\n"
+			   " Hint: Remove existing event by 'perf probe -d'\n"
+			   "       or force duplicates by 'perf probe -f'\n"
+			   "       or set 'force=yes' in BPF source.\n",
+			   buf);
 		ret = -EEXIST;
 		goto out;
 	}
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1273322 — [PATCH 35/37] perf hists browser: Support folded callchains

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-11-19 19:00 +0100
Subject[PATCH 35/37] perf hists browser: Support folded callchains
Message-ID<qwBF0-44P-25@gated-at.bofh.it>
In reply to#1273315
From: Namhyung Kim <namhyung@kernel.org>

The folded callchain mode prints all chains in a single line.

Currently perf report --tui doesn't support folded callchains.  Like
flat callchains, only leaf nodes are added to the final rbtree so it
should show entries in parent nodes.  To do that, add flat_val list to
struct callchain_node and show them along with the (normal) val list.

For example, folded callchain looks like below:

  $ perf report -g folded --tui
  Samples: 234  of event 'cycles:pp', Event count (approx.): 32605268
    Overhead  Command  Shared Object     Symbol
  -   39.93%  swapper  [kernel.vmlinux]  [k] intel_idle
     + 28.63% intel_idle; cpuidle_enter_state; cpuidle_enter; ...
     + 11.30% intel_idle; cpuidle_enter_state; cpuidle_enter; ...

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Tested-by: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1447047946-1691-9-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/ui/browsers/hists.c | 125 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 124 insertions(+), 1 deletion(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index c44af461a68f..a211b7b6a81e 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -207,6 +207,11 @@ static int callchain_node__count_flat_rows(struct callchain_node *node)
 	return n;
 }
 
+static int callchain_node__count_folded_rows(struct callchain_node *node __maybe_unused)
+{
+	return 1;
+}
+
 static int callchain_node__count_rows(struct callchain_node *node)
 {
 	struct callchain_list *chain;
@@ -215,6 +220,8 @@ static int callchain_node__count_rows(struct callchain_node *node)
 
 	if (callchain_param.mode == CHAIN_FLAT)
 		return callchain_node__count_flat_rows(node);
+	else if (callchain_param.mode == CHAIN_FOLDED)
+		return callchain_node__count_folded_rows(node);
 
 	list_for_each_entry(chain, &node->val, list) {
 		++n;
@@ -311,7 +318,8 @@ static void callchain__init_have_children(struct rb_root *root)
 	for (nd = rb_first(root); nd; nd = rb_next(nd)) {
 		struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node);
 		callchain_node__init_have_children(node, has_sibling);
-		if (callchain_param.mode == CHAIN_FLAT)
+		if (callchain_param.mode == CHAIN_FLAT ||
+		    callchain_param.mode == CHAIN_FOLDED)
 			callchain_node__make_parent_list(node);
 	}
 }
@@ -723,6 +731,116 @@ out:
 	return row - first_row;
 }
 
+static char *hist_browser__folded_callchain_str(struct hist_browser *browser,
+						struct callchain_list *chain,
+						char *value_str, char *old_str)
+{
+	char bf[1024];
+	const char *str;
+	char *new;
+
+	str = callchain_list__sym_name(chain, bf, sizeof(bf),
+				       browser->show_dso);
+	if (old_str) {
+		if (asprintf(&new, "%s%s%s", old_str,
+			     symbol_conf.field_sep ?: ";", str) < 0)
+			new = NULL;
+	} else {
+		if (value_str) {
+			if (asprintf(&new, "%s %s", value_str, str) < 0)
+				new = NULL;
+		} else {
+			if (asprintf(&new, "%s", str) < 0)
+				new = NULL;
+		}
+	}
+	return new;
+}
+
+static int hist_browser__show_callchain_folded(struct hist_browser *browser,
+					       struct rb_root *root,
+					       unsigned short row, u64 total,
+					       print_callchain_entry_fn print,
+					       struct callchain_print_arg *arg,
+					       check_output_full_fn is_output_full)
+{
+	struct rb_node *node;
+	int first_row = row, offset = LEVEL_OFFSET_STEP;
+	bool need_percent;
+
+	node = rb_first(root);
+	need_percent = node && rb_next(node);
+
+	while (node) {
+		struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
+		struct rb_node *next = rb_next(node);
+		struct callchain_list *chain, *first_chain = NULL;
+		int first = true;
+		char *value_str = NULL, *value_str_alloc = NULL;
+		char *chain_str = NULL, *chain_str_alloc = NULL;
+
+		if (arg->row_offset != 0) {
+			arg->row_offset--;
+			goto next;
+		}
+
+		if (need_percent) {
+			char buf[64];
+
+			callchain_node__scnprintf_value(child, buf, sizeof(buf), total);
+			if (asprintf(&value_str, "%s", buf) < 0) {
+				value_str = (char *)"<...>";
+				goto do_print;
+			}
+			value_str_alloc = value_str;
+		}
+
+		list_for_each_entry(chain, &child->parent_val, list) {
+			chain_str = hist_browser__folded_callchain_str(browser,
+						chain, value_str, chain_str);
+			if (first) {
+				first = false;
+				first_chain = chain;
+			}
+
+			if (chain_str == NULL) {
+				chain_str = (char *)"Not enough memory!";
+				goto do_print;
+			}
+
+			chain_str_alloc = chain_str;
+		}
+
+		list_for_each_entry(chain, &child->val, list) {
+			chain_str = hist_browser__folded_callchain_str(browser,
+						chain, value_str, chain_str);
+			if (first) {
+				first = false;
+				first_chain = chain;
+			}
+
+			if (chain_str == NULL) {
+				chain_str = (char *)"Not enough memory!";
+				goto do_print;
+			}
+
+			chain_str_alloc = chain_str;
+		}
+
+do_print:
+		print(browser, first_chain, chain_str, offset, row++, arg);
+		free(value_str_alloc);
+		free(chain_str_alloc);
+
+next:
+		if (is_output_full(browser, row))
+			break;
+		node = next;
+	}
+
+	return row - first_row;
+}
+
 static int hist_browser__show_callchain(struct hist_browser *browser,
 					struct rb_root *root, int level,
 					unsigned short row, u64 total,
@@ -980,6 +1098,11 @@ static int hist_browser__show_entry(struct hist_browser *browser,
 					&entry->sorted_chain, row, total,
 					hist_browser__show_callchain_entry, &arg,
 					hist_browser__check_output_full);
+		} else if (callchain_param.mode == CHAIN_FOLDED) {
+			printed += hist_browser__show_callchain_folded(browser,
+					&entry->sorted_chain, row, total,
+					hist_browser__show_callchain_entry, &arg,
+					hist_browser__check_output_full);
 		} else {
 			printed += hist_browser__show_callchain(browser,
 					&entry->sorted_chain, 1, row, total,
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1273324 — [PATCH 37/37] perf ui/gtk: Support folded callchains

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-11-19 19:00 +0100
Subject[PATCH 37/37] perf ui/gtk: Support folded callchains
Message-ID<qwBF1-44P-39@gated-at.bofh.it>
In reply to#1273315
From: Namhyung Kim <namhyung@kernel.org>

The folded callchain mode is to print all chains in a single line.
Currently perf report --gtk doesn't support folded callchains.  Like
flat callchains, only leaf nodes are added to the final rbtree so it
should show entries in parent nodes.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Tested-by: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1447047946-1691-11-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/ui/gtk/hists.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 62 insertions(+)

diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
index 0b24cd6d38a4..467717276ab6 100644
--- a/tools/perf/ui/gtk/hists.c
+++ b/tools/perf/ui/gtk/hists.c
@@ -152,6 +152,66 @@ static void perf_gtk__add_callchain_flat(struct rb_root *root, GtkTreeStore *sto
 	}
 }
 
+static void perf_gtk__add_callchain_folded(struct rb_root *root, GtkTreeStore *store,
+					   GtkTreeIter *parent, int col, u64 total)
+{
+	struct rb_node *nd;
+
+	for (nd = rb_first(root); nd; nd = rb_next(nd)) {
+		struct callchain_node *node;
+		struct callchain_list *chain;
+		GtkTreeIter iter;
+		char buf[64];
+		char *str, *str_alloc = NULL;
+		bool first = true;
+
+		node = rb_entry(nd, struct callchain_node, rb_node);
+
+		callchain_node__make_parent_list(node);
+
+		list_for_each_entry(chain, &node->parent_val, list) {
+			char name[1024];
+
+			callchain_list__sym_name(chain, name, sizeof(name), false);
+
+			if (asprintf(&str, "%s%s%s",
+				     first ? "" : str_alloc,
+				     first ? "" : symbol_conf.field_sep ?: "; ",
+				     name) < 0)
+				return;
+
+			first = false;
+			free(str_alloc);
+			str_alloc = str;
+		}
+
+		list_for_each_entry(chain, &node->val, list) {
+			char name[1024];
+
+			callchain_list__sym_name(chain, name, sizeof(name), false);
+
+			if (asprintf(&str, "%s%s%s",
+				     first ? "" : str_alloc,
+				     first ? "" : symbol_conf.field_sep ?: "; ",
+				     name) < 0)
+				return;
+
+			first = false;
+			free(str_alloc);
+			str_alloc = str;
+		}
+
+		gtk_tree_store_append(store, &iter, parent);
+
+		callchain_node__scnprintf_value(node, buf, sizeof(buf), total);
+		gtk_tree_store_set(store, &iter, 0, buf, -1);
+
+		gtk_tree_store_set(store, &iter, col, str, -1);
+
+		free(str_alloc);
+	}
+}
+
 static void perf_gtk__add_callchain_graph(struct rb_root *root, GtkTreeStore *store,
 					  GtkTreeIter *parent, int col, u64 total)
 {
@@ -207,6 +267,8 @@ static void perf_gtk__add_callchain(struct rb_root *root, GtkTreeStore *store,
 {
 	if (callchain_param.mode == CHAIN_FLAT)
 		perf_gtk__add_callchain_flat(root, store, parent, col, total);
+	else if (callchain_param.mode == CHAIN_FOLDED)
+		perf_gtk__add_callchain_folded(root, store, parent, col, total);
 	else
 		perf_gtk__add_callchain_graph(root, store, parent, col, total);
 }
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1273325 — [PATCH 36/37] perf ui/gtk: Support flat callchains

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-11-19 19:00 +0100
Subject[PATCH 36/37] perf ui/gtk: Support flat callchains
Message-ID<qwBF0-44P-29@gated-at.bofh.it>
In reply to#1273315
From: Namhyung Kim <namhyung@kernel.org>

The flat callchain mode is to print all chains in a simple flat
hierarchy so make it easy to see.

Currently perf report --gtk doesn't show flat callchains properly.  With
flat callchains, only leaf nodes are added to the final rbtree so it
should show entries in parent nodes.  To do that, add parent_val list to
struct callchain_node and show them along with the (normal) val list.

See the previous commit on TUI support for more information.

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Pekka Enberg <penberg@kernel.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1447047946-1691-10-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/ui/gtk/hists.c | 80 ++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 76 insertions(+), 4 deletions(-)

diff --git a/tools/perf/ui/gtk/hists.c b/tools/perf/ui/gtk/hists.c
index cff7bb9d9632..0b24cd6d38a4 100644
--- a/tools/perf/ui/gtk/hists.c
+++ b/tools/perf/ui/gtk/hists.c
@@ -89,8 +89,71 @@ void perf_gtk__init_hpp(void)
 				perf_gtk__hpp_color_overhead_acc;
 }
 
-static void perf_gtk__add_callchain(struct rb_root *root, GtkTreeStore *store,
-				    GtkTreeIter *parent, int col, u64 total)
+static void perf_gtk__add_callchain_flat(struct rb_root *root, GtkTreeStore *store,
+					 GtkTreeIter *parent, int col, u64 total)
+{
+	struct rb_node *nd;
+	bool has_single_node = (rb_first(root) == rb_last(root));
+
+	for (nd = rb_first(root); nd; nd = rb_next(nd)) {
+		struct callchain_node *node;
+		struct callchain_list *chain;
+		GtkTreeIter iter, new_parent;
+		bool need_new_parent;
+
+		node = rb_entry(nd, struct callchain_node, rb_node);
+
+		new_parent = *parent;
+		need_new_parent = !has_single_node;
+
+		callchain_node__make_parent_list(node);
+
+		list_for_each_entry(chain, &node->parent_val, list) {
+			char buf[128];
+
+			gtk_tree_store_append(store, &iter, &new_parent);
+
+			callchain_node__scnprintf_value(node, buf, sizeof(buf), total);
+			gtk_tree_store_set(store, &iter, 0, buf, -1);
+
+			callchain_list__sym_name(chain, buf, sizeof(buf), false);
+			gtk_tree_store_set(store, &iter, col, buf, -1);
+
+			if (need_new_parent) {
+				/*
+				 * Only show the top-most symbol in a callchain
+				 * if it's not the only callchain.
+				 */
+				new_parent = iter;
+				need_new_parent = false;
+			}
+		}
+
+		list_for_each_entry(chain, &node->val, list) {
+			char buf[128];
+
+			gtk_tree_store_append(store, &iter, &new_parent);
+
+			callchain_node__scnprintf_value(node, buf, sizeof(buf), total);
+			gtk_tree_store_set(store, &iter, 0, buf, -1);
+
+			callchain_list__sym_name(chain, buf, sizeof(buf), false);
+			gtk_tree_store_set(store, &iter, col, buf, -1);
+
+			if (need_new_parent) {
+				/*
+				 * Only show the top-most symbol in a callchain
+				 * if it's not the only callchain.
+				 */
+				new_parent = iter;
+				need_new_parent = false;
+			}
+		}
+	}
+}
+
+static void perf_gtk__add_callchain_graph(struct rb_root *root, GtkTreeStore *store,
+					  GtkTreeIter *parent, int col, u64 total)
 {
 	struct rb_node *nd;
 	bool has_single_node = (rb_first(root) == rb_last(root));
@@ -134,11 +197,20 @@ static void perf_gtk__add_callchain(struct rb_root *root, GtkTreeStore *store,
 			child_total = total;
 
 		/* Now 'iter' contains info of the last callchain_list */
-		perf_gtk__add_callchain(&node->rb_root, store, &iter, col,
-					child_total);
+		perf_gtk__add_callchain_graph(&node->rb_root, store, &iter, col,
+					      child_total);
 	}
 }
 
+static void perf_gtk__add_callchain(struct rb_root *root, GtkTreeStore *store,
+				    GtkTreeIter *parent, int col, u64 total)
+{
+	if (callchain_param.mode == CHAIN_FLAT)
+		perf_gtk__add_callchain_flat(root, store, parent, col, total);
+	else
+		perf_gtk__add_callchain_graph(root, store, parent, col, total);
+}
+
 static void on_row_activated(GtkTreeView *view, GtkTreePath *path,
 			     GtkTreeViewColumn *col __maybe_unused,
 			     gpointer user_data __maybe_unused)
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1273326 — [PATCH 34/37] perf hists browser: Support flat callchains

FromArnaldo Carvalho de Melo <acme@kernel.org>
Date2015-11-19 19:00 +0100
Subject[PATCH 34/37] perf hists browser: Support flat callchains
Message-ID<qwBF1-44P-41@gated-at.bofh.it>
In reply to#1273315
From: Namhyung Kim <namhyung@kernel.org>

The flat callchain mode is to print all chains in a single, simple
hierarchy so make it easy to see.

Currently perf report --tui doesn't show flat callchains properly.  With
flat callchains, only leaf nodes are added to the final rbtree so it
should show entries in parent nodes.  To do that, add parent_val list to
struct callchain_node and show them along with the (normal) val list.

For example, consider following callchains with '-g graph'.

  $ perf report -g graph
  - 39.93%  swapper  [kernel.vmlinux]  [k] intel_idle
       intel_idle
       cpuidle_enter_state
       cpuidle_enter
       call_cpuidle
     - cpu_startup_entry
          28.63% start_secondary
        - 11.30% rest_init
             start_kernel
             x86_64_start_reservations
             x86_64_start_kernel

Before:
  $ perf report -g flat
  - 39.93%  swapper  [kernel.vmlinux]  [k] intel_idle
       28.63% start_secondary
     - 11.30% rest_init
          start_kernel
          x86_64_start_reservations
          x86_64_start_kernel

After:
  $ perf report -g flat
  - 39.93%  swapper  [kernel.vmlinux]  [k] intel_idle
     - 28.63% intel_idle
          cpuidle_enter_state
          cpuidle_enter
          call_cpuidle
          cpu_startup_entry
          start_secondary
     - 11.30% intel_idle
          cpuidle_enter_state
          cpuidle_enter
          call_cpuidle
          cpu_startup_entry
          start_kernel
          x86_64_start_reservations
          x86_64_start_kernel

Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Tested-by: Brendan Gregg <brendan.d.gregg@gmail.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Kan Liang <kan.liang@intel.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Link: http://lkml.kernel.org/r/1447047946-1691-8-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
---
 tools/perf/ui/browsers/hists.c | 122 ++++++++++++++++++++++++++++++++++++++++-
 tools/perf/util/callchain.c    |  44 +++++++++++++++
 tools/perf/util/callchain.h    |   2 +
 3 files changed, 166 insertions(+), 2 deletions(-)

diff --git a/tools/perf/ui/browsers/hists.c b/tools/perf/ui/browsers/hists.c
index 0746d41d9efe..c44af461a68f 100644
--- a/tools/perf/ui/browsers/hists.c
+++ b/tools/perf/ui/browsers/hists.c
@@ -178,12 +178,44 @@ static int callchain_node__count_rows_rb_tree(struct callchain_node *node)
 	return n;
 }
 
+static int callchain_node__count_flat_rows(struct callchain_node *node)
+{
+	struct callchain_list *chain;
+	char folded_sign = 0;
+	int n = 0;
+
+	list_for_each_entry(chain, &node->parent_val, list) {
+		if (!folded_sign) {
+			/* only check first chain list entry */
+			folded_sign = callchain_list__folded(chain);
+			if (folded_sign == '+')
+				return 1;
+		}
+		n++;
+	}
+
+	list_for_each_entry(chain, &node->val, list) {
+		if (!folded_sign) {
+			/* node->parent_val list might be empty */
+			folded_sign = callchain_list__folded(chain);
+			if (folded_sign == '+')
+				return 1;
+		}
+		n++;
+	}
+
+	return n;
+}
+
 static int callchain_node__count_rows(struct callchain_node *node)
 {
 	struct callchain_list *chain;
 	bool unfolded = false;
 	int n = 0;
 
+	if (callchain_param.mode == CHAIN_FLAT)
+		return callchain_node__count_flat_rows(node);
+
 	list_for_each_entry(chain, &node->val, list) {
 		++n;
 		unfolded = chain->unfolded;
@@ -263,7 +295,7 @@ static void callchain_node__init_have_children(struct callchain_node *node,
 	chain = list_entry(node->val.next, struct callchain_list, list);
 	chain->has_children = has_sibling;
 
-	if (!list_empty(&node->val)) {
+	if (node->val.next != node->val.prev) {
 		chain = list_entry(node->val.prev, struct callchain_list, list);
 		chain->has_children = !RB_EMPTY_ROOT(&node->rb_root);
 	}
@@ -279,6 +311,8 @@ static void callchain__init_have_children(struct rb_root *root)
 	for (nd = rb_first(root); nd; nd = rb_next(nd)) {
 		struct callchain_node *node = rb_entry(nd, struct callchain_node, rb_node);
 		callchain_node__init_have_children(node, has_sibling);
+		if (callchain_param.mode == CHAIN_FLAT)
+			callchain_node__make_parent_list(node);
 	}
 }
 
@@ -612,6 +646,83 @@ static int hist_browser__show_callchain_list(struct hist_browser *browser,
 	return 1;
 }
 
+static int hist_browser__show_callchain_flat(struct hist_browser *browser,
+					     struct rb_root *root,
+					     unsigned short row, u64 total,
+					     print_callchain_entry_fn print,
+					     struct callchain_print_arg *arg,
+					     check_output_full_fn is_output_full)
+{
+	struct rb_node *node;
+	int first_row = row, offset = LEVEL_OFFSET_STEP;
+	bool need_percent;
+
+	node = rb_first(root);
+	need_percent = node && rb_next(node);
+
+	while (node) {
+		struct callchain_node *child = rb_entry(node, struct callchain_node, rb_node);
+		struct rb_node *next = rb_next(node);
+		struct callchain_list *chain;
+		char folded_sign = ' ';
+		int first = true;
+		int extra_offset = 0;
+
+		list_for_each_entry(chain, &child->parent_val, list) {
+			bool was_first = first;
+
+			if (first)
+				first = false;
+			else if (need_percent)
+				extra_offset = LEVEL_OFFSET_STEP;
+
+			folded_sign = callchain_list__folded(chain);
+
+			row += hist_browser__show_callchain_list(browser, child,
+							chain, row, total,
+							was_first && need_percent,
+							offset + extra_offset,
+							print, arg);
+
+			if (is_output_full(browser, row))
+				goto out;
+
+			if (folded_sign == '+')
+				goto next;
+		}
+
+		list_for_each_entry(chain, &child->val, list) {
+			bool was_first = first;
+
+			if (first)
+				first = false;
+			else if (need_percent)
+				extra_offset = LEVEL_OFFSET_STEP;
+
+			folded_sign = callchain_list__folded(chain);
+
+			row += hist_browser__show_callchain_list(browser, child,
+							chain, row, total,
+							was_first && need_percent,
+							offset + extra_offset,
+							print, arg);
+
+			if (is_output_full(browser, row))
+				goto out;
+
+			if (folded_sign == '+')
+				break;
+		}
+
+next:
+		if (is_output_full(browser, row))
+			break;
+		node = next;
+	}
+out:
+	return row - first_row;
+}
+
 static int hist_browser__show_callchain(struct hist_browser *browser,
 					struct rb_root *root, int level,
 					unsigned short row, u64 total,
@@ -864,10 +975,17 @@ static int hist_browser__show_entry(struct hist_browser *browser,
 				total = entry->stat.period;
 		}
 
-		printed += hist_browser__show_callchain(browser,
+		if (callchain_param.mode == CHAIN_FLAT) {
+			printed += hist_browser__show_callchain_flat(browser,
+					&entry->sorted_chain, row, total,
+					hist_browser__show_callchain_entry, &arg,
+					hist_browser__check_output_full);
+		} else {
+			printed += hist_browser__show_callchain(browser,
 					&entry->sorted_chain, 1, row, total,
 					hist_browser__show_callchain_entry, &arg,
 					hist_browser__check_output_full);
+		}
 
 		if (arg.is_current_entry)
 			browser->he_selection = entry;
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c
index 717c58c1da58..fc3b1e0d09ee 100644
--- a/tools/perf/util/callchain.c
+++ b/tools/perf/util/callchain.c
@@ -387,6 +387,7 @@ create_child(struct callchain_node *parent, bool inherit_children)
 	}
 	new->parent = parent;
 	INIT_LIST_HEAD(&new->val);
+	INIT_LIST_HEAD(&new->parent_val);
 
 	if (inherit_children) {
 		struct rb_node *n;
@@ -894,6 +895,11 @@ static void free_callchain_node(struct callchain_node *node)
 	struct callchain_node *child;
 	struct rb_node *n;
 
+	list_for_each_entry_safe(list, tmp, &node->parent_val, list) {
+		list_del(&list->list);
+		free(list);
+	}
+
 	list_for_each_entry_safe(list, tmp, &node->val, list) {
 		list_del(&list->list);
 		free(list);
@@ -917,3 +923,41 @@ void free_callchain(struct callchain_root *root)
 
 	free_callchain_node(&root->node);
 }
+
+int callchain_node__make_parent_list(struct callchain_node *node)
+{
+	struct callchain_node *parent = node->parent;
+	struct callchain_list *chain, *new;
+	LIST_HEAD(head);
+
+	while (parent) {
+		list_for_each_entry_reverse(chain, &parent->val, list) {
+			new = malloc(sizeof(*new));
+			if (new == NULL)
+				goto out;
+			*new = *chain;
+			new->has_children = false;
+			list_add_tail(&new->list, &head);
+		}
+		parent = parent->parent;
+	}
+
+	list_for_each_entry_safe_reverse(chain, new, &head, list)
+		list_move_tail(&chain->list, &node->parent_val);
+
+	if (!list_empty(&node->parent_val)) {
+		chain = list_first_entry(&node->parent_val, struct callchain_list, list);
+		chain->has_children = rb_prev(&node->rb_node) || rb_next(&node->rb_node);
+
+		chain = list_first_entry(&node->val, struct callchain_list, list);
+		chain->has_children = false;
+	}
+	return 0;
+
+out:
+	list_for_each_entry_safe(chain, new, &head, list) {
+		list_del(&chain->list);
+		free(chain);
+	}
+	return -ENOMEM;
+}
diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h
index 47bc0c57f764..6e9b5f2099e1 100644
--- a/tools/perf/util/callchain.h
+++ b/tools/perf/util/callchain.h
@@ -56,6 +56,7 @@ enum chain_order {
 struct callchain_node {
 	struct callchain_node	*parent;
 	struct list_head	val;
+	struct list_head	parent_val;
 	struct rb_node		rb_node_in; /* to insert nodes in an rbtree */
 	struct rb_node		rb_node;    /* to sort nodes in an output tree */
 	struct rb_root		rb_root_in; /* input tree of children */
@@ -251,5 +252,6 @@ int callchain_node__fprintf_value(struct callchain_node *node,
 				  FILE *fp, u64 total);
 
 void free_callchain(struct callchain_root *root);
+int callchain_node__make_parent_list(struct callchain_node *node);
 
 #endif	/* __PERF_CALLCHAIN_H */
-- 
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1275471 — Re: [PATCH 34/37] perf hists browser: Support flat callchains

FromFrederic Weisbecker <fweisbec@gmail.com>
Date2015-11-23 16:20 +0100
SubjectRe: [PATCH 34/37] perf hists browser: Support flat callchains
Message-ID<qy14m-3zj-29@gated-at.bofh.it>
In reply to#1273326
On Thu, Nov 19, 2015 at 02:53:20PM -0300, Arnaldo Carvalho de Melo wrote:
> From: Namhyung Kim <namhyung@kernel.org>
> 
> The flat callchain mode is to print all chains in a single, simple
> hierarchy so make it easy to see.
> 
> Currently perf report --tui doesn't show flat callchains properly.  With
> flat callchains, only leaf nodes are added to the final rbtree so it
> should show entries in parent nodes.  To do that, add parent_val list to
> struct callchain_node and show them along with the (normal) val list.
> 
> For example, consider following callchains with '-g graph'.
> 
>   $ perf report -g graph
>   - 39.93%  swapper  [kernel.vmlinux]  [k] intel_idle
>        intel_idle
>        cpuidle_enter_state
>        cpuidle_enter
>        call_cpuidle
>      - cpu_startup_entry
>           28.63% start_secondary
>         - 11.30% rest_init
>              start_kernel
>              x86_64_start_reservations
>              x86_64_start_kernel
> 
> Before:
>   $ perf report -g flat
>   - 39.93%  swapper  [kernel.vmlinux]  [k] intel_idle
>        28.63% start_secondary
>      - 11.30% rest_init
>           start_kernel
>           x86_64_start_reservations
>           x86_64_start_kernel
> 
> After:
>   $ perf report -g flat
>   - 39.93%  swapper  [kernel.vmlinux]  [k] intel_idle
>      - 28.63% intel_idle
>           cpuidle_enter_state
>           cpuidle_enter
>           call_cpuidle
>           cpu_startup_entry
>           start_secondary
>      - 11.30% intel_idle
>           cpuidle_enter_state
>           cpuidle_enter
>           call_cpuidle
>           cpu_startup_entry
>           start_kernel
>           x86_64_start_reservations
>           x86_64_start_kernel
> 
> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
> Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> Tested-by: Brendan Gregg <brendan.d.gregg@gmail.com>
> Cc: Andi Kleen <andi@firstfloor.org>
> Cc: David Ahern <dsahern@gmail.com>
> Cc: Frederic Weisbecker <fweisbec@gmail.com>
> Cc: Jiri Olsa <jolsa@redhat.com>
> Cc: Kan Liang <kan.liang@intel.com>
> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Link: http://lkml.kernel.org/r/1447047946-1691-8-git-send-email-namhyung@kernel.org
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> ---

[...]

> +int callchain_node__make_parent_list(struct callchain_node *node)
> +{
> +	struct callchain_node *parent = node->parent;
> +	struct callchain_list *chain, *new;
> +	LIST_HEAD(head);
> +
> +	while (parent) {
> +		list_for_each_entry_reverse(chain, &parent->val, list) {
> +			new = malloc(sizeof(*new));
> +			if (new == NULL)
> +				goto out;
> +			*new = *chain;
> +			new->has_children = false;
> +			list_add_tail(&new->list, &head);
> +		}
> +		parent = parent->parent;
> +	}
> +
> +	list_for_each_entry_safe_reverse(chain, new, &head, list)
> +		list_move_tail(&chain->list, &node->parent_val);
> +
> +	if (!list_empty(&node->parent_val)) {
> +		chain = list_first_entry(&node->parent_val, struct callchain_list, list);
> +		chain->has_children = rb_prev(&node->rb_node) || rb_next(&node->rb_node);
> +
> +		chain = list_first_entry(&node->val, struct callchain_list, list);
> +		chain->has_children = false;

I'm a bit puzzled with this, can't we rewind through the parents on printing or adding
to the flat rbtree instead of having this parent_val field?

Thanks.
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1276066 — Re: [PATCH 34/37] perf hists browser: Support flat callchains

FromNamhyung Kim <namhyung@kernel.org>
Date2015-11-24 06:30 +0100
SubjectRe: [PATCH 34/37] perf hists browser: Support flat callchains
Message-ID<qyekV-3Pb-3@gated-at.bofh.it>
In reply to#1275471
On Mon, Nov 23, 2015 at 04:16:48PM +0100, Frederic Weisbecker wrote:
> On Thu, Nov 19, 2015 at 02:53:20PM -0300, Arnaldo Carvalho de Melo wrote:
> > From: Namhyung Kim <namhyung@kernel.org>
> > 
> > The flat callchain mode is to print all chains in a single, simple
> > hierarchy so make it easy to see.
> > 
> > Currently perf report --tui doesn't show flat callchains properly.  With
> > flat callchains, only leaf nodes are added to the final rbtree so it
> > should show entries in parent nodes.  To do that, add parent_val list to
> > struct callchain_node and show them along with the (normal) val list.
> > 
> > For example, consider following callchains with '-g graph'.
> > 
> >   $ perf report -g graph
> >   - 39.93%  swapper  [kernel.vmlinux]  [k] intel_idle
> >        intel_idle
> >        cpuidle_enter_state
> >        cpuidle_enter
> >        call_cpuidle
> >      - cpu_startup_entry
> >           28.63% start_secondary
> >         - 11.30% rest_init
> >              start_kernel
> >              x86_64_start_reservations
> >              x86_64_start_kernel
> > 
> > Before:
> >   $ perf report -g flat
> >   - 39.93%  swapper  [kernel.vmlinux]  [k] intel_idle
> >        28.63% start_secondary
> >      - 11.30% rest_init
> >           start_kernel
> >           x86_64_start_reservations
> >           x86_64_start_kernel
> > 
> > After:
> >   $ perf report -g flat
> >   - 39.93%  swapper  [kernel.vmlinux]  [k] intel_idle
> >      - 28.63% intel_idle
> >           cpuidle_enter_state
> >           cpuidle_enter
> >           call_cpuidle
> >           cpu_startup_entry
> >           start_secondary
> >      - 11.30% intel_idle
> >           cpuidle_enter_state
> >           cpuidle_enter
> >           call_cpuidle
> >           cpu_startup_entry
> >           start_kernel
> >           x86_64_start_reservations
> >           x86_64_start_kernel
> > 
> > Signed-off-by: Namhyung Kim <namhyung@kernel.org>
> > Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> > Tested-by: Brendan Gregg <brendan.d.gregg@gmail.com>
> > Cc: Andi Kleen <andi@firstfloor.org>
> > Cc: David Ahern <dsahern@gmail.com>
> > Cc: Frederic Weisbecker <fweisbec@gmail.com>
> > Cc: Jiri Olsa <jolsa@redhat.com>
> > Cc: Kan Liang <kan.liang@intel.com>
> > Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
> > Link: http://lkml.kernel.org/r/1447047946-1691-8-git-send-email-namhyung@kernel.org
> > Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
> > ---
> 
> [...]
> 
> > +int callchain_node__make_parent_list(struct callchain_node *node)
> > +{
> > +	struct callchain_node *parent = node->parent;
> > +	struct callchain_list *chain, *new;
> > +	LIST_HEAD(head);
> > +
> > +	while (parent) {
> > +		list_for_each_entry_reverse(chain, &parent->val, list) {
> > +			new = malloc(sizeof(*new));
> > +			if (new == NULL)
> > +				goto out;
> > +			*new = *chain;
> > +			new->has_children = false;
> > +			list_add_tail(&new->list, &head);
> > +		}
> > +		parent = parent->parent;
> > +	}
> > +
> > +	list_for_each_entry_safe_reverse(chain, new, &head, list)
> > +		list_move_tail(&chain->list, &node->parent_val);
> > +
> > +	if (!list_empty(&node->parent_val)) {
> > +		chain = list_first_entry(&node->parent_val, struct callchain_list, list);
> > +		chain->has_children = rb_prev(&node->rb_node) || rb_next(&node->rb_node);
> > +
> > +		chain = list_first_entry(&node->val, struct callchain_list, list);
> > +		chain->has_children = false;
> 
> I'm a bit puzzled with this, can't we rewind through the parents on printing or adding
> to the flat rbtree instead of having this parent_val field?

Yes, this code is to simplify things on parent nodes.  Maybe we could
go up to parents and print the callchain list there as you said.

However, problem I think is how to handle 'has_children' information
on parents.  That info controls folding status of each callchain.  As
the info is in the struct callchain_list and flat or folded callchain
mode require the info should be in the top-most entry, I cannot share
entries in parent nodes.

Thus I simply copied callchain lists in parents to leaf nodes.  Yes,
it will consume some memory but can simplify the code.

Thank you for your review anyway!
Namhyung
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1276535 — Re: [PATCH 34/37] perf hists browser: Support flat callchains

FromArnaldo Carvalho de Melo <arnaldo.melo@gmail.com>
Date2015-11-24 15:50 +0100
SubjectRe: [PATCH 34/37] perf hists browser: Support flat callchains
Message-ID<qyn4S-Xh-23@gated-at.bofh.it>
In reply to#1276066
Em Tue, Nov 24, 2015 at 02:27:08PM +0900, Namhyung Kim escreveu:
> On Mon, Nov 23, 2015 at 04:16:48PM +0100, Frederic Weisbecker wrote:
> > On Thu, Nov 19, 2015 at 02:53:20PM -0300, Arnaldo Carvalho de Melo wrote:
> > > From: Namhyung Kim <namhyung@kernel.org>
> > [...]
> > 
> > > +int callchain_node__make_parent_list(struct callchain_node *node)
> > > +{
> > > +	struct callchain_node *parent = node->parent;
> > > +	struct callchain_list *chain, *new;
> > > +	LIST_HEAD(head);
> > > +
> > > +	while (parent) {
> > > +		list_for_each_entry_reverse(chain, &parent->val, list) {
> > > +			new = malloc(sizeof(*new));
> > > +			if (new == NULL)
> > > +				goto out;
> > > +			*new = *chain;
> > > +			new->has_children = false;
> > > +			list_add_tail(&new->list, &head);
> > > +		}
> > > +		parent = parent->parent;
> > > +	}
> > > +
> > > +	list_for_each_entry_safe_reverse(chain, new, &head, list)
> > > +		list_move_tail(&chain->list, &node->parent_val);
> > > +
> > > +	if (!list_empty(&node->parent_val)) {
> > > +		chain = list_first_entry(&node->parent_val, struct callchain_list, list);
> > > +		chain->has_children = rb_prev(&node->rb_node) || rb_next(&node->rb_node);
> > > +
> > > +		chain = list_first_entry(&node->val, struct callchain_list, list);
> > > +		chain->has_children = false;
> > 
> > I'm a bit puzzled with this, can't we rewind through the parents on printing or adding
> > to the flat rbtree instead of having this parent_val field?
> 
> Yes, this code is to simplify things on parent nodes.  Maybe we could
> go up to parents and print the callchain list there as you said.
> 
> However, problem I think is how to handle 'has_children' information
> on parents.  That info controls folding status of each callchain.  As
> the info is in the struct callchain_list and flat or folded callchain
> mode require the info should be in the top-most entry, I cannot share
> entries in parent nodes.
> 
> Thus I simply copied callchain lists in parents to leaf nodes.  Yes,
> it will consume some memory but can simplify the code.

I haven't done any measuring, but I'm noticing that 'perf top -g' is
showing more warnings about not being able to process events fast enough
and so ends up losing events, I tried with --max-stack 16 and it helped,
this is just a heads up.

Perhaps my workstation workloads are gettning deeper callchains over
time, but perhaps this is the cost of processing callchains that is
increasing, I need to stop and try to quantify this.

We really need to look at reducing the overhead of processing
callchains.

- Arnaldo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1276958 — Re: [PATCH 34/37] perf hists browser: Support flat callchains

FromNamhyung Kim <namhyung@kernel.org>
Date2015-11-25 02:30 +0100
SubjectRe: [PATCH 34/37] perf hists browser: Support flat callchains
Message-ID<qyx4e-7Bk-7@gated-at.bofh.it>
In reply to#1276535
Hi Arnaldo,

On Tue, Nov 24, 2015 at 12:45:51PM -0200, Arnaldo Carvalho de Melo wrote:
> Em Tue, Nov 24, 2015 at 02:27:08PM +0900, Namhyung Kim escreveu:
> > On Mon, Nov 23, 2015 at 04:16:48PM +0100, Frederic Weisbecker wrote:
> > > On Thu, Nov 19, 2015 at 02:53:20PM -0300, Arnaldo Carvalho de Melo wrote:
> > > > From: Namhyung Kim <namhyung@kernel.org>
> > > [...]
> > > 
> > > > +int callchain_node__make_parent_list(struct callchain_node *node)
> > > > +{
> > > > +	struct callchain_node *parent = node->parent;
> > > > +	struct callchain_list *chain, *new;
> > > > +	LIST_HEAD(head);
> > > > +
> > > > +	while (parent) {
> > > > +		list_for_each_entry_reverse(chain, &parent->val, list) {
> > > > +			new = malloc(sizeof(*new));
> > > > +			if (new == NULL)
> > > > +				goto out;
> > > > +			*new = *chain;
> > > > +			new->has_children = false;
> > > > +			list_add_tail(&new->list, &head);
> > > > +		}
> > > > +		parent = parent->parent;
> > > > +	}
> > > > +
> > > > +	list_for_each_entry_safe_reverse(chain, new, &head, list)
> > > > +		list_move_tail(&chain->list, &node->parent_val);
> > > > +
> > > > +	if (!list_empty(&node->parent_val)) {
> > > > +		chain = list_first_entry(&node->parent_val, struct callchain_list, list);
> > > > +		chain->has_children = rb_prev(&node->rb_node) || rb_next(&node->rb_node);
> > > > +
> > > > +		chain = list_first_entry(&node->val, struct callchain_list, list);
> > > > +		chain->has_children = false;
> > > 
> > > I'm a bit puzzled with this, can't we rewind through the parents on printing or adding
> > > to the flat rbtree instead of having this parent_val field?
> > 
> > Yes, this code is to simplify things on parent nodes.  Maybe we could
> > go up to parents and print the callchain list there as you said.
> > 
> > However, problem I think is how to handle 'has_children' information
> > on parents.  That info controls folding status of each callchain.  As
> > the info is in the struct callchain_list and flat or folded callchain
> > mode require the info should be in the top-most entry, I cannot share
> > entries in parent nodes.
> > 
> > Thus I simply copied callchain lists in parents to leaf nodes.  Yes,
> > it will consume some memory but can simplify the code.
> 
> I haven't done any measuring, but I'm noticing that 'perf top -g' is
> showing more warnings about not being able to process events fast enough
> and so ends up losing events, I tried with --max-stack 16 and it helped,
> this is just a heads up.

OK, but it seems that it's not related to this patch since this patch
only affects flat or folded callchain mode.

> 
> Perhaps my workstation workloads are gettning deeper callchains over
> time, but perhaps this is the cost of processing callchains that is
> increasing, I need to stop and try to quantify this.
> 
> We really need to look at reducing the overhead of processing
> callchains.

Right, but with my multi-thread work, I realized that perf is getting
heavier recently.  I guess it's mostly due to the atomic refcount
work.  I need to get back to the multi-thread work..

Anyway I made a initial multi-thread support for perf top too.  I
think I posted it to the list, but I cannot find the link.  You can
take a look at it on 'perf/top-threaded-v1' branch in my tree.

  git.kernel.org/pub/scm/linux/kernel/git/namhyung/linux-perf.git



Thanks,
Namhyung
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1276960 — Re: [PATCH 34/37] perf hists browser: Support flat callchains

FromArnaldo Carvalho de Melo <arnaldo.melo@gmail.com>
Date2015-11-25 02:40 +0100
SubjectRe: [PATCH 34/37] perf hists browser: Support flat callchains
Message-ID<qyxdT-7EM-1@gated-at.bofh.it>
In reply to#1276958
Em Wed, Nov 25, 2015 at 10:26:08AM +0900, Namhyung Kim escreveu:
> On Tue, Nov 24, 2015 at 12:45:51PM -0200, Arnaldo Carvalho de Melo wrote:
> > Em Tue, Nov 24, 2015 at 02:27:08PM +0900, Namhyung Kim escreveu:
> > > On Mon, Nov 23, 2015 at 04:16:48PM +0100, Frederic Weisbecker wrote:
> > > > On Thu, Nov 19, 2015 at 02:53:20PM -0300, Arnaldo Carvalho de Melo wrote:
> > > > > From: Namhyung Kim <namhyung@kernel.org>
> > > > [...]
> > > Thus I simply copied callchain lists in parents to leaf nodes.  Yes,
> > > it will consume some memory but can simplify the code.
> > 
> > I haven't done any measuring, but I'm noticing that 'perf top -g' is
> > showing more warnings about not being able to process events fast enough
> > and so ends up losing events, I tried with --max-stack 16 and it helped,
> > this is just a heads up.
> 
> OK, but it seems that it's not related to this patch since this patch
> only affects flat or folded callchain mode.

Well, doesn't this patch makes some of the involved data structures
larger, thus putting more pressure on the L1 cache, etc? It may well be
related, but we need to measure.

> > Perhaps my workstation workloads are gettning deeper callchains over
> > time, but perhaps this is the cost of processing callchains that is
> > increasing, I need to stop and try to quantify this.
> > 
> > We really need to look at reducing the overhead of processing
> > callchains.
> 
> Right, but with my multi-thread work, I realized that perf is getting
> heavier recently.  I guess it's mostly due to the atomic refcount
> work.  I need to get back to the multi-thread work..

We really need to measure this ;-)
 
- Arnaldo
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1276968 — Re: [PATCH 34/37] perf hists browser: Support flat callchains

FromArnaldo Carvalho de Melo <arnaldo.melo@gmail.com>
Date2015-11-25 03:20 +0100
SubjectRe: [PATCH 34/37] perf hists browser: Support flat callchains
Message-ID<qyxQB-89y-1@gated-at.bofh.it>
In reply to#1276960
Em Tue, Nov 24, 2015 at 10:34:18PM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Wed, Nov 25, 2015 at 10:26:08AM +0900, Namhyung Kim escreveu:
> > On Tue, Nov 24, 2015 at 12:45:51PM -0200, Arnaldo Carvalho de Melo wrote:
> > > Em Tue, Nov 24, 2015 at 02:27:08PM +0900, Namhyung Kim escreveu:
> > > > On Mon, Nov 23, 2015 at 04:16:48PM +0100, Frederic Weisbecker wrote:
> > > > > On Thu, Nov 19, 2015 at 02:53:20PM -0300, Arnaldo Carvalho de Melo wrote:
> > > > > > From: Namhyung Kim <namhyung@kernel.org>
> > > > > [...]
> > > > Thus I simply copied callchain lists in parents to leaf nodes.  Yes,
> > > > it will consume some memory but can simplify the code.
> > > 
> > > I haven't done any measuring, but I'm noticing that 'perf top -g' is
> > > showing more warnings about not being able to process events fast enough
> > > and so ends up losing events, I tried with --max-stack 16 and it helped,
> > > this is just a heads up.
> > 
> > OK, but it seems that it's not related to this patch since this patch
> > only affects flat or folded callchain mode.
> 
> Well, doesn't this patch makes some of the involved data structures
> larger, thus putting more pressure on the L1 cache, etc? It may well be
> related, but we need to measure.
> 
> > > Perhaps my workstation workloads are gettning deeper callchains over
> > > time, but perhaps this is the cost of processing callchains that is
> > > increasing, I need to stop and try to quantify this.
> > > 
> > > We really need to look at reducing the overhead of processing
> > > callchains.
> > 
> > Right, but with my multi-thread work, I realized that perf is getting
> > heavier recently.  I guess it's mostly due to the atomic refcount
> > work.  I need to get back to the multi-thread work..
> 
> We really need to measure this ;-)

So, something strange, if I use:

[acme@zoo linux]$ cat ~/bin/allmod 
rm -rf ../build/allmodconfig/ ; mkdir ../build/allmodconfig/ ; make O=../build/allmodconfig/ allmodconfig ; make -j32 O=../build/allmodconfig
[acme@zoo linux]$

To generate background load, I don't see that much this:

+    8.55%     8.49%  libc-2┌─Warning!──────────────────────────────────────────────┐ ▒
+    7.08%     6.98%  perf  │Events are being lost, check IO/CPU overload!          │ ▒
+    6.84%     0.04%  perf  │                                                       │ ▒
+    6.01%     0.09%  perf  │You may want to run 'perf' using a RT scheduler policy:│ ▒
+    5.26%     0.13%  [kerne│                                                       │t▒
+    4.96%     1.50%  perf  │ perf top -r 80                                        │ ▒
+    4.76%     3.58%  perf  │                                                       │ ▒
+    4.69%     0.05%  perf  │Or reduce the sampling frequency.                      │ ▒

Its with a low loadavg:

[acme@zoo linux]$ cat /proc/loadavg 
0.75 0.79 0.64 3/549 21259

That it pops up :-\

If I take a snapshot with 'P'

# head -40 perf.hist.0
+   21.43%    21.09%  libc-2.20.so          [.] _int_malloc
+   19.49%     0.00%  perf                  [.] cmd_top
+   19.46%     0.02%  perf                  [.] perf_top__mmap_read_idx
+   19.03%     0.06%  perf                  [.] hist_entry_iter__add
+   16.46%     1.85%  perf                  [.] iter_add_next_cumulative_entry
+   12.09%    11.98%  libc-2.20.so          [.] free
+   10.68%    10.61%  libc-2.20.so          [.] __libc_calloc
+    9.61%     0.09%  perf                  [.] hists__decay_entries
+    8.92%     8.85%  libc-2.20.so          [.] malloc_consolidate
+    8.17%     6.33%  perf                  [.] free_callchain_node
+    7.94%     0.09%  perf                  [.] hist_entry__delete
+    6.22%     0.03%  perf                  [.] callchain_append
+    6.20%     6.11%  perf                  [.] append_chain_children
+    5.44%     1.50%  perf                  [.] __hists__add_entry
+    4.34%     0.14%  [kernel]              [k] entry_SYSCALL_64_fastpath
+    3.69%     3.67%  perf                  [.] sort__dso_cmp
+    3.12%     0.20%  perf                  [.] hists__output_resort
+    2.88%     0.00%  [unknown]             [.] 0x6d86258d4c544155
+    2.88%     0.00%  libc-2.20.so          [.] __libc_start_main
+    2.88%     0.00%  perf                  [.] main
+    2.88%     0.00%  perf                  [.] run_builtin
+    2.66%     0.00%  libpthread-2.20.so    [.] start_thread
+    2.66%     0.00%  perf                  [.] display_thread_tui
+    2.66%     0.00%  perf                  [.] perf_evlist__tui_browse_hists
+    2.66%     0.00%  perf                  [.] perf_evsel__hists_browse
+    2.49%     0.07%  [kernel]              [k] sys_futex
+    2.42%     0.06%  [kernel]              [k] do_futex
     2.24%     0.00%  perf                  [.] perf_top__sort_new_samples
+    1.92%     0.51%  perf                  [.] hists__collapse_resort
+    1.87%     1.86%  perf                  [.] hpp__sort_overhead_acc
+    1.69%     0.09%  libc-2.20.so          [.] __lll_unlock_wake_private
+    1.45%     1.44%  perf                  [.] hpp__nop_cmp
     1.45%     1.43%  perf                  [.] rb_erase
+    1.44%     1.42%  perf                  [.] __sort__hpp_cmp
     1.31%     0.16%  libc-2.20.so          [.] __lll_lock_wait_private
     1.18%     0.19%  [kernel]              [k] futex_wake
+    1.13%     1.13%  perf                  [.] sort__sym_cmp
     1.11%     0.02%  [kernel]              [k] schedule
     1.09%     0.22%  [kernel]              [k] __schedule
     0.99%     0.08%  [kernel]              [k] futex_wait

So its quite a lot of mallocs, i.e. just do a 'perf top -g' and wait a
bit, malloc goes on bubbling up to the top, about the same time it
starts showing that popup screen telling that we're losing events.

If I use --no-children, to see if there is a difference, using either
--call-graph caller or callee, it doesn't get more than about 1%.

Ok, now I tried with "perf top --call-graph caller" i.e. with
--children, and looked at the _int_malloc callchains I get really long,
bogus callchains, see below. That explains why I don't lose events when
I use --max-stack.

I'll have to stop now, and I put the full perf.hist.1 at
http://vger.kernel.org/~acme/perf/perf.hist.1.xz

- Arnaldo

[root@zoo ~]# head -60 perf.hist.1
-   17.92%    17.10%  libc-2.20.so                        [.] _int_malloc
   + 112.80% _int_malloc
     11.14% 0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
        0x41bf5118
        0x41bf5068
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


#1277803 — Re: [PATCH 34/37] perf hists browser: Support flat callchains

FromNamhyung Kim <namhyung@kernel.org>
Date2015-11-25 22:10 +0100
SubjectRe: [PATCH 34/37] perf hists browser: Support flat callchains
Message-ID<qyPua-3am-21@gated-at.bofh.it>
In reply to#1276968
Hi Arnaldo,

On Tue, Nov 24, 2015 at 11:10:25PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Tue, Nov 24, 2015 at 10:34:18PM -0300, Arnaldo Carvalho de Melo escreveu:
> > Em Wed, Nov 25, 2015 at 10:26:08AM +0900, Namhyung Kim escreveu:
> > > On Tue, Nov 24, 2015 at 12:45:51PM -0200, Arnaldo Carvalho de Melo wrote:
> > > > Em Tue, Nov 24, 2015 at 02:27:08PM +0900, Namhyung Kim escreveu:
> > > > > On Mon, Nov 23, 2015 at 04:16:48PM +0100, Frederic Weisbecker wrote:
> > > > > > On Thu, Nov 19, 2015 at 02:53:20PM -0300, Arnaldo Carvalho de Melo wrote:
> > > > > > > From: Namhyung Kim <namhyung@kernel.org>
> > > > > > [...]
> > > > > Thus I simply copied callchain lists in parents to leaf nodes.  Yes,
> > > > > it will consume some memory but can simplify the code.
> > > > 
> > > > I haven't done any measuring, but I'm noticing that 'perf top -g' is
> > > > showing more warnings about not being able to process events fast enough
> > > > and so ends up losing events, I tried with --max-stack 16 and it helped,
> > > > this is just a heads up.
> > > 
> > > OK, but it seems that it's not related to this patch since this patch
> > > only affects flat or folded callchain mode.
> > 
> > Well, doesn't this patch makes some of the involved data structures
> > larger, thus putting more pressure on the L1 cache, etc? It may well be
> > related, but we need to measure.
> > 
> > > > Perhaps my workstation workloads are gettning deeper callchains over
> > > > time, but perhaps this is the cost of processing callchains that is
> > > > increasing, I need to stop and try to quantify this.
> > > > 
> > > > We really need to look at reducing the overhead of processing
> > > > callchains.
> > > 
> > > Right, but with my multi-thread work, I realized that perf is getting
> > > heavier recently.  I guess it's mostly due to the atomic refcount
> > > work.  I need to get back to the multi-thread work..
> > 
> > We really need to measure this ;-)
> 
> So, something strange, if I use:
> 
> [acme@zoo linux]$ cat ~/bin/allmod 
> rm -rf ../build/allmodconfig/ ; mkdir ../build/allmodconfig/ ; make O=../build/allmodconfig/ allmodconfig ; make -j32 O=../build/allmodconfig
> [acme@zoo linux]$
> 
> To generate background load, I don't see that much this:
> 
> +    8.55%     8.49%  libc-2┌─Warning!──────────────────────────────────────────────┐ ▒
> +    7.08%     6.98%  perf  │Events are being lost, check IO/CPU overload!          │ ▒
> +    6.84%     0.04%  perf  │                                                       │ ▒
> +    6.01%     0.09%  perf  │You may want to run 'perf' using a RT scheduler policy:│ ▒
> +    5.26%     0.13%  [kerne│                                                       │t▒
> +    4.96%     1.50%  perf  │ perf top -r 80                                        │ ▒
> +    4.76%     3.58%  perf  │                                                       │ ▒
> +    4.69%     0.05%  perf  │Or reduce the sampling frequency.                      │ ▒
> 
> Its with a low loadavg:
> 
> [acme@zoo linux]$ cat /proc/loadavg 
> 0.75 0.79 0.64 3/549 21259
> 
> That it pops up :-\
> 
> If I take a snapshot with 'P'
> 
> # head -40 perf.hist.0
> +   21.43%    21.09%  libc-2.20.so          [.] _int_malloc
> +   19.49%     0.00%  perf                  [.] cmd_top
> +   19.46%     0.02%  perf                  [.] perf_top__mmap_read_idx
> +   19.03%     0.06%  perf                  [.] hist_entry_iter__add
> +   16.46%     1.85%  perf                  [.] iter_add_next_cumulative_entry
> +   12.09%    11.98%  libc-2.20.so          [.] free
> +   10.68%    10.61%  libc-2.20.so          [.] __libc_calloc
> +    9.61%     0.09%  perf                  [.] hists__decay_entries
> +    8.92%     8.85%  libc-2.20.so          [.] malloc_consolidate
> +    8.17%     6.33%  perf                  [.] free_callchain_node
> +    7.94%     0.09%  perf                  [.] hist_entry__delete
> +    6.22%     0.03%  perf                  [.] callchain_append
> +    6.20%     6.11%  perf                  [.] append_chain_children
> +    5.44%     1.50%  perf                  [.] __hists__add_entry
> +    4.34%     0.14%  [kernel]              [k] entry_SYSCALL_64_fastpath
> +    3.69%     3.67%  perf                  [.] sort__dso_cmp
> +    3.12%     0.20%  perf                  [.] hists__output_resort
> +    2.88%     0.00%  [unknown]             [.] 0x6d86258d4c544155
> +    2.88%     0.00%  libc-2.20.so          [.] __libc_start_main
> +    2.88%     0.00%  perf                  [.] main
> +    2.88%     0.00%  perf                  [.] run_builtin
> +    2.66%     0.00%  libpthread-2.20.so    [.] start_thread
> +    2.66%     0.00%  perf                  [.] display_thread_tui
> +    2.66%     0.00%  perf                  [.] perf_evlist__tui_browse_hists
> +    2.66%     0.00%  perf                  [.] perf_evsel__hists_browse
> +    2.49%     0.07%  [kernel]              [k] sys_futex
> +    2.42%     0.06%  [kernel]              [k] do_futex
>      2.24%     0.00%  perf                  [.] perf_top__sort_new_samples
> +    1.92%     0.51%  perf                  [.] hists__collapse_resort
> +    1.87%     1.86%  perf                  [.] hpp__sort_overhead_acc
> +    1.69%     0.09%  libc-2.20.so          [.] __lll_unlock_wake_private
> +    1.45%     1.44%  perf                  [.] hpp__nop_cmp
>      1.45%     1.43%  perf                  [.] rb_erase
> +    1.44%     1.42%  perf                  [.] __sort__hpp_cmp
>      1.31%     0.16%  libc-2.20.so          [.] __lll_lock_wait_private
>      1.18%     0.19%  [kernel]              [k] futex_wake
> +    1.13%     1.13%  perf                  [.] sort__sym_cmp
>      1.11%     0.02%  [kernel]              [k] schedule
>      1.09%     0.22%  [kernel]              [k] __schedule
>      0.99%     0.08%  [kernel]              [k] futex_wait
> 
> So its quite a lot of mallocs, i.e. just do a 'perf top -g' and wait a
> bit, malloc goes on bubbling up to the top, about the same time it
> starts showing that popup screen telling that we're losing events.
> 
> If I use --no-children, to see if there is a difference, using either
> --call-graph caller or callee, it doesn't get more than about 1%.
> 
> Ok, now I tried with "perf top --call-graph caller" i.e. with
> --children, and looked at the _int_malloc callchains I get really long,
> bogus callchains, see below. That explains why I don't lose events when
> I use --max-stack.
> 
> I'll have to stop now, and I put the full perf.hist.1 at
> http://vger.kernel.org/~acme/perf/perf.hist.1.xz
> 
> - Arnaldo
> 
> [root@zoo ~]# head -60 perf.hist.1
> -   17.92%    17.10%  libc-2.20.so                        [.] _int_malloc
>    + 112.80% _int_malloc
>      11.14% 0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068
>         0x41bf5118
>         0x41bf5068

Hmm.. we should cut off the loop in the broken callchains.  And it'd
be good to apply --hide-unresolved to callchains as well.  I'll take a
look at it.

Thanks,
Namhyung
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[toc] | [prev] | [next] | [standalone]


Page 1 of 3  [1] 2 3  Next page →

Back to top | Article view | linux.kernel


csiph-web