Merge branch 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 17 Sep 2019 00:06:21 +0000 (17:06 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 17 Sep 2019 00:06:21 +0000 (17:06 -0700)
Pull perf updates from Ingo Molnar:
 "Kernel side changes:

   - Improved kbprobes robustness

   - Intel PEBS support for PT hardware tracing

   - Other Intel PT improvements: high order pages memory footprint
     reduction and various related cleanups

   - Misc cleanups

  The perf tooling side has been very busy in this cycle, with over 300
  commits. This is an incomplete high-level summary of the many
  improvements done by over 30 developers:

   - Lots of updates to the following tools:

      'perf c2c'
      'perf config'
      'perf record'
      'perf report'
      'perf script'
      'perf test'
      'perf top'
      'perf trace'

   - Updates to libperf and libtraceevent, and a consolidation of the
     proliferation of x86 instruction decoder libraries.

   - Vendor event updates for Intel and PowerPC CPUs,

   - Updates to hardware tracing tooling for ARM and Intel CPUs,

   - ... and lots of other changes and cleanups - see the shortlog and
     Git log for details"

* 'perf-core-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (322 commits)
  kprobes: Prohibit probing on BUG() and WARN() address
  perf/x86: Make more stuff static
  x86, perf: Fix the dependency of the x86 insn decoder selftest
  objtool: Ignore intentional differences for the x86 insn decoder
  objtool: Update sync-check.sh from perf's check-headers.sh
  perf build: Ignore intentional differences for the x86 insn decoder
  perf intel-pt: Use shared x86 insn decoder
  perf intel-pt: Remove inat.c from build dependency list
  perf: Update .gitignore file
  objtool: Move x86 insn decoder to a common location
  perf metricgroup: Support multiple events for metricgroup
  perf metricgroup: Scale the metric result
  perf pmu: Change convert_scale from static to global
  perf symbols: Move mem_info and branch_info out of symbol.h
  perf auxtrace: Uninline functions that touch perf_session
  perf tools: Remove needless evlist.h include directives
  perf tools: Remove needless evlist.h include directives
  perf tools: Remove needless thread_map.h include directives
  perf tools: Remove needless thread.h include directives
  perf tools: Remove needless map.h include directives
  ...

441 files changed:
arch/x86/Kconfig.debug
arch/x86/events/core.c
arch/x86/events/intel/core.c
arch/x86/events/intel/cstate.c
arch/x86/events/intel/ds.c
arch/x86/events/intel/lbr.c
arch/x86/events/intel/pt.c
arch/x86/events/intel/pt.h
arch/x86/events/intel/rapl.c
arch/x86/events/msr.c
arch/x86/events/perf_event.h
arch/x86/include/asm/intel_pt.h
arch/x86/include/asm/msr-index.h
include/linux/bug.h
include/linux/perf_event.h
include/uapi/linux/perf_event.h
kernel/events/core.c
kernel/kprobes.c
tools/Makefile
tools/arch/x86/include/asm/cpufeatures.h
tools/arch/x86/include/asm/inat.h [moved from tools/perf/util/intel-pt-decoder/inat.h with 100% similarity]
tools/arch/x86/include/asm/inat_types.h [moved from tools/objtool/arch/x86/include/asm/inat_types.h with 100% similarity]
tools/arch/x86/include/asm/insn.h [moved from tools/perf/util/intel-pt-decoder/insn.h with 100% similarity]
tools/arch/x86/include/asm/orc_types.h [moved from tools/objtool/arch/x86/include/asm/orc_types.h with 100% similarity]
tools/arch/x86/lib/inat.c [moved from tools/objtool/arch/x86/lib/inat.c with 98% similarity]
tools/arch/x86/lib/insn.c [moved from tools/objtool/arch/x86/lib/insn.c with 99% similarity]
tools/arch/x86/lib/x86-opcode-map.txt [moved from tools/objtool/arch/x86/lib/x86-opcode-map.txt with 100% similarity]
tools/arch/x86/tools/gen-insn-attr-x86.awk [moved from tools/objtool/arch/x86/tools/gen-insn-attr-x86.awk with 100% similarity]
tools/build/Makefile.feature
tools/build/feature/Makefile
tools/build/feature/test-libcap.c [new file with mode: 0644]
tools/include/linux/bitops.h
tools/include/linux/bits.h
tools/include/linux/const.h [new file with mode: 0644]
tools/include/linux/ring_buffer.h
tools/include/uapi/asm/bitsperlong.h
tools/include/uapi/linux/const.h [new file with mode: 0644]
tools/include/uapi/linux/perf_event.h
tools/lib/traceevent/Makefile
tools/lib/traceevent/event-parse-api.c
tools/lib/traceevent/event-parse-local.h
tools/lib/traceevent/event-parse.c
tools/lib/traceevent/event-parse.h
tools/lib/traceevent/event-plugin.c
tools/objtool/Makefile
tools/objtool/arch/x86/Build
tools/objtool/arch/x86/decode.c
tools/objtool/arch/x86/include/asm/inat.h [deleted file]
tools/objtool/arch/x86/include/asm/insn.h [deleted file]
tools/objtool/sync-check.sh
tools/perf/.gitignore
tools/perf/Documentation/intel-pt.txt
tools/perf/Documentation/itrace.txt
tools/perf/Documentation/perf-config.txt
tools/perf/Documentation/perf-record.txt
tools/perf/Documentation/perf-report.txt
tools/perf/Documentation/perf-script.txt
tools/perf/Documentation/perf-top.txt
tools/perf/Documentation/perf-trace.txt
tools/perf/Documentation/perf.data-file-format.txt
tools/perf/Makefile.config
tools/perf/Makefile.perf
tools/perf/arch/arm/annotate/instructions.c
tools/perf/arch/arm/util/auxtrace.c
tools/perf/arch/arm/util/cs-etm.c
tools/perf/arch/arm64/annotate/instructions.c
tools/perf/arch/arm64/util/arm-spe.c
tools/perf/arch/arm64/util/header.c
tools/perf/arch/arm64/util/sym-handling.c
tools/perf/arch/common.c
tools/perf/arch/common.h
tools/perf/arch/powerpc/entry/syscalls/syscall.tbl
tools/perf/arch/powerpc/util/kvm-stat.c
tools/perf/arch/powerpc/util/mem-events.c
tools/perf/arch/powerpc/util/perf_regs.c
tools/perf/arch/powerpc/util/sym-handling.c
tools/perf/arch/powerpc/util/unwind-libdw.c
tools/perf/arch/s390/util/auxtrace.c
tools/perf/arch/s390/util/kvm-stat.c
tools/perf/arch/x86/tests/bp-modify.c
tools/perf/arch/x86/tests/insn-x86.c
tools/perf/arch/x86/tests/intel-cqm.c
tools/perf/arch/x86/tests/perf-time-to-tsc.c
tools/perf/arch/x86/tests/rdpmc.c
tools/perf/arch/x86/util/archinsn.c
tools/perf/arch/x86/util/auxtrace.c
tools/perf/arch/x86/util/header.c
tools/perf/arch/x86/util/intel-bts.c
tools/perf/arch/x86/util/intel-pt.c
tools/perf/arch/x86/util/kvm-stat.c
tools/perf/arch/x86/util/perf_regs.c
tools/perf/arch/x86/util/tsc.c
tools/perf/bench/epoll-ctl.c
tools/perf/bench/epoll-wait.c
tools/perf/bench/futex-hash.c
tools/perf/bench/futex-lock-pi.c
tools/perf/bench/futex-requeue.c
tools/perf/bench/futex-wake-parallel.c
tools/perf/bench/futex-wake.c
tools/perf/bench/mem-functions.c
tools/perf/bench/numa.c
tools/perf/bench/sched-messaging.c
tools/perf/bench/sched-pipe.c
tools/perf/builtin-annotate.c
tools/perf/builtin-bench.c
tools/perf/builtin-buildid-cache.c
tools/perf/builtin-buildid-list.c
tools/perf/builtin-c2c.c
tools/perf/builtin-config.c
tools/perf/builtin-data.c
tools/perf/builtin-diff.c
tools/perf/builtin-evlist.c
tools/perf/builtin-ftrace.c
tools/perf/builtin-help.c
tools/perf/builtin-inject.c
tools/perf/builtin-kallsyms.c
tools/perf/builtin-kmem.c
tools/perf/builtin-kvm.c
tools/perf/builtin-list.c
tools/perf/builtin-lock.c
tools/perf/builtin-mem.c
tools/perf/builtin-probe.c
tools/perf/builtin-record.c
tools/perf/builtin-report.c
tools/perf/builtin-sched.c
tools/perf/builtin-script.c
tools/perf/builtin-stat.c
tools/perf/builtin-timechart.c
tools/perf/builtin-top.c
tools/perf/builtin-trace.c
tools/perf/builtin-version.c
tools/perf/builtin.h
tools/perf/check-headers.sh
tools/perf/examples/bpf/augmented_raw_syscalls.c
tools/perf/include/bpf/bpf.h
tools/perf/lib/Build [new file with mode: 0644]
tools/perf/lib/Documentation/Makefile [new file with mode: 0644]
tools/perf/lib/Documentation/man/libperf.rst [new file with mode: 0644]
tools/perf/lib/Documentation/tutorial/tutorial.rst [new file with mode: 0644]
tools/perf/lib/Makefile [new file with mode: 0644]
tools/perf/lib/core.c [new file with mode: 0644]
tools/perf/lib/cpumap.c [new file with mode: 0644]
tools/perf/lib/evlist.c [new file with mode: 0644]
tools/perf/lib/evsel.c [new file with mode: 0644]
tools/perf/lib/include/internal/cpumap.h [new file with mode: 0644]
tools/perf/lib/include/internal/evlist.h [new file with mode: 0644]
tools/perf/lib/include/internal/evsel.h [new file with mode: 0644]
tools/perf/lib/include/internal/lib.h [new file with mode: 0644]
tools/perf/lib/include/internal/tests.h [new file with mode: 0644]
tools/perf/lib/include/internal/threadmap.h [new file with mode: 0644]
tools/perf/lib/include/internal/xyarray.h [moved from tools/perf/util/xyarray.h with 77% similarity]
tools/perf/lib/include/perf/core.h [new file with mode: 0644]
tools/perf/lib/include/perf/cpumap.h [new file with mode: 0644]
tools/perf/lib/include/perf/event.h [new file with mode: 0644]
tools/perf/lib/include/perf/evlist.h [new file with mode: 0644]
tools/perf/lib/include/perf/evsel.h [new file with mode: 0644]
tools/perf/lib/include/perf/threadmap.h [new file with mode: 0644]
tools/perf/lib/internal.h [new file with mode: 0644]
tools/perf/lib/lib.c [new file with mode: 0644]
tools/perf/lib/libperf.map [new file with mode: 0644]
tools/perf/lib/libperf.pc.template [new file with mode: 0644]
tools/perf/lib/tests/Makefile [new file with mode: 0644]
tools/perf/lib/tests/test-cpumap.c [new file with mode: 0644]
tools/perf/lib/tests/test-evlist.c [new file with mode: 0644]
tools/perf/lib/tests/test-evsel.c [new file with mode: 0644]
tools/perf/lib/tests/test-threadmap.c [new file with mode: 0644]
tools/perf/lib/threadmap.c [new file with mode: 0644]
tools/perf/lib/xyarray.c [new file with mode: 0644]
tools/perf/perf-sys.h
tools/perf/perf.c
tools/perf/perf.h
tools/perf/pmu-events/arch/powerpc/power9/memory.json
tools/perf/pmu-events/arch/powerpc/power9/other.json
tools/perf/pmu-events/arch/x86/icelake/cache.json [new file with mode: 0644]
tools/perf/pmu-events/arch/x86/icelake/floating-point.json [new file with mode: 0644]
tools/perf/pmu-events/arch/x86/icelake/frontend.json [new file with mode: 0644]
tools/perf/pmu-events/arch/x86/icelake/memory.json [new file with mode: 0644]
tools/perf/pmu-events/arch/x86/icelake/other.json [new file with mode: 0644]
tools/perf/pmu-events/arch/x86/icelake/pipeline.json [new file with mode: 0644]
tools/perf/pmu-events/arch/x86/icelake/virtual-memory.json [new file with mode: 0644]
tools/perf/pmu-events/arch/x86/mapfile.csv
tools/perf/pmu-events/arch/x86/tremontx/cache.json [new file with mode: 0644]
tools/perf/pmu-events/arch/x86/tremontx/frontend.json [new file with mode: 0644]
tools/perf/pmu-events/arch/x86/tremontx/memory.json [new file with mode: 0644]
tools/perf/pmu-events/arch/x86/tremontx/other.json [new file with mode: 0644]
tools/perf/pmu-events/arch/x86/tremontx/pipeline.json [new file with mode: 0644]
tools/perf/pmu-events/arch/x86/tremontx/uncore-memory.json [new file with mode: 0644]
tools/perf/pmu-events/arch/x86/tremontx/uncore-other.json [new file with mode: 0644]
tools/perf/pmu-events/arch/x86/tremontx/uncore-power.json [new file with mode: 0644]
tools/perf/pmu-events/arch/x86/tremontx/virtual-memory.json [new file with mode: 0644]
tools/perf/scripts/perl/Perf-Trace-Util/Context.c
tools/perf/scripts/python/Perf-Trace-Util/Context.c
tools/perf/tests/attr.c
tools/perf/tests/backward-ring-buffer.c
tools/perf/tests/bitmap.c
tools/perf/tests/bp_account.c
tools/perf/tests/bp_signal.c
tools/perf/tests/bp_signal_overflow.c
tools/perf/tests/bpf.c
tools/perf/tests/builtin-test.c
tools/perf/tests/code-reading.c
tools/perf/tests/cpumap.c
tools/perf/tests/dso-data.c
tools/perf/tests/dwarf-unwind.c
tools/perf/tests/event-times.c
tools/perf/tests/event_update.c
tools/perf/tests/evsel-roundtrip-name.c
tools/perf/tests/evsel-tp-sched.c
tools/perf/tests/expr.c
tools/perf/tests/hists_common.c
tools/perf/tests/hists_cumulate.c
tools/perf/tests/hists_filter.c
tools/perf/tests/hists_link.c
tools/perf/tests/hists_output.c
tools/perf/tests/keep-tracking.c
tools/perf/tests/kmod-path.c
tools/perf/tests/llvm.c
tools/perf/tests/make
tools/perf/tests/mem.c
tools/perf/tests/mem2node.c
tools/perf/tests/mmap-basic.c
tools/perf/tests/mmap-thread-lookup.c
tools/perf/tests/openat-syscall-all-cpus.c
tools/perf/tests/openat-syscall-tp-fields.c
tools/perf/tests/openat-syscall.c
tools/perf/tests/parse-events.c
tools/perf/tests/parse-no-sample-id-all.c
tools/perf/tests/perf-record.c
tools/perf/tests/sample-parsing.c
tools/perf/tests/sdt.c
tools/perf/tests/shell/record+zstd_comp_decomp.sh
tools/perf/tests/shell/trace+probe_vfs_getname.sh
tools/perf/tests/stat.c
tools/perf/tests/sw-clock.c
tools/perf/tests/switch-tracking.c
tools/perf/tests/task-exit.c
tools/perf/tests/thread-map.c
tools/perf/tests/thread-mg-share.c
tools/perf/tests/time-utils-test.c
tools/perf/tests/topology.c
tools/perf/tests/unit_number__scnprintf.c
tools/perf/tests/vmlinux-kallsyms.c
tools/perf/tests/wp.c
tools/perf/trace/beauty/ioctl.c
tools/perf/ui/browser.c
tools/perf/ui/browser.h
tools/perf/ui/browsers/annotate.c
tools/perf/ui/browsers/header.c
tools/perf/ui/browsers/hists.c
tools/perf/ui/browsers/map.c
tools/perf/ui/browsers/res_sample.c
tools/perf/ui/browsers/scripts.c
tools/perf/ui/gtk/annotate.c
tools/perf/ui/gtk/browser.c
tools/perf/ui/gtk/gtk.h
tools/perf/ui/gtk/helpline.c
tools/perf/ui/gtk/hists.c
tools/perf/ui/gtk/setup.c
tools/perf/ui/gtk/util.c
tools/perf/ui/helpline.c
tools/perf/ui/helpline.h
tools/perf/ui/hist.c
tools/perf/ui/progress.c
tools/perf/ui/setup.c
tools/perf/ui/stdio/hist.c
tools/perf/ui/tui/helpline.c
tools/perf/ui/tui/progress.c
tools/perf/ui/tui/setup.c
tools/perf/ui/tui/util.c
tools/perf/ui/util.c
tools/perf/ui/util.h
tools/perf/util/Build
tools/perf/util/annotate.c
tools/perf/util/annotate.h
tools/perf/util/arm-spe.c
tools/perf/util/auxtrace.c
tools/perf/util/auxtrace.h
tools/perf/util/bpf-event.c
tools/perf/util/bpf-event.h
tools/perf/util/bpf-loader.c
tools/perf/util/bpf-loader.h
tools/perf/util/bpf-prologue.c
tools/perf/util/branch.c
tools/perf/util/branch.h
tools/perf/util/build-id.c
tools/perf/util/build-id.h
tools/perf/util/c++/clang-c.h
tools/perf/util/c++/clang-test.cpp
tools/perf/util/cacheline.c [new file with mode: 0644]
tools/perf/util/cacheline.h [new file with mode: 0644]
tools/perf/util/callchain.c
tools/perf/util/callchain.h
tools/perf/util/cap.c [new file with mode: 0644]
tools/perf/util/cap.h [new file with mode: 0644]
tools/perf/util/cgroup.c
tools/perf/util/cgroup.h
tools/perf/util/cloexec.c
tools/perf/util/color.c
tools/perf/util/color_config.c
tools/perf/util/config.c
tools/perf/util/counts.c
tools/perf/util/counts.h
tools/perf/util/cpumap.c
tools/perf/util/cpumap.h
tools/perf/util/cputopo.c
tools/perf/util/cputopo.h
tools/perf/util/cs-etm.c
tools/perf/util/cs-etm.h
tools/perf/util/data-convert-bt.c
tools/perf/util/data.c
tools/perf/util/db-export.c
tools/perf/util/db-export.h
tools/perf/util/debug.c
tools/perf/util/debug.h
tools/perf/util/dso.c
tools/perf/util/dso.h
tools/perf/util/dsos.c [new file with mode: 0644]
tools/perf/util/dsos.h [new file with mode: 0644]
tools/perf/util/dwarf-aux.c
tools/perf/util/dwarf-aux.h
tools/perf/util/env.c
tools/perf/util/env.h
tools/perf/util/event.c
tools/perf/util/event.h
tools/perf/util/events_stats.h [new file with mode: 0644]
tools/perf/util/evlist.c
tools/perf/util/evlist.h
tools/perf/util/evsel.c
tools/perf/util/evsel.h
tools/perf/util/evsel_fprintf.c
tools/perf/util/evswitch.c [new file with mode: 0644]
tools/perf/util/evswitch.h [new file with mode: 0644]
tools/perf/util/expr.y
tools/perf/util/genelf.c
tools/perf/util/genelf_debug.c
tools/perf/util/get_current_dir_name.c
tools/perf/util/header.c
tools/perf/util/header.h
tools/perf/util/hist.c
tools/perf/util/hist.h
tools/perf/util/intel-bts.c
tools/perf/util/intel-pt-decoder/Build
tools/perf/util/intel-pt-decoder/gen-insn-attr-x86.awk [deleted file]
tools/perf/util/intel-pt-decoder/inat.c [deleted file]
tools/perf/util/intel-pt-decoder/inat_types.h [deleted file]
tools/perf/util/intel-pt-decoder/insn.c [deleted file]
tools/perf/util/intel-pt-decoder/intel-pt-decoder.c
tools/perf/util/intel-pt-decoder/intel-pt-insn-decoder.c
tools/perf/util/intel-pt-decoder/x86-opcode-map.txt [deleted file]
tools/perf/util/intel-pt.c
tools/perf/util/jitdump.c
tools/perf/util/kvm-stat.h
tools/perf/util/llvm-utils.c
tools/perf/util/llvm-utils.h
tools/perf/util/lzma.c
tools/perf/util/machine.c
tools/perf/util/machine.h
tools/perf/util/map.c
tools/perf/util/map.h
tools/perf/util/map_groups.h
tools/perf/util/mem-events.c
tools/perf/util/mem-events.h
tools/perf/util/mem2node.c
tools/perf/util/mem2node.h
tools/perf/util/metricgroup.c
tools/perf/util/metricgroup.h
tools/perf/util/mmap.c
tools/perf/util/mmap.h
tools/perf/util/namespaces.c
tools/perf/util/namespaces.h
tools/perf/util/ordered-events.c
tools/perf/util/parse-branch-options.c
tools/perf/util/parse-events.c
tools/perf/util/parse-events.h
tools/perf/util/parse-events.l
tools/perf/util/path.c
tools/perf/util/path.h
tools/perf/util/perf-hooks.c
tools/perf/util/pmu.c
tools/perf/util/pmu.h
tools/perf/util/probe-event.c
tools/perf/util/probe-file.c
tools/perf/util/probe-finder.c
tools/perf/util/pstack.c
tools/perf/util/python-ext-sources
tools/perf/util/python.c
tools/perf/util/record.c
tools/perf/util/record.h [new file with mode: 0644]
tools/perf/util/s390-cpumsf.c
tools/perf/util/s390-sample-raw.c
tools/perf/util/sample-raw.c
tools/perf/util/sample-raw.h
tools/perf/util/scripting-engines/trace-event-perl.c
tools/perf/util/scripting-engines/trace-event-python.c
tools/perf/util/session.c
tools/perf/util/session.h
tools/perf/util/setup.py
tools/perf/util/sort.c
tools/perf/util/sort.h
tools/perf/util/stat-display.c
tools/perf/util/stat-shadow.c
tools/perf/util/stat.c
tools/perf/util/stat.h
tools/perf/util/strbuf.c
tools/perf/util/svghelper.c
tools/perf/util/svghelper.h
tools/perf/util/symbol-elf.c
tools/perf/util/symbol-minimal.c
tools/perf/util/symbol.c
tools/perf/util/symbol.h
tools/perf/util/symbol_fprintf.c
tools/perf/util/symsrc.h [new file with mode: 0644]
tools/perf/util/syscalltbl.c
tools/perf/util/syscalltbl.h
tools/perf/util/target.c
tools/perf/util/thread-stack.c
tools/perf/util/thread.c
tools/perf/util/thread.h
tools/perf/util/thread_map.c
tools/perf/util/thread_map.h
tools/perf/util/time-utils.c
tools/perf/util/time-utils.h
tools/perf/util/tool.h
tools/perf/util/top.c
tools/perf/util/top.h
tools/perf/util/trace-event-info.c
tools/perf/util/trace-event-parse.c
tools/perf/util/trace-event-read.c
tools/perf/util/trace-event-scripting.c
tools/perf/util/trace-event.h
tools/perf/util/trigger.h
tools/perf/util/unwind-libdw.c
tools/perf/util/unwind-libunwind-local.c
tools/perf/util/unwind-libunwind.c
tools/perf/util/unwind.h
tools/perf/util/util-cxx.h [deleted file]
tools/perf/util/util.c
tools/perf/util/util.h
tools/perf/util/values.c
tools/perf/util/vdso.c
tools/perf/util/zlib.c

index 71c92db47c412af588686489f4a9c6dec4e96929..bf9cd83de7773087951ad22dcafba77dba9b54f8 100644 (file)
@@ -171,7 +171,7 @@ config HAVE_MMIOTRACE_SUPPORT
 
 config X86_DECODER_SELFTEST
        bool "x86 instruction decoder selftest"
-       depends on DEBUG_KERNEL && KPROBES
+       depends on DEBUG_KERNEL && INSTRUCTION_DECODER
        depends on !COMPILE_TEST
        ---help---
         Perform x86 instruction decoder selftests at build time.
index 325959d19d9a859b0f153d9c3a09ec9fe54833a2..15b90b1a8fb171d6dbcdda96de6e451d8713d95b 100644 (file)
@@ -1005,6 +1005,27 @@ static int collect_events(struct cpu_hw_events *cpuc, struct perf_event *leader,
 
        /* current number of events already accepted */
        n = cpuc->n_events;
+       if (!cpuc->n_events)
+               cpuc->pebs_output = 0;
+
+       if (!cpuc->is_fake && leader->attr.precise_ip) {
+               /*
+                * For PEBS->PT, if !aux_event, the group leader (PT) went
+                * away, the group was broken down and this singleton event
+                * can't schedule any more.
+                */
+               if (is_pebs_pt(leader) && !leader->aux_event)
+                       return -EINVAL;
+
+               /*
+                * pebs_output: 0: no PEBS so far, 1: PT, 2: DS
+                */
+               if (cpuc->pebs_output &&
+                   cpuc->pebs_output != is_pebs_pt(leader) + 1)
+                       return -EINVAL;
+
+               cpuc->pebs_output = is_pebs_pt(leader) + 1;
+       }
 
        if (is_x86_event(leader)) {
                if (n >= max_count)
@@ -2241,6 +2262,17 @@ static int x86_pmu_check_period(struct perf_event *event, u64 value)
        return 0;
 }
 
+static int x86_pmu_aux_output_match(struct perf_event *event)
+{
+       if (!(pmu.capabilities & PERF_PMU_CAP_AUX_OUTPUT))
+               return 0;
+
+       if (x86_pmu.aux_output_match)
+               return x86_pmu.aux_output_match(event);
+
+       return 0;
+}
+
 static struct pmu pmu = {
        .pmu_enable             = x86_pmu_enable,
        .pmu_disable            = x86_pmu_disable,
@@ -2266,6 +2298,8 @@ static struct pmu pmu = {
        .sched_task             = x86_pmu_sched_task,
        .task_ctx_size          = sizeof(struct x86_perf_task_context),
        .check_period           = x86_pmu_check_period,
+
+       .aux_output_match       = x86_pmu_aux_output_match,
 };
 
 void arch_perf_update_userpage(struct perf_event *event,
index e4c2cb65ea50a15ef8c35a934e87f23dfdf32ee0..43c966d1208ebe1b5abeef7058e884d0d6e81c14 100644 (file)
@@ -18,6 +18,7 @@
 #include <asm/cpufeature.h>
 #include <asm/hardirq.h>
 #include <asm/intel-family.h>
+#include <asm/intel_pt.h>
 #include <asm/apic.h>
 #include <asm/cpu_device_id.h>
 
@@ -3298,6 +3299,13 @@ static int intel_pmu_hw_config(struct perf_event *event)
                }
        }
 
+       if (event->attr.aux_output) {
+               if (!event->attr.precise_ip)
+                       return -EINVAL;
+
+               event->hw.flags |= PERF_X86_EVENT_PEBS_VIA_PT;
+       }
+
        if (event->attr.type != PERF_TYPE_RAW)
                return 0;
 
@@ -3816,6 +3824,14 @@ static int intel_pmu_check_period(struct perf_event *event, u64 value)
        return intel_pmu_has_bts_period(event, value) ? -EINVAL : 0;
 }
 
+static int intel_pmu_aux_output_match(struct perf_event *event)
+{
+       if (!x86_pmu.intel_cap.pebs_output_pt_available)
+               return 0;
+
+       return is_intel_pt_event(event);
+}
+
 PMU_FORMAT_ATTR(offcore_rsp, "config1:0-63");
 
 PMU_FORMAT_ATTR(ldlat, "config1:0-15");
@@ -3940,6 +3956,8 @@ static __initconst const struct x86_pmu intel_pmu = {
        .sched_task             = intel_pmu_sched_task,
 
        .check_period           = intel_pmu_check_period,
+
+       .aux_output_match       = intel_pmu_aux_output_match,
 };
 
 static __init void intel_clovertown_quirk(void)
index 688592b34564987a726a944cc178a897175b5d68..db498b5d4aae67802beb2811eac36f3dbad624ad 100644 (file)
@@ -446,7 +446,7 @@ static int cstate_cpu_init(unsigned int cpu)
        return 0;
 }
 
-const struct attribute_group *core_attr_update[] = {
+static const struct attribute_group *core_attr_update[] = {
        &group_cstate_core_c1,
        &group_cstate_core_c3,
        &group_cstate_core_c6,
@@ -454,7 +454,7 @@ const struct attribute_group *core_attr_update[] = {
        NULL,
 };
 
-const struct attribute_group *pkg_attr_update[] = {
+static const struct attribute_group *pkg_attr_update[] = {
        &group_cstate_pkg_c2,
        &group_cstate_pkg_c3,
        &group_cstate_pkg_c6,
index f1269e804e9b70a1e144ede95677d6ddb5f76044..ce83950036c56ad8f88459a6a6f7a44decdeeb04 100644 (file)
@@ -902,6 +902,9 @@ struct event_constraint *intel_pebs_constraints(struct perf_event *event)
  */
 static inline bool pebs_needs_sched_cb(struct cpu_hw_events *cpuc)
 {
+       if (cpuc->n_pebs == cpuc->n_pebs_via_pt)
+               return false;
+
        return cpuc->n_pebs && (cpuc->n_pebs == cpuc->n_large_pebs);
 }
 
@@ -919,6 +922,9 @@ static inline void pebs_update_threshold(struct cpu_hw_events *cpuc)
        u64 threshold;
        int reserved;
 
+       if (cpuc->n_pebs_via_pt)
+               return;
+
        if (x86_pmu.flags & PMU_FL_PEBS_ALL)
                reserved = x86_pmu.max_pebs_events + x86_pmu.num_counters_fixed;
        else
@@ -1059,10 +1065,40 @@ void intel_pmu_pebs_add(struct perf_event *event)
        cpuc->n_pebs++;
        if (hwc->flags & PERF_X86_EVENT_LARGE_PEBS)
                cpuc->n_large_pebs++;
+       if (hwc->flags & PERF_X86_EVENT_PEBS_VIA_PT)
+               cpuc->n_pebs_via_pt++;
 
        pebs_update_state(needed_cb, cpuc, event, true);
 }
 
+static void intel_pmu_pebs_via_pt_disable(struct perf_event *event)
+{
+       struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+       if (!is_pebs_pt(event))
+               return;
+
+       if (!(cpuc->pebs_enabled & ~PEBS_VIA_PT_MASK))
+               cpuc->pebs_enabled &= ~PEBS_VIA_PT_MASK;
+}
+
+static void intel_pmu_pebs_via_pt_enable(struct perf_event *event)
+{
+       struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+       struct hw_perf_event *hwc = &event->hw;
+       struct debug_store *ds = cpuc->ds;
+
+       if (!is_pebs_pt(event))
+               return;
+
+       if (!(event->hw.flags & PERF_X86_EVENT_LARGE_PEBS))
+               cpuc->pebs_enabled |= PEBS_PMI_AFTER_EACH_RECORD;
+
+       cpuc->pebs_enabled |= PEBS_OUTPUT_PT;
+
+       wrmsrl(MSR_RELOAD_PMC0 + hwc->idx, ds->pebs_event_reset[hwc->idx]);
+}
+
 void intel_pmu_pebs_enable(struct perf_event *event)
 {
        struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
@@ -1100,6 +1136,8 @@ void intel_pmu_pebs_enable(struct perf_event *event)
        } else {
                ds->pebs_event_reset[hwc->idx] = 0;
        }
+
+       intel_pmu_pebs_via_pt_enable(event);
 }
 
 void intel_pmu_pebs_del(struct perf_event *event)
@@ -1111,6 +1149,8 @@ void intel_pmu_pebs_del(struct perf_event *event)
        cpuc->n_pebs--;
        if (hwc->flags & PERF_X86_EVENT_LARGE_PEBS)
                cpuc->n_large_pebs--;
+       if (hwc->flags & PERF_X86_EVENT_PEBS_VIA_PT)
+               cpuc->n_pebs_via_pt--;
 
        pebs_update_state(needed_cb, cpuc, event, false);
 }
@@ -1120,7 +1160,8 @@ void intel_pmu_pebs_disable(struct perf_event *event)
        struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
        struct hw_perf_event *hwc = &event->hw;
 
-       if (cpuc->n_pebs == cpuc->n_large_pebs)
+       if (cpuc->n_pebs == cpuc->n_large_pebs &&
+           cpuc->n_pebs != cpuc->n_pebs_via_pt)
                intel_pmu_drain_pebs_buffer();
 
        cpuc->pebs_enabled &= ~(1ULL << hwc->idx);
@@ -1131,6 +1172,8 @@ void intel_pmu_pebs_disable(struct perf_event *event)
        else if (event->hw.flags & PERF_X86_EVENT_PEBS_ST)
                cpuc->pebs_enabled &= ~(1ULL << 63);
 
+       intel_pmu_pebs_via_pt_disable(event);
+
        if (cpuc->enabled)
                wrmsrl(MSR_IA32_PEBS_ENABLE, cpuc->pebs_enabled);
 
@@ -2031,6 +2074,12 @@ void __init intel_ds_init(void)
                                          PERF_SAMPLE_REGS_INTR);
                        }
                        pr_cont("PEBS fmt4%c%s, ", pebs_type, pebs_qual);
+
+                       if (x86_pmu.intel_cap.pebs_output_pt_available) {
+                               pr_cont("PEBS-via-PT, ");
+                               x86_get_pmu()->capabilities |= PERF_PMU_CAP_AUX_OUTPUT;
+                       }
+
                        break;
 
                default:
index 6f814a27416b4268b94f0d83a69b022548c226e3..ea54634eabf3d99b262404997c56296b784a3ec7 100644 (file)
@@ -273,7 +273,7 @@ static inline bool lbr_from_signext_quirk_needed(void)
        return !tsx_support && (lbr_desc[lbr_format] & LBR_TSX);
 }
 
-DEFINE_STATIC_KEY_FALSE(lbr_from_quirk_key);
+static DEFINE_STATIC_KEY_FALSE(lbr_from_quirk_key);
 
 /* If quirk is enabled, ensure sign extension is 63 bits: */
 inline u64 lbr_from_signext_quirk_wr(u64 val)
index d3dc2274ddd419ed7db5d44af16b4ff70d4ec723..b1bb4d28e0be7ecbf162057357fc49715948b0b6 100644 (file)
@@ -545,33 +545,62 @@ static void pt_config_buffer(void *buf, unsigned int topa_idx,
        wrmsrl(MSR_IA32_RTIT_OUTPUT_MASK, reg);
 }
 
-/*
- * Keep ToPA table-related metadata on the same page as the actual table,
- * taking up a few words from the top
- */
-
-#define TENTS_PER_PAGE (((PAGE_SIZE - 40) / sizeof(struct topa_entry)) - 1)
-
 /**
- * struct topa - page-sized ToPA table with metadata at the top
- * @table:     actual ToPA table entries, as understood by PT hardware
+ * struct topa - ToPA metadata
  * @list:      linkage to struct pt_buffer's list of tables
- * @phys:      physical address of this page
  * @offset:    offset of the first entry in this table in the buffer
  * @size:      total size of all entries in this table
  * @last:      index of the last initialized entry in this table
+ * @z_count:   how many times the first entry repeats
  */
 struct topa {
-       struct topa_entry       table[TENTS_PER_PAGE];
        struct list_head        list;
-       u64                     phys;
        u64                     offset;
        size_t                  size;
        int                     last;
+       unsigned int            z_count;
 };
 
+/*
+ * Keep ToPA table-related metadata on the same page as the actual table,
+ * taking up a few words from the top
+ */
+
+#define TENTS_PER_PAGE \
+       ((PAGE_SIZE - sizeof(struct topa)) / sizeof(struct topa_entry))
+
+/**
+ * struct topa_page - page-sized ToPA table with metadata at the top
+ * @table:     actual ToPA table entries, as understood by PT hardware
+ * @topa:      metadata
+ */
+struct topa_page {
+       struct topa_entry       table[TENTS_PER_PAGE];
+       struct topa             topa;
+};
+
+static inline struct topa_page *topa_to_page(struct topa *topa)
+{
+       return container_of(topa, struct topa_page, topa);
+}
+
+static inline struct topa_page *topa_entry_to_page(struct topa_entry *te)
+{
+       return (struct topa_page *)((unsigned long)te & PAGE_MASK);
+}
+
+static inline phys_addr_t topa_pfn(struct topa *topa)
+{
+       return PFN_DOWN(virt_to_phys(topa_to_page(topa)));
+}
+
 /* make -1 stand for the last table entry */
-#define TOPA_ENTRY(t, i) ((i) == -1 ? &(t)->table[(t)->last] : &(t)->table[(i)])
+#define TOPA_ENTRY(t, i)                               \
+       ((i) == -1                                      \
+               ? &topa_to_page(t)->table[(t)->last]    \
+               : &topa_to_page(t)->table[(i)])
+#define TOPA_ENTRY_SIZE(t, i) (sizes(TOPA_ENTRY((t), (i))->size))
+#define TOPA_ENTRY_PAGES(t, i) (1 << TOPA_ENTRY((t), (i))->size)
 
 /**
  * topa_alloc() - allocate page-sized ToPA table
@@ -583,27 +612,26 @@ struct topa {
 static struct topa *topa_alloc(int cpu, gfp_t gfp)
 {
        int node = cpu_to_node(cpu);
-       struct topa *topa;
+       struct topa_page *tp;
        struct page *p;
 
        p = alloc_pages_node(node, gfp | __GFP_ZERO, 0);
        if (!p)
                return NULL;
 
-       topa = page_address(p);
-       topa->last = 0;
-       topa->phys = page_to_phys(p);
+       tp = page_address(p);
+       tp->topa.last = 0;
 
        /*
         * In case of singe-entry ToPA, always put the self-referencing END
         * link as the 2nd entry in the table
         */
        if (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries)) {
-               TOPA_ENTRY(topa, 1)->base = topa->phys >> TOPA_SHIFT;
-               TOPA_ENTRY(topa, 1)->end = 1;
+               TOPA_ENTRY(&tp->topa, 1)->base = page_to_phys(p);
+               TOPA_ENTRY(&tp->topa, 1)->end = 1;
        }
 
-       return topa;
+       return &tp->topa;
 }
 
 /**
@@ -643,7 +671,7 @@ static void topa_insert_table(struct pt_buffer *buf, struct topa *topa)
 
        BUG_ON(last->last != TENTS_PER_PAGE - 1);
 
-       TOPA_ENTRY(last, -1)->base = topa->phys >> TOPA_SHIFT;
+       TOPA_ENTRY(last, -1)->base = topa_pfn(topa);
        TOPA_ENTRY(last, -1)->end = 1;
 }
 
@@ -670,7 +698,7 @@ static bool topa_table_full(struct topa *topa)
  *
  * Return:     0 on success or error code.
  */
-static int topa_insert_pages(struct pt_buffer *buf, gfp_t gfp)
+static int topa_insert_pages(struct pt_buffer *buf, int cpu, gfp_t gfp)
 {
        struct topa *topa = buf->last;
        int order = 0;
@@ -681,13 +709,18 @@ static int topa_insert_pages(struct pt_buffer *buf, gfp_t gfp)
                order = page_private(p);
 
        if (topa_table_full(topa)) {
-               topa = topa_alloc(buf->cpu, gfp);
+               topa = topa_alloc(cpu, gfp);
                if (!topa)
                        return -ENOMEM;
 
                topa_insert_table(buf, topa);
        }
 
+       if (topa->z_count == topa->last - 1) {
+               if (order == TOPA_ENTRY(topa, topa->last - 1)->size)
+                       topa->z_count++;
+       }
+
        TOPA_ENTRY(topa, -1)->base = page_to_phys(p) >> TOPA_SHIFT;
        TOPA_ENTRY(topa, -1)->size = order;
        if (!buf->snapshot &&
@@ -713,23 +746,26 @@ static void pt_topa_dump(struct pt_buffer *buf)
        struct topa *topa;
 
        list_for_each_entry(topa, &buf->tables, list) {
+               struct topa_page *tp = topa_to_page(topa);
                int i;
 
-               pr_debug("# table @%p (%016Lx), off %llx size %zx\n", topa->table,
-                        topa->phys, topa->offset, topa->size);
+               pr_debug("# table @%p, off %llx size %zx\n", tp->table,
+                        topa->offset, topa->size);
                for (i = 0; i < TENTS_PER_PAGE; i++) {
                        pr_debug("# entry @%p (%lx sz %u %c%c%c) raw=%16llx\n",
-                                &topa->table[i],
-                                (unsigned long)topa->table[i].base << TOPA_SHIFT,
-                                sizes(topa->table[i].size),
-                                topa->table[i].end ?  'E' : ' ',
-                                topa->table[i].intr ? 'I' : ' ',
-                                topa->table[i].stop ? 'S' : ' ',
-                                *(u64 *)&topa->table[i]);
+                                &tp->table[i],
+                                (unsigned long)tp->table[i].base << TOPA_SHIFT,
+                                sizes(tp->table[i].size),
+                                tp->table[i].end ?  'E' : ' ',
+                                tp->table[i].intr ? 'I' : ' ',
+                                tp->table[i].stop ? 'S' : ' ',
+                                *(u64 *)&tp->table[i]);
                        if ((intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries) &&
-                            topa->table[i].stop) ||
-                           topa->table[i].end)
+                            tp->table[i].stop) ||
+                           tp->table[i].end)
                                break;
+                       if (!i && topa->z_count)
+                               i += topa->z_count;
                }
        }
 }
@@ -771,7 +807,7 @@ static void pt_update_head(struct pt *pt)
 
        /* offset of the current output region within this table */
        for (topa_idx = 0; topa_idx < buf->cur_idx; topa_idx++)
-               base += sizes(buf->cur->table[topa_idx].size);
+               base += TOPA_ENTRY_SIZE(buf->cur, topa_idx);
 
        if (buf->snapshot) {
                local_set(&buf->data_size, base);
@@ -791,7 +827,7 @@ static void pt_update_head(struct pt *pt)
  */
 static void *pt_buffer_region(struct pt_buffer *buf)
 {
-       return phys_to_virt(buf->cur->table[buf->cur_idx].base << TOPA_SHIFT);
+       return phys_to_virt(TOPA_ENTRY(buf->cur, buf->cur_idx)->base << TOPA_SHIFT);
 }
 
 /**
@@ -800,7 +836,7 @@ static void *pt_buffer_region(struct pt_buffer *buf)
  */
 static size_t pt_buffer_region_size(struct pt_buffer *buf)
 {
-       return sizes(buf->cur->table[buf->cur_idx].size);
+       return TOPA_ENTRY_SIZE(buf->cur, buf->cur_idx);
 }
 
 /**
@@ -830,7 +866,7 @@ static void pt_handle_status(struct pt *pt)
                 * know.
                 */
                if (!intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries) ||
-                   buf->output_off == sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) {
+                   buf->output_off == pt_buffer_region_size(buf)) {
                        perf_aux_output_flag(&pt->handle,
                                             PERF_AUX_FLAG_TRUNCATED);
                        advance++;
@@ -868,9 +904,11 @@ static void pt_handle_status(struct pt *pt)
 static void pt_read_offset(struct pt_buffer *buf)
 {
        u64 offset, base_topa;
+       struct topa_page *tp;
 
        rdmsrl(MSR_IA32_RTIT_OUTPUT_BASE, base_topa);
-       buf->cur = phys_to_virt(base_topa);
+       tp = phys_to_virt(base_topa);
+       buf->cur = &tp->topa;
 
        rdmsrl(MSR_IA32_RTIT_OUTPUT_MASK, offset);
        /* offset within current output region */
@@ -879,29 +917,97 @@ static void pt_read_offset(struct pt_buffer *buf)
        buf->cur_idx = (offset & 0xffffff80) >> 7;
 }
 
-/**
- * pt_topa_next_entry() - obtain index of the first page in the next ToPA entry
- * @buf:       PT buffer.
- * @pg:                Page offset in the buffer.
- *
- * When advancing to the next output region (ToPA entry), given a page offset
- * into the buffer, we need to find the offset of the first page in the next
- * region.
- */
-static unsigned int pt_topa_next_entry(struct pt_buffer *buf, unsigned int pg)
+static struct topa_entry *
+pt_topa_entry_for_page(struct pt_buffer *buf, unsigned int pg)
 {
-       struct topa_entry *te = buf->topa_index[pg];
+       struct topa_page *tp;
+       struct topa *topa;
+       unsigned int idx, cur_pg = 0, z_pg = 0, start_idx = 0;
 
-       /* one region */
-       if (buf->first == buf->last && buf->first->last == 1)
-               return pg;
+       /*
+        * Indicates a bug in the caller.
+        */
+       if (WARN_ON_ONCE(pg >= buf->nr_pages))
+               return NULL;
+
+       /*
+        * First, find the ToPA table where @pg fits. With high
+        * order allocations, there shouldn't be many of these.
+        */
+       list_for_each_entry(topa, &buf->tables, list) {
+               if (topa->offset + topa->size > pg << PAGE_SHIFT)
+                       goto found;
+       }
+
+       /*
+        * Hitting this means we have a problem in the ToPA
+        * allocation code.
+        */
+       WARN_ON_ONCE(1);
 
-       do {
-               pg++;
-               pg &= buf->nr_pages - 1;
-       } while (buf->topa_index[pg] == te);
+       return NULL;
 
-       return pg;
+found:
+       /*
+        * Indicates a problem in the ToPA allocation code.
+        */
+       if (WARN_ON_ONCE(topa->last == -1))
+               return NULL;
+
+       tp = topa_to_page(topa);
+       cur_pg = PFN_DOWN(topa->offset);
+       if (topa->z_count) {
+               z_pg = TOPA_ENTRY_PAGES(topa, 0) * (topa->z_count + 1);
+               start_idx = topa->z_count + 1;
+       }
+
+       /*
+        * Multiple entries at the beginning of the table have the same size,
+        * ideally all of them; if @pg falls there, the search is done.
+        */
+       if (pg >= cur_pg && pg < cur_pg + z_pg) {
+               idx = (pg - cur_pg) / TOPA_ENTRY_PAGES(topa, 0);
+               return &tp->table[idx];
+       }
+
+       /*
+        * Otherwise, slow path: iterate through the remaining entries.
+        */
+       for (idx = start_idx, cur_pg += z_pg; idx < topa->last; idx++) {
+               if (cur_pg + TOPA_ENTRY_PAGES(topa, idx) > pg)
+                       return &tp->table[idx];
+
+               cur_pg += TOPA_ENTRY_PAGES(topa, idx);
+       }
+
+       /*
+        * Means we couldn't find a ToPA entry in the table that does match.
+        */
+       WARN_ON_ONCE(1);
+
+       return NULL;
+}
+
+static struct topa_entry *
+pt_topa_prev_entry(struct pt_buffer *buf, struct topa_entry *te)
+{
+       unsigned long table = (unsigned long)te & ~(PAGE_SIZE - 1);
+       struct topa_page *tp;
+       struct topa *topa;
+
+       tp = (struct topa_page *)table;
+       if (tp->table != te)
+               return --te;
+
+       topa = &tp->topa;
+       if (topa == buf->first)
+               topa = buf->last;
+       else
+               topa = list_prev_entry(topa, list);
+
+       tp = topa_to_page(topa);
+
+       return &tp->table[topa->last - 1];
 }
 
 /**
@@ -925,8 +1031,7 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf,
        unsigned long idx, npages, wakeup;
 
        /* can't stop in the middle of an output region */
-       if (buf->output_off + handle->size + 1 <
-           sizes(TOPA_ENTRY(buf->cur, buf->cur_idx)->size)) {
+       if (buf->output_off + handle->size + 1 < pt_buffer_region_size(buf)) {
                perf_aux_output_flag(handle, PERF_AUX_FLAG_TRUNCATED);
                return -EINVAL;
        }
@@ -937,9 +1042,13 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf,
                return 0;
 
        /* clear STOP and INT from current entry */
-       buf->topa_index[buf->stop_pos]->stop = 0;
-       buf->topa_index[buf->stop_pos]->intr = 0;
-       buf->topa_index[buf->intr_pos]->intr = 0;
+       if (buf->stop_te) {
+               buf->stop_te->stop = 0;
+               buf->stop_te->intr = 0;
+       }
+
+       if (buf->intr_te)
+               buf->intr_te->intr = 0;
 
        /* how many pages till the STOP marker */
        npages = handle->size >> PAGE_SHIFT;
@@ -950,7 +1059,12 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf,
 
        idx = (head >> PAGE_SHIFT) + npages;
        idx &= buf->nr_pages - 1;
-       buf->stop_pos = idx;
+
+       if (idx != buf->stop_pos) {
+               buf->stop_pos = idx;
+               buf->stop_te = pt_topa_entry_for_page(buf, idx);
+               buf->stop_te = pt_topa_prev_entry(buf, buf->stop_te);
+       }
 
        wakeup = handle->wakeup >> PAGE_SHIFT;
 
@@ -960,50 +1074,19 @@ static int pt_buffer_reset_markers(struct pt_buffer *buf,
                idx = wakeup;
 
        idx &= buf->nr_pages - 1;
-       buf->intr_pos = idx;
+       if (idx != buf->intr_pos) {
+               buf->intr_pos = idx;
+               buf->intr_te = pt_topa_entry_for_page(buf, idx);
+               buf->intr_te = pt_topa_prev_entry(buf, buf->intr_te);
+       }
 
-       buf->topa_index[buf->stop_pos]->stop = 1;
-       buf->topa_index[buf->stop_pos]->intr = 1;
-       buf->topa_index[buf->intr_pos]->intr = 1;
+       buf->stop_te->stop = 1;
+       buf->stop_te->intr = 1;
+       buf->intr_te->intr = 1;
 
        return 0;
 }
 
-/**
- * pt_buffer_setup_topa_index() - build topa_index[] table of regions
- * @buf:       PT buffer.
- *
- * topa_index[] references output regions indexed by offset into the
- * buffer for purposes of quick reverse lookup.
- */
-static void pt_buffer_setup_topa_index(struct pt_buffer *buf)
-{
-       struct topa *cur = buf->first, *prev = buf->last;
-       struct topa_entry *te_cur = TOPA_ENTRY(cur, 0),
-               *te_prev = TOPA_ENTRY(prev, prev->last - 1);
-       int pg = 0, idx = 0;
-
-       while (pg < buf->nr_pages) {
-               int tidx;
-
-               /* pages within one topa entry */
-               for (tidx = 0; tidx < 1 << te_cur->size; tidx++, pg++)
-                       buf->topa_index[pg] = te_prev;
-
-               te_prev = te_cur;
-
-               if (idx == cur->last - 1) {
-                       /* advance to next topa table */
-                       idx = 0;
-                       cur = list_entry(cur->list.next, struct topa, list);
-               } else {
-                       idx++;
-               }
-               te_cur = TOPA_ENTRY(cur, idx);
-       }
-
-}
-
 /**
  * pt_buffer_reset_offsets() - adjust buffer's write pointers from aux_head
  * @buf:       PT buffer.
@@ -1021,18 +1104,20 @@ static void pt_buffer_setup_topa_index(struct pt_buffer *buf)
  */
 static void pt_buffer_reset_offsets(struct pt_buffer *buf, unsigned long head)
 {
+       struct topa_page *cur_tp;
+       struct topa_entry *te;
        int pg;
 
        if (buf->snapshot)
                head &= (buf->nr_pages << PAGE_SHIFT) - 1;
 
        pg = (head >> PAGE_SHIFT) & (buf->nr_pages - 1);
-       pg = pt_topa_next_entry(buf, pg);
+       te = pt_topa_entry_for_page(buf, pg);
 
-       buf->cur = (struct topa *)((unsigned long)buf->topa_index[pg] & PAGE_MASK);
-       buf->cur_idx = ((unsigned long)buf->topa_index[pg] -
-                       (unsigned long)buf->cur) / sizeof(struct topa_entry);
-       buf->output_off = head & (sizes(buf->cur->table[buf->cur_idx].size) - 1);
+       cur_tp = topa_entry_to_page(te);
+       buf->cur = &cur_tp->topa;
+       buf->cur_idx = te - TOPA_ENTRY(buf->cur, 0);
+       buf->output_off = head & (pt_buffer_region_size(buf) - 1);
 
        local64_set(&buf->head, head);
        local_set(&buf->data_size, 0);
@@ -1061,31 +1146,29 @@ static void pt_buffer_fini_topa(struct pt_buffer *buf)
  * @size:      Total size of all regions within this ToPA.
  * @gfp:       Allocation flags.
  */
-static int pt_buffer_init_topa(struct pt_buffer *buf, unsigned long nr_pages,
-                              gfp_t gfp)
+static int pt_buffer_init_topa(struct pt_buffer *buf, int cpu,
+                              unsigned long nr_pages, gfp_t gfp)
 {
        struct topa *topa;
        int err;
 
-       topa = topa_alloc(buf->cpu, gfp);
+       topa = topa_alloc(cpu, gfp);
        if (!topa)
                return -ENOMEM;
 
        topa_insert_table(buf, topa);
 
        while (buf->nr_pages < nr_pages) {
-               err = topa_insert_pages(buf, gfp);
+               err = topa_insert_pages(buf, cpu, gfp);
                if (err) {
                        pt_buffer_fini_topa(buf);
                        return -ENOMEM;
                }
        }
 
-       pt_buffer_setup_topa_index(buf);
-
        /* link last table to the first one, unless we're double buffering */
        if (intel_pt_validate_hw_cap(PT_CAP_topa_multiple_entries)) {
-               TOPA_ENTRY(buf->last, -1)->base = buf->first->phys >> TOPA_SHIFT;
+               TOPA_ENTRY(buf->last, -1)->base = topa_pfn(buf->first);
                TOPA_ENTRY(buf->last, -1)->end = 1;
        }
 
@@ -1119,18 +1202,18 @@ pt_buffer_setup_aux(struct perf_event *event, void **pages,
                cpu = raw_smp_processor_id();
        node = cpu_to_node(cpu);
 
-       buf = kzalloc_node(offsetof(struct pt_buffer, topa_index[nr_pages]),
-                          GFP_KERNEL, node);
+       buf = kzalloc_node(sizeof(struct pt_buffer), GFP_KERNEL, node);
        if (!buf)
                return NULL;
 
-       buf->cpu = cpu;
        buf->snapshot = snapshot;
        buf->data_pages = pages;
+       buf->stop_pos = -1;
+       buf->intr_pos = -1;
 
        INIT_LIST_HEAD(&buf->tables);
 
-       ret = pt_buffer_init_topa(buf, nr_pages, GFP_KERNEL);
+       ret = pt_buffer_init_topa(buf, cpu, nr_pages, GFP_KERNEL);
        if (ret) {
                kfree(buf);
                return NULL;
@@ -1296,7 +1379,7 @@ void intel_pt_interrupt(void)
                        return;
                }
 
-               pt_config_buffer(buf->cur->table, buf->cur_idx,
+               pt_config_buffer(topa_to_page(buf->cur)->table, buf->cur_idx,
                                 buf->output_off);
                pt_config(event);
        }
@@ -1361,7 +1444,7 @@ static void pt_event_start(struct perf_event *event, int mode)
        WRITE_ONCE(pt->handle_nmi, 1);
        hwc->state = 0;
 
-       pt_config_buffer(buf->cur->table, buf->cur_idx,
+       pt_config_buffer(topa_to_page(buf->cur)->table, buf->cur_idx,
                         buf->output_off);
        pt_config(event);
 
@@ -1481,6 +1564,11 @@ void cpu_emergency_stop_pt(void)
                pt_event_stop(pt->handle.event, PERF_EF_UPDATE);
 }
 
+int is_intel_pt_event(struct perf_event *event)
+{
+       return event->pmu == &pt_pmu.pmu;
+}
+
 static __init int pt_init(void)
 {
        int ret, cpu, prior_warn = 0;
index 63fe4063fbd69f7b2e907c41febfb58fd9dee05c..1d2bb75723741461b47b70825fe3475cf9531127 100644 (file)
@@ -53,7 +53,6 @@ struct pt_pmu {
 /**
  * struct pt_buffer - buffer configuration; one buffer per task_struct or
  *             cpu, depending on perf event configuration
- * @cpu:       cpu for per-cpu allocation
  * @tables:    list of ToPA tables in this buffer
  * @first:     shorthand for first topa table
  * @last:      shorthand for last topa table
@@ -65,13 +64,14 @@ struct pt_pmu {
  * @lost:      if data was lost/truncated
  * @head:      logical write offset inside the buffer
  * @snapshot:  if this is for a snapshot/overwrite counter
- * @stop_pos:  STOP topa entry in the buffer
- * @intr_pos:  INT topa entry in the buffer
+ * @stop_pos:  STOP topa entry index
+ * @intr_pos:  INT topa entry index
+ * @stop_te:   STOP topa entry pointer
+ * @intr_te:   INT topa entry pointer
  * @data_pages:        array of pages from perf
  * @topa_index:        table of topa entries indexed by page offset
  */
 struct pt_buffer {
-       int                     cpu;
        struct list_head        tables;
        struct topa             *first, *last, *cur;
        unsigned int            cur_idx;
@@ -80,9 +80,9 @@ struct pt_buffer {
        local_t                 data_size;
        local64_t               head;
        bool                    snapshot;
-       unsigned long           stop_pos, intr_pos;
+       long                    stop_pos, intr_pos;
+       struct topa_entry       *stop_te, *intr_te;
        void                    **data_pages;
-       struct topa_entry       *topa_index[0];
 };
 
 #define PT_FILTERS_NUM 4
index 64ab51ffdf06308c22dba65134d654c599f07c22..f34b9491ea6eafa4cc7d293bd5aaffec5b62a5e0 100644 (file)
@@ -634,7 +634,7 @@ static void cleanup_rapl_pmus(void)
        kfree(rapl_pmus);
 }
 
-const struct attribute_group *rapl_attr_update[] = {
+static const struct attribute_group *rapl_attr_update[] = {
        &rapl_events_cores_group,
        &rapl_events_pkg_group,
        &rapl_events_ram_group,
index 9431447541e9707d54b74aa04dcae34cce670ee2..5812e8747d1f0de1e739960d5b5bf3947c3d73be 100644 (file)
@@ -167,7 +167,7 @@ static const struct attribute_group *attr_groups[] = {
        NULL,
 };
 
-const struct attribute_group *attr_update[] = {
+static const struct attribute_group *attr_update[] = {
        &group_aperf,
        &group_mperf,
        &group_pperf,
index 8751008fc1703d231168ebfbcd4b1ed1107bb6f7..ecacfbf4ebc12c6fa3d64139f7cdf90ef02c76e1 100644 (file)
@@ -76,6 +76,7 @@ static inline bool constraint_match(struct event_constraint *c, u64 ecode)
 #define PERF_X86_EVENT_EXCL_ACCT       0x0100 /* accounted EXCL event */
 #define PERF_X86_EVENT_AUTO_RELOAD     0x0200 /* use PEBS auto-reload */
 #define PERF_X86_EVENT_LARGE_PEBS      0x0400 /* use large PEBS */
+#define PERF_X86_EVENT_PEBS_VIA_PT     0x0800 /* use PT buffer for PEBS */
 
 struct amd_nb {
        int nb_id;  /* NorthBridge id */
@@ -85,6 +86,11 @@ struct amd_nb {
 };
 
 #define PEBS_COUNTER_MASK      ((1ULL << MAX_PEBS_EVENTS) - 1)
+#define PEBS_PMI_AFTER_EACH_RECORD BIT_ULL(60)
+#define PEBS_OUTPUT_OFFSET     61
+#define PEBS_OUTPUT_MASK       (3ull << PEBS_OUTPUT_OFFSET)
+#define PEBS_OUTPUT_PT         (1ull << PEBS_OUTPUT_OFFSET)
+#define PEBS_VIA_PT_MASK       (PEBS_OUTPUT_PT | PEBS_PMI_AFTER_EACH_RECORD)
 
 /*
  * Flags PEBS can handle without an PMI.
@@ -211,6 +217,8 @@ struct cpu_hw_events {
        u64                     pebs_enabled;
        int                     n_pebs;
        int                     n_large_pebs;
+       int                     n_pebs_via_pt;
+       int                     pebs_output;
 
        /* Current super set of events hardware configuration */
        u64                     pebs_data_cfg;
@@ -510,6 +518,8 @@ union perf_capabilities {
                 */
                u64     full_width_write:1;
                u64     pebs_baseline:1;
+               u64     pebs_metrics_available:1;
+               u64     pebs_output_pt_available:1;
        };
        u64     capabilities;
 };
@@ -692,6 +702,8 @@ struct x86_pmu {
         * Check period value for PERF_EVENT_IOC_PERIOD ioctl.
         */
        int (*check_period) (struct perf_event *event, u64 period);
+
+       int (*aux_output_match) (struct perf_event *event);
 };
 
 struct x86_perf_task_context {
@@ -901,6 +913,11 @@ static inline int amd_pmu_init(void)
 
 #endif /* CONFIG_CPU_SUP_AMD */
 
+static inline int is_pebs_pt(struct perf_event *event)
+{
+       return !!(event->hw.flags & PERF_X86_EVENT_PEBS_VIA_PT);
+}
+
 #ifdef CONFIG_CPU_SUP_INTEL
 
 static inline bool intel_pmu_has_bts_period(struct perf_event *event, u64 period)
index 634f99b1dc22e8b584364c7544f787ab1d68641f..423b788f495e92ce8b059509c84feedbb66d9e37 100644 (file)
@@ -28,10 +28,12 @@ enum pt_capabilities {
 void cpu_emergency_stop_pt(void);
 extern u32 intel_pt_validate_hw_cap(enum pt_capabilities cap);
 extern u32 intel_pt_validate_cap(u32 *caps, enum pt_capabilities cap);
+extern int is_intel_pt_event(struct perf_event *event);
 #else
 static inline void cpu_emergency_stop_pt(void) {}
 static inline u32 intel_pt_validate_hw_cap(enum pt_capabilities cap) { return 0; }
 static inline u32 intel_pt_validate_cap(u32 *caps, enum pt_capabilities capability) { return 0; }
+static inline int is_intel_pt_event(struct perf_event *event) { return 0; }
 #endif
 
 #endif /* _ASM_X86_INTEL_PT_H */
index 271d837d69a8868118d811dabaa5739d482c2c0c..de753206b4274e35fbdd58cd50eaeaf69475447b 100644 (file)
 /* Alternative perfctr range with full access. */
 #define MSR_IA32_PMC0                  0x000004c1
 
+/* Auto-reload via MSR instead of DS area */
+#define MSR_RELOAD_PMC0                        0x000014c1
+#define MSR_RELOAD_FIXED_CTR0          0x00001309
+
 /* AMD64 MSRs. Not complete. See the architecture manual for a more
    complete list. */
 
index fe5916550da8c5c4da102dd91385eef8123167f6..f639bd0122f3958b28daf0724e5e1a889d7e4a66 100644 (file)
@@ -47,6 +47,11 @@ void generic_bug_clear_once(void);
 
 #else  /* !CONFIG_GENERIC_BUG */
 
+static inline void *find_bug(unsigned long bugaddr)
+{
+       return NULL;
+}
+
 static inline enum bug_trap_type report_bug(unsigned long bug_addr,
                                            struct pt_regs *regs)
 {
index e8ad3c590a231d7b1f64ca73a437c2105da4eac5..61448c19a132c29c92238e782330401ddf0fba17 100644 (file)
@@ -246,6 +246,7 @@ struct perf_event;
 #define PERF_PMU_CAP_ITRACE                    0x20
 #define PERF_PMU_CAP_HETEROGENEOUS_CPUS                0x40
 #define PERF_PMU_CAP_NO_EXCLUDE                        0x80
+#define PERF_PMU_CAP_AUX_OUTPUT                        0x100
 
 /**
  * struct pmu - generic performance monitoring unit
@@ -446,6 +447,16 @@ struct pmu {
        void (*addr_filters_sync)       (struct perf_event *event);
                                        /* optional */
 
+       /*
+        * Check if event can be used for aux_output purposes for
+        * events of this PMU.
+        *
+        * Runs from perf_event_open(). Should return 0 for "no match"
+        * or non-zero for "match".
+        */
+       int (*aux_output_match)         (struct perf_event *event);
+                                       /* optional */
+
        /*
         * Filter events for PMU-specific reasons.
         */
@@ -681,6 +692,9 @@ struct perf_event {
        struct perf_addr_filter_range   *addr_filter_ranges;
        unsigned long                   addr_filters_gen;
 
+       /* for aux_output events */
+       struct perf_event               *aux_event;
+
        void (*destroy)(struct perf_event *);
        struct rcu_head                 rcu_head;
 
index 7198ddd0c6b11d07286aa60504aedc6a0bea69ed..bb7b271397a665d31b30d2986c8783267b1ad0e6 100644 (file)
@@ -374,7 +374,8 @@ struct perf_event_attr {
                                namespaces     :  1, /* include namespaces data */
                                ksymbol        :  1, /* include ksymbol events */
                                bpf_event      :  1, /* include bpf events */
-                               __reserved_1   : 33;
+                               aux_output     :  1, /* generate AUX records instead of events */
+                               __reserved_1   : 32;
 
        union {
                __u32           wakeup_events;    /* wakeup every n events */
index 0463c1151baebb612b617cbf3b189fdde1990d28..2aad959e6def727accc954163a3d8f532e3fd83b 100644 (file)
@@ -1887,6 +1887,89 @@ list_del_event(struct perf_event *event, struct perf_event_context *ctx)
        ctx->generation++;
 }
 
+static int
+perf_aux_output_match(struct perf_event *event, struct perf_event *aux_event)
+{
+       if (!has_aux(aux_event))
+               return 0;
+
+       if (!event->pmu->aux_output_match)
+               return 0;
+
+       return event->pmu->aux_output_match(aux_event);
+}
+
+static void put_event(struct perf_event *event);
+static void event_sched_out(struct perf_event *event,
+                           struct perf_cpu_context *cpuctx,
+                           struct perf_event_context *ctx);
+
+static void perf_put_aux_event(struct perf_event *event)
+{
+       struct perf_event_context *ctx = event->ctx;
+       struct perf_cpu_context *cpuctx = __get_cpu_context(ctx);
+       struct perf_event *iter;
+
+       /*
+        * If event uses aux_event tear down the link
+        */
+       if (event->aux_event) {
+               iter = event->aux_event;
+               event->aux_event = NULL;
+               put_event(iter);
+               return;
+       }
+
+       /*
+        * If the event is an aux_event, tear down all links to
+        * it from other events.
+        */
+       for_each_sibling_event(iter, event->group_leader) {
+               if (iter->aux_event != event)
+                       continue;
+
+               iter->aux_event = NULL;
+               put_event(event);
+
+               /*
+                * If it's ACTIVE, schedule it out and put it into ERROR
+                * state so that we don't try to schedule it again. Note
+                * that perf_event_enable() will clear the ERROR status.
+                */
+               event_sched_out(iter, cpuctx, ctx);
+               perf_event_set_state(event, PERF_EVENT_STATE_ERROR);
+       }
+}
+
+static int perf_get_aux_event(struct perf_event *event,
+                             struct perf_event *group_leader)
+{
+       /*
+        * Our group leader must be an aux event if we want to be
+        * an aux_output. This way, the aux event will precede its
+        * aux_output events in the group, and therefore will always
+        * schedule first.
+        */
+       if (!group_leader)
+               return 0;
+
+       if (!perf_aux_output_match(event, group_leader))
+               return 0;
+
+       if (!atomic_long_inc_not_zero(&group_leader->refcount))
+               return 0;
+
+       /*
+        * Link aux_outputs to their aux event; this is undone in
+        * perf_group_detach() by perf_put_aux_event(). When the
+        * group in torn down, the aux_output events loose their
+        * link to the aux_event and can't schedule any more.
+        */
+       event->aux_event = group_leader;
+
+       return 1;
+}
+
 static void perf_group_detach(struct perf_event *event)
 {
        struct perf_event *sibling, *tmp;
@@ -1902,6 +1985,8 @@ static void perf_group_detach(struct perf_event *event)
 
        event->attach_state &= ~PERF_ATTACH_GROUP;
 
+       perf_put_aux_event(event);
+
        /*
         * If this is a sibling, remove it from its group.
         */
@@ -10426,6 +10511,12 @@ perf_event_alloc(struct perf_event_attr *attr, int cpu,
                goto err_ns;
        }
 
+       if (event->attr.aux_output &&
+           !(pmu->capabilities & PERF_PMU_CAP_AUX_OUTPUT)) {
+               err = -EOPNOTSUPP;
+               goto err_pmu;
+       }
+
        err = exclusive_event_init(event);
        if (err)
                goto err_pmu;
@@ -11082,6 +11173,8 @@ SYSCALL_DEFINE5(perf_event_open,
                }
        }
 
+       if (event->attr.aux_output && !perf_get_aux_event(event, group_leader))
+               goto err_locked;
 
        /*
         * Must be under the same ctx::mutex as perf_install_in_context(),
index d9770a5393c89925d2fa3f391dfb341a34a70409..ebe8315a756a2593f0e9bab3f37efe7885a347ed 100644 (file)
@@ -1514,7 +1514,8 @@ static int check_kprobe_address_safe(struct kprobe *p,
        /* Ensure it is not in reserved area nor out of text */
        if (!kernel_text_address((unsigned long) p->addr) ||
            within_kprobe_blacklist((unsigned long) p->addr) ||
-           jump_label_text_reserved(p->addr, p->addr)) {
+           jump_label_text_reserved(p->addr, p->addr) ||
+           find_bug((unsigned long)p->addr)) {
                ret = -EINVAL;
                goto out;
        }
index 68defd7ecf5d6980e464d3ecc08f9ba57660446e..7e42f7b8bfa7349fd505303ed85c44e17a16ae1b 100644 (file)
@@ -10,6 +10,7 @@ help:
        @echo 'Possible targets:'
        @echo ''
        @echo '  acpi                   - ACPI tools'
+       @echo '  bpf                    - misc BPF tools'
        @echo '  cgroup                 - cgroup tools'
        @echo '  cpupower               - a tool for all things x86 CPU power'
        @echo '  debugging              - tools for debugging'
@@ -23,12 +24,11 @@ help:
        @echo '  kvm_stat               - top-like utility for displaying kvm statistics'
        @echo '  leds                   - LEDs  tools'
        @echo '  liblockdep             - user-space wrapper for kernel locking-validator'
-       @echo '  bpf                    - misc BPF tools'
+       @echo '  objtool                - an ELF object analysis tool'
        @echo '  pci                    - PCI tools'
        @echo '  perf                   - Linux performance measurement and analysis tool'
        @echo '  selftests              - various kernel selftests'
        @echo '  spi                    - spi tools'
-       @echo '  objtool                - an ELF object analysis tool'
        @echo '  tmon                   - thermal monitoring and tuning tool'
        @echo '  turbostat              - Intel CPU idle stats and freq reporting tool'
        @echo '  usb                    - USB testing tools'
index 998c2cc083633f2c564f3cae528b787f7f712f25..e880f2408e29d5e56bb659d851ccb254cc9a148e 100644 (file)
 #define X86_FEATURE_CQM_OCCUP_LLC      (11*32+ 1) /* LLC occupancy monitoring */
 #define X86_FEATURE_CQM_MBM_TOTAL      (11*32+ 2) /* LLC Total MBM monitoring */
 #define X86_FEATURE_CQM_MBM_LOCAL      (11*32+ 3) /* LLC Local MBM monitoring */
+#define X86_FEATURE_FENCE_SWAPGS_USER  (11*32+ 4) /* "" LFENCE in user entry SWAPGS path */
+#define X86_FEATURE_FENCE_SWAPGS_KERNEL        (11*32+ 5) /* "" LFENCE in kernel entry SWAPGS path */
 
 /* Intel-defined CPU features, CPUID level 0x00000007:1 (EAX), word 12 */
 #define X86_FEATURE_AVX512_BF16                (12*32+ 5) /* AVX512 BFLOAT16 instructions */
 #define X86_BUG_L1TF                   X86_BUG(18) /* CPU is affected by L1 Terminal Fault */
 #define X86_BUG_MDS                    X86_BUG(19) /* CPU is affected by Microarchitectural data sampling */
 #define X86_BUG_MSBDS_ONLY             X86_BUG(20) /* CPU is only affected by the  MSDBS variant of BUG_MDS */
+#define X86_BUG_SWAPGS                 X86_BUG(21) /* CPU is affected by speculation through SWAPGS */
 
 #endif /* _ASM_X86_CPUFEATURES_H */
similarity index 98%
rename from tools/objtool/arch/x86/lib/inat.c
rename to tools/arch/x86/lib/inat.c
index 12539fca75c4ae72437e2d2c1e3332faebd09c3d..4f5ed49e1b4eeda62b6831cf02a137f0e562cbcd 100644 (file)
@@ -4,7 +4,7 @@
  *
  * Written by Masami Hiramatsu <mhiramat@redhat.com>
  */
-#include <asm/insn.h>
+#include "../include/asm/insn.h"
 
 /* Attribute tables are generated from opcode map */
 #include "inat-tables.c"
similarity index 99%
rename from tools/objtool/arch/x86/lib/insn.c
rename to tools/arch/x86/lib/insn.c
index 0b5862ba6a75e04b069dd02c8917bb6e598fba0f..79e048f1d90280c999547a928a6cb402481f375d 100644 (file)
@@ -10,8 +10,8 @@
 #else
 #include <string.h>
 #endif
-#include <asm/inat.h>
-#include <asm/insn.h>
+#include "../include/asm/inat.h"
+#include "../include/asm/insn.h"
 
 /* Verify next sizeof(t) bytes can be on the same instruction */
 #define validate_next(t, insn, n)      \
index 86b793dffbc45f06dae59dde8a9125b8432bf9fd..8a19753cc26aab4198903c92c133531d3b708682 100644 (file)
@@ -42,6 +42,7 @@ FEATURE_TESTS_BASIC :=                  \
         gtk2-infobar                    \
         libaudit                        \
         libbfd                          \
+        libcap                          \
         libelf                          \
         libelf-getphdrnum               \
         libelf-gelf_getnote             \
@@ -110,6 +111,7 @@ FEATURE_DISPLAY ?=              \
          gtk2                   \
          libaudit               \
          libbfd                 \
+         libcap                 \
          libelf                 \
          libnuma                \
          numa_num_possible_cpus \
index 0658b8cd0e534e92739bdce12beb8e673b03af60..8499385365c029aeb529cf1ead9e77d6877d8852 100644 (file)
@@ -20,6 +20,7 @@ FILES=                                          \
          test-libbfd-liberty.bin                \
          test-libbfd-liberty-z.bin              \
          test-cplus-demangle.bin                \
+         test-libcap.bin                       \
          test-libelf.bin                        \
          test-libelf-getphdrnum.bin             \
          test-libelf-gelf_getnote.bin           \
@@ -105,6 +106,9 @@ $(OUTPUT)test-fortify-source.bin:
 $(OUTPUT)test-bionic.bin:
        $(BUILD)
 
+$(OUTPUT)test-libcap.bin:
+       $(BUILD) -lcap
+
 $(OUTPUT)test-libelf.bin:
        $(BUILD) -lelf
 
diff --git a/tools/build/feature/test-libcap.c b/tools/build/feature/test-libcap.c
new file mode 100644 (file)
index 0000000..d2a2e15
--- /dev/null
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <sys/capability.h>
+#include <linux/capability.h>
+
+int main(void)
+{
+       cap_flag_value_t val;
+       cap_t caps = cap_get_proc();
+
+       if (!caps)
+               return 1;
+
+       if (cap_get_flag(caps, CAP_SYS_ADMIN, CAP_EFFECTIVE, &val) != 0)
+               return 1;
+
+       if (cap_free(caps) != 0)
+               return 1;
+
+       return 0;
+}
index 0b0ef3abc966e98c806bf7148d1d3f66fa096102..140c8362f1139a0b002e8c1a9aaaa98dd80f159c 100644 (file)
@@ -3,6 +3,7 @@
 #define _TOOLS_LINUX_BITOPS_H_
 
 #include <asm/types.h>
+#include <limits.h>
 #ifndef __WORDSIZE
 #define __WORDSIZE (__SIZEOF_LONG__ * 8)
 #endif
index 2b7b532c1d51d6352a524fd827f9fd776f690f78..669d69441a625c1639d0699671b9ee41405e84a1 100644 (file)
@@ -1,13 +1,15 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #ifndef __LINUX_BITS_H
 #define __LINUX_BITS_H
+
+#include <linux/const.h>
 #include <asm/bitsperlong.h>
 
-#define BIT(nr)                        (1UL << (nr))
-#define BIT_ULL(nr)            (1ULL << (nr))
-#define BIT_MASK(nr)           (1UL << ((nr) % BITS_PER_LONG))
+#define BIT(nr)                        (UL(1) << (nr))
+#define BIT_ULL(nr)            (ULL(1) << (nr))
+#define BIT_MASK(nr)           (UL(1) << ((nr) % BITS_PER_LONG))
 #define BIT_WORD(nr)           ((nr) / BITS_PER_LONG)
-#define BIT_ULL_MASK(nr)       (1ULL << ((nr) % BITS_PER_LONG_LONG))
+#define BIT_ULL_MASK(nr)       (ULL(1) << ((nr) % BITS_PER_LONG_LONG))
 #define BIT_ULL_WORD(nr)       ((nr) / BITS_PER_LONG_LONG)
 #define BITS_PER_BYTE          8
 
  * GENMASK_ULL(39, 21) gives us the 64bit vector 0x000000ffffe00000.
  */
 #define GENMASK(h, l) \
-       (((~0UL) - (1UL << (l)) + 1) & (~0UL >> (BITS_PER_LONG - 1 - (h))))
+       (((~UL(0)) - (UL(1) << (l)) + 1) & \
+        (~UL(0) >> (BITS_PER_LONG - 1 - (h))))
 
 #define GENMASK_ULL(h, l) \
-       (((~0ULL) - (1ULL << (l)) + 1) & \
-        (~0ULL >> (BITS_PER_LONG_LONG - 1 - (h))))
+       (((~ULL(0)) - (ULL(1) << (l)) + 1) & \
+        (~ULL(0) >> (BITS_PER_LONG_LONG - 1 - (h))))
 
 #endif /* __LINUX_BITS_H */
diff --git a/tools/include/linux/const.h b/tools/include/linux/const.h
new file mode 100644 (file)
index 0000000..7b55a55
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef _LINUX_CONST_H
+#define _LINUX_CONST_H
+
+#include <uapi/linux/const.h>
+
+#define UL(x)          (_UL(x))
+#define ULL(x)         (_ULL(x))
+
+#endif /* _LINUX_CONST_H */
index 9a083ae6047306b4bc599ef91e40ffbba18c5d3b..6c02617377c29b4f9fb758593dd5f2566518cfd9 100644 (file)
@@ -2,6 +2,7 @@
 #define _TOOLS_LINUX_RING_BUFFER_H_
 
 #include <asm/barrier.h>
+#include <linux/perf_event.h>
 
 /*
  * Contract with kernel for walking the perf ring buffer from
index 57aaeaf8e192038ae37eceaa0b60fba82b5f6013..edba4d93e9e6a346572d12e7def7e01f1c88822d 100644 (file)
@@ -1,22 +1,22 @@
 /* SPDX-License-Identifier: GPL-2.0 */
 #if defined(__i386__) || defined(__x86_64__)
-#include "../../arch/x86/include/uapi/asm/bitsperlong.h"
+#include "../../../arch/x86/include/uapi/asm/bitsperlong.h"
 #elif defined(__aarch64__)
-#include "../../arch/arm64/include/uapi/asm/bitsperlong.h"
+#include "../../../arch/arm64/include/uapi/asm/bitsperlong.h"
 #elif defined(__powerpc__)
-#include "../../arch/powerpc/include/uapi/asm/bitsperlong.h"
+#include "../../../arch/powerpc/include/uapi/asm/bitsperlong.h"
 #elif defined(__s390__)
-#include "../../arch/s390/include/uapi/asm/bitsperlong.h"
+#include "../../../arch/s390/include/uapi/asm/bitsperlong.h"
 #elif defined(__sparc__)
-#include "../../arch/sparc/include/uapi/asm/bitsperlong.h"
+#include "../../../arch/sparc/include/uapi/asm/bitsperlong.h"
 #elif defined(__mips__)
-#include "../../arch/mips/include/uapi/asm/bitsperlong.h"
+#include "../../../arch/mips/include/uapi/asm/bitsperlong.h"
 #elif defined(__ia64__)
-#include "../../arch/ia64/include/uapi/asm/bitsperlong.h"
+#include "../../../arch/ia64/include/uapi/asm/bitsperlong.h"
 #elif defined(__riscv)
-#include "../../arch/riscv/include/uapi/asm/bitsperlong.h"
+#include "../../../arch/riscv/include/uapi/asm/bitsperlong.h"
 #elif defined(__alpha__)
-#include "../../arch/alpha/include/uapi/asm/bitsperlong.h"
+#include "../../../arch/alpha/include/uapi/asm/bitsperlong.h"
 #else
 #include <asm-generic/bitsperlong.h>
 #endif
diff --git a/tools/include/uapi/linux/const.h b/tools/include/uapi/linux/const.h
new file mode 100644 (file)
index 0000000..5ed721a
--- /dev/null
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
+/* const.h: Macros for dealing with constants.  */
+
+#ifndef _UAPI_LINUX_CONST_H
+#define _UAPI_LINUX_CONST_H
+
+/* Some constant macros are used in both assembler and
+ * C code.  Therefore we cannot annotate them always with
+ * 'UL' and other type specifiers unilaterally.  We
+ * use the following macros to deal with this.
+ *
+ * Similarly, _AT() will cast an expression with a type in C, but
+ * leave it unchanged in asm.
+ */
+
+#ifdef __ASSEMBLY__
+#define _AC(X,Y)       X
+#define _AT(T,X)       X
+#else
+#define __AC(X,Y)      (X##Y)
+#define _AC(X,Y)       __AC(X,Y)
+#define _AT(T,X)       ((T)(X))
+#endif
+
+#define _UL(x)         (_AC(x, UL))
+#define _ULL(x)                (_AC(x, ULL))
+
+#define _BITUL(x)      (_UL(1) << (x))
+#define _BITULL(x)     (_ULL(1) << (x))
+
+#endif /* _UAPI_LINUX_CONST_H */
index 7198ddd0c6b11d07286aa60504aedc6a0bea69ed..bb7b271397a665d31b30d2986c8783267b1ad0e6 100644 (file)
@@ -374,7 +374,8 @@ struct perf_event_attr {
                                namespaces     :  1, /* include namespaces data */
                                ksymbol        :  1, /* include ksymbol events */
                                bpf_event      :  1, /* include bpf events */
-                               __reserved_1   : 33;
+                               aux_output     :  1, /* generate AUX records instead of events */
+                               __reserved_1   : 32;
 
        union {
                __u32           wakeup_events;    /* wakeup every n events */
index 3292c290654f643c2894acaa944e4a82a17fa13b..a39cdd0d890da4f4e8f8837ce3e41ca74b0a3c8e 100644 (file)
@@ -62,15 +62,15 @@ set_plugin_dir := 1
 
 # Set plugin_dir to preffered global plugin location
 # If we install under $HOME directory we go under
-# $(HOME)/.traceevent/plugins
+# $(HOME)/.local/lib/traceevent/plugins
 #
 # We dont set PLUGIN_DIR in case we install under $HOME
 # directory, because by default the code looks under:
-# $(HOME)/.traceevent/plugins by default.
+# $(HOME)/.local/lib/traceevent/plugins by default.
 #
 ifeq ($(plugin_dir),)
 ifeq ($(prefix),$(HOME))
-override plugin_dir = $(HOME)/.traceevent/plugins
+override plugin_dir = $(HOME)/.local/lib/traceevent/plugins
 set_plugin_dir := 0
 else
 override plugin_dir = $(libdir)/traceevent/plugins
@@ -266,8 +266,8 @@ endef
 
 define do_generate_dynamic_list_file
        symbol_type=`$(NM) -u -D $1 | awk 'NF>1 {print $$1}' | \
-       xargs echo "U W w" | tr ' ' '\n' | sort -u | xargs echo`;\
-       if [ "$$symbol_type" = "U W w" ];then                           \
+       xargs echo "U w W" | tr 'w ' 'W\n' | sort -u | xargs echo`;\
+       if [ "$$symbol_type" = "U W" ];then                             \
                (echo '{';                                              \
                $(NM) -u -D $1 | awk 'NF>1 {print "\t"$$2";"}' | sort -u;\
                echo '};';                                              \
index 988587840c801eac49391d318e281589aad97e35..4faf52a657913ff2fcb32ff2340c19fe4a7c6a9d 100644 (file)
@@ -302,33 +302,6 @@ void tep_set_local_bigendian(struct tep_handle *tep, enum tep_endian endian)
                tep->host_bigendian = endian;
 }
 
-/**
- * tep_is_latency_format - get if the latency output format is configured
- * @tep: a handle to the tep_handle
- *
- * This returns true if the latency output format is configured
- * If @tep is NULL, false is returned.
- */
-bool tep_is_latency_format(struct tep_handle *tep)
-{
-       if (tep)
-               return (tep->latency_format);
-       return false;
-}
-
-/**
- * tep_set_latency_format - set the latency output format
- * @tep: a handle to the tep_handle
- * @lat: non zero for latency output format
- *
- * This sets the latency output format
-  */
-void tep_set_latency_format(struct tep_handle *tep, int lat)
-{
-       if (tep)
-               tep->latency_format = lat;
-}
-
 /**
  * tep_is_old_format - get if an old kernel is used
  * @tep: a handle to the tep_handle
@@ -344,19 +317,6 @@ bool tep_is_old_format(struct tep_handle *tep)
        return false;
 }
 
-/**
- * tep_set_print_raw - set a flag to force print in raw format
- * @tep: a handle to the tep_handle
- * @print_raw: the new value of the print_raw flag
- *
- * This sets a flag to force print in raw format
- */
-void tep_set_print_raw(struct tep_handle *tep, int print_raw)
-{
-       if (tep)
-               tep->print_raw = print_raw;
-}
-
 /**
  * tep_set_test_filters - set a flag to test a filter string
  * @tep: a handle to the tep_handle
index 09aa142f7fdd82f0d1b561bf4c6095b0c14b1f1a..cee469803a34ac63885499c2f64b3de65b371946 100644 (file)
@@ -28,8 +28,6 @@ struct tep_handle {
        enum tep_endian file_bigendian;
        enum tep_endian host_bigendian;
 
-       int latency_format;
-
        int old_format;
 
        int cpus;
@@ -70,8 +68,6 @@ struct tep_handle {
        int ld_offset;
        int ld_size;
 
-       int print_raw;
-
        int test_filters;
 
        int flags;
@@ -85,8 +81,6 @@ struct tep_handle {
 
        /* cache */
        struct tep_event *last_event;
-
-       char *trace_clock;
 };
 
 void tep_free_event(struct tep_event *event);
index b36b536a9fcbaa9ce8ee336a6c1df355fa533295..bb22238debfe1f932f2fe48bd4c6647ba726d9cc 100644 (file)
@@ -142,6 +142,25 @@ static int cmdline_cmp(const void *a, const void *b)
        return 0;
 }
 
+/* Looking for where to place the key */
+static int cmdline_slot_cmp(const void *a, const void *b)
+{
+       const struct tep_cmdline *ca = a;
+       const struct tep_cmdline *cb = b;
+       const struct tep_cmdline *cb1 = cb + 1;
+
+       if (ca->pid < cb->pid)
+               return -1;
+
+       if (ca->pid > cb->pid) {
+               if (ca->pid <= cb1->pid)
+                       return 0;
+               return 1;
+       }
+
+       return 0;
+}
+
 struct cmdline_list {
        struct cmdline_list     *next;
        char                    *comm;
@@ -239,6 +258,7 @@ static int add_new_comm(struct tep_handle *tep,
        struct tep_cmdline *cmdline;
        struct tep_cmdline key;
        char *new_comm;
+       int cnt;
 
        if (!pid)
                return 0;
@@ -269,21 +289,43 @@ static int add_new_comm(struct tep_handle *tep,
                errno = ENOMEM;
                return -1;
        }
+       tep->cmdlines = cmdlines;
 
-       cmdlines[tep->cmdline_count].comm = strdup(comm);
-       if (!cmdlines[tep->cmdline_count].comm) {
-               free(cmdlines);
+       key.comm = strdup(comm);
+       if (!key.comm) {
                errno = ENOMEM;
                return -1;
        }
 
-       cmdlines[tep->cmdline_count].pid = pid;
-               
-       if (cmdlines[tep->cmdline_count].comm)
+       if (!tep->cmdline_count) {
+               /* no entries yet */
+               tep->cmdlines[0] = key;
                tep->cmdline_count++;
+               return 0;
+       }
 
-       qsort(cmdlines, tep->cmdline_count, sizeof(*cmdlines), cmdline_cmp);
-       tep->cmdlines = cmdlines;
+       /* Now find where we want to store the new cmdline */
+       cmdline = bsearch(&key, tep->cmdlines, tep->cmdline_count - 1,
+                         sizeof(*tep->cmdlines), cmdline_slot_cmp);
+
+       cnt = tep->cmdline_count;
+       if (cmdline) {
+               /* cmdline points to the one before the spot we want */
+               cmdline++;
+               cnt -= cmdline - tep->cmdlines;
+
+       } else {
+               /* The new entry is either before or after the list */
+               if (key.pid > tep->cmdlines[tep->cmdline_count - 1].pid) {
+                       tep->cmdlines[tep->cmdline_count++] = key;
+                       return 0;
+               }
+               cmdline = &tep->cmdlines[0];
+       }
+       memmove(cmdline + 1, cmdline, (cnt * sizeof(*cmdline)));
+       *cmdline = key;
+
+       tep->cmdline_count++;
 
        return 0;
 }
@@ -351,16 +393,6 @@ int tep_override_comm(struct tep_handle *tep, const char *comm, int pid)
        return _tep_register_comm(tep, comm, pid, true);
 }
 
-int tep_register_trace_clock(struct tep_handle *tep, const char *trace_clock)
-{
-       tep->trace_clock = strdup(trace_clock);
-       if (!tep->trace_clock) {
-               errno = ENOMEM;
-               return -1;
-       }
-       return 0;
-}
-
 struct func_map {
        unsigned long long              addr;
        char                            *func;
@@ -5170,24 +5202,20 @@ out_failed:
        }
 }
 
-/**
- * tep_data_latency_format - parse the data for the latency format
- * @tep: a handle to the trace event parser context
- * @s: the trace_seq to write to
- * @record: the record to read from
- *
+/*
  * This parses out the Latency format (interrupts disabled,
  * need rescheduling, in hard/soft interrupt, preempt count
  * and lock depth) and places it into the trace_seq.
  */
-void tep_data_latency_format(struct tep_handle *tep,
-                            struct trace_seq *s, struct tep_record *record)
+static void data_latency_format(struct tep_handle *tep, struct trace_seq *s,
+                               char *format, struct tep_record *record)
 {
        static int check_lock_depth = 1;
        static int check_migrate_disable = 1;
        static int lock_depth_exists;
        static int migrate_disable_exists;
        unsigned int lat_flags;
+       struct trace_seq sq;
        unsigned int pc;
        int lock_depth = 0;
        int migrate_disable = 0;
@@ -5195,6 +5223,7 @@ void tep_data_latency_format(struct tep_handle *tep,
        int softirq;
        void *data = record->data;
 
+       trace_seq_init(&sq);
        lat_flags = parse_common_flags(tep, data);
        pc = parse_common_pc(tep, data);
        /* lock_depth may not always exist */
@@ -5222,7 +5251,7 @@ void tep_data_latency_format(struct tep_handle *tep,
        hardirq = lat_flags & TRACE_FLAG_HARDIRQ;
        softirq = lat_flags & TRACE_FLAG_SOFTIRQ;
 
-       trace_seq_printf(s, "%c%c%c",
+       trace_seq_printf(&sq, "%c%c%c",
               (lat_flags & TRACE_FLAG_IRQS_OFF) ? 'd' :
               (lat_flags & TRACE_FLAG_IRQS_NOSUPPORT) ?
               'X' : '.',
@@ -5232,24 +5261,32 @@ void tep_data_latency_format(struct tep_handle *tep,
               hardirq ? 'h' : softirq ? 's' : '.');
 
        if (pc)
-               trace_seq_printf(s, "%x", pc);
+               trace_seq_printf(&sq, "%x", pc);
        else
-               trace_seq_putc(s, '.');
+               trace_seq_printf(&sq, ".");
 
        if (migrate_disable_exists) {
                if (migrate_disable < 0)
-                       trace_seq_putc(s, '.');
+                       trace_seq_printf(&sq, ".");
                else
-                       trace_seq_printf(s, "%d", migrate_disable);
+                       trace_seq_printf(&sq, "%d", migrate_disable);
        }
 
        if (lock_depth_exists) {
                if (lock_depth < 0)
-                       trace_seq_putc(s, '.');
+                       trace_seq_printf(&sq, ".");
                else
-                       trace_seq_printf(s, "%d", lock_depth);
+                       trace_seq_printf(&sq, "%d", lock_depth);
+       }
+
+       if (sq.state == TRACE_SEQ__MEM_ALLOC_FAILED) {
+               s->state = TRACE_SEQ__MEM_ALLOC_FAILED;
+               return;
        }
 
+       trace_seq_terminate(&sq);
+       trace_seq_puts(s, sq.buffer);
+       trace_seq_destroy(&sq);
        trace_seq_terminate(s);
 }
 
@@ -5410,21 +5447,16 @@ int tep_cmdline_pid(struct tep_handle *tep, struct tep_cmdline *cmdline)
        return cmdline->pid;
 }
 
-/**
- * tep_event_info - parse the data into the print format
- * @s: the trace_seq to write to
- * @event: the handle to the event
- * @record: the record to read from
- *
+/*
  * This parses the raw @data using the given @event information and
  * writes the print format into the trace_seq.
  */
-void tep_event_info(struct trace_seq *s, struct tep_event *event,
-                   struct tep_record *record)
+static void print_event_info(struct trace_seq *s, char *format, bool raw,
+                            struct tep_event *event, struct tep_record *record)
 {
        int print_pretty = 1;
 
-       if (event->tep->print_raw || (event->flags & TEP_EVENT_FL_PRINTRAW))
+       if (raw || (event->flags & TEP_EVENT_FL_PRINTRAW))
                tep_print_fields(s, record->data, record->size, event);
        else {
 
@@ -5439,20 +5471,6 @@ void tep_event_info(struct trace_seq *s, struct tep_event *event,
        trace_seq_terminate(s);
 }
 
-static bool is_timestamp_in_us(char *trace_clock, bool use_trace_clock)
-{
-       if (!trace_clock || !use_trace_clock)
-               return true;
-
-       if (!strcmp(trace_clock, "local") || !strcmp(trace_clock, "global")
-           || !strcmp(trace_clock, "uptime") || !strcmp(trace_clock, "perf")
-           || !strncmp(trace_clock, "mono", 4))
-               return true;
-
-       /* trace_clock is setting in tsc or counter mode */
-       return false;
-}
-
 /**
  * tep_find_event_by_record - return the event from a given record
  * @tep: a handle to the trace event parser context
@@ -5476,129 +5494,195 @@ tep_find_event_by_record(struct tep_handle *tep, struct tep_record *record)
        return tep_find_event(tep, type);
 }
 
-/**
- * tep_print_event_task - Write the event task comm, pid and CPU
- * @tep: a handle to the trace event parser context
- * @s: the trace_seq to write to
- * @event: the handle to the record's event
- * @record: The record to get the event from
- *
- * Writes the tasks comm, pid and CPU to @s.
+/*
+ * Writes the timestamp of the record into @s. Time divisor and precision can be
+ * specified as part of printf @format string. Example:
+ *     "%3.1000d" - divide the time by 1000 and print the first 3 digits
+ *     before the dot. Thus, the timestamp "123456000" will be printed as
+ *     "123.456"
  */
-void tep_print_event_task(struct tep_handle *tep, struct trace_seq *s,
-                         struct tep_event *event,
-                         struct tep_record *record)
+static void print_event_time(struct tep_handle *tep, struct trace_seq *s,
+                                char *format, struct tep_event *event,
+                                struct tep_record *record)
+{
+       unsigned long long time;
+       char *divstr;
+       int prec = 0, pr;
+       int div = 0;
+       int p10 = 1;
+
+       if (isdigit(*(format + 1)))
+               prec = atoi(format + 1);
+       divstr = strchr(format, '.');
+       if (divstr && isdigit(*(divstr + 1)))
+               div = atoi(divstr + 1);
+       time = record->ts;
+       if (div)
+               time /= div;
+       pr = prec;
+       while (pr--)
+               p10 *= 10;
+
+       if (p10 > 1 && p10 < time)
+               trace_seq_printf(s, "%5llu.%0*llu", time / p10, prec, time % p10);
+       else
+               trace_seq_printf(s, "%12llu\n", time);
+}
+
+struct print_event_type {
+       enum {
+               EVENT_TYPE_INT = 1,
+               EVENT_TYPE_STRING,
+               EVENT_TYPE_UNKNOWN,
+       } type;
+       char format[32];
+};
+
+static void print_string(struct tep_handle *tep, struct trace_seq *s,
+                        struct tep_record *record, struct tep_event *event,
+                        const char *arg, struct print_event_type *type)
 {
-       void *data = record->data;
        const char *comm;
        int pid;
 
-       pid = parse_common_pid(tep, data);
-       comm = find_cmdline(tep, pid);
+       if (strncmp(arg, TEP_PRINT_LATENCY, strlen(TEP_PRINT_LATENCY)) == 0) {
+               data_latency_format(tep, s, type->format, record);
+       } else if (strncmp(arg, TEP_PRINT_COMM, strlen(TEP_PRINT_COMM)) == 0) {
+               pid = parse_common_pid(tep, record->data);
+               comm = find_cmdline(tep, pid);
+               trace_seq_printf(s, type->format, comm);
+       } else if (strncmp(arg, TEP_PRINT_INFO_RAW, strlen(TEP_PRINT_INFO_RAW)) == 0) {
+               print_event_info(s, type->format, true, event, record);
+       } else if (strncmp(arg, TEP_PRINT_INFO, strlen(TEP_PRINT_INFO)) == 0) {
+               print_event_info(s, type->format, false, event, record);
+       } else if  (strncmp(arg, TEP_PRINT_NAME, strlen(TEP_PRINT_NAME)) == 0) {
+               trace_seq_printf(s, type->format, event->name);
+       } else {
+               trace_seq_printf(s, "[UNKNOWN TEP TYPE %s]", arg);
+       }
 
-       if (tep->latency_format)
-               trace_seq_printf(s, "%8.8s-%-5d %3d", comm, pid, record->cpu);
-       else
-               trace_seq_printf(s, "%16s-%-5d [%03d]", comm, pid, record->cpu);
 }
 
-/**
- * tep_print_event_time - Write the event timestamp
- * @tep: a handle to the trace event parser context
- * @s: the trace_seq to write to
- * @event: the handle to the record's event
- * @record: The record to get the event from
- * @use_trace_clock: Set to parse according to the @tep->trace_clock
- *
- * Writes the timestamp of the record into @s.
- */
-void tep_print_event_time(struct tep_handle *tep, struct trace_seq *s,
-                         struct tep_event *event,
-                         struct tep_record *record,
-                         bool use_trace_clock)
+static void print_int(struct tep_handle *tep, struct trace_seq *s,
+                     struct tep_record *record, struct tep_event *event,
+                     int arg, struct print_event_type *type)
 {
-       unsigned long secs;
-       unsigned long usecs;
-       unsigned long nsecs;
-       int p;
-       bool use_usec_format;
+       int param;
 
-       use_usec_format = is_timestamp_in_us(tep->trace_clock, use_trace_clock);
-       if (use_usec_format) {
-               secs = record->ts / NSEC_PER_SEC;
-               nsecs = record->ts - secs * NSEC_PER_SEC;
+       switch (arg) {
+       case TEP_PRINT_CPU:
+               param = record->cpu;
+               break;
+       case TEP_PRINT_PID:
+               param = parse_common_pid(tep, record->data);
+               break;
+       case TEP_PRINT_TIME:
+               return print_event_time(tep, s, type->format, event, record);
+       default:
+               return;
        }
+       trace_seq_printf(s, type->format, param);
+}
 
-       if (tep->latency_format) {
-               tep_data_latency_format(tep, s, record);
-       }
+static int tep_print_event_param_type(char *format,
+                                     struct print_event_type *type)
+{
+       char *str = format + 1;
+       int i = 1;
 
-       if (use_usec_format) {
-               if (tep->flags & TEP_NSEC_OUTPUT) {
-                       usecs = nsecs;
-                       p = 9;
-               } else {
-                       usecs = (nsecs + 500) / NSEC_PER_USEC;
-                       /* To avoid usecs larger than 1 sec */
-                       if (usecs >= USEC_PER_SEC) {
-                               usecs -= USEC_PER_SEC;
-                               secs++;
-                       }
-                       p = 6;
+       type->type = EVENT_TYPE_UNKNOWN;
+       while (*str) {
+               switch (*str) {
+               case 'd':
+               case 'u':
+               case 'i':
+               case 'x':
+               case 'X':
+               case 'o':
+                       type->type = EVENT_TYPE_INT;
+                       break;
+               case 's':
+                       type->type = EVENT_TYPE_STRING;
+                       break;
                }
-
-               trace_seq_printf(s, " %5lu.%0*lu:", secs, p, usecs);
-       } else
-               trace_seq_printf(s, " %12llu:", record->ts);
+               str++;
+               i++;
+               if (type->type != EVENT_TYPE_UNKNOWN)
+                       break;
+       }
+       memset(type->format, 0, 32);
+       memcpy(type->format, format, i < 32 ? i : 31);
+       return i;
 }
 
 /**
- * tep_print_event_data - Write the event data section
+ * tep_print_event - Write various event information
  * @tep: a handle to the trace event parser context
  * @s: the trace_seq to write to
- * @event: the handle to the record's event
  * @record: The record to get the event from
- *
- * Writes the parsing of the record's data to @s.
+ * @format: a printf format string. Supported event fileds:
+ *     TEP_PRINT_PID, "%d" - event PID
+ *     TEP_PRINT_CPU, "%d" - event CPU
+ *     TEP_PRINT_COMM, "%s" - event command string
+ *     TEP_PRINT_NAME, "%s" - event name
+ *     TEP_PRINT_LATENCY, "%s" - event latency
+ *     TEP_PRINT_TIME, %d - event time stamp. A divisor and precision
+ *                     can be specified as part of this format string:
+ *                     "%precision.divisord". Example:
+ *                     "%3.1000d" - divide the time by 1000 and print the first
+ *                     3 digits before the dot. Thus, the time stamp
+ *                     "123456000" will be printed as "123.456"
+ *     TEP_PRINT_INFO, "%s" - event information. If any width is specified in
+ *                     the format string, the event information will be printed
+ *                     in raw format.
+ * Writes the specified event information into @s.
  */
-void tep_print_event_data(struct tep_handle *tep, struct trace_seq *s,
-                         struct tep_event *event,
-                         struct tep_record *record)
-{
-       static const char *spaces = "                    "; /* 20 spaces */
-       int len;
-
-       trace_seq_printf(s, " %s: ", event->name);
-
-       /* Space out the event names evenly. */
-       len = strlen(event->name);
-       if (len < 20)
-               trace_seq_printf(s, "%.*s", 20 - len, spaces);
-
-       tep_event_info(s, event, record);
-}
-
 void tep_print_event(struct tep_handle *tep, struct trace_seq *s,
-                    struct tep_record *record, bool use_trace_clock)
-{
+                    struct tep_record *record, const char *fmt, ...)
+{
+       struct print_event_type type;
+       char *format = strdup(fmt);
+       char *current = format;
+       char *str = format;
+       int offset;
+       va_list args;
        struct tep_event *event;
 
-       event = tep_find_event_by_record(tep, record);
-       if (!event) {
-               int i;
-               int type = trace_parse_common_type(tep, record->data);
-
-               do_warning("ug! no event found for type %d", type);
-               trace_seq_printf(s, "[UNKNOWN TYPE %d]", type);
-               for (i = 0; i < record->size; i++)
-                       trace_seq_printf(s, " %02x",
-                                        ((unsigned char *)record->data)[i]);
+       if (!format)
                return;
-       }
 
-       tep_print_event_task(tep, s, event, record);
-       tep_print_event_time(tep, s, event, record, use_trace_clock);
-       tep_print_event_data(tep, s, event, record);
+       event = tep_find_event_by_record(tep, record);
+       va_start(args, fmt);
+       while (*current) {
+               current = strchr(str, '%');
+               if (!current) {
+                       trace_seq_puts(s, str);
+                       break;
+               }
+               memset(&type, 0, sizeof(type));
+               offset = tep_print_event_param_type(current, &type);
+               *current = '\0';
+               trace_seq_puts(s, str);
+               current += offset;
+               switch (type.type) {
+               case EVENT_TYPE_STRING:
+                       print_string(tep, s, record, event,
+                                    va_arg(args, char*), &type);
+                       break;
+               case EVENT_TYPE_INT:
+                       print_int(tep, s, record, event,
+                                 va_arg(args, int), &type);
+                       break;
+               case EVENT_TYPE_UNKNOWN:
+               default:
+                       trace_seq_printf(s, "[UNKNOWN TYPE]");
+                       break;
+               }
+               str = current;
+
+       }
+       va_end(args);
+       free(format);
 }
 
 static int events_id_cmp(const void *a, const void *b)
@@ -6963,7 +7047,6 @@ void tep_free(struct tep_handle *tep)
                free_handler(handle);
        }
 
-       free(tep->trace_clock);
        free(tep->events);
        free(tep->sort_events);
        free(tep->func_resolver);
index 642f68ab5fb2bc7e8704bf70d44a1eb1a86c7273..d438ee44289f53dd045f3831ba90ae44ef45996b 100644 (file)
@@ -435,25 +435,24 @@ int tep_set_function_resolver(struct tep_handle *tep,
 void tep_reset_function_resolver(struct tep_handle *tep);
 int tep_register_comm(struct tep_handle *tep, const char *comm, int pid);
 int tep_override_comm(struct tep_handle *tep, const char *comm, int pid);
-int tep_register_trace_clock(struct tep_handle *tep, const char *trace_clock);
 int tep_register_function(struct tep_handle *tep, char *name,
                          unsigned long long addr, char *mod);
 int tep_register_print_string(struct tep_handle *tep, const char *fmt,
                              unsigned long long addr);
 bool tep_is_pid_registered(struct tep_handle *tep, int pid);
 
-void tep_print_event_task(struct tep_handle *tep, struct trace_seq *s,
-                         struct tep_event *event,
-                         struct tep_record *record);
-void tep_print_event_time(struct tep_handle *tep, struct trace_seq *s,
-                         struct tep_event *event,
-                         struct tep_record *record,
-                         bool use_trace_clock);
-void tep_print_event_data(struct tep_handle *tep, struct trace_seq *s,
-                         struct tep_event *event,
-                         struct tep_record *record);
+#define TEP_PRINT_INFO         "INFO"
+#define TEP_PRINT_INFO_RAW     "INFO_RAW"
+#define TEP_PRINT_COMM         "COMM"
+#define TEP_PRINT_LATENCY      "LATENCY"
+#define TEP_PRINT_NAME         "NAME"
+#define TEP_PRINT_PID          1U
+#define TEP_PRINT_TIME         2U
+#define TEP_PRINT_CPU          3U
+
 void tep_print_event(struct tep_handle *tep, struct trace_seq *s,
-                    struct tep_record *record, bool use_trace_clock);
+                    struct tep_record *record, const char *fmt, ...)
+       __attribute__ ((format (printf, 4, 5)));
 
 int tep_parse_header_page(struct tep_handle *tep, char *buf, unsigned long size,
                          int long_size);
@@ -525,8 +524,6 @@ tep_find_event_by_name(struct tep_handle *tep, const char *sys, const char *name
 struct tep_event *
 tep_find_event_by_record(struct tep_handle *tep, struct tep_record *record);
 
-void tep_data_latency_format(struct tep_handle *tep,
-                            struct trace_seq *s, struct tep_record *record);
 int tep_data_type(struct tep_handle *tep, struct tep_record *rec);
 int tep_data_pid(struct tep_handle *tep, struct tep_record *rec);
 int tep_data_preempt_count(struct tep_handle *tep, struct tep_record *rec);
@@ -541,8 +538,6 @@ void tep_print_field(struct trace_seq *s, void *data,
                     struct tep_format_field *field);
 void tep_print_fields(struct trace_seq *s, void *data,
                      int size __maybe_unused, struct tep_event *event);
-void tep_event_info(struct trace_seq *s, struct tep_event *event,
-                   struct tep_record *record);
 int tep_strerror(struct tep_handle *tep, enum tep_errno errnum,
                 char *buf, size_t buflen);
 
@@ -566,12 +561,9 @@ bool tep_is_file_bigendian(struct tep_handle *tep);
 void tep_set_file_bigendian(struct tep_handle *tep, enum tep_endian endian);
 bool tep_is_local_bigendian(struct tep_handle *tep);
 void tep_set_local_bigendian(struct tep_handle *tep, enum tep_endian endian);
-bool tep_is_latency_format(struct tep_handle *tep);
-void tep_set_latency_format(struct tep_handle *tep, int lat);
 int tep_get_header_page_size(struct tep_handle *tep);
 int tep_get_header_timestamp_size(struct tep_handle *tep);
 bool tep_is_old_format(struct tep_handle *tep);
-void tep_set_print_raw(struct tep_handle *tep, int print_raw);
 void tep_set_test_filters(struct tep_handle *tep, int test_filters);
 
 struct tep_handle *tep_alloc(void);
index 8ca28de9337a5314c23745fe9e3b90b46c86873d..e1f7ddd5a6cf0ac4b8a8b76441dcc874a1405d00 100644 (file)
@@ -18,7 +18,7 @@
 #include "event-utils.h"
 #include "trace-seq.h"
 
-#define LOCAL_PLUGIN_DIR ".traceevent/plugins"
+#define LOCAL_PLUGIN_DIR ".local/lib/traceevent/plugins/"
 
 static struct registered_plugin_options {
        struct registered_plugin_options        *next;
index 20f67fcf378d540eced6080f41c0c844f7fe8b79..d2a19b0bc05aa9de937e5753ac45b93bb9d7dd67 100644 (file)
@@ -33,7 +33,7 @@ all: $(OBJTOOL)
 
 INCLUDES := -I$(srctree)/tools/include \
            -I$(srctree)/tools/arch/$(HOSTARCH)/include/uapi \
-           -I$(srctree)/tools/objtool/arch/$(ARCH)/include
+           -I$(srctree)/tools/arch/$(ARCH)/include
 WARNINGS := $(EXTRA_WARNINGS) -Wno-switch-default -Wno-switch-enum -Wno-packed
 CFLAGS   := -Werror $(WARNINGS) $(KBUILD_HOSTCFLAGS) -g $(INCLUDES) $(LIBELF_FLAGS)
 LDFLAGS  += $(LIBELF_LIBS) $(LIBSUBCMD) $(KBUILD_HOSTLDFLAGS)
@@ -60,7 +60,7 @@ $(LIBSUBCMD): fixdep FORCE
 clean:
        $(call QUIET_CLEAN, objtool) $(RM) $(OBJTOOL)
        $(Q)find $(OUTPUT) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
-       $(Q)$(RM) $(OUTPUT)arch/x86/lib/inat-tables.c $(OUTPUT)fixdep
+       $(Q)$(RM) $(OUTPUT)arch/x86/inat-tables.c $(OUTPUT)fixdep
 
 FORCE:
 
index b998412c017d9173d27b10a760899fd0c9efa32f..7c5004008e974156194f5ab185305dfbeafc4ae0 100644 (file)
@@ -1,7 +1,7 @@
 objtool-y += decode.o
 
-inat_tables_script = arch/x86/tools/gen-insn-attr-x86.awk
-inat_tables_maps = arch/x86/lib/x86-opcode-map.txt
+inat_tables_script = ../arch/x86/tools/gen-insn-attr-x86.awk
+inat_tables_maps = ../arch/x86/lib/x86-opcode-map.txt
 
 $(OUTPUT)arch/x86/lib/inat-tables.c: $(inat_tables_script) $(inat_tables_maps)
        $(call rule_mkdir)
index 0567c47a91b1024c5171460f30c8100852837f0d..a62e032863a89dbd2941739317ea2778e752f294 100644 (file)
@@ -8,8 +8,8 @@
 
 #define unlikely(cond) (cond)
 #include <asm/insn.h>
-#include "lib/inat.c"
-#include "lib/insn.c"
+#include "../../../arch/x86/lib/inat.c"
+#include "../../../arch/x86/lib/insn.c"
 
 #include "../../elf.h"
 #include "../../arch.h"
diff --git a/tools/objtool/arch/x86/include/asm/inat.h b/tools/objtool/arch/x86/include/asm/inat.h
deleted file mode 100644 (file)
index 4cf2ad5..0000000
+++ /dev/null
@@ -1,230 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef _ASM_X86_INAT_H
-#define _ASM_X86_INAT_H
-/*
- * x86 instruction attributes
- *
- * Written by Masami Hiramatsu <mhiramat@redhat.com>
- */
-#include <asm/inat_types.h>
-
-/*
- * Internal bits. Don't use bitmasks directly, because these bits are
- * unstable. You should use checking functions.
- */
-
-#define INAT_OPCODE_TABLE_SIZE 256
-#define INAT_GROUP_TABLE_SIZE 8
-
-/* Legacy last prefixes */
-#define INAT_PFX_OPNDSZ        1       /* 0x66 */ /* LPFX1 */
-#define INAT_PFX_REPE  2       /* 0xF3 */ /* LPFX2 */
-#define INAT_PFX_REPNE 3       /* 0xF2 */ /* LPFX3 */
-/* Other Legacy prefixes */
-#define INAT_PFX_LOCK  4       /* 0xF0 */
-#define INAT_PFX_CS    5       /* 0x2E */
-#define INAT_PFX_DS    6       /* 0x3E */
-#define INAT_PFX_ES    7       /* 0x26 */
-#define INAT_PFX_FS    8       /* 0x64 */
-#define INAT_PFX_GS    9       /* 0x65 */
-#define INAT_PFX_SS    10      /* 0x36 */
-#define INAT_PFX_ADDRSZ        11      /* 0x67 */
-/* x86-64 REX prefix */
-#define INAT_PFX_REX   12      /* 0x4X */
-/* AVX VEX prefixes */
-#define INAT_PFX_VEX2  13      /* 2-bytes VEX prefix */
-#define INAT_PFX_VEX3  14      /* 3-bytes VEX prefix */
-#define INAT_PFX_EVEX  15      /* EVEX prefix */
-
-#define INAT_LSTPFX_MAX        3
-#define INAT_LGCPFX_MAX        11
-
-/* Immediate size */
-#define INAT_IMM_BYTE          1
-#define INAT_IMM_WORD          2
-#define INAT_IMM_DWORD         3
-#define INAT_IMM_QWORD         4
-#define INAT_IMM_PTR           5
-#define INAT_IMM_VWORD32       6
-#define INAT_IMM_VWORD         7
-
-/* Legacy prefix */
-#define INAT_PFX_OFFS  0
-#define INAT_PFX_BITS  4
-#define INAT_PFX_MAX    ((1 << INAT_PFX_BITS) - 1)
-#define INAT_PFX_MASK  (INAT_PFX_MAX << INAT_PFX_OFFS)
-/* Escape opcodes */
-#define INAT_ESC_OFFS  (INAT_PFX_OFFS + INAT_PFX_BITS)
-#define INAT_ESC_BITS  2
-#define INAT_ESC_MAX   ((1 << INAT_ESC_BITS) - 1)
-#define INAT_ESC_MASK  (INAT_ESC_MAX << INAT_ESC_OFFS)
-/* Group opcodes (1-16) */
-#define INAT_GRP_OFFS  (INAT_ESC_OFFS + INAT_ESC_BITS)
-#define INAT_GRP_BITS  5
-#define INAT_GRP_MAX   ((1 << INAT_GRP_BITS) - 1)
-#define INAT_GRP_MASK  (INAT_GRP_MAX << INAT_GRP_OFFS)
-/* Immediates */
-#define INAT_IMM_OFFS  (INAT_GRP_OFFS + INAT_GRP_BITS)
-#define INAT_IMM_BITS  3
-#define INAT_IMM_MASK  (((1 << INAT_IMM_BITS) - 1) << INAT_IMM_OFFS)
-/* Flags */
-#define INAT_FLAG_OFFS (INAT_IMM_OFFS + INAT_IMM_BITS)
-#define INAT_MODRM     (1 << (INAT_FLAG_OFFS))
-#define INAT_FORCE64   (1 << (INAT_FLAG_OFFS + 1))
-#define INAT_SCNDIMM   (1 << (INAT_FLAG_OFFS + 2))
-#define INAT_MOFFSET   (1 << (INAT_FLAG_OFFS + 3))
-#define INAT_VARIANT   (1 << (INAT_FLAG_OFFS + 4))
-#define INAT_VEXOK     (1 << (INAT_FLAG_OFFS + 5))
-#define INAT_VEXONLY   (1 << (INAT_FLAG_OFFS + 6))
-#define INAT_EVEXONLY  (1 << (INAT_FLAG_OFFS + 7))
-/* Attribute making macros for attribute tables */
-#define INAT_MAKE_PREFIX(pfx)  (pfx << INAT_PFX_OFFS)
-#define INAT_MAKE_ESCAPE(esc)  (esc << INAT_ESC_OFFS)
-#define INAT_MAKE_GROUP(grp)   ((grp << INAT_GRP_OFFS) | INAT_MODRM)
-#define INAT_MAKE_IMM(imm)     (imm << INAT_IMM_OFFS)
-
-/* Identifiers for segment registers */
-#define INAT_SEG_REG_IGNORE    0
-#define INAT_SEG_REG_DEFAULT   1
-#define INAT_SEG_REG_CS                2
-#define INAT_SEG_REG_SS                3
-#define INAT_SEG_REG_DS                4
-#define INAT_SEG_REG_ES                5
-#define INAT_SEG_REG_FS                6
-#define INAT_SEG_REG_GS                7
-
-/* Attribute search APIs */
-extern insn_attr_t inat_get_opcode_attribute(insn_byte_t opcode);
-extern int inat_get_last_prefix_id(insn_byte_t last_pfx);
-extern insn_attr_t inat_get_escape_attribute(insn_byte_t opcode,
-                                            int lpfx_id,
-                                            insn_attr_t esc_attr);
-extern insn_attr_t inat_get_group_attribute(insn_byte_t modrm,
-                                           int lpfx_id,
-                                           insn_attr_t esc_attr);
-extern insn_attr_t inat_get_avx_attribute(insn_byte_t opcode,
-                                         insn_byte_t vex_m,
-                                         insn_byte_t vex_pp);
-
-/* Attribute checking functions */
-static inline int inat_is_legacy_prefix(insn_attr_t attr)
-{
-       attr &= INAT_PFX_MASK;
-       return attr && attr <= INAT_LGCPFX_MAX;
-}
-
-static inline int inat_is_address_size_prefix(insn_attr_t attr)
-{
-       return (attr & INAT_PFX_MASK) == INAT_PFX_ADDRSZ;
-}
-
-static inline int inat_is_operand_size_prefix(insn_attr_t attr)
-{
-       return (attr & INAT_PFX_MASK) == INAT_PFX_OPNDSZ;
-}
-
-static inline int inat_is_rex_prefix(insn_attr_t attr)
-{
-       return (attr & INAT_PFX_MASK) == INAT_PFX_REX;
-}
-
-static inline int inat_last_prefix_id(insn_attr_t attr)
-{
-       if ((attr & INAT_PFX_MASK) > INAT_LSTPFX_MAX)
-               return 0;
-       else
-               return attr & INAT_PFX_MASK;
-}
-
-static inline int inat_is_vex_prefix(insn_attr_t attr)
-{
-       attr &= INAT_PFX_MASK;
-       return attr == INAT_PFX_VEX2 || attr == INAT_PFX_VEX3 ||
-              attr == INAT_PFX_EVEX;
-}
-
-static inline int inat_is_evex_prefix(insn_attr_t attr)
-{
-       return (attr & INAT_PFX_MASK) == INAT_PFX_EVEX;
-}
-
-static inline int inat_is_vex3_prefix(insn_attr_t attr)
-{
-       return (attr & INAT_PFX_MASK) == INAT_PFX_VEX3;
-}
-
-static inline int inat_is_escape(insn_attr_t attr)
-{
-       return attr & INAT_ESC_MASK;
-}
-
-static inline int inat_escape_id(insn_attr_t attr)
-{
-       return (attr & INAT_ESC_MASK) >> INAT_ESC_OFFS;
-}
-
-static inline int inat_is_group(insn_attr_t attr)
-{
-       return attr & INAT_GRP_MASK;
-}
-
-static inline int inat_group_id(insn_attr_t attr)
-{
-       return (attr & INAT_GRP_MASK) >> INAT_GRP_OFFS;
-}
-
-static inline int inat_group_common_attribute(insn_attr_t attr)
-{
-       return attr & ~INAT_GRP_MASK;
-}
-
-static inline int inat_has_immediate(insn_attr_t attr)
-{
-       return attr & INAT_IMM_MASK;
-}
-
-static inline int inat_immediate_size(insn_attr_t attr)
-{
-       return (attr & INAT_IMM_MASK) >> INAT_IMM_OFFS;
-}
-
-static inline int inat_has_modrm(insn_attr_t attr)
-{
-       return attr & INAT_MODRM;
-}
-
-static inline int inat_is_force64(insn_attr_t attr)
-{
-       return attr & INAT_FORCE64;
-}
-
-static inline int inat_has_second_immediate(insn_attr_t attr)
-{
-       return attr & INAT_SCNDIMM;
-}
-
-static inline int inat_has_moffset(insn_attr_t attr)
-{
-       return attr & INAT_MOFFSET;
-}
-
-static inline int inat_has_variant(insn_attr_t attr)
-{
-       return attr & INAT_VARIANT;
-}
-
-static inline int inat_accept_vex(insn_attr_t attr)
-{
-       return attr & INAT_VEXOK;
-}
-
-static inline int inat_must_vex(insn_attr_t attr)
-{
-       return attr & (INAT_VEXONLY | INAT_EVEXONLY);
-}
-
-static inline int inat_must_evex(insn_attr_t attr)
-{
-       return attr & INAT_EVEXONLY;
-}
-#endif
diff --git a/tools/objtool/arch/x86/include/asm/insn.h b/tools/objtool/arch/x86/include/asm/insn.h
deleted file mode 100644 (file)
index 154f27b..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
-#ifndef _ASM_X86_INSN_H
-#define _ASM_X86_INSN_H
-/*
- * x86 instruction analysis
- *
- * Copyright (C) IBM Corporation, 2009
- */
-
-/* insn_attr_t is defined in inat.h */
-#include <asm/inat.h>
-
-struct insn_field {
-       union {
-               insn_value_t value;
-               insn_byte_t bytes[4];
-       };
-       /* !0 if we've run insn_get_xxx() for this field */
-       unsigned char got;
-       unsigned char nbytes;
-};
-
-struct insn {
-       struct insn_field prefixes;     /*
-                                        * Prefixes
-                                        * prefixes.bytes[3]: last prefix
-                                        */
-       struct insn_field rex_prefix;   /* REX prefix */
-       struct insn_field vex_prefix;   /* VEX prefix */
-       struct insn_field opcode;       /*
-                                        * opcode.bytes[0]: opcode1
-                                        * opcode.bytes[1]: opcode2
-                                        * opcode.bytes[2]: opcode3
-                                        */
-       struct insn_field modrm;
-       struct insn_field sib;
-       struct insn_field displacement;
-       union {
-               struct insn_field immediate;
-               struct insn_field moffset1;     /* for 64bit MOV */
-               struct insn_field immediate1;   /* for 64bit imm or off16/32 */
-       };
-       union {
-               struct insn_field moffset2;     /* for 64bit MOV */
-               struct insn_field immediate2;   /* for 64bit imm or seg16 */
-       };
-
-       insn_attr_t attr;
-       unsigned char opnd_bytes;
-       unsigned char addr_bytes;
-       unsigned char length;
-       unsigned char x86_64;
-
-       const insn_byte_t *kaddr;       /* kernel address of insn to analyze */
-       const insn_byte_t *end_kaddr;   /* kernel address of last insn in buffer */
-       const insn_byte_t *next_byte;
-};
-
-#define MAX_INSN_SIZE  15
-
-#define X86_MODRM_MOD(modrm) (((modrm) & 0xc0) >> 6)
-#define X86_MODRM_REG(modrm) (((modrm) & 0x38) >> 3)
-#define X86_MODRM_RM(modrm) ((modrm) & 0x07)
-
-#define X86_SIB_SCALE(sib) (((sib) & 0xc0) >> 6)
-#define X86_SIB_INDEX(sib) (((sib) & 0x38) >> 3)
-#define X86_SIB_BASE(sib) ((sib) & 0x07)
-
-#define X86_REX_W(rex) ((rex) & 8)
-#define X86_REX_R(rex) ((rex) & 4)
-#define X86_REX_X(rex) ((rex) & 2)
-#define X86_REX_B(rex) ((rex) & 1)
-
-/* VEX bit flags  */
-#define X86_VEX_W(vex) ((vex) & 0x80)  /* VEX3 Byte2 */
-#define X86_VEX_R(vex) ((vex) & 0x80)  /* VEX2/3 Byte1 */
-#define X86_VEX_X(vex) ((vex) & 0x40)  /* VEX3 Byte1 */
-#define X86_VEX_B(vex) ((vex) & 0x20)  /* VEX3 Byte1 */
-#define X86_VEX_L(vex) ((vex) & 0x04)  /* VEX3 Byte2, VEX2 Byte1 */
-/* VEX bit fields */
-#define X86_EVEX_M(vex)        ((vex) & 0x03)          /* EVEX Byte1 */
-#define X86_VEX3_M(vex)        ((vex) & 0x1f)          /* VEX3 Byte1 */
-#define X86_VEX2_M     1                       /* VEX2.M always 1 */
-#define X86_VEX_V(vex) (((vex) & 0x78) >> 3)   /* VEX3 Byte2, VEX2 Byte1 */
-#define X86_VEX_P(vex) ((vex) & 0x03)          /* VEX3 Byte2, VEX2 Byte1 */
-#define X86_VEX_M_MAX  0x1f                    /* VEX3.M Maximum value */
-
-extern void insn_init(struct insn *insn, const void *kaddr, int buf_len, int x86_64);
-extern void insn_get_prefixes(struct insn *insn);
-extern void insn_get_opcode(struct insn *insn);
-extern void insn_get_modrm(struct insn *insn);
-extern void insn_get_sib(struct insn *insn);
-extern void insn_get_displacement(struct insn *insn);
-extern void insn_get_immediate(struct insn *insn);
-extern void insn_get_length(struct insn *insn);
-
-/* Attribute will be determined after getting ModRM (for opcode groups) */
-static inline void insn_get_attribute(struct insn *insn)
-{
-       insn_get_modrm(insn);
-}
-
-/* Instruction uses RIP-relative addressing */
-extern int insn_rip_relative(struct insn *insn);
-
-/* Init insn for kernel text */
-static inline void kernel_insn_init(struct insn *insn,
-                                   const void *kaddr, int buf_len)
-{
-#ifdef CONFIG_X86_64
-       insn_init(insn, kaddr, buf_len, 1);
-#else /* CONFIG_X86_32 */
-       insn_init(insn, kaddr, buf_len, 0);
-#endif
-}
-
-static inline int insn_is_avx(struct insn *insn)
-{
-       if (!insn->prefixes.got)
-               insn_get_prefixes(insn);
-       return (insn->vex_prefix.value != 0);
-}
-
-static inline int insn_is_evex(struct insn *insn)
-{
-       if (!insn->prefixes.got)
-               insn_get_prefixes(insn);
-       return (insn->vex_prefix.nbytes == 4);
-}
-
-/* Ensure this instruction is decoded completely */
-static inline int insn_complete(struct insn *insn)
-{
-       return insn->opcode.got && insn->modrm.got && insn->sib.got &&
-               insn->displacement.got && insn->immediate.got;
-}
-
-static inline insn_byte_t insn_vex_m_bits(struct insn *insn)
-{
-       if (insn->vex_prefix.nbytes == 2)       /* 2 bytes VEX */
-               return X86_VEX2_M;
-       else if (insn->vex_prefix.nbytes == 3)  /* 3 bytes VEX */
-               return X86_VEX3_M(insn->vex_prefix.bytes[1]);
-       else                                    /* EVEX */
-               return X86_EVEX_M(insn->vex_prefix.bytes[1]);
-}
-
-static inline insn_byte_t insn_vex_p_bits(struct insn *insn)
-{
-       if (insn->vex_prefix.nbytes == 2)       /* 2 bytes VEX */
-               return X86_VEX_P(insn->vex_prefix.bytes[1]);
-       else
-               return X86_VEX_P(insn->vex_prefix.bytes[2]);
-}
-
-/* Get the last prefix id from last prefix or VEX prefix */
-static inline int insn_last_prefix_id(struct insn *insn)
-{
-       if (insn_is_avx(insn))
-               return insn_vex_p_bits(insn);   /* VEX_p is a SIMD prefix id */
-
-       if (insn->prefixes.bytes[3])
-               return inat_get_last_prefix_id(insn->prefixes.bytes[3]);
-
-       return 0;
-}
-
-/* Offset of each field from kaddr */
-static inline int insn_offset_rex_prefix(struct insn *insn)
-{
-       return insn->prefixes.nbytes;
-}
-static inline int insn_offset_vex_prefix(struct insn *insn)
-{
-       return insn_offset_rex_prefix(insn) + insn->rex_prefix.nbytes;
-}
-static inline int insn_offset_opcode(struct insn *insn)
-{
-       return insn_offset_vex_prefix(insn) + insn->vex_prefix.nbytes;
-}
-static inline int insn_offset_modrm(struct insn *insn)
-{
-       return insn_offset_opcode(insn) + insn->opcode.nbytes;
-}
-static inline int insn_offset_sib(struct insn *insn)
-{
-       return insn_offset_modrm(insn) + insn->modrm.nbytes;
-}
-static inline int insn_offset_displacement(struct insn *insn)
-{
-       return insn_offset_sib(insn) + insn->sib.nbytes;
-}
-static inline int insn_offset_immediate(struct insn *insn)
-{
-       return insn_offset_displacement(insn) + insn->displacement.nbytes;
-}
-
-#define POP_SS_OPCODE 0x1f
-#define MOV_SREG_OPCODE 0x8e
-
-/*
- * Intel SDM Vol.3A 6.8.3 states;
- * "Any single-step trap that would be delivered following the MOV to SS
- * instruction or POP to SS instruction (because EFLAGS.TF is 1) is
- * suppressed."
- * This function returns true if @insn is MOV SS or POP SS. On these
- * instructions, single stepping is suppressed.
- */
-static inline int insn_masking_exception(struct insn *insn)
-{
-       return insn->opcode.bytes[0] == POP_SS_OPCODE ||
-               (insn->opcode.bytes[0] == MOV_SREG_OPCODE &&
-                X86_MODRM_REG(insn->modrm.bytes[0]) == 2);
-}
-
-#endif /* _ASM_X86_INSN_H */
index 1470e74e9d661184e967389f8fa09c6deeff560d..0a832e265a50766f6df3129747d4aeac57e59bc4 100755 (executable)
@@ -2,28 +2,50 @@
 # SPDX-License-Identifier: GPL-2.0
 
 FILES='
-arch/x86/lib/insn.c
-arch/x86/lib/inat.c
-arch/x86/lib/x86-opcode-map.txt
-arch/x86/tools/gen-insn-attr-x86.awk
-arch/x86/include/asm/insn.h
-arch/x86/include/asm/inat.h
 arch/x86/include/asm/inat_types.h
 arch/x86/include/asm/orc_types.h
+arch/x86/lib/x86-opcode-map.txt
+arch/x86/tools/gen-insn-attr-x86.awk
 '
 
-check()
-{
-       local file=$1
+check_2 () {
+  file1=$1
+  file2=$2
 
-       diff $file ../../$file > /dev/null ||
-               echo "Warning: synced file at 'tools/objtool/$file' differs from latest kernel version at '$file'"
+  shift
+  shift
+
+  cmd="diff $* $file1 $file2 > /dev/null"
+
+  test -f $file2 && {
+    eval $cmd || {
+      echo "Warning: Kernel ABI header at '$file1' differs from latest version at '$file2'" >&2
+      echo diff -u $file1 $file2
+    }
+  }
+}
+
+check () {
+  file=$1
+
+  shift
+
+  check_2 tools/$file $file $*
 }
 
 if [ ! -d ../../kernel ] || [ ! -d ../../tools ] || [ ! -d ../objtool ]; then
        exit 0
 fi
 
+cd ../..
+
 for i in $FILES; do
   check $i
 done
+
+check arch/x86/include/asm/inat.h     '-I "^#include [\"<]\(asm/\)*inat_types.h[\">]"'
+check arch/x86/include/asm/insn.h     '-I "^#include [\"<]\(asm/\)*inat.h[\">]"'
+check arch/x86/lib/inat.c             '-I "^#include [\"<]\(../include/\)*asm/insn.h[\">]"'
+check arch/x86/lib/insn.c             '-I "^#include [\"<]\(../include/\)*asm/in\(at\|sn\).h[\">]"'
+
+cd -
index 3e5135dded16bde491da1e711db172358f5e03c4..bf1252dc2cb074bcce1fdb0928c553a682fd649f 100644 (file)
@@ -34,3 +34,6 @@ arch/*/include/generated/
 trace/beauty/generated/
 pmu-events/pmu-events.c
 pmu-events/jevents
+feature/
+fixdep
+libtraceevent-dynamic-list
index 50c5b60101bde66828e36e5571d946f216f75cdb..e0d9e7dd4f176c2a2ea7a554e339d85c2bfab223 100644 (file)
@@ -919,3 +919,18 @@ amended to take the number of elements as a parameter.
 
 Note there is currently no advantage to using Intel PT instead of LBR, but
 that may change in the future if greater use is made of the data.
+
+
+PEBS via Intel PT
+=================
+
+Some hardware has the feature to redirect PEBS records to the Intel PT trace.
+Recording is selected by using the aux-output config term e.g.
+
+       perf record -c 10000 -e '{intel_pt/branch=0/,cycles/aux-output/ppp}' uname
+
+Note that currently, software only supports redirecting at most one PEBS event.
+
+To display PEBS events from the Intel PT trace, use the itrace 'o' option e.g.
+
+       perf script --itrace=oe
index c2182cbabde3a07196b26e44a3a8c6a0165d3cb4..82ff7dad40c2744d9619715689e060615c1e4439 100644 (file)
@@ -5,6 +5,8 @@
                x       synthesize transactions events
                w       synthesize ptwrite events
                p       synthesize power events
+               o       synthesize other events recorded due to the use
+                       of aux-output (refer to perf record)
                e       synthesize error events
                d       create a debug log
                g       synthesize a call chain (use with i or x)
index e4aa268d2e38cb14dfa262293b397baab79f1f60..c599623a1f3d8e0965371dc5fa3dc372219e7452 100644 (file)
@@ -40,6 +40,10 @@ The '$HOME/.perfconfig' file is used to store a per-user configuration.
 The file '$(sysconfdir)/perfconfig' can be used to
 store a system-wide default configuration.
 
+One an disable reading config files by setting the PERF_CONFIG environment
+variable to /dev/null, or provide an alternate config file by setting that
+variable.
+
 When reading or writing, the values are read from the system and user
 configuration files by default, and options '--system' and '--user'
 can be used to tell the command to read from or write to only that location.
index 15e0fa87241b2ce543e0346d5b835db13e2ca560..c6f9f31b603984b0187972d2db1dac338e46a5c4 100644 (file)
@@ -60,6 +60,8 @@ OPTIONS
          - 'name' : User defined event name. Single quotes (') may be used to
                    escape symbols in the name from parsing by shell and tool
                    like this: name=\'CPU_CLK_UNHALTED.THREAD:cmask=0x1\'.
+         - 'aux-output': Generate AUX records instead of events. This requires
+                         that an AUX area event is also provided.
 
           See the linkperf:perf-list[1] man page for more parameters.
 
@@ -422,9 +424,14 @@ CLOCK_BOOTTIME, CLOCK_REALTIME and CLOCK_TAI.
 -S::
 --snapshot::
 Select AUX area tracing Snapshot Mode. This option is valid only with an
-AUX area tracing event. Optionally the number of bytes to capture per
-snapshot can be specified. In Snapshot Mode, trace data is captured only when
-signal SIGUSR2 is received.
+AUX area tracing event. Optionally, certain snapshot capturing parameters
+can be specified in a string that follows this option:
+  'e': take one last snapshot on exit; guarantees that there is at least one
+       snapshot in the output file;
+  <size>: if the PMU supports this, specify the desired snapshot size.
+
+In Snapshot Mode trace data is captured only when signal SIGUSR2 is received
+and on exit if the above 'e' option is given.
 
 --proc-map-timeout::
 When processing pre-existing threads /proc/XXX/mmap, it may take a long time,
index 987261d158d4c496dd457eb4ba9c6806264f71df..7315f155803f753ea9603ed001f1daf36a09a64e 100644 (file)
@@ -438,6 +438,23 @@ OPTIONS
 
          perf report --time 0%-10%,30%-40%
 
+--switch-on EVENT_NAME::
+       Only consider events after this event is found.
+
+       This may be interesting to measure a workload only after some initialization
+       phase is over, i.e. insert a perf probe at that point and then using this
+       option with that probe.
+
+--switch-off EVENT_NAME::
+       Stop considering events after this event is found.
+
+--show-on-off-events::
+       Show the --switch-on/off events too. This has no effect in 'perf report' now
+       but probably we'll make the default not to show the switch-on/off events
+        on the --group mode and if there is only one event besides the off/on ones,
+       go straight to the histogram browser, just like 'perf report' with no events
+       explicitely specified does.
+
 --itrace::
        Options for decoding instruction tracing data. The options are:
 
index caaab28f8400fe3ddb57661abfc08ec2bd8cbb93..2599b057e47b4d3cb69b0455520bbd90adb008be 100644 (file)
@@ -417,6 +417,15 @@ include::itrace.txt[]
        For itrace only show specified functions and their callees for
        itrace. Multiple functions can be separated by comma.
 
+--switch-on EVENT_NAME::
+       Only consider events after this event is found.
+
+--switch-off EVENT_NAME::
+       Stop considering events after this event is found.
+
+--show-on-off-events::
+       Show the --switch-on/off events too.
+
 SEE ALSO
 --------
 linkperf:perf-record[1], linkperf:perf-script-perl[1],
index cfea87c6f38e531963a24c94d0a6b05b174b8936..5596129a71cf5d5136e2fba62114ebe9af411ea7 100644 (file)
@@ -266,6 +266,44 @@ Default is to monitor all CPUS.
        Record events of type PERF_RECORD_NAMESPACES and display it with the
        'cgroup_id' sort key.
 
+--switch-on EVENT_NAME::
+       Only consider events after this event is found.
+
+       E.g.:
+
+           Find out where broadcast packets are handled
+
+               perf probe -L icmp_rcv
+
+          Insert a probe there:
+
+               perf probe icmp_rcv:59
+
+          Start perf top and ask it to only consider the cycles events when a
+           broadcast packet arrives This will show a menu with two entries and
+           will start counting when a broadcast packet arrives:
+
+               perf top -e cycles,probe:icmp_rcv --switch-on=probe:icmp_rcv
+
+          Alternatively one can ask for --group and then two overhead columns
+           will appear, the first for cycles and the second for the switch-on event.
+
+               perf top --group -e cycles,probe:icmp_rcv --switch-on=probe:icmp_rcv
+
+       This may be interesting to measure a workload only after some initialization
+       phase is over, i.e. insert a perf probe at that point and use the above
+       examples replacing probe:icmp_rcv with the just-after-init probe.
+
+--switch-off EVENT_NAME::
+       Stop considering events after this event is found.
+
+--show-on-off-events::
+       Show the --switch-on/off events too. This has no effect in 'perf top' now
+       but probably we'll make the default not to show the switch-on/off events
+        on the --group mode and if there is only one event besides the off/on ones,
+       go straight to the histogram browser, just like 'perf top' with no events
+       explicitely specified does.
+
 
 INTERACTIVE PROMPTING KEYS
 --------------------------
index fc6e43262c418f278da07e37688bca39bd21917f..25b74fdb36fae410ced4982c9c7807cfcc5e8885 100644 (file)
@@ -176,6 +176,15 @@ the thread executes on the designated CPUs. Default is to monitor all CPUs.
        only at exit time or when a syscall is interrupted, i.e. in those cases this
        option is equivalent to the number of lines printed.
 
+--switch-on EVENT_NAME::
+       Only consider events after this event is found.
+
+--switch-off EVENT_NAME::
+       Stop considering events after this event is found.
+
+--show-on-off-events::
+       Show the --switch-on/off events too.
+
 --max-stack::
         Set the stack depth limit when parsing the callchain, anything
         beyond the specified depth will be ignored. Note that at this point
index d030c87ed9f57d0589faa99615b59f49761da895..b0152e1095c58af089b8cd41bbc9264bbcdd8aa3 100644 (file)
@@ -298,16 +298,21 @@ Physical memory map and its node assignments.
 
 The format of data in MEM_TOPOLOGY is as follows:
 
-   0 - version          | for future changes
-   8 - block_size_bytes | /sys/devices/system/memory/block_size_bytes
-  16 - count            | number of nodes
-
-For each node we store map of physical indexes:
-
-  32 - node id          | node index
-  40 - size             | size of bitmap
-  48 - bitmap           | bitmap of memory indexes that belongs to node
-                        | /sys/devices/system/node/node<NODE>/memory<INDEX>
+       u64 version;            // Currently 1
+       u64 block_size_bytes;   // /sys/devices/system/memory/block_size_bytes
+       u64 count;              // number of nodes
+
+struct memory_node {
+        u64 node_id;            // node index
+        u64 size;               // size of bitmap
+        struct bitmap {
+               /* size of bitmap again */
+                u64 bitmapsize;
+               /* bitmap of memory indexes that belongs to node     */
+               /* /sys/devices/system/node/node<NODE>/memory<INDEX> */
+                u64 entries[(bitmapsize/64)+1];
+        }
+}[count];
 
 The MEM_TOPOLOGY can be displayed with following command:
 
index eaf25ee104e49d0f892ab8120739ae0430471c09..a269d78456b601297f216099a58b0c6d85feb996 100644 (file)
@@ -281,11 +281,12 @@ ifeq ($(DEBUG),0)
   endif
 endif
 
+INC_FLAGS += -I$(src-perf)/lib/include
 INC_FLAGS += -I$(src-perf)/util/include
 INC_FLAGS += -I$(src-perf)/arch/$(SRCARCH)/include
-INC_FLAGS += -I$(srctree)/tools/include/uapi
 INC_FLAGS += -I$(srctree)/tools/include/
 INC_FLAGS += -I$(srctree)/tools/arch/$(SRCARCH)/include/uapi
+INC_FLAGS += -I$(srctree)/tools/include/uapi
 INC_FLAGS += -I$(srctree)/tools/arch/$(SRCARCH)/include/
 INC_FLAGS += -I$(srctree)/tools/arch/$(SRCARCH)/
 
@@ -827,6 +828,17 @@ ifndef NO_LIBZSTD
   endif
 endif
 
+ifndef NO_LIBCAP
+  ifeq ($(feature-libcap), 1)
+    CFLAGS += -DHAVE_LIBCAP_SUPPORT
+    EXTLIBS += -lcap
+    $(call detected,CONFIG_LIBCAP)
+  else
+    msg := $(warning No libcap found, disables capability support, please install libcap-devel/libcap-dev);
+    NO_LIBCAP := 1
+  endif
+endif
+
 ifndef NO_BACKTRACE
   ifeq ($(feature-backtrace), 1)
     CFLAGS += -DHAVE_BACKTRACE_SUPPORT
index 0fffd2bb6cd9786e59015e195ca29395e6661535..f9807d8c005b21c56aae787a3d0036a456606b47 100644 (file)
@@ -88,6 +88,8 @@ include ../scripts/utilities.mak
 #
 # Define NO_LIBBPF if you do not want BPF support
 #
+# Define NO_LIBCAP if you do not want process capabilities considered by perf
+#
 # Define NO_SDT if you do not want to define SDT event in perf tools,
 # note that it doesn't disable SDT scanning support.
 #
@@ -224,6 +226,7 @@ LIB_DIR         = $(srctree)/tools/lib/api/
 TRACE_EVENT_DIR = $(srctree)/tools/lib/traceevent/
 BPF_DIR         = $(srctree)/tools/lib/bpf/
 SUBCMD_DIR      = $(srctree)/tools/lib/subcmd/
+LIBPERF_DIR     = $(srctree)/tools/perf/lib/
 
 # Set FEATURE_TESTS to 'all' so all possible feature checkers are executed.
 # Without this setting the output feature dump file misses some features, for
@@ -272,6 +275,7 @@ ifneq ($(OUTPUT),)
   TE_PATH=$(OUTPUT)
   BPF_PATH=$(OUTPUT)
   SUBCMD_PATH=$(OUTPUT)
+  LIBPERF_PATH=$(OUTPUT)
 ifneq ($(subdir),)
   API_PATH=$(OUTPUT)/../lib/api/
 else
@@ -282,6 +286,7 @@ else
   API_PATH=$(LIB_DIR)
   BPF_PATH=$(BPF_DIR)
   SUBCMD_PATH=$(SUBCMD_DIR)
+  LIBPERF_PATH=$(LIBPERF_DIR)
 endif
 
 LIBTRACEEVENT = $(TE_PATH)libtraceevent.a
@@ -303,6 +308,9 @@ LIBBPF = $(BPF_PATH)libbpf.a
 
 LIBSUBCMD = $(SUBCMD_PATH)libsubcmd.a
 
+LIBPERF = $(LIBPERF_PATH)libperf.a
+export LIBPERF
+
 # python extension build directories
 PYTHON_EXTBUILD     := $(OUTPUT)python_ext_build/
 PYTHON_EXTBUILD_LIB := $(PYTHON_EXTBUILD)lib/
@@ -348,9 +356,7 @@ endif
 
 export PERL_PATH
 
-LIBPERF_A=$(OUTPUT)libperf.a
-
-PERFLIBS = $(LIBAPI) $(LIBTRACEEVENT) $(LIBSUBCMD)
+PERFLIBS = $(LIBAPI) $(LIBTRACEEVENT) $(LIBSUBCMD) $(LIBPERF)
 ifndef NO_LIBBPF
   PERFLIBS += $(LIBBPF)
 endif
@@ -583,8 +589,6 @@ JEVENTS_IN    := $(OUTPUT)pmu-events/jevents-in.o
 
 PMU_EVENTS_IN := $(OUTPUT)pmu-events/pmu-events-in.o
 
-LIBPERF_IN := $(OUTPUT)libperf-in.o
-
 export JEVENTS
 
 build := -f $(srctree)/tools/build/Makefile.build dir=. obj
@@ -601,12 +605,9 @@ $(JEVENTS): $(JEVENTS_IN)
 $(PMU_EVENTS_IN): $(JEVENTS) FORCE
        $(Q)$(MAKE) -f $(srctree)/tools/build/Makefile.build dir=pmu-events obj=pmu-events
 
-$(LIBPERF_IN): prepare FORCE
-       $(Q)$(MAKE) $(build)=libperf
-
-$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(PMU_EVENTS_IN) $(LIBPERF_IN) $(LIBTRACEEVENT_DYNAMIC_LIST)
+$(OUTPUT)perf: $(PERFLIBS) $(PERF_IN) $(PMU_EVENTS_IN) $(LIBTRACEEVENT_DYNAMIC_LIST)
        $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(LIBTRACEEVENT_DYNAMIC_LIST_LDFLAGS) \
-               $(PERF_IN) $(PMU_EVENTS_IN) $(LIBPERF_IN) $(LIBS) -o $@
+               $(PERF_IN) $(PMU_EVENTS_IN) $(LIBS) -o $@
 
 $(GTK_IN): FORCE
        $(Q)$(MAKE) $(build)=gtk
@@ -727,9 +728,6 @@ endif
 
 $(patsubst perf-%,%.o,$(PROGRAMS)): $(wildcard */*.h)
 
-$(LIBPERF_A): $(LIBPERF_IN)
-       $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIBPERF_IN) $(LIB_OBJS)
-
 LIBTRACEEVENT_FLAGS += plugin_dir=$(plugindir_SQ) 'EXTRA_CFLAGS=$(EXTRA_CFLAGS)' 'LDFLAGS=$(LDFLAGS)'
 
 $(LIBTRACEEVENT): FORCE
@@ -762,6 +760,13 @@ $(LIBBPF)-clean:
        $(call QUIET_CLEAN, libbpf)
        $(Q)$(MAKE) -C $(BPF_DIR) O=$(OUTPUT) clean >/dev/null
 
+$(LIBPERF): FORCE
+       $(Q)$(MAKE) -C $(LIBPERF_DIR) O=$(OUTPUT) $(OUTPUT)libperf.a
+
+$(LIBPERF)-clean:
+       $(call QUIET_CLEAN, libperf)
+       $(Q)$(MAKE) -C $(LIBPERF_DIR) O=$(OUTPUT) clean >/dev/null
+
 $(LIBSUBCMD): FORCE
        $(Q)$(MAKE) -C $(SUBCMD_DIR) O=$(OUTPUT) $(OUTPUT)libsubcmd.a
 
@@ -948,7 +953,7 @@ config-clean:
 python-clean:
        $(python-clean)
 
-clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean config-clean fixdep-clean python-clean
+clean:: $(LIBTRACEEVENT)-clean $(LIBAPI)-clean $(LIBBPF)-clean $(LIBSUBCMD)-clean $(LIBPERF)-clean config-clean fixdep-clean python-clean
        $(call QUIET_CLEAN, core-objs)  $(RM) $(LIBPERF_A) $(OUTPUT)perf-archive $(OUTPUT)perf-with-kcore $(LANG_BINDINGS)
        $(Q)find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.cmd' -delete -o -name '\.*.d' -delete
        $(Q)$(RM) $(OUTPUT).config-detected
index c7d1a69b894fef7e711b9ef72941f0feba386d95..e1d4b484cc4bf4cce60fad06e28cd67c8b754a9b 100644 (file)
@@ -3,6 +3,7 @@
 #include <linux/zalloc.h>
 #include <sys/types.h>
 #include <regex.h>
+#include <stdlib.h>
 
 struct arm_annotate {
        regex_t call_insn,
index 02014740a1aa654a850fd6ae4cb5aafd2e22b582..0a6e75b8777a6ceec7eede18ef251644c4631ad8 100644 (file)
@@ -9,6 +9,7 @@
 #include <linux/zalloc.h>
 
 #include "../../util/auxtrace.h"
+#include "../../util/debug.h"
 #include "../../util/evlist.h"
 #include "../../util/pmu.h"
 #include "cs-etm.h"
@@ -50,10 +51,10 @@ static struct perf_pmu **find_all_arm_spe_pmus(int *nr_spes, int *err)
 }
 
 struct auxtrace_record
-*auxtrace_record__init(struct perf_evlist *evlist, int *err)
+*auxtrace_record__init(struct evlist *evlist, int *err)
 {
        struct perf_pmu *cs_etm_pmu;
-       struct perf_evsel *evsel;
+       struct evsel *evsel;
        bool found_etm = false;
        bool found_spe = false;
        static struct perf_pmu **arm_spe_pmus = NULL;
@@ -70,14 +71,14 @@ struct auxtrace_record
 
        evlist__for_each_entry(evlist, evsel) {
                if (cs_etm_pmu &&
-                   evsel->attr.type == cs_etm_pmu->type)
+                   evsel->core.attr.type == cs_etm_pmu->type)
                        found_etm = true;
 
                if (!nr_spes)
                        continue;
 
                for (i = 0; i < nr_spes; i++) {
-                       if (evsel->attr.type == arm_spe_pmus[i]->type) {
+                       if (evsel->core.attr.type == arm_spe_pmus[i]->type) {
                                found_spe = true;
                                break;
                        }
index 4208974c24f84d4c3215e3fcc734b152dfbc4641..c32db09baf0d13fabfc190373cbe003e46919743 100644 (file)
 #include <linux/coresight-pmu.h>
 #include <linux/kernel.h>
 #include <linux/log2.h>
+#include <linux/string.h>
 #include <linux/types.h>
 #include <linux/zalloc.h>
 
 #include "cs-etm.h"
-#include "../../perf.h"
+#include "../../util/debug.h"
+#include "../../util/record.h"
 #include "../../util/auxtrace.h"
 #include "../../util/cpumap.h"
+#include "../../util/event.h"
 #include "../../util/evlist.h"
 #include "../../util/evsel.h"
 #include "../../util/pmu.h"
-#include "../../util/thread_map.h"
 #include "../../util/cs-etm.h"
 #include "../../util/util.h"
+#include "../../util/session.h"
 
 #include <errno.h>
 #include <stdlib.h>
@@ -32,7 +35,7 @@
 struct cs_etm_recording {
        struct auxtrace_record  itr;
        struct perf_pmu         *cs_etm_pmu;
-       struct perf_evlist      *evlist;
+       struct evlist           *evlist;
        int                     wrapped_cnt;
        bool                    *wrapped;
        bool                    snapshot_mode;
@@ -55,7 +58,7 @@ static const char *metadata_etmv4_ro[CS_ETMV4_PRIV_MAX] = {
 static bool cs_etm_is_etmv4(struct auxtrace_record *itr, int cpu);
 
 static int cs_etm_set_context_id(struct auxtrace_record *itr,
-                                struct perf_evsel *evsel, int cpu)
+                                struct evsel *evsel, int cpu)
 {
        struct cs_etm_recording *ptr;
        struct perf_pmu *cs_etm_pmu;
@@ -95,7 +98,7 @@ static int cs_etm_set_context_id(struct auxtrace_record *itr,
        }
 
        /* All good, let the kernel know */
-       evsel->attr.config |= (1 << ETM_OPT_CTXTID);
+       evsel->core.attr.config |= (1 << ETM_OPT_CTXTID);
        err = 0;
 
 out:
@@ -104,7 +107,7 @@ out:
 }
 
 static int cs_etm_set_timestamp(struct auxtrace_record *itr,
-                               struct perf_evsel *evsel, int cpu)
+                               struct evsel *evsel, int cpu)
 {
        struct cs_etm_recording *ptr;
        struct perf_pmu *cs_etm_pmu;
@@ -144,7 +147,7 @@ static int cs_etm_set_timestamp(struct auxtrace_record *itr,
        }
 
        /* All good, let the kernel know */
-       evsel->attr.config |= (1 << ETM_OPT_TS);
+       evsel->core.attr.config |= (1 << ETM_OPT_TS);
        err = 0;
 
 out:
@@ -152,11 +155,11 @@ out:
 }
 
 static int cs_etm_set_option(struct auxtrace_record *itr,
-                            struct perf_evsel *evsel, u32 option)
+                            struct evsel *evsel, u32 option)
 {
        int i, err = -EINVAL;
-       struct cpu_map *event_cpus = evsel->evlist->cpus;
-       struct cpu_map *online_cpus = cpu_map__new(NULL);
+       struct perf_cpu_map *event_cpus = evsel->evlist->core.cpus;
+       struct perf_cpu_map *online_cpus = perf_cpu_map__new(NULL);
 
        /* Set option of each CPU we have */
        for (i = 0; i < cpu__max_cpu(); i++) {
@@ -181,7 +184,7 @@ static int cs_etm_set_option(struct auxtrace_record *itr,
 
        err = 0;
 out:
-       cpu_map__put(online_cpus);
+       perf_cpu_map__put(online_cpus);
        return err;
 }
 
@@ -208,14 +211,14 @@ static int cs_etm_parse_snapshot_options(struct auxtrace_record *itr,
 }
 
 static int cs_etm_set_sink_attr(struct perf_pmu *pmu,
-                               struct perf_evsel *evsel)
+                               struct evsel *evsel)
 {
        char msg[BUFSIZ], path[PATH_MAX], *sink;
        struct perf_evsel_config_term *term;
        int ret = -EINVAL;
        u32 hash;
 
-       if (evsel->attr.config2 & GENMASK(31, 0))
+       if (evsel->core.attr.config2 & GENMASK(31, 0))
                return 0;
 
        list_for_each_entry(term, &evsel->config_terms, list) {
@@ -233,7 +236,7 @@ static int cs_etm_set_sink_attr(struct perf_pmu *pmu,
                        return ret;
                }
 
-               evsel->attr.config2 |= hash;
+               evsel->core.attr.config2 |= hash;
                return 0;
        }
 
@@ -245,16 +248,16 @@ static int cs_etm_set_sink_attr(struct perf_pmu *pmu,
 }
 
 static int cs_etm_recording_options(struct auxtrace_record *itr,
-                                   struct perf_evlist *evlist,
+                                   struct evlist *evlist,
                                    struct record_opts *opts)
 {
        int ret;
        struct cs_etm_recording *ptr =
                                container_of(itr, struct cs_etm_recording, itr);
        struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
-       struct perf_evsel *evsel, *cs_etm_evsel = NULL;
-       struct cpu_map *cpus = evlist->cpus;
-       bool privileged = (geteuid() == 0 || perf_event_paranoid() < 0);
+       struct evsel *evsel, *cs_etm_evsel = NULL;
+       struct perf_cpu_map *cpus = evlist->core.cpus;
+       bool privileged = perf_event_paranoid_check(-1);
        int err = 0;
 
        ptr->evlist = evlist;
@@ -264,14 +267,14 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
                opts->record_switch_events = true;
 
        evlist__for_each_entry(evlist, evsel) {
-               if (evsel->attr.type == cs_etm_pmu->type) {
+               if (evsel->core.attr.type == cs_etm_pmu->type) {
                        if (cs_etm_evsel) {
                                pr_err("There may be only one %s event\n",
                                       CORESIGHT_ETM_PMU_NAME);
                                return -EINVAL;
                        }
-                       evsel->attr.freq = 0;
-                       evsel->attr.sample_period = 1;
+                       evsel->core.attr.freq = 0;
+                       evsel->core.attr.sample_period = 1;
                        cs_etm_evsel = evsel;
                        opts->full_auxtrace = true;
                }
@@ -396,7 +399,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
         * AUX event.  We also need the contextID in order to be notified
         * when a context switch happened.
         */
-       if (!cpu_map__empty(cpus)) {
+       if (!perf_cpu_map__empty(cpus)) {
                perf_evsel__set_sample_bit(cs_etm_evsel, CPU);
 
                err = cs_etm_set_option(itr, cs_etm_evsel,
@@ -407,7 +410,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
 
        /* Add dummy event to keep tracking */
        if (opts->full_auxtrace) {
-               struct perf_evsel *tracking_evsel;
+               struct evsel *tracking_evsel;
 
                err = parse_events(evlist, "dummy:u", NULL);
                if (err)
@@ -416,11 +419,11 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
                tracking_evsel = perf_evlist__last(evlist);
                perf_evlist__set_tracking_event(evlist, tracking_evsel);
 
-               tracking_evsel->attr.freq = 0;
-               tracking_evsel->attr.sample_period = 1;
+               tracking_evsel->core.attr.freq = 0;
+               tracking_evsel->core.attr.sample_period = 1;
 
                /* In per-cpu case, always need the time of mmap events etc */
-               if (!cpu_map__empty(cpus))
+               if (!perf_cpu_map__empty(cpus))
                        perf_evsel__set_sample_bit(tracking_evsel, TIME);
        }
 
@@ -434,11 +437,11 @@ static u64 cs_etm_get_config(struct auxtrace_record *itr)
        struct cs_etm_recording *ptr =
                        container_of(itr, struct cs_etm_recording, itr);
        struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
-       struct perf_evlist *evlist = ptr->evlist;
-       struct perf_evsel *evsel;
+       struct evlist *evlist = ptr->evlist;
+       struct evsel *evsel;
 
        evlist__for_each_entry(evlist, evsel) {
-               if (evsel->attr.type == cs_etm_pmu->type) {
+               if (evsel->core.attr.type == cs_etm_pmu->type) {
                        /*
                         * Variable perf_event_attr::config is assigned to
                         * ETMv3/PTM.  The bit fields have been made to match
@@ -447,7 +450,7 @@ static u64 cs_etm_get_config(struct auxtrace_record *itr)
                         * drivers/hwtracing/coresight/coresight-perf.c for
                         * details.
                         */
-                       config = evsel->attr.config;
+                       config = evsel->core.attr.config;
                        break;
                }
        }
@@ -485,15 +488,15 @@ static u64 cs_etmv4_get_config(struct auxtrace_record *itr)
 
 static size_t
 cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
-                     struct perf_evlist *evlist __maybe_unused)
+                     struct evlist *evlist __maybe_unused)
 {
        int i;
        int etmv3 = 0, etmv4 = 0;
-       struct cpu_map *event_cpus = evlist->cpus;
-       struct cpu_map *online_cpus = cpu_map__new(NULL);
+       struct perf_cpu_map *event_cpus = evlist->core.cpus;
+       struct perf_cpu_map *online_cpus = perf_cpu_map__new(NULL);
 
        /* cpu map is not empty, we have specific CPUs to work with */
-       if (!cpu_map__empty(event_cpus)) {
+       if (!perf_cpu_map__empty(event_cpus)) {
                for (i = 0; i < cpu__max_cpu(); i++) {
                        if (!cpu_map__has(event_cpus, i) ||
                            !cpu_map__has(online_cpus, i))
@@ -517,7 +520,7 @@ cs_etm_info_priv_size(struct auxtrace_record *itr __maybe_unused,
                }
        }
 
-       cpu_map__put(online_cpus);
+       perf_cpu_map__put(online_cpus);
 
        return (CS_ETM_HEADER_SIZE +
               (etmv4 * CS_ETMV4_PRIV_SIZE) +
@@ -564,7 +567,7 @@ static int cs_etm_get_ro(struct perf_pmu *pmu, int cpu, const char *path)
 
 static void cs_etm_get_metadata(int cpu, u32 *offset,
                                struct auxtrace_record *itr,
-                               struct auxtrace_info_event *info)
+                               struct perf_record_auxtrace_info *info)
 {
        u32 increment;
        u64 magic;
@@ -629,15 +632,15 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
 
 static int cs_etm_info_fill(struct auxtrace_record *itr,
                            struct perf_session *session,
-                           struct auxtrace_info_event *info,
+                           struct perf_record_auxtrace_info *info,
                            size_t priv_size)
 {
        int i;
        u32 offset;
        u64 nr_cpu, type;
-       struct cpu_map *cpu_map;
-       struct cpu_map *event_cpus = session->evlist->cpus;
-       struct cpu_map *online_cpus = cpu_map__new(NULL);
+       struct perf_cpu_map *cpu_map;
+       struct perf_cpu_map *event_cpus = session->evlist->core.cpus;
+       struct perf_cpu_map *online_cpus = perf_cpu_map__new(NULL);
        struct cs_etm_recording *ptr =
                        container_of(itr, struct cs_etm_recording, itr);
        struct perf_pmu *cs_etm_pmu = ptr->cs_etm_pmu;
@@ -649,11 +652,11 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
                return -EINVAL;
 
        /* If the cpu_map is empty all online CPUs are involved */
-       if (cpu_map__empty(event_cpus)) {
+       if (perf_cpu_map__empty(event_cpus)) {
                cpu_map = online_cpus;
        } else {
                /* Make sure all specified CPUs are online */
-               for (i = 0; i < cpu_map__nr(event_cpus); i++) {
+               for (i = 0; i < perf_cpu_map__nr(event_cpus); i++) {
                        if (cpu_map__has(event_cpus, i) &&
                            !cpu_map__has(online_cpus, i))
                                return -EINVAL;
@@ -662,7 +665,7 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
                cpu_map = event_cpus;
        }
 
-       nr_cpu = cpu_map__nr(cpu_map);
+       nr_cpu = perf_cpu_map__nr(cpu_map);
        /* Get PMU type as dynamically assigned by the core */
        type = cs_etm_pmu->type;
 
@@ -679,7 +682,7 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
                if (cpu_map__has(cpu_map, i))
                        cs_etm_get_metadata(i, &offset, itr, info);
 
-       cpu_map__put(online_cpus);
+       perf_cpu_map__put(online_cpus);
 
        return 0;
 }
@@ -817,11 +820,11 @@ static int cs_etm_snapshot_start(struct auxtrace_record *itr)
 {
        struct cs_etm_recording *ptr =
                        container_of(itr, struct cs_etm_recording, itr);
-       struct perf_evsel *evsel;
+       struct evsel *evsel;
 
        evlist__for_each_entry(ptr->evlist, evsel) {
-               if (evsel->attr.type == ptr->cs_etm_pmu->type)
-                       return perf_evsel__disable(evsel);
+               if (evsel->core.attr.type == ptr->cs_etm_pmu->type)
+                       return evsel__disable(evsel);
        }
        return -EINVAL;
 }
@@ -830,11 +833,11 @@ static int cs_etm_snapshot_finish(struct auxtrace_record *itr)
 {
        struct cs_etm_recording *ptr =
                        container_of(itr, struct cs_etm_recording, itr);
-       struct perf_evsel *evsel;
+       struct evsel *evsel;
 
        evlist__for_each_entry(ptr->evlist, evsel) {
-               if (evsel->attr.type == ptr->cs_etm_pmu->type)
-                       return perf_evsel__enable(evsel);
+               if (evsel->core.attr.type == ptr->cs_etm_pmu->type)
+                       return evsel__enable(evsel);
        }
        return -EINVAL;
 }
@@ -858,10 +861,10 @@ static int cs_etm_read_finish(struct auxtrace_record *itr, int idx)
 {
        struct cs_etm_recording *ptr =
                        container_of(itr, struct cs_etm_recording, itr);
-       struct perf_evsel *evsel;
+       struct evsel *evsel;
 
        evlist__for_each_entry(ptr->evlist, evsel) {
-               if (evsel->attr.type == ptr->cs_etm_pmu->type)
+               if (evsel->core.attr.type == ptr->cs_etm_pmu->type)
                        return perf_evlist__enable_event_idx(ptr->evlist,
                                                             evsel, idx);
        }
index 8f70a1b282dfbc25edde9a0f133542e2411cedd4..43aa93ed8414d2649b4321a7c5886240d167dc9b 100644 (file)
@@ -2,6 +2,7 @@
 #include <linux/compiler.h>
 #include <sys/types.h>
 #include <regex.h>
+#include <stdlib.h>
 
 struct arm64_annotate {
        regex_t call_insn,
index 2c009aa74633f1b2e90ca4938ffff5e8e9e054c5..4b364692da67907f94a629f216a7152da3c80121 100644 (file)
@@ -12,6 +12,7 @@
 #include <time.h>
 
 #include "../../util/cpumap.h"
+#include "../../util/event.h"
 #include "../../util/evsel.h"
 #include "../../util/evlist.h"
 #include "../../util/session.h"
@@ -19,6 +20,7 @@
 #include "../../util/pmu.h"
 #include "../../util/debug.h"
 #include "../../util/auxtrace.h"
+#include "../../util/record.h"
 #include "../../util/arm-spe.h"
 
 #define KiB(x) ((x) * 1024)
 struct arm_spe_recording {
        struct auxtrace_record          itr;
        struct perf_pmu                 *arm_spe_pmu;
-       struct perf_evlist              *evlist;
+       struct evlist           *evlist;
 };
 
 static size_t
 arm_spe_info_priv_size(struct auxtrace_record *itr __maybe_unused,
-                      struct perf_evlist *evlist __maybe_unused)
+                      struct evlist *evlist __maybe_unused)
 {
        return ARM_SPE_AUXTRACE_PRIV_SIZE;
 }
 
 static int arm_spe_info_fill(struct auxtrace_record *itr,
                             struct perf_session *session,
-                            struct auxtrace_info_event *auxtrace_info,
+                            struct perf_record_auxtrace_info *auxtrace_info,
                             size_t priv_size)
 {
        struct arm_spe_recording *sper =
@@ -59,27 +61,27 @@ static int arm_spe_info_fill(struct auxtrace_record *itr,
 }
 
 static int arm_spe_recording_options(struct auxtrace_record *itr,
-                                    struct perf_evlist *evlist,
+                                    struct evlist *evlist,
                                     struct record_opts *opts)
 {
        struct arm_spe_recording *sper =
                        container_of(itr, struct arm_spe_recording, itr);
        struct perf_pmu *arm_spe_pmu = sper->arm_spe_pmu;
-       struct perf_evsel *evsel, *arm_spe_evsel = NULL;
-       bool privileged = geteuid() == 0 || perf_event_paranoid() < 0;
-       struct perf_evsel *tracking_evsel;
+       struct evsel *evsel, *arm_spe_evsel = NULL;
+       bool privileged = perf_event_paranoid_check(-1);
+       struct evsel *tracking_evsel;
        int err;
 
        sper->evlist = evlist;
 
        evlist__for_each_entry(evlist, evsel) {
-               if (evsel->attr.type == arm_spe_pmu->type) {
+               if (evsel->core.attr.type == arm_spe_pmu->type) {
                        if (arm_spe_evsel) {
                                pr_err("There may be only one " ARM_SPE_PMU_NAME "x event\n");
                                return -EINVAL;
                        }
-                       evsel->attr.freq = 0;
-                       evsel->attr.sample_period = 1;
+                       evsel->core.attr.freq = 0;
+                       evsel->core.attr.sample_period = 1;
                        arm_spe_evsel = evsel;
                        opts->full_auxtrace = true;
                }
@@ -130,8 +132,8 @@ static int arm_spe_recording_options(struct auxtrace_record *itr,
        tracking_evsel = perf_evlist__last(evlist);
        perf_evlist__set_tracking_event(evlist, tracking_evsel);
 
-       tracking_evsel->attr.freq = 0;
-       tracking_evsel->attr.sample_period = 1;
+       tracking_evsel->core.attr.freq = 0;
+       tracking_evsel->core.attr.sample_period = 1;
        perf_evsel__set_sample_bit(tracking_evsel, TIME);
        perf_evsel__set_sample_bit(tracking_evsel, CPU);
        perf_evsel__reset_sample_bit(tracking_evsel, BRANCH_STACK);
@@ -160,10 +162,10 @@ static int arm_spe_read_finish(struct auxtrace_record *itr, int idx)
 {
        struct arm_spe_recording *sper =
                        container_of(itr, struct arm_spe_recording, itr);
-       struct perf_evsel *evsel;
+       struct evsel *evsel;
 
        evlist__for_each_entry(sper->evlist, evsel) {
-               if (evsel->attr.type == sper->arm_spe_pmu->type)
+               if (evsel->core.attr.type == sper->arm_spe_pmu->type)
                        return perf_evlist__enable_event_idx(sper->evlist,
                                                             evsel, idx);
        }
index 534cd2507d830a3380c3309778270e691c1eb348..e41defaaa2e686bebb5a6e3d5441e101de0459bd 100644 (file)
@@ -1,6 +1,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <api/fs/fs.h>
+#include "debug.h"
 #include "header.h"
 
 #define MIDR "/regs/identification/midr_el1"
@@ -16,7 +17,7 @@ char *get_cpuid_str(struct perf_pmu *pmu)
        const char *sysfs = sysfs__mountpoint();
        int cpu;
        u64 midr = 0;
-       struct cpu_map *cpus;
+       struct perf_cpu_map *cpus;
        FILE *file;
 
        if (!sysfs || !pmu || !pmu->cpus)
@@ -27,7 +28,7 @@ char *get_cpuid_str(struct perf_pmu *pmu)
                return NULL;
 
        /* read midr from list of cpus mapped to this pmu */
-       cpus = cpu_map__get(pmu->cpus);
+       cpus = perf_cpu_map__get(pmu->cpus);
        for (cpu = 0; cpu < cpus->nr; cpu++) {
                scnprintf(path, PATH_MAX, "%s/devices/system/cpu/cpu%d"MIDR,
                                sysfs, cpus->map[cpu]);
@@ -60,6 +61,6 @@ char *get_cpuid_str(struct perf_pmu *pmu)
                buf = NULL;
        }
 
-       cpu_map__put(cpus);
+       perf_cpu_map__put(cpus);
        return buf;
 }
index 27fcf24d6850dcc354f401137bc5087656c14daf..5df7889851305974caad7606eba46cc887bfe7de 100644 (file)
@@ -4,11 +4,9 @@
  * Copyright (C) 2015 Naveen N. Rao, IBM Corporation
  */
 
-#include "debug.h"
-#include "symbol.h"
-#include "map.h"
-#include "probe-event.h"
-#include "probe-file.h"
+#include "symbol.h" // for the elf__needs_adjust_symbols() prototype
+#include <stdbool.h>
+#include <gelf.h>
 
 #ifdef HAVE_LIBELF_SUPPORT
 bool elf__needs_adjust_symbols(GElf_Ehdr ehdr)
index 1a9e22f78c229084151ab45be7b8c5957c1efeaf..59dd875fd5e4e9711554ebcce9b04d21b000a09e 100644 (file)
@@ -1,6 +1,9 @@
 // SPDX-License-Identifier: GPL-2.0
+#include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 #include "common.h"
 #include "../util/env.h"
 #include "../util/debug.h"
index c298a446d1f6f8f0a626032208565b822cd6abbd..e965ed8bb32847ce3ae1a4fdc01ee660dcb6bd64 100644 (file)
@@ -2,7 +2,9 @@
 #ifndef ARCH_PERF_COMMON_H
 #define ARCH_PERF_COMMON_H
 
-#include "../util/env.h"
+#include <stdbool.h>
+
+struct perf_env;
 
 int perf_env__lookup_objdump(struct perf_env *env, const char **path);
 bool perf_env__single_address_space(struct perf_env *env);
index db3bbb8744afb7515f6a5c9410c3fd398a811f2f..43f736ed47f28a1dff42ffb7ae7b3e19613e0211 100644 (file)
@@ -20,7 +20,9 @@
 10     common  unlink                          sys_unlink
 11     nospu   execve                          sys_execve                      compat_sys_execve
 12     common  chdir                           sys_chdir
-13     common  time                            sys_time                        compat_sys_time
+13     32      time                            sys_time32
+13     64      time                            sys_time
+13     spu     time                            sys_time
 14     common  mknod                           sys_mknod
 15     common  chmod                           sys_chmod
 16     common  lchown                          sys_lchown
 22     spu     umount                          sys_ni_syscall
 23     common  setuid                          sys_setuid
 24     common  getuid                          sys_getuid
-25     common  stime                           sys_stime                       compat_sys_stime
+25     32      stime                           sys_stime32
+25     64      stime                           sys_stime
+25     spu     stime                           sys_stime
 26     nospu   ptrace                          sys_ptrace                      compat_sys_ptrace
 27     common  alarm                           sys_alarm
 28     32      oldfstat                        sys_fstat                       sys_ni_syscall
 28     64      oldfstat                        sys_ni_syscall
 28     spu     oldfstat                        sys_ni_syscall
 29     nospu   pause                           sys_pause
-30     nospu   utime                           sys_utime                       compat_sys_utime
+30     32      utime                           sys_utime32
+30     64      utime                           sys_utime
 31     common  stty                            sys_ni_syscall
 32     common  gtty                            sys_ni_syscall
 33     common  access                          sys_access
 121    common  setdomainname                   sys_setdomainname
 122    common  uname                           sys_newuname
 123    common  modify_ldt                      sys_ni_syscall
-124    common  adjtimex                        sys_adjtimex                    compat_sys_adjtimex
+124    32      adjtimex                        sys_adjtimex_time32
+124    64      adjtimex                        sys_adjtimex
+124    spu     adjtimex                        sys_adjtimex
 125    common  mprotect                        sys_mprotect
 126    32      sigprocmask                     sys_sigprocmask                 compat_sys_sigprocmask
 126    64      sigprocmask                     sys_ni_syscall
 158    common  sched_yield                     sys_sched_yield
 159    common  sched_get_priority_max          sys_sched_get_priority_max
 160    common  sched_get_priority_min          sys_sched_get_priority_min
-161    common  sched_rr_get_interval           sys_sched_rr_get_interval       compat_sys_sched_rr_get_interval
-162    common  nanosleep                       sys_nanosleep                   compat_sys_nanosleep
+161    32      sched_rr_get_interval           sys_sched_rr_get_interval_time32
+161    64      sched_rr_get_interval           sys_sched_rr_get_interval
+161    spu     sched_rr_get_interval           sys_sched_rr_get_interval
+162    32      nanosleep                       sys_nanosleep_time32
+162    64      nanosleep                       sys_nanosleep
+162    spu     nanosleep                       sys_nanosleep
 163    common  mremap                          sys_mremap
 164    common  setresuid                       sys_setresuid
 165    common  getresuid                       sys_getresuid
 173    nospu   rt_sigaction                    sys_rt_sigaction                compat_sys_rt_sigaction
 174    nospu   rt_sigprocmask                  sys_rt_sigprocmask              compat_sys_rt_sigprocmask
 175    nospu   rt_sigpending                   sys_rt_sigpending               compat_sys_rt_sigpending
-176    nospu   rt_sigtimedwait                 sys_rt_sigtimedwait             compat_sys_rt_sigtimedwait
+176    32      rt_sigtimedwait                 sys_rt_sigtimedwait_time32      compat_sys_rt_sigtimedwait_time32
+176    64      rt_sigtimedwait                 sys_rt_sigtimedwait
 177    nospu   rt_sigqueueinfo                 sys_rt_sigqueueinfo             compat_sys_rt_sigqueueinfo
 178    nospu   rt_sigsuspend                   sys_rt_sigsuspend               compat_sys_rt_sigsuspend
 179    common  pread64                         sys_pread64                     compat_sys_pread64
 218    common  removexattr                     sys_removexattr
 219    common  lremovexattr                    sys_lremovexattr
 220    common  fremovexattr                    sys_fremovexattr
-221    common  futex                           sys_futex                       compat_sys_futex
+221    32      futex                           sys_futex_time32
+221    64      futex                           sys_futex
+221    spu     futex                           sys_futex
 222    common  sched_setaffinity               sys_sched_setaffinity           compat_sys_sched_setaffinity
 223    common  sched_getaffinity               sys_sched_getaffinity           compat_sys_sched_getaffinity
 # 224 unused
 226    32      sendfile64                      sys_sendfile64                  compat_sys_sendfile64
 227    common  io_setup                        sys_io_setup                    compat_sys_io_setup
 228    common  io_destroy                      sys_io_destroy
-229    common  io_getevents                    sys_io_getevents                compat_sys_io_getevents
+229    32      io_getevents                    sys_io_getevents_time32
+229    64      io_getevents                    sys_io_getevents
+229    spu     io_getevents                    sys_io_getevents
 230    common  io_submit                       sys_io_submit                   compat_sys_io_submit
 231    common  io_cancel                       sys_io_cancel
 232    nospu   set_tid_address                 sys_set_tid_address
 238    common  epoll_wait                      sys_epoll_wait
 239    common  remap_file_pages                sys_remap_file_pages
 240    common  timer_create                    sys_timer_create                compat_sys_timer_create
-241    common  timer_settime                   sys_timer_settime               compat_sys_timer_settime
-242    common  timer_gettime                   sys_timer_gettime               compat_sys_timer_gettime
+241    32      timer_settime                   sys_timer_settime32
+241    64      timer_settime                   sys_timer_settime
+241    spu     timer_settime                   sys_timer_settime
+242    32      timer_gettime                   sys_timer_gettime32
+242    64      timer_gettime                   sys_timer_gettime
+242    spu     timer_gettime                   sys_timer_gettime
 243    common  timer_getoverrun                sys_timer_getoverrun
 244    common  timer_delete                    sys_timer_delete
-245    common  clock_settime                   sys_clock_settime               compat_sys_clock_settime
-246    common  clock_gettime                   sys_clock_gettime               compat_sys_clock_gettime
-247    common  clock_getres                    sys_clock_getres                compat_sys_clock_getres
-248    common  clock_nanosleep                 sys_clock_nanosleep             compat_sys_clock_nanosleep
+245    32      clock_settime                   sys_clock_settime32
+245    64      clock_settime                   sys_clock_settime
+245    spu     clock_settime                   sys_clock_settime
+246    32      clock_gettime                   sys_clock_gettime32
+246    64      clock_gettime                   sys_clock_gettime
+246    spu     clock_gettime                   sys_clock_gettime
+247    32      clock_getres                    sys_clock_getres_time32
+247    64      clock_getres                    sys_clock_getres
+247    spu     clock_getres                    sys_clock_getres
+248    32      clock_nanosleep                 sys_clock_nanosleep_time32
+248    64      clock_nanosleep                 sys_clock_nanosleep
+248    spu     clock_nanosleep                 sys_clock_nanosleep
 249    32      swapcontext                     ppc_swapcontext                 ppc32_swapcontext
 249    64      swapcontext                     ppc64_swapcontext
 249    spu     swapcontext                     sys_ni_syscall
 250    common  tgkill                          sys_tgkill
-251    common  utimes                          sys_utimes                      compat_sys_utimes
+251    32      utimes                          sys_utimes_time32
+251    64      utimes                          sys_utimes
+251    spu     utimes                          sys_utimes
 252    common  statfs64                        sys_statfs64                    compat_sys_statfs64
 253    common  fstatfs64                       sys_fstatfs64                   compat_sys_fstatfs64
 254    32      fadvise64_64                    ppc_fadvise64_64
 261    nospu   set_mempolicy                   sys_set_mempolicy               compat_sys_set_mempolicy
 262    nospu   mq_open                         sys_mq_open                     compat_sys_mq_open
 263    nospu   mq_unlink                       sys_mq_unlink
-264    nospu   mq_timedsend                    sys_mq_timedsend                compat_sys_mq_timedsend
-265    nospu   mq_timedreceive                 sys_mq_timedreceive             compat_sys_mq_timedreceive
+264    32      mq_timedsend                    sys_mq_timedsend_time32
+264    64      mq_timedsend                    sys_mq_timedsend
+265    32      mq_timedreceive                 sys_mq_timedreceive_time32
+265    64      mq_timedreceive                 sys_mq_timedreceive
 266    nospu   mq_notify                       sys_mq_notify                   compat_sys_mq_notify
 267    nospu   mq_getsetattr                   sys_mq_getsetattr               compat_sys_mq_getsetattr
 268    nospu   kexec_load                      sys_kexec_load                  compat_sys_kexec_load
 277    nospu   inotify_rm_watch                sys_inotify_rm_watch
 278    nospu   spu_run                         sys_spu_run
 279    nospu   spu_create                      sys_spu_create
-280    nospu   pselect6                        sys_pselect6                    compat_sys_pselect6
-281    nospu   ppoll                           sys_ppoll                       compat_sys_ppoll
+280    32      pselect6                        sys_pselect6_time32             compat_sys_pselect6_time32
+280    64      pselect6                        sys_pselect6
+281    32      ppoll                           sys_ppoll_time32                compat_sys_ppoll_time32
+281    64      ppoll                           sys_ppoll
 282    common  unshare                         sys_unshare
 283    common  splice                          sys_splice
 284    common  tee                             sys_tee
 287    common  mkdirat                         sys_mkdirat
 288    common  mknodat                         sys_mknodat
 289    common  fchownat                        sys_fchownat
-290    common  futimesat                       sys_futimesat                   compat_sys_futimesat
+290    32      futimesat                       sys_futimesat_time32
+290    64      futimesat                       sys_futimesat
+290    spu     utimesat                        sys_futimesat
 291    32      fstatat64                       sys_fstatat64
 291    64      newfstatat                      sys_newfstatat
 291    spu     newfstatat                      sys_newfstatat
 301    common  move_pages                      sys_move_pages                  compat_sys_move_pages
 302    common  getcpu                          sys_getcpu
 303    nospu   epoll_pwait                     sys_epoll_pwait                 compat_sys_epoll_pwait
-304    common  utimensat                       sys_utimensat                   compat_sys_utimensat
+304    32      utimensat                       sys_utimensat_time32
+304    64      utimensat                       sys_utimensat
+304    spu     utimensat                       sys_utimensat
 305    common  signalfd                        sys_signalfd                    compat_sys_signalfd
 306    common  timerfd_create                  sys_timerfd_create
 307    common  eventfd                         sys_eventfd
 308    common  sync_file_range2                sys_sync_file_range2            compat_sys_sync_file_range2
 309    nospu   fallocate                       sys_fallocate                   compat_sys_fallocate
 310    nospu   subpage_prot                    sys_subpage_prot
-311    common  timerfd_settime                 sys_timerfd_settime             compat_sys_timerfd_settime
-312    common  timerfd_gettime                 sys_timerfd_gettime             compat_sys_timerfd_gettime
+311    32      timerfd_settime                 sys_timerfd_settime32
+311    64      timerfd_settime                 sys_timerfd_settime
+311    spu     timerfd_settime                 sys_timerfd_settime
+312    32      timerfd_gettime                 sys_timerfd_gettime32
+312    64      timerfd_gettime                 sys_timerfd_gettime
+312    spu     timerfd_gettime                 sys_timerfd_gettime
 313    common  signalfd4                       sys_signalfd4                   compat_sys_signalfd4
 314    common  eventfd2                        sys_eventfd2
 315    common  epoll_create1                   sys_epoll_create1
 340    common  getsockopt                      sys_getsockopt                  compat_sys_getsockopt
 341    common  sendmsg                         sys_sendmsg                     compat_sys_sendmsg
 342    common  recvmsg                         sys_recvmsg                     compat_sys_recvmsg
-343    common  recvmmsg                        sys_recvmmsg                    compat_sys_recvmmsg
+343    32      recvmmsg                        sys_recvmmsg_time32             compat_sys_recvmmsg_time32
+343    64      recvmmsg                        sys_recvmmsg
+343    spu     recvmmsg                        sys_recvmmsg
 344    common  accept4                         sys_accept4
 345    common  name_to_handle_at               sys_name_to_handle_at
 346    common  open_by_handle_at               sys_open_by_handle_at           compat_sys_open_by_handle_at
-347    common  clock_adjtime                   sys_clock_adjtime               compat_sys_clock_adjtime
+347    32      clock_adjtime                   sys_clock_adjtime32
+347    64      clock_adjtime                   sys_clock_adjtime
+347    spu     clock_adjtime                   sys_clock_adjtime
 348    common  syncfs                          sys_syncfs
 349    common  sendmmsg                        sys_sendmmsg                    compat_sys_sendmmsg
 350    common  setns                           sys_setns
 363    spu     switch_endian                   sys_ni_syscall
 364    common  userfaultfd                     sys_userfaultfd
 365    common  membarrier                      sys_membarrier
+# 366-377 originally left for IPC, now unused
 378    nospu   mlock2                          sys_mlock2
 379    nospu   copy_file_range                 sys_copy_file_range
 380    common  preadv2                         sys_preadv2                     compat_sys_preadv2
 385    nospu   pkey_free                       sys_pkey_free
 386    nospu   pkey_mprotect                   sys_pkey_mprotect
 387    nospu   rseq                            sys_rseq
-388    nospu   io_pgetevents                   sys_io_pgetevents               compat_sys_io_pgetevents
+388    32      io_pgetevents                   sys_io_pgetevents_time32        compat_sys_io_pgetevents
+388    64      io_pgetevents                   sys_io_pgetevents
+# room for arch specific syscalls
+392    64      semtimedop                      sys_semtimedop
+393    common  semget                          sys_semget
+394    common  semctl                          sys_semctl                      compat_sys_semctl
+395    common  shmget                          sys_shmget
+396    common  shmctl                          sys_shmctl                      compat_sys_shmctl
+397    common  shmat                           sys_shmat                       compat_sys_shmat
+398    common  shmdt                           sys_shmdt
+399    common  msgget                          sys_msgget
+400    common  msgsnd                          sys_msgsnd                      compat_sys_msgsnd
+401    common  msgrcv                          sys_msgrcv                      compat_sys_msgrcv
+402    common  msgctl                          sys_msgctl                      compat_sys_msgctl
+403    32      clock_gettime64                 sys_clock_gettime               sys_clock_gettime
+404    32      clock_settime64                 sys_clock_settime               sys_clock_settime
+405    32      clock_adjtime64                 sys_clock_adjtime               sys_clock_adjtime
+406    32      clock_getres_time64             sys_clock_getres                sys_clock_getres
+407    32      clock_nanosleep_time64          sys_clock_nanosleep             sys_clock_nanosleep
+408    32      timer_gettime64                 sys_timer_gettime               sys_timer_gettime
+409    32      timer_settime64                 sys_timer_settime               sys_timer_settime
+410    32      timerfd_gettime64               sys_timerfd_gettime             sys_timerfd_gettime
+411    32      timerfd_settime64               sys_timerfd_settime             sys_timerfd_settime
+412    32      utimensat_time64                sys_utimensat                   sys_utimensat
+413    32      pselect6_time64                 sys_pselect6                    compat_sys_pselect6_time64
+414    32      ppoll_time64                    sys_ppoll                       compat_sys_ppoll_time64
+416    32      io_pgetevents_time64            sys_io_pgetevents               sys_io_pgetevents
+417    32      recvmmsg_time64                 sys_recvmmsg                    compat_sys_recvmmsg_time64
+418    32      mq_timedsend_time64             sys_mq_timedsend                sys_mq_timedsend
+419    32      mq_timedreceive_time64          sys_mq_timedreceive             sys_mq_timedreceive
+420    32      semtimedop_time64               sys_semtimedop                  sys_semtimedop
+421    32      rt_sigtimedwait_time64          sys_rt_sigtimedwait             compat_sys_rt_sigtimedwait_time64
+422    32      futex_time64                    sys_futex                       sys_futex
+423    32      sched_rr_get_interval_time64    sys_sched_rr_get_interval       sys_sched_rr_get_interval
+424    common  pidfd_send_signal               sys_pidfd_send_signal
+425    common  io_uring_setup                  sys_io_uring_setup
+426    common  io_uring_enter                  sys_io_uring_enter
+427    common  io_uring_register               sys_io_uring_register
+428    common  open_tree                       sys_open_tree
+429    common  move_mount                      sys_move_mount
+430    common  fsopen                          sys_fsopen
+431    common  fsconfig                        sys_fsconfig
+432    common  fsmount                         sys_fsmount
+433    common  fspick                          sys_fspick
+434    common  pidfd_open                      sys_pidfd_open
+435    nospu   clone3                          ppc_clone3
index f9db341c47b608eb7d89a290a1c952d98675488a..f0dbf7b075c8d86f6bae680e2e43e2b70a0f8aab 100644 (file)
@@ -32,7 +32,7 @@ const char *ppc_book3s_hv_kvm_tp[] = {
 const char *kvm_events_tp[NR_TPS + 1];
 const char *kvm_exit_reason;
 
-static void hcall_event_get_key(struct perf_evsel *evsel,
+static void hcall_event_get_key(struct evsel *evsel,
                                struct perf_sample *sample,
                                struct event_key *key)
 {
@@ -55,14 +55,14 @@ static const char *get_hcall_exit_reason(u64 exit_code)
        return "UNKNOWN";
 }
 
-static bool hcall_event_end(struct perf_evsel *evsel,
+static bool hcall_event_end(struct evsel *evsel,
                            struct perf_sample *sample __maybe_unused,
                            struct event_key *key __maybe_unused)
 {
        return (!strcmp(evsel->name, kvm_events_tp[3]));
 }
 
-static bool hcall_event_begin(struct perf_evsel *evsel,
+static bool hcall_event_begin(struct evsel *evsel,
                              struct perf_sample *sample, struct event_key *key)
 {
        if (!strcmp(evsel->name, kvm_events_tp[2])) {
@@ -106,7 +106,7 @@ const char * const kvm_skip_events[] = {
 };
 
 
-static int is_tracepoint_available(const char *str, struct perf_evlist *evlist)
+static int is_tracepoint_available(const char *str, struct evlist *evlist)
 {
        struct parse_events_error err;
        int ret;
@@ -119,7 +119,7 @@ static int is_tracepoint_available(const char *str, struct perf_evlist *evlist)
 }
 
 static int ppc__setup_book3s_hv(struct perf_kvm_stat *kvm,
-                               struct perf_evlist *evlist)
+                               struct evlist *evlist)
 {
        const char **events_ptr;
        int i, nr_tp = 0, err = -1;
@@ -146,7 +146,7 @@ static int ppc__setup_book3s_hv(struct perf_kvm_stat *kvm,
 /* Wrapper to setup kvm tracepoints */
 static int ppc__setup_kvm_tp(struct perf_kvm_stat *kvm)
 {
-       struct perf_evlist *evlist = perf_evlist__new();
+       struct evlist *evlist = evlist__new();
 
        if (evlist == NULL)
                return -ENOMEM;
index d08311f04e95fc7d0ac00226b38b39ec62b31bca..07fb5e049488168de1d91cfd192bee083db1fa3b 100644 (file)
@@ -1,4 +1,5 @@
 // SPDX-License-Identifier: GPL-2.0
+#include "map_symbol.h"
 #include "mem-events.h"
 
 /* PowerPC does not support 'ldlat' parameter. */
index f14102b855098f37296e95d321767f433c97b533..e9c436eeffc9d8f390eb564619283e49897c0adf 100644 (file)
@@ -4,7 +4,6 @@
 #include <regex.h>
 #include <linux/zalloc.h>
 
-#include "../../perf.h"
 #include "../../util/perf_regs.h"
 #include "../../util/debug.h"
 
index b0a67eaf2ce8c12246809cbffbdae5719b75d753..8a4b717e0a533993af7a087c4b8e2df90b6493d7 100644 (file)
@@ -5,6 +5,7 @@
  */
 
 #include "debug.h"
+#include "dso.h"
 #include "symbol.h"
 #include "map.h"
 #include "probe-event.h"
index 7a1f05ef2fc031d5b77268b48b2e3c85ff0ebd48..abf2dbc7f829a966fc0471eb548d47967c4908ad 100644 (file)
@@ -1,5 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0
 #include <elfutils/libdwfl.h>
+#include <linux/kernel.h>
 #include "../../util/unwind-libdw.h"
 #include "../../util/perf_regs.h"
 #include "../../util/event.h"
index 0fe1be93f375f1bcf7ca2ec620ba97bedb1b55f1..b0fb70e38960dc9c339aaa7348eb5bff73f2459e 100644 (file)
@@ -8,6 +8,7 @@
 #include "../../util/evlist.h"
 #include "../../util/auxtrace.h"
 #include "../../util/evsel.h"
+#include "../../util/record.h"
 
 #define PERF_EVENT_CPUM_SF             0xB0000 /* Event: Basic-sampling */
 #define PERF_EVENT_CPUM_SF_DIAG                0xBD000 /* Event: Combined-sampling */
@@ -20,7 +21,7 @@ static void cpumsf_free(struct auxtrace_record *itr)
 }
 
 static size_t cpumsf_info_priv_size(struct auxtrace_record *itr __maybe_unused,
-                                   struct perf_evlist *evlist __maybe_unused)
+                                   struct evlist *evlist __maybe_unused)
 {
        return 0;
 }
@@ -28,7 +29,7 @@ static size_t cpumsf_info_priv_size(struct auxtrace_record *itr __maybe_unused,
 static int
 cpumsf_info_fill(struct auxtrace_record *itr __maybe_unused,
                 struct perf_session *session __maybe_unused,
-                struct auxtrace_info_event *auxtrace_info __maybe_unused,
+                struct perf_record_auxtrace_info *auxtrace_info __maybe_unused,
                 size_t priv_size __maybe_unused)
 {
        auxtrace_info->type = PERF_AUXTRACE_S390_CPUMSF;
@@ -43,7 +44,7 @@ cpumsf_reference(struct auxtrace_record *itr __maybe_unused)
 
 static int
 cpumsf_recording_options(struct auxtrace_record *ar __maybe_unused,
-                        struct perf_evlist *evlist __maybe_unused,
+                        struct evlist *evlist __maybe_unused,
                         struct record_opts *opts)
 {
        unsigned int factor = 1;
@@ -82,19 +83,19 @@ cpumsf_parse_snapshot_options(struct auxtrace_record *itr __maybe_unused,
  * auxtrace_record__init is called when perf record
  * check if the event really need auxtrace
  */
-struct auxtrace_record *auxtrace_record__init(struct perf_evlist *evlist,
+struct auxtrace_record *auxtrace_record__init(struct evlist *evlist,
                                              int *err)
 {
        struct auxtrace_record *aux;
-       struct perf_evsel *pos;
+       struct evsel *pos;
        int diagnose = 0;
 
        *err = 0;
-       if (evlist->nr_entries == 0)
+       if (evlist->core.nr_entries == 0)
                return NULL;
 
        evlist__for_each_entry(evlist, pos) {
-               if (pos->attr.config == PERF_EVENT_CPUM_SF_DIAG) {
+               if (pos->core.attr.config == PERF_EVENT_CPUM_SF_DIAG) {
                        diagnose = 1;
                        break;
                }
index f852f2a77e0ae3b34342a8009b51c41ed29f8710..0fd4e9f49ed01eb13879687bda7de26a2e8b8157 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <errno.h>
+#include <string.h>
 #include "../../util/kvm-stat.h"
 #include "../../util/evsel.h"
 #include <asm/sie.h>
@@ -23,7 +24,7 @@ const char *kvm_exit_reason = "icptcode";
 const char *kvm_entry_trace = "kvm:kvm_s390_sie_enter";
 const char *kvm_exit_trace = "kvm:kvm_s390_sie_exit";
 
-static void event_icpt_insn_get_key(struct perf_evsel *evsel,
+static void event_icpt_insn_get_key(struct evsel *evsel,
                                    struct perf_sample *sample,
                                    struct event_key *key)
 {
@@ -34,7 +35,7 @@ static void event_icpt_insn_get_key(struct perf_evsel *evsel,