Merge remote-tracking branch 'torvalds/master' into perf/core
authorArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 8 Mar 2021 13:11:33 +0000 (10:11 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Mon, 8 Mar 2021 13:11:33 +0000 (10:11 -0300)
To pick up the fixes sent for v5.12 and continue development based on
v5.12-rc2, i.e. without the swap on file bug.

This also gets a slightly newer and better tools/perf/arch/arm/util/cs-etm.c
patch version, using the BIT() macro, that had already been slated to
v5.13 but ended up going to v5.12-rc1 on an older version.

Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
31 files changed:
tools/perf/Documentation/perf-config.txt
tools/perf/Documentation/perf-report.txt
tools/perf/Documentation/perf.txt
tools/perf/Makefile.config
tools/perf/Makefile.perf
tools/perf/arch/arm/util/cs-etm.c
tools/perf/arch/mips/Makefile [new file with mode: 0644]
tools/perf/arch/mips/entry/syscalls/mksyscalltbl [new file with mode: 0644]
tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl [new file with mode: 0644]
tools/perf/arch/mips/include/dwarf-regs-table.h [new file with mode: 0644]
tools/perf/arch/mips/include/perf_regs.h [new file with mode: 0644]
tools/perf/arch/mips/util/Build [new file with mode: 0644]
tools/perf/arch/mips/util/dwarf-regs.c [new file with mode: 0644]
tools/perf/arch/mips/util/perf_regs.c [new file with mode: 0644]
tools/perf/arch/mips/util/unwind-libunwind.c [new file with mode: 0644]
tools/perf/bench/inject-buildid.c
tools/perf/builtin-report.c
tools/perf/check-headers.sh
tools/perf/pmu-events/arch/powerpc/power9/metrics.json
tools/perf/tests/parse-metric.c
tools/perf/tests/shell/buildid.sh
tools/perf/ui/browsers/annotate.c
tools/perf/util/annotate.c
tools/perf/util/annotate.h
tools/perf/util/bpf_counter.h
tools/perf/util/bpf_skel/bpf_prog_profiler.bpf.c
tools/perf/util/cs-etm-decoder/cs-etm-decoder.c
tools/perf/util/cs-etm.c
tools/perf/util/cs-etm.h
tools/perf/util/dwarf-regs.c
tools/perf/util/syscalltbl.c

index 153bde1..154a1ce 100644 (file)
@@ -393,6 +393,12 @@ annotate.*::
 
                This option works with tui, stdio2 browsers.
 
+       annotate.demangle::
+               Demangle symbol names to human readable form. Default is 'true'.
+
+       annotate.demangle_kernel::
+               Demangle kernel symbol names to human readable form. Default is 'true'.
+
 hist.*::
        hist.percentage::
                This option control the way to calculate overhead of filtered entries -
index f546b5e..87112e8 100644 (file)
@@ -224,6 +224,9 @@ OPTIONS
 --dump-raw-trace::
         Dump raw trace in ASCII.
 
+--disable-order::
+       Disable raw trace ordering.
+
 -g::
 --call-graph=<print_type,threshold[,print_limit],order,sort_key[,branch],value>::
         Display call chains using type, min percent threshold, print limit,
index c130a3c..9c330cd 100644 (file)
@@ -76,3 +76,15 @@ SEE ALSO
 linkperf:perf-stat[1], linkperf:perf-top[1],
 linkperf:perf-record[1], linkperf:perf-report[1],
 linkperf:perf-list[1]
+
+linkperf:perf-annotate[1],linkperf:perf-archive[1],
+linkperf:perf-bench[1], linkperf:perf-buildid-cache[1],
+linkperf:perf-buildid-list[1], linkperf:perf-c2c[1],
+linkperf:perf-config[1], linkperf:perf-data[1], linkperf:perf-diff[1],
+linkperf:perf-evlist[1], linkperf:perf-ftrace[1],
+linkperf:perf-help[1], linkperf:perf-inject[1],
+linkperf:perf-intel-pt[1], linkperf:perf-kallsyms[1],
+linkperf:perf-kmem[1], linkperf:perf-kvm[1], linkperf:perf-lock[1],
+linkperf:perf-mem[1], linkperf:perf-probe[1], linkperf:perf-sched[1],
+linkperf:perf-script[1], linkperf:perf-test[1],
+linkperf:perf-trace[1], linkperf:perf-version[1]
index d8e59d3..3514fe9 100644 (file)
@@ -32,7 +32,7 @@ ifneq ($(NO_SYSCALL_TABLE),1)
       NO_SYSCALL_TABLE := 0
     endif
   else
-    ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc arm64 s390))
+    ifeq ($(SRCARCH),$(filter $(SRCARCH),powerpc arm64 s390 mips))
       NO_SYSCALL_TABLE := 0
     endif
   endif
@@ -87,6 +87,13 @@ ifeq ($(ARCH),s390)
   CFLAGS += -fPIC -I$(OUTPUT)arch/s390/include/generated
 endif
 
+ifeq ($(ARCH),mips)
+  NO_PERF_REGS := 0
+  CFLAGS += -I$(OUTPUT)arch/mips/include/generated
+  CFLAGS += -I../../arch/mips/include/uapi -I../../arch/mips/include/generated/uapi
+  LIBUNWIND_LIBS = -lunwind -lunwind-mips
+endif
+
 ifeq ($(NO_PERF_REGS),0)
   $(call detected,CONFIG_PERF_REGS)
 endif
index f6e6096..a7d768f 100644 (file)
@@ -1021,7 +1021,7 @@ $(BPFTOOL): | $(SKEL_TMP_OUT)
                OUTPUT=$(SKEL_TMP_OUT)/ bootstrap
 
 $(SKEL_TMP_OUT)/%.bpf.o: util/bpf_skel/%.bpf.c $(LIBBPF) | $(SKEL_TMP_OUT)
-       $(QUIET_CLANG)$(CLANG) -g -O2 -target bpf $(BPF_INCLUDE) \
+       $(QUIET_CLANG)$(CLANG) -g -O2 -target bpf -Wall -Werror $(BPF_INCLUDE) \
          -c $(filter util/bpf_skel/%.bpf.c,$^) -o $@ && $(LLVM_STRIP) -g $@
 
 $(SKEL_OUT)/%.skel.h: $(SKEL_TMP_OUT)/%.bpf.o | $(BPFTOOL)
index c25c878..0a44bc4 100644 (file)
@@ -67,6 +67,7 @@ static int cs_etm_set_context_id(struct auxtrace_record *itr,
        char path[PATH_MAX];
        int err = -EINVAL;
        u32 val;
+       u64 contextid;
 
        ptr = container_of(itr, struct cs_etm_recording, itr);
        cs_etm_pmu = ptr->cs_etm_pmu;
@@ -86,25 +87,59 @@ static int cs_etm_set_context_id(struct auxtrace_record *itr,
                goto out;
        }
 
+       /* User has configured for PID tracing, respects it. */
+       contextid = evsel->core.attr.config &
+                       (BIT(ETM_OPT_CTXTID) | BIT(ETM_OPT_CTXTID2));
+
        /*
-        * TRCIDR2.CIDSIZE, bit [9-5], indicates whether contextID tracing
-        * is supported:
-        *  0b00000 Context ID tracing is not supported.
-        *  0b00100 Maximum of 32-bit Context ID size.
-        *  All other values are reserved.
+        * If user doesn't configure the contextid format, parse PMU format and
+        * enable PID tracing according to the "contextid" format bits:
+        *
+        *   If bit ETM_OPT_CTXTID is set, trace CONTEXTIDR_EL1;
+        *   If bit ETM_OPT_CTXTID2 is set, trace CONTEXTIDR_EL2.
         */
-       val = BMVAL(val, 5, 9);
-       if (!val || val != 0x4) {
-               err = -EINVAL;
-               goto out;
+       if (!contextid)
+               contextid = perf_pmu__format_bits(&cs_etm_pmu->format,
+                                                 "contextid");
+
+       if (contextid & BIT(ETM_OPT_CTXTID)) {
+               /*
+                * TRCIDR2.CIDSIZE, bit [9-5], indicates whether contextID
+                * tracing is supported:
+                *  0b00000 Context ID tracing is not supported.
+                *  0b00100 Maximum of 32-bit Context ID size.
+                *  All other values are reserved.
+                */
+               val = BMVAL(val, 5, 9);
+               if (!val || val != 0x4) {
+                       pr_err("%s: CONTEXTIDR_EL1 isn't supported\n",
+                              CORESIGHT_ETM_PMU_NAME);
+                       err = -EINVAL;
+                       goto out;
+               }
+       }
+
+       if (contextid & BIT(ETM_OPT_CTXTID2)) {
+               /*
+                * TRCIDR2.VMIDOPT[30:29] != 0 and
+                * TRCIDR2.VMIDSIZE[14:10] == 0b00100 (32bit virtual contextid)
+                * We can't support CONTEXTIDR in VMID if the size of the
+                * virtual context id is < 32bit.
+                * Any value of VMIDSIZE >= 4 (i.e, > 32bit) is fine for us.
+                */
+               if (!BMVAL(val, 29, 30) || BMVAL(val, 10, 14) < 4) {
+                       pr_err("%s: CONTEXTIDR_EL2 isn't supported\n",
+                              CORESIGHT_ETM_PMU_NAME);
+                       err = -EINVAL;
+                       goto out;
+               }
        }
 
        /* All good, let the kernel know */
-       evsel->core.attr.config |= (1 << ETM_OPT_CTXTID);
+       evsel->core.attr.config |= contextid;
        err = 0;
 
 out:
-
        return err;
 }
 
@@ -173,17 +208,17 @@ static int cs_etm_set_option(struct auxtrace_record *itr,
                    !cpu_map__has(online_cpus, i))
                        continue;
 
-               if (option & ETM_SET_OPT_CTXTID) {
+               if (option & BIT(ETM_OPT_CTXTID)) {
                        err = cs_etm_set_context_id(itr, evsel, i);
                        if (err)
                                goto out;
                }
-               if (option & ETM_SET_OPT_TS) {
+               if (option & BIT(ETM_OPT_TS)) {
                        err = cs_etm_set_timestamp(itr, evsel, i);
                        if (err)
                                goto out;
                }
-               if (option & ~(ETM_SET_OPT_MASK))
+               if (option & ~(BIT(ETM_OPT_CTXTID) | BIT(ETM_OPT_TS)))
                        /* Nothing else is currently supported */
                        goto out;
        }
@@ -410,7 +445,7 @@ static int cs_etm_recording_options(struct auxtrace_record *itr,
                evsel__set_sample_bit(cs_etm_evsel, CPU);
 
                err = cs_etm_set_option(itr, cs_etm_evsel,
-                                       ETM_SET_OPT_CTXTID | ETM_SET_OPT_TS);
+                                       BIT(ETM_OPT_CTXTID) | BIT(ETM_OPT_TS));
                if (err)
                        goto out;
        }
@@ -489,7 +524,9 @@ static u64 cs_etmv4_get_config(struct auxtrace_record *itr)
                config |= BIT(ETM4_CFG_BIT_TS);
        if (config_opts & BIT(ETM_OPT_RETSTK))
                config |= BIT(ETM4_CFG_BIT_RETSTK);
-
+       if (config_opts & BIT(ETM_OPT_CTXTID2))
+               config |= BIT(ETM4_CFG_BIT_VMID) |
+                         BIT(ETM4_CFG_BIT_VMID_OPT);
        return config;
 }
 
@@ -576,7 +613,7 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
                                struct auxtrace_record *itr,
                                struct perf_record_auxtrace_info *info)
 {
-       u32 increment;
+       u32 increment, nr_trc_params;
        u64 magic;
        struct cs_etm_recording *ptr =
                        container_of(itr, struct cs_etm_recording, itr);
@@ -611,6 +648,7 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
 
                /* How much space was used */
                increment = CS_ETMV4_PRIV_MAX;
+               nr_trc_params = CS_ETMV4_PRIV_MAX - CS_ETMV4_TRCCONFIGR;
        } else {
                magic = __perf_cs_etmv3_magic;
                /* Get configuration register */
@@ -628,11 +666,13 @@ static void cs_etm_get_metadata(int cpu, u32 *offset,
 
                /* How much space was used */
                increment = CS_ETM_PRIV_MAX;
+               nr_trc_params = CS_ETM_PRIV_MAX - CS_ETM_ETMCR;
        }
 
        /* Build generic header portion */
        info->priv[*offset + CS_ETM_MAGIC] = magic;
        info->priv[*offset + CS_ETM_CPU] = cpu;
+       info->priv[*offset + CS_ETM_NR_TRC_PARAMS] = nr_trc_params;
        /* Where the next CPU entry should start from */
        *offset += increment;
 }
@@ -678,7 +718,7 @@ static int cs_etm_info_fill(struct auxtrace_record *itr,
 
        /* First fill out the session header */
        info->type = PERF_AUXTRACE_CS_ETM;
-       info->priv[CS_HEADER_VERSION_0] = 0;
+       info->priv[CS_HEADER_VERSION] = CS_HEADER_CURRENT_VERSION;
        info->priv[CS_PMU_TYPE_CPUS] = type << 32;
        info->priv[CS_PMU_TYPE_CPUS] |= nr_cpu;
        info->priv[CS_ETM_SNAPSHOT] = ptr->snapshot_mode;
diff --git a/tools/perf/arch/mips/Makefile b/tools/perf/arch/mips/Makefile
new file mode 100644 (file)
index 0000000..8bc0907
--- /dev/null
@@ -0,0 +1,22 @@
+# SPDX-License-Identifier: GPL-2.0
+ifndef NO_DWARF
+PERF_HAVE_DWARF_REGS := 1
+endif
+
+# Syscall table generation for perf
+out    := $(OUTPUT)arch/mips/include/generated/asm
+header := $(out)/syscalls_n64.c
+sysprf := $(srctree)/tools/perf/arch/mips/entry/syscalls
+sysdef := $(sysprf)/syscall_n64.tbl
+systbl := $(sysprf)/mksyscalltbl
+
+# Create output directory if not already present
+_dummy := $(shell [ -d '$(out)' ] || mkdir -p '$(out)')
+
+$(header): $(sysdef) $(systbl)
+       $(Q)$(SHELL) '$(systbl)' $(sysdef) > $@
+
+clean::
+       $(call QUIET_CLEAN, mips) $(RM) $(header)
+
+archheaders: $(header)
diff --git a/tools/perf/arch/mips/entry/syscalls/mksyscalltbl b/tools/perf/arch/mips/entry/syscalls/mksyscalltbl
new file mode 100644 (file)
index 0000000..fb1f494
--- /dev/null
@@ -0,0 +1,32 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0
+#
+# Generate system call table for perf. Derived from
+# s390 script.
+#
+# Author(s):  Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
+# Changed by: Tiezhu Yang <yangtiezhu@loongson.cn>
+
+SYSCALL_TBL=$1
+
+if ! test -r $SYSCALL_TBL; then
+       echo "Could not read input file" >&2
+       exit 1
+fi
+
+create_table()
+{
+       local max_nr nr abi sc discard
+
+       echo 'static const char *syscalltbl_mips_n64[] = {'
+       while read nr abi sc discard; do
+               printf '\t[%d] = "%s",\n' $nr $sc
+               max_nr=$nr
+       done
+       echo '};'
+       echo "#define SYSCALLTBL_MIPS_N64_MAX_ID $max_nr"
+}
+
+grep -E "^[[:digit:]]+[[:space:]]+(n64)" $SYSCALL_TBL  \
+       |sort -k1 -n                                    \
+       |create_table
diff --git a/tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl b/tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl
new file mode 100644 (file)
index 0000000..9164969
--- /dev/null
@@ -0,0 +1,358 @@
+# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
+#
+# system call numbers and entry vectors for mips
+#
+# The format is:
+# <number> <abi> <name> <entry point>
+#
+# The <abi> is always "n64" for this file.
+#
+0      n64     read                            sys_read
+1      n64     write                           sys_write
+2      n64     open                            sys_open
+3      n64     close                           sys_close
+4      n64     stat                            sys_newstat
+5      n64     fstat                           sys_newfstat
+6      n64     lstat                           sys_newlstat
+7      n64     poll                            sys_poll
+8      n64     lseek                           sys_lseek
+9      n64     mmap                            sys_mips_mmap
+10     n64     mprotect                        sys_mprotect
+11     n64     munmap                          sys_munmap
+12     n64     brk                             sys_brk
+13     n64     rt_sigaction                    sys_rt_sigaction
+14     n64     rt_sigprocmask                  sys_rt_sigprocmask
+15     n64     ioctl                           sys_ioctl
+16     n64     pread64                         sys_pread64
+17     n64     pwrite64                        sys_pwrite64
+18     n64     readv                           sys_readv
+19     n64     writev                          sys_writev
+20     n64     access                          sys_access
+21     n64     pipe                            sysm_pipe
+22     n64     _newselect                      sys_select
+23     n64     sched_yield                     sys_sched_yield
+24     n64     mremap                          sys_mremap
+25     n64     msync                           sys_msync
+26     n64     mincore                         sys_mincore
+27     n64     madvise                         sys_madvise
+28     n64     shmget                          sys_shmget
+29     n64     shmat                           sys_shmat
+30     n64     shmctl                          sys_old_shmctl
+31     n64     dup                             sys_dup
+32     n64     dup2                            sys_dup2
+33     n64     pause                           sys_pause
+34     n64     nanosleep                       sys_nanosleep
+35     n64     getitimer                       sys_getitimer
+36     n64     setitimer                       sys_setitimer
+37     n64     alarm                           sys_alarm
+38     n64     getpid                          sys_getpid
+39     n64     sendfile                        sys_sendfile64
+40     n64     socket                          sys_socket
+41     n64     connect                         sys_connect
+42     n64     accept                          sys_accept
+43     n64     sendto                          sys_sendto
+44     n64     recvfrom                        sys_recvfrom
+45     n64     sendmsg                         sys_sendmsg
+46     n64     recvmsg                         sys_recvmsg
+47     n64     shutdown                        sys_shutdown
+48     n64     bind                            sys_bind
+49     n64     listen                          sys_listen
+50     n64     getsockname                     sys_getsockname
+51     n64     getpeername                     sys_getpeername
+52     n64     socketpair                      sys_socketpair
+53     n64     setsockopt                      sys_setsockopt
+54     n64     getsockopt                      sys_getsockopt
+55     n64     clone                           __sys_clone
+56     n64     fork                            __sys_fork
+57     n64     execve                          sys_execve
+58     n64     exit                            sys_exit
+59     n64     wait4                           sys_wait4
+60     n64     kill                            sys_kill
+61     n64     uname                           sys_newuname
+62     n64     semget                          sys_semget
+63     n64     semop                           sys_semop
+64     n64     semctl                          sys_old_semctl
+65     n64     shmdt                           sys_shmdt
+66     n64     msgget                          sys_msgget
+67     n64     msgsnd                          sys_msgsnd
+68     n64     msgrcv                          sys_msgrcv
+69     n64     msgctl                          sys_old_msgctl
+70     n64     fcntl                           sys_fcntl
+71     n64     flock                           sys_flock
+72     n64     fsync                           sys_fsync
+73     n64     fdatasync                       sys_fdatasync
+74     n64     truncate                        sys_truncate
+75     n64     ftruncate                       sys_ftruncate
+76     n64     getdents                        sys_getdents
+77     n64     getcwd                          sys_getcwd
+78     n64     chdir                           sys_chdir
+79     n64     fchdir                          sys_fchdir
+80     n64     rename                          sys_rename
+81     n64     mkdir                           sys_mkdir
+82     n64     rmdir                           sys_rmdir
+83     n64     creat                           sys_creat
+84     n64     link                            sys_link
+85     n64     unlink                          sys_unlink
+86     n64     symlink                         sys_symlink
+87     n64     readlink                        sys_readlink
+88     n64     chmod                           sys_chmod
+89     n64     fchmod                          sys_fchmod
+90     n64     chown                           sys_chown
+91     n64     fchown                          sys_fchown
+92     n64     lchown                          sys_lchown
+93     n64     umask                           sys_umask
+94     n64     gettimeofday                    sys_gettimeofday
+95     n64     getrlimit                       sys_getrlimit
+96     n64     getrusage                       sys_getrusage
+97     n64     sysinfo                         sys_sysinfo
+98     n64     times                           sys_times
+99     n64     ptrace                          sys_ptrace
+100    n64     getuid                          sys_getuid
+101    n64     syslog                          sys_syslog
+102    n64     getgid                          sys_getgid
+103    n64     setuid                          sys_setuid
+104    n64     setgid                          sys_setgid
+105    n64     geteuid                         sys_geteuid
+106    n64     getegid                         sys_getegid
+107    n64     setpgid                         sys_setpgid
+108    n64     getppid                         sys_getppid
+109    n64     getpgrp                         sys_getpgrp
+110    n64     setsid                          sys_setsid
+111    n64     setreuid                        sys_setreuid
+112    n64     setregid                        sys_setregid
+113    n64     getgroups                       sys_getgroups
+114    n64     setgroups                       sys_setgroups
+115    n64     setresuid                       sys_setresuid
+116    n64     getresuid                       sys_getresuid
+117    n64     setresgid                       sys_setresgid
+118    n64     getresgid                       sys_getresgid
+119    n64     getpgid                         sys_getpgid
+120    n64     setfsuid                        sys_setfsuid
+121    n64     setfsgid                        sys_setfsgid
+122    n64     getsid                          sys_getsid
+123    n64     capget                          sys_capget
+124    n64     capset                          sys_capset
+125    n64     rt_sigpending                   sys_rt_sigpending
+126    n64     rt_sigtimedwait                 sys_rt_sigtimedwait
+127    n64     rt_sigqueueinfo                 sys_rt_sigqueueinfo
+128    n64     rt_sigsuspend                   sys_rt_sigsuspend
+129    n64     sigaltstack                     sys_sigaltstack
+130    n64     utime                           sys_utime
+131    n64     mknod                           sys_mknod
+132    n64     personality                     sys_personality
+133    n64     ustat                           sys_ustat
+134    n64     statfs                          sys_statfs
+135    n64     fstatfs                         sys_fstatfs
+136    n64     sysfs                           sys_sysfs
+137    n64     getpriority                     sys_getpriority
+138    n64     setpriority                     sys_setpriority
+139    n64     sched_setparam                  sys_sched_setparam
+140    n64     sched_getparam                  sys_sched_getparam
+141    n64     sched_setscheduler              sys_sched_setscheduler
+142    n64     sched_getscheduler              sys_sched_getscheduler
+143    n64     sched_get_priority_max          sys_sched_get_priority_max
+144    n64     sched_get_priority_min          sys_sched_get_priority_min
+145    n64     sched_rr_get_interval           sys_sched_rr_get_interval
+146    n64     mlock                           sys_mlock
+147    n64     munlock                         sys_munlock
+148    n64     mlockall                        sys_mlockall
+149    n64     munlockall                      sys_munlockall
+150    n64     vhangup                         sys_vhangup
+151    n64     pivot_root                      sys_pivot_root
+152    n64     _sysctl                         sys_ni_syscall
+153    n64     prctl                           sys_prctl
+154    n64     adjtimex                        sys_adjtimex
+155    n64     setrlimit                       sys_setrlimit
+156    n64     chroot                          sys_chroot
+157    n64     sync                            sys_sync
+158    n64     acct                            sys_acct
+159    n64     settimeofday                    sys_settimeofday
+160    n64     mount                           sys_mount
+161    n64     umount2                         sys_umount
+162    n64     swapon                          sys_swapon
+163    n64     swapoff                         sys_swapoff
+164    n64     reboot                          sys_reboot
+165    n64     sethostname                     sys_sethostname
+166    n64     setdomainname                   sys_setdomainname
+167    n64     create_module                   sys_ni_syscall
+168    n64     init_module                     sys_init_module
+169    n64     delete_module                   sys_delete_module
+170    n64     get_kernel_syms                 sys_ni_syscall
+171    n64     query_module                    sys_ni_syscall
+172    n64     quotactl                        sys_quotactl
+173    n64     nfsservctl                      sys_ni_syscall
+174    n64     getpmsg                         sys_ni_syscall
+175    n64     putpmsg                         sys_ni_syscall
+176    n64     afs_syscall                     sys_ni_syscall
+# 177 reserved for security
+177    n64     reserved177                     sys_ni_syscall
+178    n64     gettid                          sys_gettid
+179    n64     readahead                       sys_readahead
+180    n64     setxattr                        sys_setxattr
+181    n64     lsetxattr                       sys_lsetxattr
+182    n64     fsetxattr                       sys_fsetxattr
+183    n64     getxattr                        sys_getxattr
+184    n64     lgetxattr                       sys_lgetxattr
+185    n64     fgetxattr                       sys_fgetxattr
+186    n64     listxattr                       sys_listxattr
+187    n64     llistxattr                      sys_llistxattr
+188    n64     flistxattr                      sys_flistxattr
+189    n64     removexattr                     sys_removexattr
+190    n64     lremovexattr                    sys_lremovexattr
+191    n64     fremovexattr                    sys_fremovexattr
+192    n64     tkill                           sys_tkill
+193    n64     reserved193                     sys_ni_syscall
+194    n64     futex                           sys_futex
+195    n64     sched_setaffinity               sys_sched_setaffinity
+196    n64     sched_getaffinity               sys_sched_getaffinity
+197    n64     cacheflush                      sys_cacheflush
+198    n64     cachectl                        sys_cachectl
+199    n64     sysmips                         __sys_sysmips
+200    n64     io_setup                        sys_io_setup
+201    n64     io_destroy                      sys_io_destroy
+202    n64     io_getevents                    sys_io_getevents
+203    n64     io_submit                       sys_io_submit
+204    n64     io_cancel                       sys_io_cancel
+205    n64     exit_group                      sys_exit_group
+206    n64     lookup_dcookie                  sys_lookup_dcookie
+207    n64     epoll_create                    sys_epoll_create
+208    n64     epoll_ctl                       sys_epoll_ctl
+209    n64     epoll_wait                      sys_epoll_wait
+210    n64     remap_file_pages                sys_remap_file_pages
+211    n64     rt_sigreturn                    sys_rt_sigreturn
+212    n64     set_tid_address                 sys_set_tid_address
+213    n64     restart_syscall                 sys_restart_syscall
+214    n64     semtimedop                      sys_semtimedop
+215    n64     fadvise64                       sys_fadvise64_64
+216    n64     timer_create                    sys_timer_create
+217    n64     timer_settime                   sys_timer_settime
+218    n64     timer_gettime                   sys_timer_gettime
+219    n64     timer_getoverrun                sys_timer_getoverrun
+220    n64     timer_delete                    sys_timer_delete
+221    n64     clock_settime                   sys_clock_settime
+222    n64     clock_gettime                   sys_clock_gettime
+223    n64     clock_getres                    sys_clock_getres
+224    n64     clock_nanosleep                 sys_clock_nanosleep
+225    n64     tgkill                          sys_tgkill
+226    n64     utimes                          sys_utimes
+227    n64     mbind                           sys_mbind
+228    n64     get_mempolicy                   sys_get_mempolicy
+229    n64     set_mempolicy                   sys_set_mempolicy
+230    n64     mq_open                         sys_mq_open
+231    n64     mq_unlink                       sys_mq_unlink
+232    n64     mq_timedsend                    sys_mq_timedsend
+233    n64     mq_timedreceive                 sys_mq_timedreceive
+234    n64     mq_notify                       sys_mq_notify
+235    n64     mq_getsetattr                   sys_mq_getsetattr
+236    n64     vserver                         sys_ni_syscall
+237    n64     waitid                          sys_waitid
+# 238 was sys_setaltroot
+239    n64     add_key                         sys_add_key
+240    n64     request_key                     sys_request_key
+241    n64     keyctl                          sys_keyctl
+242    n64     set_thread_area                 sys_set_thread_area
+243    n64     inotify_init                    sys_inotify_init
+244    n64     inotify_add_watch               sys_inotify_add_watch
+245    n64     inotify_rm_watch                sys_inotify_rm_watch
+246    n64     migrate_pages                   sys_migrate_pages
+247    n64     openat                          sys_openat
+248    n64     mkdirat                         sys_mkdirat
+249    n64     mknodat                         sys_mknodat
+250    n64     fchownat                        sys_fchownat
+251    n64     futimesat                       sys_futimesat
+252    n64     newfstatat                      sys_newfstatat
+253    n64     unlinkat                        sys_unlinkat
+254    n64     renameat                        sys_renameat
+255    n64     linkat                          sys_linkat
+256    n64     symlinkat                       sys_symlinkat
+257    n64     readlinkat                      sys_readlinkat
+258    n64     fchmodat                        sys_fchmodat
+259    n64     faccessat                       sys_faccessat
+260    n64     pselect6                        sys_pselect6
+261    n64     ppoll                           sys_ppoll
+262    n64     unshare                         sys_unshare
+263    n64     splice                          sys_splice
+264    n64     sync_file_range                 sys_sync_file_range
+265    n64     tee                             sys_tee
+266    n64     vmsplice                        sys_vmsplice
+267    n64     move_pages                      sys_move_pages
+268    n64     set_robust_list                 sys_set_robust_list
+269    n64     get_robust_list                 sys_get_robust_list
+270    n64     kexec_load                      sys_kexec_load
+271    n64     getcpu                          sys_getcpu
+272    n64     epoll_pwait                     sys_epoll_pwait
+273    n64     ioprio_set                      sys_ioprio_set
+274    n64     ioprio_get                      sys_ioprio_get
+275    n64     utimensat                       sys_utimensat
+276    n64     signalfd                        sys_signalfd
+277    n64     timerfd                         sys_ni_syscall
+278    n64     eventfd                         sys_eventfd
+279    n64     fallocate                       sys_fallocate
+280    n64     timerfd_create                  sys_timerfd_create
+281    n64     timerfd_gettime                 sys_timerfd_gettime
+282    n64     timerfd_settime                 sys_timerfd_settime
+283    n64     signalfd4                       sys_signalfd4
+284    n64     eventfd2                        sys_eventfd2
+285    n64     epoll_create1                   sys_epoll_create1
+286    n64     dup3                            sys_dup3
+287    n64     pipe2                           sys_pipe2
+288    n64     inotify_init1                   sys_inotify_init1
+289    n64     preadv                          sys_preadv
+290    n64     pwritev                         sys_pwritev
+291    n64     rt_tgsigqueueinfo               sys_rt_tgsigqueueinfo
+292    n64     perf_event_open                 sys_perf_event_open
+293    n64     accept4                         sys_accept4
+294    n64     recvmmsg                        sys_recvmmsg
+295    n64     fanotify_init                   sys_fanotify_init
+296    n64     fanotify_mark                   sys_fanotify_mark
+297    n64     prlimit64                       sys_prlimit64
+298    n64     name_to_handle_at               sys_name_to_handle_at
+299    n64     open_by_handle_at               sys_open_by_handle_at
+300    n64     clock_adjtime                   sys_clock_adjtime
+301    n64     syncfs                          sys_syncfs
+302    n64     sendmmsg                        sys_sendmmsg
+303    n64     setns                           sys_setns
+304    n64     process_vm_readv                sys_process_vm_readv
+305    n64     process_vm_writev               sys_process_vm_writev
+306    n64     kcmp                            sys_kcmp
+307    n64     finit_module                    sys_finit_module
+308    n64     getdents64                      sys_getdents64
+309    n64     sched_setattr                   sys_sched_setattr
+310    n64     sched_getattr                   sys_sched_getattr
+311    n64     renameat2                       sys_renameat2
+312    n64     seccomp                         sys_seccomp
+313    n64     getrandom                       sys_getrandom
+314    n64     memfd_create                    sys_memfd_create
+315    n64     bpf                             sys_bpf
+316    n64     execveat                        sys_execveat
+317    n64     userfaultfd                     sys_userfaultfd
+318    n64     membarrier                      sys_membarrier
+319    n64     mlock2                          sys_mlock2
+320    n64     copy_file_range                 sys_copy_file_range
+321    n64     preadv2                         sys_preadv2
+322    n64     pwritev2                        sys_pwritev2
+323    n64     pkey_mprotect                   sys_pkey_mprotect
+324    n64     pkey_alloc                      sys_pkey_alloc
+325    n64     pkey_free                       sys_pkey_free
+326    n64     statx                           sys_statx
+327    n64     rseq                            sys_rseq
+328    n64     io_pgetevents                   sys_io_pgetevents
+# 329 through 423 are reserved to sync up with other architectures
+424    n64     pidfd_send_signal               sys_pidfd_send_signal
+425    n64     io_uring_setup                  sys_io_uring_setup
+426    n64     io_uring_enter                  sys_io_uring_enter
+427    n64     io_uring_register               sys_io_uring_register
+428    n64     open_tree                       sys_open_tree
+429    n64     move_mount                      sys_move_mount
+430    n64     fsopen                          sys_fsopen
+431    n64     fsconfig                        sys_fsconfig
+432    n64     fsmount                         sys_fsmount
+433    n64     fspick                          sys_fspick
+434    n64     pidfd_open                      sys_pidfd_open
+435    n64     clone3                          __sys_clone3
+436    n64     close_range                     sys_close_range
+437    n64     openat2                         sys_openat2
+438    n64     pidfd_getfd                     sys_pidfd_getfd
+439    n64     faccessat2                      sys_faccessat2
+440    n64     process_madvise                 sys_process_madvise
+441    n64     epoll_pwait2                    sys_epoll_pwait2
diff --git a/tools/perf/arch/mips/include/dwarf-regs-table.h b/tools/perf/arch/mips/include/dwarf-regs-table.h
new file mode 100644 (file)
index 0000000..5badbcd
--- /dev/null
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * dwarf-regs-table.h : Mapping of DWARF debug register numbers into
+ * register names.
+ *
+ * Copyright (C) 2013 Cavium, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#ifdef DEFINE_DWARF_REGSTR_TABLE
+#undef REG_DWARFNUM_NAME
+#define REG_DWARFNUM_NAME(reg, idx)    [idx] = "$" #reg
+static const char * const mips_regstr_tbl[] = {
+       "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",
+       "$10", "$11", "$12", "$13", "$14", "$15", "$16", "$17", "$18", "$19",
+       "$20", "$21", "$22", "$23", "$24", "$25", "$26", "$27", "$28", "%29",
+       "$30", "$31",
+       REG_DWARFNUM_NAME(hi, 64),
+       REG_DWARFNUM_NAME(lo, 65),
+};
+#endif
diff --git a/tools/perf/arch/mips/include/perf_regs.h b/tools/perf/arch/mips/include/perf_regs.h
new file mode 100644 (file)
index 0000000..ee73b36
--- /dev/null
@@ -0,0 +1,84 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef ARCH_PERF_REGS_H
+#define ARCH_PERF_REGS_H
+
+#include <stdlib.h>
+#include <linux/types.h>
+#include <asm/perf_regs.h>
+
+#define PERF_REGS_MAX PERF_REG_MIPS_MAX
+#define PERF_REG_IP PERF_REG_MIPS_PC
+#define PERF_REG_SP PERF_REG_MIPS_R29
+
+#define PERF_REGS_MASK ((1ULL << PERF_REG_MIPS_MAX) - 1)
+
+static inline const char *__perf_reg_name(int id)
+{
+       switch (id) {
+       case PERF_REG_MIPS_PC:
+               return "PC";
+       case PERF_REG_MIPS_R1:
+               return "$1";
+       case PERF_REG_MIPS_R2:
+               return "$2";
+       case PERF_REG_MIPS_R3:
+               return "$3";
+       case PERF_REG_MIPS_R4:
+               return "$4";
+       case PERF_REG_MIPS_R5:
+               return "$5";
+       case PERF_REG_MIPS_R6:
+               return "$6";
+       case PERF_REG_MIPS_R7:
+               return "$7";
+       case PERF_REG_MIPS_R8:
+               return "$8";
+       case PERF_REG_MIPS_R9:
+               return "$9";
+       case PERF_REG_MIPS_R10:
+               return "$10";
+       case PERF_REG_MIPS_R11:
+               return "$11";
+       case PERF_REG_MIPS_R12:
+               return "$12";
+       case PERF_REG_MIPS_R13:
+               return "$13";
+       case PERF_REG_MIPS_R14:
+               return "$14";
+       case PERF_REG_MIPS_R15:
+               return "$15";
+       case PERF_REG_MIPS_R16:
+               return "$16";
+       case PERF_REG_MIPS_R17:
+               return "$17";
+       case PERF_REG_MIPS_R18:
+               return "$18";
+       case PERF_REG_MIPS_R19:
+               return "$19";
+       case PERF_REG_MIPS_R20:
+               return "$20";
+       case PERF_REG_MIPS_R21:
+               return "$21";
+       case PERF_REG_MIPS_R22:
+               return "$22";
+       case PERF_REG_MIPS_R23:
+               return "$23";
+       case PERF_REG_MIPS_R24:
+               return "$24";
+       case PERF_REG_MIPS_R25:
+               return "$25";
+       case PERF_REG_MIPS_R28:
+               return "$28";
+       case PERF_REG_MIPS_R29:
+               return "$29";
+       case PERF_REG_MIPS_R30:
+               return "$30";
+       case PERF_REG_MIPS_R31:
+               return "$31";
+       default:
+               break;
+       }
+       return NULL;
+}
+
+#endif /* ARCH_PERF_REGS_H */
diff --git a/tools/perf/arch/mips/util/Build b/tools/perf/arch/mips/util/Build
new file mode 100644 (file)
index 0000000..51c8900
--- /dev/null
@@ -0,0 +1,3 @@
+perf-y += perf_regs.o
+perf-$(CONFIG_DWARF) += dwarf-regs.o
+perf-$(CONFIG_LOCAL_LIBUNWIND) += unwind-libunwind.o
diff --git a/tools/perf/arch/mips/util/dwarf-regs.c b/tools/perf/arch/mips/util/dwarf-regs.c
new file mode 100644 (file)
index 0000000..25c13a9
--- /dev/null
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * dwarf-regs.c : Mapping of DWARF debug register numbers into register names.
+ *
+ * Copyright (C) 2013 Cavium, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <stdio.h>
+#include <dwarf-regs.h>
+
+static const char *mips_gpr_names[32] = {
+       "$0", "$1", "$2", "$3", "$4", "$5", "$6", "$7", "$8", "$9",
+       "$10", "$11", "$12", "$13", "$14", "$15", "$16", "$17", "$18", "$19",
+       "$20", "$21", "$22", "$23", "$24", "$25", "$26", "$27", "$28", "$29",
+       "$30", "$31"
+};
+
+const char *get_arch_regstr(unsigned int n)
+{
+       if (n < 32)
+               return mips_gpr_names[n];
+       if (n == 64)
+               return "hi";
+       if (n == 65)
+               return "lo";
+       return NULL;
+}
diff --git a/tools/perf/arch/mips/util/perf_regs.c b/tools/perf/arch/mips/util/perf_regs.c
new file mode 100644 (file)
index 0000000..2864e2e
--- /dev/null
@@ -0,0 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
+#include "../../util/perf_regs.h"
+
+const struct sample_reg sample_reg_masks[] = {
+       SMPL_REG_END
+};
diff --git a/tools/perf/arch/mips/util/unwind-libunwind.c b/tools/perf/arch/mips/util/unwind-libunwind.c
new file mode 100644 (file)
index 0000000..0d8c99c
--- /dev/null
@@ -0,0 +1,22 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <errno.h>
+#include <libunwind.h>
+#include "perf_regs.h"
+#include "../../util/unwind.h"
+#include "util/debug.h"
+
+int libunwind__arch_reg_id(int regnum)
+{
+       switch (regnum) {
+       case UNW_MIPS_R1 ... UNW_MIPS_R25:
+               return regnum - UNW_MIPS_R1 + PERF_REG_MIPS_R1;
+       case UNW_MIPS_R28 ... UNW_MIPS_R31:
+               return regnum - UNW_MIPS_R28 + PERF_REG_MIPS_R28;
+       case UNW_MIPS_PC:
+               return PERF_REG_MIPS_PC;
+       default:
+               pr_err("unwind: invalid reg id %d\n", regnum);
+               return -EINVAL;
+       }
+}
index 280227e..55d373b 100644 (file)
@@ -372,7 +372,7 @@ static int inject_build_id(struct bench_data *data, u64 *max_rss)
                        len += synthesize_flush(data);
        }
 
-       /* tihs makes the child to finish */
+       /* this makes the child to finish */
        close(data->input_pipe[1]);
 
        wait4(data->pid, &status, 0, &rusage);
index 2a845d6..0d65c98 100644 (file)
@@ -84,6 +84,7 @@ struct report {
        bool                    nonany_branch_mode;
        bool                    group_set;
        bool                    stitch_lbr;
+       bool                    disable_order;
        int                     max_stack;
        struct perf_read_values show_threads_values;
        struct annotation_options annotation_opts;
@@ -1296,6 +1297,8 @@ int cmd_report(int argc, const char **argv)
        OPTS_EVSWITCH(&report.evswitch),
        OPT_BOOLEAN(0, "total-cycles", &report.total_cycles_mode,
                    "Sort all blocks by 'Sampled Cycles%'"),
+       OPT_BOOLEAN(0, "disable-order", &report.disable_order,
+                   "Disable raw trace ordering"),
        OPT_END()
        };
        struct perf_data data = {
@@ -1329,7 +1332,7 @@ int cmd_report(int argc, const char **argv)
        if (report.mmaps_mode)
                report.tasks_mode = true;
 
-       if (dump_trace)
+       if (dump_trace && report.disable_order)
                report.tool.ordered_events = false;
 
        if (quiet)
index dded93a..39eada9 100755 (executable)
@@ -146,6 +146,7 @@ check arch/x86/lib/insn.c             '-I "^#include [\"<]\(../include/\)*asm/in
 check_2 tools/perf/arch/x86/entry/syscalls/syscall_64.tbl arch/x86/entry/syscalls/syscall_64.tbl
 check_2 tools/perf/arch/powerpc/entry/syscalls/syscall.tbl arch/powerpc/kernel/syscalls/syscall.tbl
 check_2 tools/perf/arch/s390/entry/syscalls/syscall.tbl arch/s390/kernel/syscalls/syscall.tbl
+check_2 tools/perf/arch/mips/entry/syscalls/syscall_n64.tbl arch/mips/kernel/syscalls/syscall_n64.tbl
 
 for i in $BEAUTY_FILES; do
   beauty_check $i -B
index f8784c6..140402d 100644 (file)
         "MetricGroup": "instruction_stats_percent_per_ref",
         "MetricName": "inst_from_rmem_percent"
     },
-    {
-        "BriefDescription": "%L2 Modified CO Cache read Utilization (4 pclks per disp attempt)",
-        "MetricExpr": "((PM_L2_CASTOUT_MOD/2)*4)/ PM_RUN_CYC * 100",
-        "MetricGroup": "l2_stats",
-        "MetricName": "l2_co_m_rd_util"
-    },
-    {
-        "BriefDescription": "L2 dcache invalidates per run inst (per core)",
-        "MetricExpr": "(PM_L2_DC_INV / 2) / PM_RUN_INST_CMPL * 100",
-        "MetricGroup": "l2_stats",
-        "MetricName": "l2_dc_inv_rate_percent"
-    },
     {
         "BriefDescription": "Demand load misses as a % of L2 LD dispatches (per thread)",
         "MetricExpr": "PM_L1_DCACHE_RELOAD_VALID / (PM_L2_LD / 2) * 100",
         "MetricGroup": "l2_stats",
         "MetricName": "l2_dem_ld_disp_percent"
     },
-    {
-        "BriefDescription": "L2 Icache invalidates per run inst (per core)",
-        "MetricExpr": "(PM_L2_IC_INV / 2) / PM_RUN_INST_CMPL * 100",
-        "MetricGroup": "l2_stats",
-        "MetricName": "l2_ic_inv_rate_percent"
-    },
-    {
-        "BriefDescription": "L2 Inst misses as a % of total L2 Inst dispatches (per thread)",
-        "MetricExpr": "PM_L2_INST_MISS / PM_L2_INST * 100",
-        "MetricGroup": "l2_stats",
-        "MetricName": "l2_inst_miss_ratio_percent"
-    },
-    {
-        "BriefDescription": "Average number of cycles between L2 Load hits",
-        "MetricExpr": "(PM_L2_LD_HIT / PM_RUN_CYC) / 2",
-        "MetricGroup": "l2_stats",
-        "MetricName": "l2_ld_hit_frequency"
-    },
-    {
-        "BriefDescription": "Average number of cycles between L2 Load misses",
-        "MetricExpr": "(PM_L2_LD_MISS / PM_RUN_CYC) / 2",
-        "MetricGroup": "l2_stats",
-        "MetricName": "l2_ld_miss_frequency"
-    },
-    {
-        "BriefDescription": "L2 Load misses as a % of total L2 Load dispatches (per thread)",
-        "MetricExpr": "PM_L2_LD_MISS / PM_L2_LD * 100",
-        "MetricGroup": "l2_stats",
-        "MetricName": "l2_ld_miss_ratio_percent"
-    },
-    {
-        "BriefDescription": "% L2 load disp attempts Cache read Utilization (4 pclks per disp attempt)",
-        "MetricExpr": "((PM_L2_RCLD_DISP/2)*4)/ PM_RUN_CYC * 100",
-        "MetricGroup": "l2_stats",
-        "MetricName": "l2_ld_rd_util"
-    },
-    {
-        "BriefDescription": "L2 load misses that require a cache write (4 pclks per disp attempt) % of pclks",
-        "MetricExpr": "((( PM_L2_LD_DISP - PM_L2_LD_HIT)/2)*4)/ PM_RUN_CYC * 100",
-        "MetricGroup": "l2_stats",
-        "MetricName": "l2_ldmiss_wr_util"
-    },
-    {
-        "BriefDescription": "L2 local pump prediction success",
-        "MetricExpr": "PM_L2_LOC_GUESS_CORRECT / (PM_L2_LOC_GUESS_CORRECT + PM_L2_LOC_GUESS_WRONG) * 100",
-        "MetricGroup": "l2_stats",
-        "MetricName": "l2_local_pred_correct_percent"
-    },
-    {
-        "BriefDescription": "L2 COs that were in M,Me,Mu state as a % of all L2 COs",
-        "MetricExpr": "PM_L2_CASTOUT_MOD / (PM_L2_CASTOUT_MOD + PM_L2_CASTOUT_SHR) * 100",
-        "MetricGroup": "l2_stats",
-        "MetricName": "l2_mod_co_percent"
-    },
-    {
-        "BriefDescription": "% of L2 Load RC dispatch atampts that failed because of address collisions and cclass conflicts",
-        "MetricExpr": "(PM_L2_RCLD_DISP_FAIL_ADDR )/ PM_L2_RCLD_DISP * 100",
-        "MetricGroup": "l2_stats",
-        "MetricName": "l2_rc_ld_disp_addr_fail_percent"
-    },
-    {
-        "BriefDescription": "% of L2 Load RC dispatch attempts that failed",
-        "MetricExpr": "(PM_L2_RCLD_DISP_FAIL_ADDR + PM_L2_RCLD_DISP_FAIL_OTHER)/ PM_L2_RCLD_DISP * 100",
-        "MetricGroup": "l2_stats",
-        "MetricName": "l2_rc_ld_disp_fail_percent"
-    },
-    {
-        "BriefDescription": "% of L2 Store RC dispatch atampts that failed because of address collisions and cclass conflicts",
-        "MetricExpr": "PM_L2_RCST_DISP_FAIL_ADDR / PM_L2_RCST_DISP * 100",
-        "MetricGroup": "l2_stats",
-        "MetricName": "l2_rc_st_disp_addr_fail_percent"
-    },
-    {
-        "BriefDescription": "% of L2 Store RC dispatch attempts that failed",
-        "MetricExpr": "(PM_L2_RCST_DISP_FAIL_ADDR + PM_L2_RCST_DISP_FAIL_OTHER)/ PM_L2_RCST_DISP * 100",
-        "MetricGroup": "l2_stats",
-        "MetricName": "l2_rc_st_disp_fail_percent"
-    },
-    {
-        "BriefDescription": "L2 Cache Read Utilization (per core)",
-        "MetricExpr": "(((PM_L2_RCLD_DISP/2)*4)/ PM_RUN_CYC * 100) + (((PM_L2_RCST_DISP/2)*4)/PM_RUN_CYC * 100) + (((PM_L2_CASTOUT_MOD/2)*4)/PM_RUN_CYC * 100)",
-        "MetricGroup": "l2_stats",
-        "MetricName": "l2_rd_util_percent"
-    },
-    {
-        "BriefDescription": "L2 COs that were in T,Te,Si,S state as a % of all L2 COs",
-        "MetricExpr": "PM_L2_CASTOUT_SHR / (PM_L2_CASTOUT_MOD + PM_L2_CASTOUT_SHR) * 100",
-        "MetricGroup": "l2_stats",
-        "MetricName": "l2_shr_co_percent"
-    },
     {
         "BriefDescription": "L2 Store misses as a % of total L2 Store dispatches (per thread)",
         "MetricExpr": "PM_L2_ST_MISS / PM_L2_ST * 100",
         "MetricGroup": "l2_stats",
         "MetricName": "l2_st_miss_ratio_percent"
     },
-    {
-        "BriefDescription": "% L2 store disp attempts Cache read Utilization (4 pclks per disp attempt)",
-        "MetricExpr": "((PM_L2_RCST_DISP/2)*4) / PM_RUN_CYC * 100",
-        "MetricGroup": "l2_stats",
-        "MetricName": "l2_st_rd_util"
-    },
     {
         "BriefDescription": "L2 stores that require a cache write (4 pclks per disp attempt) % of pclks",
         "MetricExpr": "((PM_L2_ST_DISP/2)*4) / PM_RUN_CYC * 100",
         "MetricGroup": "l2_stats",
         "MetricName": "l2_st_wr_util"
     },
-    {
-        "BriefDescription": "L2 Cache Write Utilization (per core)",
-        "MetricExpr": "((((PM_L2_LD_DISP - PM_L2_LD_HIT)/2)*4) / PM_RUN_CYC * 100) + (((PM_L2_ST_DISP/2)*4) / PM_RUN_CYC * 100)",
-        "MetricGroup": "l2_stats",
-        "MetricName": "l2_wr_util_percent"
-    },
-    {
-        "BriefDescription": "Average number of cycles between L3 Load hits",
-        "MetricExpr": "(PM_L3_LD_HIT / PM_RUN_CYC) / 2",
-        "MetricGroup": "l3_stats",
-        "MetricName": "l3_ld_hit_frequency"
-    },
-    {
-        "BriefDescription": "Average number of cycles between L3 Load misses",
-        "MetricExpr": "(PM_L3_LD_MISS / PM_RUN_CYC) / 2",
-        "MetricGroup": "l3_stats",
-        "MetricName": "l3_ld_miss_frequency"
-    },
-    {
-        "BriefDescription": "Average number of Write-in machines used. 1 of 8 WI machines is sampled every L3 cycle",
-        "MetricExpr": "(PM_L3_WI_USAGE / PM_RUN_CYC) * 8",
-        "MetricGroup": "l3_stats",
-        "MetricName": "l3_wi_usage"
-    },
     {
         "BriefDescription": "Average icache miss latency",
         "MetricExpr": "PM_IC_DEMAND_CYC / PM_IC_DEMAND_REQ",
index 6dc1db1..55bf52e 100644 (file)
@@ -98,7 +98,7 @@ static u64 find_value(const char *name, struct value *values)
                if (!strcmp(name, v->event))
                        return v->val;
                v++;
-       };
+       }
        return 0;
 }
 
index 416af61..f05670d 100755 (executable)
@@ -14,18 +14,56 @@ if ! [ -x "$(command -v cc)" ]; then
        exit 2
 fi
 
+# check what we need to test windows binaries
+add_pe=1
+run_pe=1
+if ! perf version --build-options | grep -q 'libbfd: .* on '; then
+       echo "WARNING: perf not built with libbfd. PE binaries will not be tested."
+       add_pe=0
+       run_pe=0
+fi
+if ! which wine > /dev/null; then
+       echo "WARNING: wine not found. PE binaries will not be run."
+       run_pe=0
+fi
+
+# set up wine
+if [ ${run_pe} -eq 1 ]; then
+       wineprefix=$(mktemp -d /tmp/perf.wineprefix.XXX)
+       export WINEPREFIX=${wineprefix}
+       # clear display variables to prevent wine from popping up dialogs
+       unset DISPLAY
+       unset WAYLAND_DISPLAY
+fi
+
 ex_md5=$(mktemp /tmp/perf.ex.MD5.XXX)
 ex_sha1=$(mktemp /tmp/perf.ex.SHA1.XXX)
+ex_pe=$(dirname $0)/../pe-file.exe
 
 echo 'int main(void) { return 0; }' | cc -Wl,--build-id=sha1 -o ${ex_sha1} -x c -
 echo 'int main(void) { return 0; }' | cc -Wl,--build-id=md5 -o ${ex_md5} -x c -
 
-echo "test binaries: ${ex_sha1} ${ex_md5}"
+echo "test binaries: ${ex_sha1} ${ex_md5} ${ex_pe}"
 
 check()
 {
-       id=`readelf -n ${1} 2>/dev/null | grep 'Build ID' | awk '{print $3}'`
-
+       case $1 in
+       *.exe)
+               # We don't have a tool that can pull a nicely formatted build-id out of
+               # a PE file, but we can extract the whole section with objcopy and
+               # format it ourselves. The .buildid section is a Debug Directory
+               # containing a CodeView entry:
+               #     https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#debug-directory-image-only
+               #     https://github.com/dotnet/runtime/blob/da94c022576a5c3bbc0e896f006565905eb137f9/docs/design/specs/PE-COFF.md
+               # The build-id starts at byte 33 and must be rearranged into a GUID.
+               id=`objcopy -O binary --only-section=.buildid $1 /dev/stdout | \
+                       cut -c 33-48 | hexdump -ve '/1 "%02x"' | \
+                       sed 's@^\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)\(.*\)0a$@\4\3\2\1\6\5\8\7\9@'`
+               ;;
+       *)
+               id=`readelf -n ${1} 2>/dev/null | grep 'Build ID' | awk '{print $3}'`
+               ;;
+       esac
        echo "build id: ${id}"
 
        link=${build_id_dir}/.build-id/${id:0:2}/${id:2}
@@ -50,7 +88,7 @@ check()
                exit 1
        fi
 
-       ${perf} buildid-cache -l | grep $id
+       ${perf} buildid-cache -l | grep ${id}
        if [ $? -ne 0 ]; then
                echo "failed: ${id} is not reported by \"perf buildid-cache -l\""
                exit 1
@@ -79,16 +117,20 @@ test_record()
 {
        data=$(mktemp /tmp/perf.data.XXX)
        build_id_dir=$(mktemp -d /tmp/perf.debug.XXX)
+       log=$(mktemp /tmp/perf.log.XXX)
        perf="perf --buildid-dir ${build_id_dir}"
 
-       ${perf} record --buildid-all -o ${data} ${1}
+       echo "running: perf record $@"
+       ${perf} record --buildid-all -o ${data} $@ &> ${log}
        if [ $? -ne 0 ]; then
-               echo "failed: record ${1}"
+               echo "failed: record $@"
+               echo "see log: ${log}"
                exit 1
        fi
 
-       check ${1}
+       check ${@: -1}
 
+       rm -f ${log}
        rm -rf ${build_id_dir}
        rm -rf ${data}
 }
@@ -96,12 +138,21 @@ test_record()
 # add binaries manual via perf buildid-cache -a
 test_add ${ex_sha1}
 test_add ${ex_md5}
+if [ ${add_pe} -eq 1 ]; then
+       test_add ${ex_pe}
+fi
 
 # add binaries via perf record post processing
 test_record ${ex_sha1}
 test_record ${ex_md5}
+if [ ${run_pe} -eq 1 ]; then
+       test_record wine ${ex_pe}
+fi
 
 # cleanup
 rm ${ex_sha1} ${ex_md5}
+if [ ${run_pe} -eq 1 ]; then
+       rm -r ${wineprefix}
+fi
 
 exit ${err}
index 35b82ca..9f75d76 100644 (file)
@@ -381,6 +381,25 @@ static bool annotate_browser__toggle_source(struct annotate_browser *browser)
        return true;
 }
 
+#define SYM_TITLE_MAX_SIZE (PATH_MAX + 64)
+
+static void annotate_browser__show_full_location(struct ui_browser *browser)
+{
+       struct annotate_browser *ab = container_of(browser, struct annotate_browser, b);
+       struct disasm_line *cursor = disasm_line(ab->selection);
+       struct annotation_line *al = &cursor->al;
+
+       if (al->offset != -1)
+               ui_helpline__puts("Only available for source code lines.");
+       else if (al->fileloc == NULL)
+               ui_helpline__puts("No source file location.");
+       else {
+               char help_line[SYM_TITLE_MAX_SIZE];
+               sprintf (help_line, "Source file location: %s", al->fileloc);
+               ui_helpline__puts(help_line);
+       }
+}
+
 static void ui_browser__init_asm_mode(struct ui_browser *browser)
 {
        struct annotation *notes = browser__annotation(browser);
@@ -388,8 +407,6 @@ static void ui_browser__init_asm_mode(struct ui_browser *browser)
        browser->nr_entries = notes->nr_asm_entries;
 }
 
-#define SYM_TITLE_MAX_SIZE (PATH_MAX + 64)
-
 static int sym_title(struct symbol *sym, struct map *map, char *title,
                     size_t sz, int percent_type)
 {
@@ -747,6 +764,7 @@ static int annotate_browser__run(struct annotate_browser *browser,
                "c             Show min/max cycle\n"
                "/             Search string\n"
                "k             Toggle line numbers\n"
+               "l             Show full source file location\n"
                "P             Print to [symbol_name].annotation file.\n"
                "r             Run available scripts\n"
                "p             Toggle percent type [local/global]\n"
@@ -760,6 +778,9 @@ static int annotate_browser__run(struct annotate_browser *browser,
                case 'k':
                        notes->options->show_linenr = !notes->options->show_linenr;
                        continue;
+               case 'l':
+                       annotate_browser__show_full_location (&browser->b);
+                       continue;
                case 'H':
                        nd = browser->curr_hot;
                        break;
index e60841b..18eee25 100644 (file)
@@ -1161,6 +1161,7 @@ struct annotate_args {
        s64                       offset;
        char                      *line;
        int                       line_nr;
+       char                      *fileloc;
 };
 
 static void annotation_line__init(struct annotation_line *al,
@@ -1170,6 +1171,7 @@ static void annotation_line__init(struct annotation_line *al,
        al->offset = args->offset;
        al->line = strdup(args->line);
        al->line_nr = args->line_nr;
+       al->fileloc = args->fileloc;
        al->data_nr = nr;
 }
 
@@ -1482,7 +1484,7 @@ annotation_line__print(struct annotation_line *al, struct symbol *sym, u64 start
  */
 static int symbol__parse_objdump_line(struct symbol *sym,
                                      struct annotate_args *args,
-                                     char *parsed_line, int *line_nr)
+                                     char *parsed_line, int *line_nr, char **fileloc)
 {
        struct map *map = args->ms.map;
        struct annotation *notes = symbol__annotation(sym);
@@ -1494,6 +1496,7 @@ static int symbol__parse_objdump_line(struct symbol *sym,
        /* /filename:linenr ? Save line number and ignore. */
        if (regexec(&file_lineno, parsed_line, 2, match, 0) == 0) {
                *line_nr = atoi(parsed_line + match[1].rm_so);
+               *fileloc = strdup(parsed_line);
                return 0;
        }
 
@@ -1513,6 +1516,7 @@ static int symbol__parse_objdump_line(struct symbol *sym,
        args->offset  = offset;
        args->line    = parsed_line;
        args->line_nr = *line_nr;
+       args->fileloc = *fileloc;
        args->ms.sym  = sym;
 
        dl = disasm_line__new(args);
@@ -1807,6 +1811,7 @@ static int symbol__disassemble_bpf(struct symbol *sym,
                        args->offset = -1;
                        args->line = strdup(srcline);
                        args->line_nr = 0;
+                       args->fileloc = NULL;
                        args->ms.sym  = sym;
                        dl = disasm_line__new(args);
                        if (dl) {
@@ -1818,6 +1823,7 @@ static int symbol__disassemble_bpf(struct symbol *sym,
                args->offset = pc;
                args->line = buf + prev_buf_size;
                args->line_nr = 0;
+               args->fileloc = NULL;
                args->ms.sym  = sym;
                dl = disasm_line__new(args);
                if (dl)
@@ -1852,6 +1858,7 @@ symbol__disassemble_bpf_image(struct symbol *sym,
        args->offset = -1;
        args->line = strdup("to be implemented");
        args->line_nr = 0;
+       args->fileloc = NULL;
        dl = disasm_line__new(args);
        if (dl)
                annotation_line__add(&dl->al, &notes->src->source);
@@ -1933,6 +1940,7 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
        bool delete_extract = false;
        bool decomp = false;
        int lineno = 0;
+       char *fileloc = NULL;
        int nline;
        char *line;
        size_t line_len;
@@ -2060,7 +2068,7 @@ static int symbol__disassemble(struct symbol *sym, struct annotate_args *args)
                 * See disasm_line__new() and struct disasm_line::line_nr.
                 */
                if (symbol__parse_objdump_line(sym, args, expanded_line,
-                                              &lineno) < 0)
+                                              &lineno, &fileloc) < 0)
                        break;
                nline++;
        }
@@ -3144,6 +3152,10 @@ static int annotation__config(const char *var, const char *value, void *data)
                opt->use_offset = perf_config_bool("use_offset", value);
        } else if (!strcmp(var, "annotate.disassembler_style")) {
                opt->disassembler_style = value;
+       } else if (!strcmp(var, "annotate.demangle")) {
+               symbol_conf.demangle = perf_config_bool("demangle", value);
+       } else if (!strcmp(var, "annotate.demangle_kernel")) {
+               symbol_conf.demangle_kernel = perf_config_bool("demangle_kernel", value);
        } else {
                pr_debug("%s variable unknown, ignoring...", var);
        }
index 096cdaf..3757416 100644 (file)
@@ -84,6 +84,7 @@ struct annotation_options {
             print_lines,
             full_path,
             show_linenr,
+            show_fileloc,
             show_nr_jumps,
             show_minmax_cycle,
             show_asm_raw,
@@ -136,6 +137,7 @@ struct annotation_line {
        s64                      offset;
        char                    *line;
        int                      line_nr;
+       char                    *fileloc;
        int                      jump_sources;
        float                    ipc;
        u64                      cycles;
index 2eca210..cb9c532 100644 (file)
@@ -38,7 +38,7 @@ int bpf_counter__install_pe(struct evsel *evsel, int cpu, int fd);
 
 #else /* HAVE_BPF_SKEL */
 
-#include<linux/err.h>
+#include <linux/err.h>
 
 static inline int bpf_counter__load(struct evsel *evsel __maybe_unused,
                                    struct target *target __maybe_unused)
index c7cec92..ab12b4c 100644 (file)
@@ -52,7 +52,7 @@ int BPF_PROG(fentry_XXX)
 static inline void
 fexit_update_maps(struct bpf_perf_event_value *after)
 {
-       struct bpf_perf_event_value *before, diff, *accum;
+       struct bpf_perf_event_value *before, diff;
        __u32 zero = 0;
 
        before = bpf_map_lookup_elem(&fentry_readings, &zero);
@@ -78,7 +78,6 @@ int BPF_PROG(fexit_XXX)
 {
        struct bpf_perf_event_value reading;
        __u32 cpu = bpf_get_smp_processor_id();
-       __u32 one = 1, zero = 0;
        int err;
 
        /* read all events before updating the maps, to reduce error */
index 3f4bc40..4052c9c 100644 (file)
@@ -6,6 +6,7 @@
  * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
  */
 
+#include <linux/coresight-pmu.h>
 #include <linux/err.h>
 #include <linux/list.h>
 #include <linux/zalloc.h>
@@ -491,13 +492,42 @@ cs_etm_decoder__set_tid(struct cs_etm_queue *etmq,
                        const ocsd_generic_trace_elem *elem,
                        const uint8_t trace_chan_id)
 {
-       pid_t tid;
+       pid_t tid = -1;
+       static u64 pid_fmt;
+       int ret;
 
-       /* Ignore PE_CONTEXT packets that don't have a valid contextID */
-       if (!elem->context.ctxt_id_valid)
+       /*
+        * As all the ETMs run at the same exception level, the system should
+        * have the same PID format crossing CPUs.  So cache the PID format
+        * and reuse it for sequential decoding.
+        */
+       if (!pid_fmt) {
+               ret = cs_etm__get_pid_fmt(trace_chan_id, &pid_fmt);
+               if (ret)
+                       return OCSD_RESP_FATAL_SYS_ERR;
+       }
+
+       /*
+        * Process the PE_CONTEXT packets if we have a valid contextID or VMID.
+        * If the kernel is running at EL2, the PID is traced in CONTEXTIDR_EL2
+        * as VMID, Bit ETM_OPT_CTXTID2 is set in this case.
+        */
+       switch (pid_fmt) {
+       case BIT(ETM_OPT_CTXTID):
+               if (elem->context.ctxt_id_valid)
+                       tid = elem->context.context_id;
+               break;
+       case BIT(ETM_OPT_CTXTID2):
+               if (elem->context.vmid_valid)
+                       tid = elem->context.vmid;
+               break;
+       default:
+               break;
+       }
+
+       if (tid == -1)
                return OCSD_RESP_CONT;
 
-       tid =  elem->context.context_id;
        if (cs_etm__etmq_set_tid(etmq, tid, trace_chan_id))
                return OCSD_RESP_FATAL_SYS_ERR;
 
index a2a369e..9ac80fc 100644 (file)
@@ -7,6 +7,7 @@
  */
 
 #include <linux/bitops.h>
+#include <linux/coresight-pmu.h>
 #include <linux/err.h>
 #include <linux/kernel.h>
 #include <linux/log2.h>
@@ -156,6 +157,47 @@ int cs_etm__get_cpu(u8 trace_chan_id, int *cpu)
        return 0;
 }
 
+/*
+ * The returned PID format is presented by two bits:
+ *
+ *   Bit ETM_OPT_CTXTID: CONTEXTIDR or CONTEXTIDR_EL1 is traced;
+ *   Bit ETM_OPT_CTXTID2: CONTEXTIDR_EL2 is traced.
+ *
+ * It's possible that the two bits ETM_OPT_CTXTID and ETM_OPT_CTXTID2
+ * are enabled at the same time when the session runs on an EL2 kernel.
+ * This means the CONTEXTIDR_EL1 and CONTEXTIDR_EL2 both will be
+ * recorded in the trace data, the tool will selectively use
+ * CONTEXTIDR_EL2 as PID.
+ */
+int cs_etm__get_pid_fmt(u8 trace_chan_id, u64 *pid_fmt)
+{
+       struct int_node *inode;
+       u64 *metadata, val;
+
+       inode = intlist__find(traceid_list, trace_chan_id);
+       if (!inode)
+               return -EINVAL;
+
+       metadata = inode->priv;
+
+       if (metadata[CS_ETM_MAGIC] == __perf_cs_etmv3_magic) {
+               val = metadata[CS_ETM_ETMCR];
+               /* CONTEXTIDR is traced */
+               if (val & BIT(ETM_OPT_CTXTID))
+                       *pid_fmt = BIT(ETM_OPT_CTXTID);
+       } else {
+               val = metadata[CS_ETMV4_TRCCONFIGR];
+               /* CONTEXTIDR_EL2 is traced */
+               if (val & (BIT(ETM4_CFG_BIT_VMID) | BIT(ETM4_CFG_BIT_VMID_OPT)))
+                       *pid_fmt = BIT(ETM_OPT_CTXTID2);
+               /* CONTEXTIDR_EL1 is traced */
+               else if (val & BIT(ETM4_CFG_BIT_CTXTID))
+                       *pid_fmt = BIT(ETM_OPT_CTXTID);
+       }
+
+       return 0;
+}
+
 void cs_etm__etmq_set_traceid_queue_timestamp(struct cs_etm_queue *etmq,
                                              u8 trace_chan_id)
 {
@@ -2435,7 +2477,7 @@ static bool cs_etm__is_timeless_decoding(struct cs_etm_auxtrace *etm)
 }
 
 static const char * const cs_etm_global_header_fmts[] = {
-       [CS_HEADER_VERSION_0]   = "     Header version                 %llx\n",
+       [CS_HEADER_VERSION]     = "     Header version                 %llx\n",
        [CS_PMU_TYPE_CPUS]      = "     PMU type/num cpus              %llx\n",
        [CS_ETM_SNAPSHOT]       = "     Snapshot                       %llx\n",
 };
@@ -2443,6 +2485,7 @@ static const char * const cs_etm_global_header_fmts[] = {
 static const char * const cs_etm_priv_fmts[] = {
        [CS_ETM_MAGIC]          = "     Magic number                   %llx\n",
        [CS_ETM_CPU]            = "     CPU                            %lld\n",
+       [CS_ETM_NR_TRC_PARAMS]  = "     NR_TRC_PARAMS                  %llx\n",
        [CS_ETM_ETMCR]          = "     ETMCR                          %llx\n",
        [CS_ETM_ETMTRACEIDR]    = "     ETMTRACEIDR                    %llx\n",
        [CS_ETM_ETMCCER]        = "     ETMCCER                        %llx\n",
@@ -2452,6 +2495,7 @@ static const char * const cs_etm_priv_fmts[] = {
 static const char * const cs_etmv4_priv_fmts[] = {
        [CS_ETM_MAGIC]          = "     Magic number                   %llx\n",
        [CS_ETM_CPU]            = "     CPU                            %lld\n",
+       [CS_ETM_NR_TRC_PARAMS]  = "     NR_TRC_PARAMS                  %llx\n",
        [CS_ETMV4_TRCCONFIGR]   = "     TRCCONFIGR                     %llx\n",
        [CS_ETMV4_TRCTRACEIDR]  = "     TRCTRACEIDR                    %llx\n",
        [CS_ETMV4_TRCIDR0]      = "     TRCIDR0                        %llx\n",
@@ -2461,26 +2505,167 @@ static const char * const cs_etmv4_priv_fmts[] = {
        [CS_ETMV4_TRCAUTHSTATUS] = "    TRCAUTHSTATUS                  %llx\n",
 };
 
-static void cs_etm__print_auxtrace_info(__u64 *val, int num)
+static const char * const param_unk_fmt =
+       "       Unknown parameter [%d]         %llx\n";
+static const char * const magic_unk_fmt =
+       "       Magic number Unknown           %llx\n";
+
+static int cs_etm__print_cpu_metadata_v0(__u64 *val, int *offset)
 {
-       int i, j, cpu = 0;
+       int i = *offset, j, nr_params = 0, fmt_offset;
+       __u64 magic;
 
-       for (i = 0; i < CS_HEADER_VERSION_0_MAX; i++)
-               fprintf(stdout, cs_etm_global_header_fmts[i], val[i]);
+       /* check magic value */
+       magic = val[i + CS_ETM_MAGIC];
+       if ((magic != __perf_cs_etmv3_magic) &&
+           (magic != __perf_cs_etmv4_magic)) {
+               /* failure - note bad magic value */
+               fprintf(stdout, magic_unk_fmt, magic);
+               return -EINVAL;
+       }
+
+       /* print common header block */
+       fprintf(stdout, cs_etm_priv_fmts[CS_ETM_MAGIC], val[i++]);
+       fprintf(stdout, cs_etm_priv_fmts[CS_ETM_CPU], val[i++]);
+
+       if (magic == __perf_cs_etmv3_magic) {
+               nr_params = CS_ETM_NR_TRC_PARAMS_V0;
+               fmt_offset = CS_ETM_ETMCR;
+               /* after common block, offset format index past NR_PARAMS */
+               for (j = fmt_offset; j < nr_params + fmt_offset; j++, i++)
+                       fprintf(stdout, cs_etm_priv_fmts[j], val[i]);
+       } else if (magic == __perf_cs_etmv4_magic) {
+               nr_params = CS_ETMV4_NR_TRC_PARAMS_V0;
+               fmt_offset = CS_ETMV4_TRCCONFIGR;
+               /* after common block, offset format index past NR_PARAMS */
+               for (j = fmt_offset; j < nr_params + fmt_offset; j++, i++)
+                       fprintf(stdout, cs_etmv4_priv_fmts[j], val[i]);
+       }
+       *offset = i;
+       return 0;
+}
+
+static int cs_etm__print_cpu_metadata_v1(__u64 *val, int *offset)
+{
+       int i = *offset, j, total_params = 0;
+       __u64 magic;
+
+       magic = val[i + CS_ETM_MAGIC];
+       /* total params to print is NR_PARAMS + common block size for v1 */
+       total_params = val[i + CS_ETM_NR_TRC_PARAMS] + CS_ETM_COMMON_BLK_MAX_V1;
 
-       for (i = CS_HEADER_VERSION_0_MAX; cpu < num; cpu++) {
-               if (val[i] == __perf_cs_etmv3_magic)
-                       for (j = 0; j < CS_ETM_PRIV_MAX; j++, i++)
+       if (magic == __perf_cs_etmv3_magic) {
+               for (j = 0; j < total_params; j++, i++) {
+                       /* if newer record - could be excess params */
+                       if (j >= CS_ETM_PRIV_MAX)
+                               fprintf(stdout, param_unk_fmt, j, val[i]);
+                       else
                                fprintf(stdout, cs_etm_priv_fmts[j], val[i]);
-               else if (val[i] == __perf_cs_etmv4_magic)
-                       for (j = 0; j < CS_ETMV4_PRIV_MAX; j++, i++)
+               }
+       } else if (magic == __perf_cs_etmv4_magic) {
+               for (j = 0; j < total_params; j++, i++) {
+                       /* if newer record - could be excess params */
+                       if (j >= CS_ETMV4_PRIV_MAX)
+                               fprintf(stdout, param_unk_fmt, j, val[i]);
+                       else
                                fprintf(stdout, cs_etmv4_priv_fmts[j], val[i]);
-               else
-                       /* failure.. return */
+               }
+       } else {
+               /* failure - note bad magic value and error out */
+               fprintf(stdout, magic_unk_fmt, magic);
+               return -EINVAL;
+       }
+       *offset = i;
+       return 0;
+}
+
+static void cs_etm__print_auxtrace_info(__u64 *val, int num)
+{
+       int i, cpu = 0, version, err;
+
+       /* bail out early on bad header version */
+       version = val[0];
+       if (version > CS_HEADER_CURRENT_VERSION) {
+               /* failure.. return */
+               fprintf(stdout, "       Unknown Header Version = %x, ", version);
+               fprintf(stdout, "Version supported <= %x\n", CS_HEADER_CURRENT_VERSION);
+               return;
+       }
+
+       for (i = 0; i < CS_HEADER_VERSION_MAX; i++)
+               fprintf(stdout, cs_etm_global_header_fmts[i], val[i]);
+
+       for (i = CS_HEADER_VERSION_MAX; cpu < num; cpu++) {
+               if (version == 0)
+                       err = cs_etm__print_cpu_metadata_v0(val, &i);
+               else if (version == 1)
+                       err = cs_etm__print_cpu_metadata_v1(val, &i);
+               if (err)
                        return;
        }
 }
 
+/*
+ * Read a single cpu parameter block from the auxtrace_info priv block.
+ *
+ * For version 1 there is a per cpu nr_params entry. If we are handling
+ * version 1 file, then there may be less, the same, or more params
+ * indicated by this value than the compile time number we understand.
+ *
+ * For a version 0 info block, there are a fixed number, and we need to
+ * fill out the nr_param value in the metadata we create.
+ */
+static u64 *cs_etm__create_meta_blk(u64 *buff_in, int *buff_in_offset,
+                                   int out_blk_size, int nr_params_v0)
+{
+       u64 *metadata = NULL;
+       int hdr_version;
+       int nr_in_params, nr_out_params, nr_cmn_params;
+       int i, k;
+
+       metadata = zalloc(sizeof(*metadata) * out_blk_size);
+       if (!metadata)
+               return NULL;
+
+       /* read block current index & version */
+       i = *buff_in_offset;
+       hdr_version = buff_in[CS_HEADER_VERSION];
+
+       if (!hdr_version) {
+       /* read version 0 info block into a version 1 metadata block  */
+               nr_in_params = nr_params_v0;
+               metadata[CS_ETM_MAGIC] = buff_in[i + CS_ETM_MAGIC];
+               metadata[CS_ETM_CPU] = buff_in[i + CS_ETM_CPU];
+               metadata[CS_ETM_NR_TRC_PARAMS] = nr_in_params;
+               /* remaining block params at offset +1 from source */
+               for (k = CS_ETM_COMMON_BLK_MAX_V1 - 1; k < nr_in_params; k++)
+                       metadata[k + 1] = buff_in[i + k];
+               /* version 0 has 2 common params */
+               nr_cmn_params = 2;
+       } else {
+       /* read version 1 info block - input and output nr_params may differ */
+               /* version 1 has 3 common params */
+               nr_cmn_params = 3;
+               nr_in_params = buff_in[i + CS_ETM_NR_TRC_PARAMS];
+
+               /* if input has more params than output - skip excess */
+               nr_out_params = nr_in_params + nr_cmn_params;
+               if (nr_out_params > out_blk_size)
+                       nr_out_params = out_blk_size;
+
+               for (k = CS_ETM_MAGIC; k < nr_out_params; k++)
+                       metadata[k] = buff_in[i + k];
+
+               /* record the actual nr params we copied */
+               metadata[CS_ETM_NR_TRC_PARAMS] = nr_out_params - nr_cmn_params;
+       }
+
+       /* adjust in offset by number of in params used */
+       i += nr_in_params + nr_cmn_params;
+       *buff_in_offset = i;
+       return metadata;
+}
+
 int cs_etm__process_auxtrace_info(union perf_event *event,
                                  struct perf_session *session)
 {
@@ -2492,11 +2677,12 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
        int info_header_size;
        int total_size = auxtrace_info->header.size;
        int priv_size = 0;
-       int num_cpu;
-       int err = 0, idx = -1;
-       int i, j, k;
+       int num_cpu, trcidr_idx;
+       int err = 0;
+       int i, j;
        u64 *ptr, *hdr = NULL;
        u64 **metadata = NULL;
+       u64 hdr_version;
 
        /*
         * sizeof(auxtrace_info_event::type) +
@@ -2512,16 +2698,21 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
        /* First the global part */
        ptr = (u64 *) auxtrace_info->priv;
 
-       /* Look for version '0' of the header */
-       if (ptr[0] != 0)
+       /* Look for version of the header */
+       hdr_version = ptr[0];
+       if (hdr_version > CS_HEADER_CURRENT_VERSION) {
+               /* print routine will print an error on bad version */
+               if (dump_trace)
+                       cs_etm__print_auxtrace_info(auxtrace_info->priv, 0);
                return -EINVAL;
+       }
 
-       hdr = zalloc(sizeof(*hdr) * CS_HEADER_VERSION_0_MAX);
+       hdr = zalloc(sizeof(*hdr) * CS_HEADER_VERSION_MAX);
        if (!hdr)
                return -ENOMEM;
 
        /* Extract header information - see cs-etm.h for format */
-       for (i = 0; i < CS_HEADER_VERSION_0_MAX; i++)
+       for (i = 0; i < CS_HEADER_VERSION_MAX; i++)
                hdr[i] = ptr[i];
        num_cpu = hdr[CS_PMU_TYPE_CPUS] & 0xffffffff;
        pmu_type = (unsigned int) ((hdr[CS_PMU_TYPE_CPUS] >> 32) &
@@ -2552,35 +2743,31 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
         */
        for (j = 0; j < num_cpu; j++) {
                if (ptr[i] == __perf_cs_etmv3_magic) {
-                       metadata[j] = zalloc(sizeof(*metadata[j]) *
-                                            CS_ETM_PRIV_MAX);
-                       if (!metadata[j]) {
-                               err = -ENOMEM;
-                               goto err_free_metadata;
-                       }
-                       for (k = 0; k < CS_ETM_PRIV_MAX; k++)
-                               metadata[j][k] = ptr[i + k];
+                       metadata[j] =
+                               cs_etm__create_meta_blk(ptr, &i,
+                                                       CS_ETM_PRIV_MAX,
+                                                       CS_ETM_NR_TRC_PARAMS_V0);
 
                        /* The traceID is our handle */
-                       idx = metadata[j][CS_ETM_ETMTRACEIDR];
-                       i += CS_ETM_PRIV_MAX;
+                       trcidr_idx = CS_ETM_ETMTRACEIDR;
+
                } else if (ptr[i] == __perf_cs_etmv4_magic) {
-                       metadata[j] = zalloc(sizeof(*metadata[j]) *
-                                            CS_ETMV4_PRIV_MAX);
-                       if (!metadata[j]) {
-                               err = -ENOMEM;
-                               goto err_free_metadata;
-                       }
-                       for (k = 0; k < CS_ETMV4_PRIV_MAX; k++)
-                               metadata[j][k] = ptr[i + k];
+                       metadata[j] =
+                               cs_etm__create_meta_blk(ptr, &i,
+                                                       CS_ETMV4_PRIV_MAX,
+                                                       CS_ETMV4_NR_TRC_PARAMS_V0);
 
                        /* The traceID is our handle */
-                       idx = metadata[j][CS_ETMV4_TRCTRACEIDR];
-                       i += CS_ETMV4_PRIV_MAX;
+                       trcidr_idx = CS_ETMV4_TRCTRACEIDR;
+               }
+
+               if (!metadata[j]) {
+                       err = -ENOMEM;
+                       goto err_free_metadata;
                }
 
                /* Get an RB node for this CPU */
-               inode = intlist__findnew(traceid_list, idx);
+               inode = intlist__findnew(traceid_list, metadata[j][trcidr_idx]);
 
                /* Something went wrong, no need to continue */
                if (!inode) {
@@ -2601,7 +2788,7 @@ int cs_etm__process_auxtrace_info(union perf_event *event,
        }
 
        /*
-        * Each of CS_HEADER_VERSION_0_MAX, CS_ETM_PRIV_MAX and
+        * Each of CS_HEADER_VERSION_MAX, CS_ETM_PRIV_MAX and
         * CS_ETMV4_PRIV_MAX mark how many double words are in the
         * global metadata, and each cpu's metadata respectively.
         * The following tests if the correct number of double words was
@@ -2703,6 +2890,12 @@ err_free_traceid_list:
        intlist__delete(traceid_list);
 err_free_hdr:
        zfree(&hdr);
-
+       /*
+        * At this point, as a minimum we have valid header. Dump the rest of
+        * the info section - the print routines will error out on structural
+        * issues.
+        */
+       if (dump_trace)
+               cs_etm__print_auxtrace_info(auxtrace_info->priv, num_cpu);
        return err;
 }
index 4ad925d..85ed11e 100644 (file)
@@ -17,23 +17,37 @@ struct perf_session;
  */
 enum {
        /* Starting with 0x0 */
-       CS_HEADER_VERSION_0,
+       CS_HEADER_VERSION,
        /* PMU->type (32 bit), total # of CPUs (32 bit) */
        CS_PMU_TYPE_CPUS,
        CS_ETM_SNAPSHOT,
-       CS_HEADER_VERSION_0_MAX,
+       CS_HEADER_VERSION_MAX,
 };
 
+/*
+ * Update the version for new format.
+ *
+ * New version 1 format adds a param count to the per cpu metadata.
+ * This allows easy adding of new metadata parameters.
+ * Requires that new params always added after current ones.
+ * Also allows client reader to handle file versions that are different by
+ * checking the number of params in the file vs the number expected.
+ */
+#define CS_HEADER_CURRENT_VERSION 1
+
 /* Beginning of header common to both ETMv3 and V4 */
 enum {
        CS_ETM_MAGIC,
        CS_ETM_CPU,
+       /* Number of trace config params in following ETM specific block */
+       CS_ETM_NR_TRC_PARAMS,
+       CS_ETM_COMMON_BLK_MAX_V1,
 };
 
 /* ETMv3/PTM metadata */
 enum {
        /* Dynamic, configurable parameters */
-       CS_ETM_ETMCR = CS_ETM_CPU + 1,
+       CS_ETM_ETMCR = CS_ETM_COMMON_BLK_MAX_V1,
        CS_ETM_ETMTRACEIDR,
        /* RO, taken from sysFS */
        CS_ETM_ETMCCER,
@@ -41,10 +55,13 @@ enum {
        CS_ETM_PRIV_MAX,
 };
 
+/* define fixed version 0 length - allow new format reader to read old files. */
+#define CS_ETM_NR_TRC_PARAMS_V0 (CS_ETM_ETMIDR - CS_ETM_ETMCR + 1)
+
 /* ETMv4 metadata */
 enum {
        /* Dynamic, configurable parameters */
-       CS_ETMV4_TRCCONFIGR = CS_ETM_CPU + 1,
+       CS_ETMV4_TRCCONFIGR = CS_ETM_COMMON_BLK_MAX_V1,
        CS_ETMV4_TRCTRACEIDR,
        /* RO, taken from sysFS */
        CS_ETMV4_TRCIDR0,
@@ -55,6 +72,9 @@ enum {
        CS_ETMV4_PRIV_MAX,
 };
 
+/* define fixed version 0 length - allow new format reader to read old files. */
+#define CS_ETMV4_NR_TRC_PARAMS_V0 (CS_ETMV4_TRCAUTHSTATUS - CS_ETMV4_TRCCONFIGR + 1)
+
 /*
  * ETMv3 exception encoding number:
  * See Embedded Trace Macrocell spcification (ARM IHI 0014Q)
@@ -162,7 +182,7 @@ struct cs_etm_packet_queue {
 
 #define BMVAL(val, lsb, msb)   ((val & GENMASK(msb, lsb)) >> lsb)
 
-#define CS_ETM_HEADER_SIZE (CS_HEADER_VERSION_0_MAX * sizeof(u64))
+#define CS_ETM_HEADER_SIZE (CS_HEADER_VERSION_MAX * sizeof(u64))
 
 #define __perf_cs_etmv3_magic 0x3030303030303030ULL
 #define __perf_cs_etmv4_magic 0x4040404040404040ULL
@@ -173,6 +193,7 @@ struct cs_etm_packet_queue {
 int cs_etm__process_auxtrace_info(union perf_event *event,
                                  struct perf_session *session);
 int cs_etm__get_cpu(u8 trace_chan_id, int *cpu);
+int cs_etm__get_pid_fmt(u8 trace_chan_id, u64 *pid_fmt);
 int cs_etm__etmq_set_tid(struct cs_etm_queue *etmq,
                         pid_t tid, u8 trace_chan_id);
 bool cs_etm__etmq_is_timeless(struct cs_etm_queue *etmq);
index 1b49ece..3fa4486 100644 (file)
@@ -24,6 +24,7 @@
 #include "../arch/s390/include/dwarf-regs-table.h"
 #include "../arch/sparc/include/dwarf-regs-table.h"
 #include "../arch/xtensa/include/dwarf-regs-table.h"
+#include "../arch/mips/include/dwarf-regs-table.h"
 
 #define __get_dwarf_regstr(tbl, n) (((n) < ARRAY_SIZE(tbl)) ? (tbl)[(n)] : NULL)
 
@@ -53,6 +54,8 @@ const char *get_dwarf_regstr(unsigned int n, unsigned int machine)
                return __get_dwarf_regstr(sparc_regstr_tbl, n);
        case EM_XTENSA:
                return __get_dwarf_regstr(xtensa_regstr_tbl, n);
+       case EM_MIPS:
+               return __get_dwarf_regstr(mips_regstr_tbl, n);
        default:
                pr_err("ELF MACHINE %x is not supported.\n", machine);
        }
index 03bd99d..a2e9068 100644 (file)
@@ -34,6 +34,10 @@ static const char **syscalltbl_native = syscalltbl_powerpc_32;
 #include <asm/syscalls.c>
 const int syscalltbl_native_max_id = SYSCALLTBL_ARM64_MAX_ID;
 static const char **syscalltbl_native = syscalltbl_arm64;
+#elif defined(__mips__)
+#include <asm/syscalls_n64.c>
+const int syscalltbl_native_max_id = SYSCALLTBL_MIPS_N64_MAX_ID;
+static const char **syscalltbl_native = syscalltbl_mips_n64;
 #endif
 
 struct syscall {