diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-29 11:58:50 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-04-29 11:58:50 -0400 |
| commit | 7d9e55feae5543b16ec9d433079c9db455929a67 (patch) | |
| tree | b6b7c0fe9c585b8375a383a8605be0f40c477b71 | |
| parent | cdface5209349930ae1b51338763c8e029971b97 (diff) | |
| parent | d4652f614f2163a56aee4c03a88af76f98d52161 (diff) | |
Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull perf fixes from Thomas Gleixner:
"The perf update contains the following bits:
x86:
- Prevent setting freeze_on_smi on PerfMon V1 CPUs to avoid #GP
perf stat:
- Keep the '/' event modifier separator in fallback, for example when
fallbacking from 'cpu/cpu-cycles/' to user level only, where it
should become 'cpu/cpu-cycles/u' and not 'cpu/cpu-cycles/:u' (Jiri
Olsa)
- Fix PMU events parsing rule, improving error reporting for invalid
events (Jiri Olsa)
- Disable write_backward and other event attributes for !group events
in a group, fixing, for instance this group: '{cycles,msr/aperf/}:S'
that has leader sampling (:S) and where just the 'cycles', the
leader event, should have the write_backward attribute set, in this
case it all fails because the PMU where 'msr/aperf/' lives doesn't
accepts write_backward style sampling (Jiri Olsa)
- Only fall back group read for leader (Kan Liang)
- Fix core PMU alias list for x86 platform (Kan Liang)
- Print out hint for mixed PMU group error (Kan Liang)
- Fix duplicate PMU name for interval print (Kan Liang)
Core:
- Set main kernel end address properly when reading kernel and module
maps (Namhyung Kim)
perf mem:
- Fix incorrect entries and add missing man options (Sangwon Hong)
s/390:
- Remove s390 specific strcmp_cpuid_cmp function (Thomas Richter)
- Adapt 'perf test' case record+probe_libc_inet_pton.sh for s390
- Fix s390 undefined record__auxtrace_init() return value in 'perf
record' (Thomas Richter)"
* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
perf/x86/intel: Don't enable freeze-on-smi for PerfMon V1
perf stat: Fix duplicate PMU name for interval print
perf evsel: Only fall back group read for leader
perf stat: Print out hint for mixed PMU group error
perf pmu: Fix core PMU alias list for X86 platform
perf record: Fix s390 undefined record__auxtrace_init() return value
perf mem: Document incorrect and missing options
perf evsel: Disable write_backward for leader sampling group events
perf pmu: Fix pmu events parsing rule
perf stat: Keep the / modifier separator in fallback
perf test: Adapt test case record+probe_libc_inet_pton.sh for s390
perf list: Remove s390 specific strcmp_cpuid_cmp function
perf machine: Set main kernel end address properly
| -rw-r--r-- | arch/x86/events/intel/core.c | 9 | ||||
| -rw-r--r-- | tools/perf/Documentation/perf-mem.txt | 41 | ||||
| -rw-r--r-- | tools/perf/arch/s390/util/auxtrace.c | 1 | ||||
| -rw-r--r-- | tools/perf/arch/s390/util/header.c | 18 | ||||
| -rw-r--r-- | tools/perf/builtin-stat.c | 40 | ||||
| -rw-r--r-- | tools/perf/pmu-events/arch/s390/mapfile.csv | 10 | ||||
| -rw-r--r-- | tools/perf/tests/attr/test-record-group-sampling | 3 | ||||
| -rwxr-xr-x | tools/perf/tests/shell/record+probe_libc_inet_pton.sh | 6 | ||||
| -rw-r--r-- | tools/perf/util/evsel.c | 18 | ||||
| -rw-r--r-- | tools/perf/util/evsel.h | 1 | ||||
| -rw-r--r-- | tools/perf/util/machine.c | 30 | ||||
| -rw-r--r-- | tools/perf/util/parse-events.y | 8 | ||||
| -rw-r--r-- | tools/perf/util/pmu.c | 22 |
13 files changed, 129 insertions, 78 deletions
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c index 607bf565a90c..707b2a96e516 100644 --- a/arch/x86/events/intel/core.c +++ b/arch/x86/events/intel/core.c | |||
| @@ -3339,7 +3339,8 @@ static void intel_pmu_cpu_starting(int cpu) | |||
| 3339 | 3339 | ||
| 3340 | cpuc->lbr_sel = NULL; | 3340 | cpuc->lbr_sel = NULL; |
| 3341 | 3341 | ||
| 3342 | flip_smm_bit(&x86_pmu.attr_freeze_on_smi); | 3342 | if (x86_pmu.version > 1) |
| 3343 | flip_smm_bit(&x86_pmu.attr_freeze_on_smi); | ||
| 3343 | 3344 | ||
| 3344 | if (!cpuc->shared_regs) | 3345 | if (!cpuc->shared_regs) |
| 3345 | return; | 3346 | return; |
| @@ -3502,6 +3503,8 @@ static __initconst const struct x86_pmu core_pmu = { | |||
| 3502 | .cpu_dying = intel_pmu_cpu_dying, | 3503 | .cpu_dying = intel_pmu_cpu_dying, |
| 3503 | }; | 3504 | }; |
| 3504 | 3505 | ||
| 3506 | static struct attribute *intel_pmu_attrs[]; | ||
| 3507 | |||
| 3505 | static __initconst const struct x86_pmu intel_pmu = { | 3508 | static __initconst const struct x86_pmu intel_pmu = { |
| 3506 | .name = "Intel", | 3509 | .name = "Intel", |
| 3507 | .handle_irq = intel_pmu_handle_irq, | 3510 | .handle_irq = intel_pmu_handle_irq, |
| @@ -3533,6 +3536,8 @@ static __initconst const struct x86_pmu intel_pmu = { | |||
| 3533 | .format_attrs = intel_arch3_formats_attr, | 3536 | .format_attrs = intel_arch3_formats_attr, |
| 3534 | .events_sysfs_show = intel_event_sysfs_show, | 3537 | .events_sysfs_show = intel_event_sysfs_show, |
| 3535 | 3538 | ||
| 3539 | .attrs = intel_pmu_attrs, | ||
| 3540 | |||
| 3536 | .cpu_prepare = intel_pmu_cpu_prepare, | 3541 | .cpu_prepare = intel_pmu_cpu_prepare, |
| 3537 | .cpu_starting = intel_pmu_cpu_starting, | 3542 | .cpu_starting = intel_pmu_cpu_starting, |
| 3538 | .cpu_dying = intel_pmu_cpu_dying, | 3543 | .cpu_dying = intel_pmu_cpu_dying, |
| @@ -3911,8 +3916,6 @@ __init int intel_pmu_init(void) | |||
| 3911 | 3916 | ||
| 3912 | x86_pmu.max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, x86_pmu.num_counters); | 3917 | x86_pmu.max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, x86_pmu.num_counters); |
| 3913 | 3918 | ||
| 3914 | |||
| 3915 | x86_pmu.attrs = intel_pmu_attrs; | ||
| 3916 | /* | 3919 | /* |
| 3917 | * Quirk: v2 perfmon does not report fixed-purpose events, so | 3920 | * Quirk: v2 perfmon does not report fixed-purpose events, so |
| 3918 | * assume at least 3 events, when not running in a hypervisor: | 3921 | * assume at least 3 events, when not running in a hypervisor: |
diff --git a/tools/perf/Documentation/perf-mem.txt b/tools/perf/Documentation/perf-mem.txt index 8806ed5f3802..f8d2167cf3e7 100644 --- a/tools/perf/Documentation/perf-mem.txt +++ b/tools/perf/Documentation/perf-mem.txt | |||
| @@ -28,29 +28,46 @@ OPTIONS | |||
| 28 | <command>...:: | 28 | <command>...:: |
| 29 | Any command you can specify in a shell. | 29 | Any command you can specify in a shell. |
| 30 | 30 | ||
| 31 | -i:: | ||
| 32 | --input=<file>:: | ||
| 33 | Input file name. | ||
| 34 | |||
| 31 | -f:: | 35 | -f:: |
| 32 | --force:: | 36 | --force:: |
| 33 | Don't do ownership validation | 37 | Don't do ownership validation |
| 34 | 38 | ||
| 35 | -t:: | 39 | -t:: |
| 36 | --type=:: | 40 | --type=<type>:: |
| 37 | Select the memory operation type: load or store (default: load,store) | 41 | Select the memory operation type: load or store (default: load,store) |
| 38 | 42 | ||
| 39 | -D:: | 43 | -D:: |
| 40 | --dump-raw-samples=:: | 44 | --dump-raw-samples:: |
| 41 | Dump the raw decoded samples on the screen in a format that is easy to parse with | 45 | Dump the raw decoded samples on the screen in a format that is easy to parse with |
| 42 | one sample per line. | 46 | one sample per line. |
| 43 | 47 | ||
| 44 | -x:: | 48 | -x:: |
| 45 | --field-separator:: | 49 | --field-separator=<separator>:: |
| 46 | Specify the field separator used when dump raw samples (-D option). By default, | 50 | Specify the field separator used when dump raw samples (-D option). By default, |
| 47 | The separator is the space character. | 51 | The separator is the space character. |
| 48 | 52 | ||
| 49 | -C:: | 53 | -C:: |
| 50 | --cpu-list:: | 54 | --cpu=<cpu>:: |
| 51 | Restrict dump of raw samples to those provided via this option. Note that the same | 55 | Monitor only on the list of CPUs provided. Multiple CPUs can be provided as a |
| 52 | option can be passed in record mode. It will be interpreted the same way as perf | 56 | comma-separated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2. Default |
| 53 | record. | 57 | is to monitor all CPUS. |
| 58 | -U:: | ||
| 59 | --hide-unresolved:: | ||
| 60 | Only display entries resolved to a symbol. | ||
| 61 | |||
| 62 | -p:: | ||
| 63 | --phys-data:: | ||
| 64 | Record/Report sample physical addresses | ||
| 65 | |||
| 66 | RECORD OPTIONS | ||
| 67 | -------------- | ||
| 68 | -e:: | ||
| 69 | --event <event>:: | ||
| 70 | Event selector. Use 'perf mem record -e list' to list available events. | ||
| 54 | 71 | ||
| 55 | -K:: | 72 | -K:: |
| 56 | --all-kernel:: | 73 | --all-kernel:: |
| @@ -60,12 +77,12 @@ OPTIONS | |||
| 60 | --all-user:: | 77 | --all-user:: |
| 61 | Configure all used events to run in user space. | 78 | Configure all used events to run in user space. |
| 62 | 79 | ||
| 63 | --ldload:: | 80 | -v:: |
| 64 | Specify desired latency for loads event. | 81 | --verbose:: |
| 82 | Be more verbose (show counter open errors, etc) | ||
| 65 | 83 | ||
| 66 | -p:: | 84 | --ldlat <n>:: |
| 67 | --phys-data:: | 85 | Specify desired latency for loads event. |
| 68 | Record/Report sample physical addresses | ||
| 69 | 86 | ||
| 70 | In addition, for report all perf report options are valid, and for record | 87 | In addition, for report all perf report options are valid, and for record |
| 71 | all perf record options. | 88 | all perf record options. |
diff --git a/tools/perf/arch/s390/util/auxtrace.c b/tools/perf/arch/s390/util/auxtrace.c index 6cb48e4cffd9..3afe8256eff2 100644 --- a/tools/perf/arch/s390/util/auxtrace.c +++ b/tools/perf/arch/s390/util/auxtrace.c | |||
| @@ -87,6 +87,7 @@ struct auxtrace_record *auxtrace_record__init(struct perf_evlist *evlist, | |||
| 87 | struct perf_evsel *pos; | 87 | struct perf_evsel *pos; |
| 88 | int diagnose = 0; | 88 | int diagnose = 0; |
| 89 | 89 | ||
| 90 | *err = 0; | ||
| 90 | if (evlist->nr_entries == 0) | 91 | if (evlist->nr_entries == 0) |
| 91 | return NULL; | 92 | return NULL; |
| 92 | 93 | ||
diff --git a/tools/perf/arch/s390/util/header.c b/tools/perf/arch/s390/util/header.c index a4c30f1c70be..163b92f33998 100644 --- a/tools/perf/arch/s390/util/header.c +++ b/tools/perf/arch/s390/util/header.c | |||
| @@ -146,21 +146,3 @@ char *get_cpuid_str(struct perf_pmu *pmu __maybe_unused) | |||
| 146 | zfree(&buf); | 146 | zfree(&buf); |
| 147 | return buf; | 147 | return buf; |
| 148 | } | 148 | } |
| 149 | |||
| 150 | /* | ||
| 151 | * Compare the cpuid string returned by get_cpuid() function | ||
| 152 | * with the name generated by the jevents file read from | ||
| 153 | * pmu-events/arch/s390/mapfile.csv. | ||
| 154 | * | ||
| 155 | * Parameter mapcpuid is the cpuid as stored in the | ||
| 156 | * pmu-events/arch/s390/mapfile.csv. This is just the type number. | ||
| 157 | * Parameter cpuid is the cpuid returned by function get_cpuid(). | ||
| 158 | */ | ||
| 159 | int strcmp_cpuid_str(const char *mapcpuid, const char *cpuid) | ||
| 160 | { | ||
| 161 | char *cp = strchr(cpuid, ','); | ||
| 162 | |||
| 163 | if (cp == NULL) | ||
| 164 | return -1; | ||
| 165 | return strncmp(cp + 1, mapcpuid, strlen(mapcpuid)); | ||
| 166 | } | ||
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c index 147a27e8c937..f17dc601b0f3 100644 --- a/tools/perf/builtin-stat.c +++ b/tools/perf/builtin-stat.c | |||
| @@ -172,6 +172,7 @@ static bool interval_count; | |||
| 172 | static const char *output_name; | 172 | static const char *output_name; |
| 173 | static int output_fd; | 173 | static int output_fd; |
| 174 | static int print_free_counters_hint; | 174 | static int print_free_counters_hint; |
| 175 | static int print_mixed_hw_group_error; | ||
| 175 | 176 | ||
| 176 | struct perf_stat { | 177 | struct perf_stat { |
| 177 | bool record; | 178 | bool record; |
| @@ -1126,6 +1127,30 @@ static void abs_printout(int id, int nr, struct perf_evsel *evsel, double avg) | |||
| 1126 | fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); | 1127 | fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); |
| 1127 | } | 1128 | } |
| 1128 | 1129 | ||
| 1130 | static bool is_mixed_hw_group(struct perf_evsel *counter) | ||
| 1131 | { | ||
| 1132 | struct perf_evlist *evlist = counter->evlist; | ||
| 1133 | u32 pmu_type = counter->attr.type; | ||
| 1134 | struct perf_evsel *pos; | ||
| 1135 | |||
| 1136 | if (counter->nr_members < 2) | ||
| 1137 | return false; | ||
| 1138 | |||
| 1139 | evlist__for_each_entry(evlist, pos) { | ||
| 1140 | /* software events can be part of any hardware group */ | ||
| 1141 | if (pos->attr.type == PERF_TYPE_SOFTWARE) | ||
| 1142 | continue; | ||
| 1143 | if (pmu_type == PERF_TYPE_SOFTWARE) { | ||
| 1144 | pmu_type = pos->attr.type; | ||
| 1145 | continue; | ||
| 1146 | } | ||
| 1147 | if (pmu_type != pos->attr.type) | ||
| 1148 | return true; | ||
| 1149 | } | ||
| 1150 | |||
| 1151 | return false; | ||
| 1152 | } | ||
| 1153 | |||
| 1129 | static void printout(int id, int nr, struct perf_evsel *counter, double uval, | 1154 | static void printout(int id, int nr, struct perf_evsel *counter, double uval, |
| 1130 | char *prefix, u64 run, u64 ena, double noise, | 1155 | char *prefix, u64 run, u64 ena, double noise, |
| 1131 | struct runtime_stat *st) | 1156 | struct runtime_stat *st) |
| @@ -1178,8 +1203,11 @@ static void printout(int id, int nr, struct perf_evsel *counter, double uval, | |||
| 1178 | counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, | 1203 | counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, |
| 1179 | csv_sep); | 1204 | csv_sep); |
| 1180 | 1205 | ||
| 1181 | if (counter->supported) | 1206 | if (counter->supported) { |
| 1182 | print_free_counters_hint = 1; | 1207 | print_free_counters_hint = 1; |
| 1208 | if (is_mixed_hw_group(counter)) | ||
| 1209 | print_mixed_hw_group_error = 1; | ||
| 1210 | } | ||
| 1183 | 1211 | ||
| 1184 | fprintf(stat_config.output, "%-*s%s", | 1212 | fprintf(stat_config.output, "%-*s%s", |
| 1185 | csv_output ? 0 : unit_width, | 1213 | csv_output ? 0 : unit_width, |
| @@ -1256,7 +1284,8 @@ static void uniquify_event_name(struct perf_evsel *counter) | |||
| 1256 | char *new_name; | 1284 | char *new_name; |
| 1257 | char *config; | 1285 | char *config; |
| 1258 | 1286 | ||
| 1259 | if (!counter->pmu_name || !strncmp(counter->name, counter->pmu_name, | 1287 | if (counter->uniquified_name || |
| 1288 | !counter->pmu_name || !strncmp(counter->name, counter->pmu_name, | ||
| 1260 | strlen(counter->pmu_name))) | 1289 | strlen(counter->pmu_name))) |
| 1261 | return; | 1290 | return; |
| 1262 | 1291 | ||
| @@ -1274,6 +1303,8 @@ static void uniquify_event_name(struct perf_evsel *counter) | |||
| 1274 | counter->name = new_name; | 1303 | counter->name = new_name; |
| 1275 | } | 1304 | } |
| 1276 | } | 1305 | } |
| 1306 | |||
| 1307 | counter->uniquified_name = true; | ||
| 1277 | } | 1308 | } |
| 1278 | 1309 | ||
| 1279 | static void collect_all_aliases(struct perf_evsel *counter, | 1310 | static void collect_all_aliases(struct perf_evsel *counter, |
| @@ -1757,6 +1788,11 @@ static void print_footer(void) | |||
| 1757 | " echo 0 > /proc/sys/kernel/nmi_watchdog\n" | 1788 | " echo 0 > /proc/sys/kernel/nmi_watchdog\n" |
| 1758 | " perf stat ...\n" | 1789 | " perf stat ...\n" |
| 1759 | " echo 1 > /proc/sys/kernel/nmi_watchdog\n"); | 1790 | " echo 1 > /proc/sys/kernel/nmi_watchdog\n"); |
| 1791 | |||
| 1792 | if (print_mixed_hw_group_error) | ||
| 1793 | fprintf(output, | ||
| 1794 | "The events in group usually have to be from " | ||
| 1795 | "the same PMU. Try reorganizing the group.\n"); | ||
| 1760 | } | 1796 | } |
| 1761 | 1797 | ||
| 1762 | static void print_counters(struct timespec *ts, int argc, const char **argv) | 1798 | static void print_counters(struct timespec *ts, int argc, const char **argv) |
diff --git a/tools/perf/pmu-events/arch/s390/mapfile.csv b/tools/perf/pmu-events/arch/s390/mapfile.csv index ca7682748a4b..78bcf7f8e206 100644 --- a/tools/perf/pmu-events/arch/s390/mapfile.csv +++ b/tools/perf/pmu-events/arch/s390/mapfile.csv | |||
| @@ -1,6 +1,6 @@ | |||
| 1 | Family-model,Version,Filename,EventType | 1 | Family-model,Version,Filename,EventType |
| 2 | 209[78],1,cf_z10,core | 2 | ^IBM.209[78].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_z10,core |
| 3 | 281[78],1,cf_z196,core | 3 | ^IBM.281[78].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_z196,core |
| 4 | 282[78],1,cf_zec12,core | 4 | ^IBM.282[78].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_zec12,core |
| 5 | 296[45],1,cf_z13,core | 5 | ^IBM.296[45].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_z13,core |
| 6 | 3906,3,cf_z14,core | 6 | ^IBM.390[67].*[13]\.[1-5].[[:xdigit:]]+$,3,cf_z14,core |
diff --git a/tools/perf/tests/attr/test-record-group-sampling b/tools/perf/tests/attr/test-record-group-sampling index f906b793196f..8a33ca4f9e1f 100644 --- a/tools/perf/tests/attr/test-record-group-sampling +++ b/tools/perf/tests/attr/test-record-group-sampling | |||
| @@ -35,3 +35,6 @@ inherit=0 | |||
| 35 | # sampling disabled | 35 | # sampling disabled |
| 36 | sample_freq=0 | 36 | sample_freq=0 |
| 37 | sample_period=0 | 37 | sample_period=0 |
| 38 | freq=0 | ||
| 39 | write_backward=0 | ||
| 40 | sample_id_all=0 | ||
diff --git a/tools/perf/tests/shell/record+probe_libc_inet_pton.sh b/tools/perf/tests/shell/record+probe_libc_inet_pton.sh index 1ecc1f0ff84a..016882dbbc16 100755 --- a/tools/perf/tests/shell/record+probe_libc_inet_pton.sh +++ b/tools/perf/tests/shell/record+probe_libc_inet_pton.sh | |||
| @@ -19,12 +19,10 @@ trace_libc_inet_pton_backtrace() { | |||
| 19 | expected[1]=".*inet_pton[[:space:]]\($libc\)$" | 19 | expected[1]=".*inet_pton[[:space:]]\($libc\)$" |
| 20 | case "$(uname -m)" in | 20 | case "$(uname -m)" in |
| 21 | s390x) | 21 | s390x) |
| 22 | eventattr='call-graph=dwarf' | 22 | eventattr='call-graph=dwarf,max-stack=4' |
| 23 | expected[2]="gaih_inet.*[[:space:]]\($libc|inlined\)$" | 23 | expected[2]="gaih_inet.*[[:space:]]\($libc|inlined\)$" |
| 24 | expected[3]="__GI_getaddrinfo[[:space:]]\($libc|inlined\)$" | 24 | expected[3]="(__GI_)?getaddrinfo[[:space:]]\($libc|inlined\)$" |
| 25 | expected[4]="main[[:space:]]\(.*/bin/ping.*\)$" | 25 | expected[4]="main[[:space:]]\(.*/bin/ping.*\)$" |
| 26 | expected[5]="__libc_start_main[[:space:]]\($libc\)$" | ||
| 27 | expected[6]="_start[[:space:]]\(.*/bin/ping.*\)$" | ||
| 28 | ;; | 26 | ;; |
| 29 | *) | 27 | *) |
| 30 | eventattr='max-stack=3' | 28 | eventattr='max-stack=3' |
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index 3e87486c28fe..4cd2cf93f726 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
| @@ -930,8 +930,11 @@ void perf_evsel__config(struct perf_evsel *evsel, struct record_opts *opts, | |||
| 930 | * than leader in case leader 'leads' the sampling. | 930 | * than leader in case leader 'leads' the sampling. |
| 931 | */ | 931 | */ |
| 932 | if ((leader != evsel) && leader->sample_read) { | 932 | if ((leader != evsel) && leader->sample_read) { |
| 933 | attr->sample_freq = 0; | 933 | attr->freq = 0; |
| 934 | attr->sample_period = 0; | 934 | attr->sample_freq = 0; |
| 935 | attr->sample_period = 0; | ||
| 936 | attr->write_backward = 0; | ||
| 937 | attr->sample_id_all = 0; | ||
| 935 | } | 938 | } |
| 936 | 939 | ||
| 937 | if (opts->no_samples) | 940 | if (opts->no_samples) |
| @@ -1922,7 +1925,8 @@ try_fallback: | |||
| 1922 | goto fallback_missing_features; | 1925 | goto fallback_missing_features; |
| 1923 | } else if (!perf_missing_features.group_read && | 1926 | } else if (!perf_missing_features.group_read && |
| 1924 | evsel->attr.inherit && | 1927 | evsel->attr.inherit && |
| 1925 | (evsel->attr.read_format & PERF_FORMAT_GROUP)) { | 1928 | (evsel->attr.read_format & PERF_FORMAT_GROUP) && |
| 1929 | perf_evsel__is_group_leader(evsel)) { | ||
| 1926 | perf_missing_features.group_read = true; | 1930 | perf_missing_features.group_read = true; |
| 1927 | pr_debug2("switching off group read\n"); | 1931 | pr_debug2("switching off group read\n"); |
| 1928 | goto fallback_missing_features; | 1932 | goto fallback_missing_features; |
| @@ -2754,8 +2758,14 @@ bool perf_evsel__fallback(struct perf_evsel *evsel, int err, | |||
| 2754 | (paranoid = perf_event_paranoid()) > 1) { | 2758 | (paranoid = perf_event_paranoid()) > 1) { |
| 2755 | const char *name = perf_evsel__name(evsel); | 2759 | const char *name = perf_evsel__name(evsel); |
| 2756 | char *new_name; | 2760 | char *new_name; |
| 2761 | const char *sep = ":"; | ||
| 2757 | 2762 | ||
| 2758 | if (asprintf(&new_name, "%s%su", name, strchr(name, ':') ? "" : ":") < 0) | 2763 | /* Is there already the separator in the name. */ |
| 2764 | if (strchr(name, '/') || | ||
| 2765 | strchr(name, ':')) | ||
| 2766 | sep = ""; | ||
| 2767 | |||
| 2768 | if (asprintf(&new_name, "%s%su", name, sep) < 0) | ||
| 2759 | return false; | 2769 | return false; |
| 2760 | 2770 | ||
| 2761 | if (evsel->name) | 2771 | if (evsel->name) |
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index d3ee3af618ef..92ec009a292d 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
| @@ -115,6 +115,7 @@ struct perf_evsel { | |||
| 115 | unsigned int sample_size; | 115 | unsigned int sample_size; |
| 116 | int id_pos; | 116 | int id_pos; |
| 117 | int is_pos; | 117 | int is_pos; |
| 118 | bool uniquified_name; | ||
| 118 | bool snapshot; | 119 | bool snapshot; |
| 119 | bool supported; | 120 | bool supported; |
| 120 | bool needs_swap; | 121 | bool needs_swap; |
diff --git a/tools/perf/util/machine.c b/tools/perf/util/machine.c index 2eca8478e24f..32d50492505d 100644 --- a/tools/perf/util/machine.c +++ b/tools/perf/util/machine.c | |||
| @@ -1019,13 +1019,6 @@ int machine__load_vmlinux_path(struct machine *machine, enum map_type type) | |||
| 1019 | return ret; | 1019 | return ret; |
| 1020 | } | 1020 | } |
| 1021 | 1021 | ||
| 1022 | static void map_groups__fixup_end(struct map_groups *mg) | ||
| 1023 | { | ||
| 1024 | int i; | ||
| 1025 | for (i = 0; i < MAP__NR_TYPES; ++i) | ||
| 1026 | __map_groups__fixup_end(mg, i); | ||
| 1027 | } | ||
| 1028 | |||
| 1029 | static char *get_kernel_version(const char *root_dir) | 1022 | static char *get_kernel_version(const char *root_dir) |
| 1030 | { | 1023 | { |
| 1031 | char version[PATH_MAX]; | 1024 | char version[PATH_MAX]; |
| @@ -1233,6 +1226,7 @@ int machine__create_kernel_maps(struct machine *machine) | |||
| 1233 | { | 1226 | { |
| 1234 | struct dso *kernel = machine__get_kernel(machine); | 1227 | struct dso *kernel = machine__get_kernel(machine); |
| 1235 | const char *name = NULL; | 1228 | const char *name = NULL; |
| 1229 | struct map *map; | ||
| 1236 | u64 addr = 0; | 1230 | u64 addr = 0; |
| 1237 | int ret; | 1231 | int ret; |
| 1238 | 1232 | ||
| @@ -1259,13 +1253,25 @@ int machine__create_kernel_maps(struct machine *machine) | |||
| 1259 | machine__destroy_kernel_maps(machine); | 1253 | machine__destroy_kernel_maps(machine); |
| 1260 | return -1; | 1254 | return -1; |
| 1261 | } | 1255 | } |
| 1262 | machine__set_kernel_mmap(machine, addr, 0); | 1256 | |
| 1257 | /* we have a real start address now, so re-order the kmaps */ | ||
| 1258 | map = machine__kernel_map(machine); | ||
| 1259 | |||
| 1260 | map__get(map); | ||
| 1261 | map_groups__remove(&machine->kmaps, map); | ||
| 1262 | |||
| 1263 | /* assume it's the last in the kmaps */ | ||
| 1264 | machine__set_kernel_mmap(machine, addr, ~0ULL); | ||
| 1265 | |||
| 1266 | map_groups__insert(&machine->kmaps, map); | ||
| 1267 | map__put(map); | ||
| 1263 | } | 1268 | } |
| 1264 | 1269 | ||
| 1265 | /* | 1270 | /* update end address of the kernel map using adjacent module address */ |
| 1266 | * Now that we have all the maps created, just set the ->end of them: | 1271 | map = map__next(machine__kernel_map(machine)); |
| 1267 | */ | 1272 | if (map) |
| 1268 | map_groups__fixup_end(&machine->kmaps); | 1273 | machine__set_kernel_mmap(machine, addr, map->start); |
| 1274 | |||
| 1269 | return 0; | 1275 | return 0; |
| 1270 | } | 1276 | } |
| 1271 | 1277 | ||
diff --git a/tools/perf/util/parse-events.y b/tools/perf/util/parse-events.y index 7afeb80cc39e..d14464c42714 100644 --- a/tools/perf/util/parse-events.y +++ b/tools/perf/util/parse-events.y | |||
| @@ -224,15 +224,15 @@ event_def: event_pmu | | |||
| 224 | event_bpf_file | 224 | event_bpf_file |
| 225 | 225 | ||
| 226 | event_pmu: | 226 | event_pmu: |
| 227 | PE_NAME opt_event_config | 227 | PE_NAME '/' event_config '/' |
| 228 | { | 228 | { |
| 229 | struct list_head *list, *orig_terms, *terms; | 229 | struct list_head *list, *orig_terms, *terms; |
| 230 | 230 | ||
| 231 | if (parse_events_copy_term_list($2, &orig_terms)) | 231 | if (parse_events_copy_term_list($3, &orig_terms)) |
| 232 | YYABORT; | 232 | YYABORT; |
| 233 | 233 | ||
| 234 | ALLOC_LIST(list); | 234 | ALLOC_LIST(list); |
| 235 | if (parse_events_add_pmu(_parse_state, list, $1, $2, false)) { | 235 | if (parse_events_add_pmu(_parse_state, list, $1, $3, false)) { |
| 236 | struct perf_pmu *pmu = NULL; | 236 | struct perf_pmu *pmu = NULL; |
| 237 | int ok = 0; | 237 | int ok = 0; |
| 238 | char *pattern; | 238 | char *pattern; |
| @@ -262,7 +262,7 @@ PE_NAME opt_event_config | |||
| 262 | if (!ok) | 262 | if (!ok) |
| 263 | YYABORT; | 263 | YYABORT; |
| 264 | } | 264 | } |
| 265 | parse_events_terms__delete($2); | 265 | parse_events_terms__delete($3); |
| 266 | parse_events_terms__delete(orig_terms); | 266 | parse_events_terms__delete(orig_terms); |
| 267 | $$ = list; | 267 | $$ = list; |
| 268 | } | 268 | } |
diff --git a/tools/perf/util/pmu.c b/tools/perf/util/pmu.c index 61a5e5027338..d2fb597c9a8c 100644 --- a/tools/perf/util/pmu.c +++ b/tools/perf/util/pmu.c | |||
| @@ -539,9 +539,10 @@ static bool pmu_is_uncore(const char *name) | |||
| 539 | 539 | ||
| 540 | /* | 540 | /* |
| 541 | * PMU CORE devices have different name other than cpu in sysfs on some | 541 | * PMU CORE devices have different name other than cpu in sysfs on some |
| 542 | * platforms. looking for possible sysfs files to identify as core device. | 542 | * platforms. |
| 543 | * Looking for possible sysfs files to identify the arm core device. | ||
| 543 | */ | 544 | */ |
| 544 | static int is_pmu_core(const char *name) | 545 | static int is_arm_pmu_core(const char *name) |
| 545 | { | 546 | { |
| 546 | struct stat st; | 547 | struct stat st; |
| 547 | char path[PATH_MAX]; | 548 | char path[PATH_MAX]; |
| @@ -550,12 +551,6 @@ static int is_pmu_core(const char *name) | |||
| 550 | if (!sysfs) | 551 | if (!sysfs) |
| 551 | return 0; | 552 | return 0; |
| 552 | 553 | ||
| 553 | /* Look for cpu sysfs (x86 and others) */ | ||
| 554 | scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu", sysfs); | ||
| 555 | if ((stat(path, &st) == 0) && | ||
| 556 | (strncmp(name, "cpu", strlen("cpu")) == 0)) | ||
| 557 | return 1; | ||
| 558 | |||
| 559 | /* Look for cpu sysfs (specific to arm) */ | 554 | /* Look for cpu sysfs (specific to arm) */ |
| 560 | scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s/cpus", | 555 | scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s/cpus", |
| 561 | sysfs, name); | 556 | sysfs, name); |
| @@ -586,7 +581,7 @@ char * __weak get_cpuid_str(struct perf_pmu *pmu __maybe_unused) | |||
| 586 | * cpuid string generated on this platform. | 581 | * cpuid string generated on this platform. |
| 587 | * Otherwise return non-zero. | 582 | * Otherwise return non-zero. |
| 588 | */ | 583 | */ |
| 589 | int __weak strcmp_cpuid_str(const char *mapcpuid, const char *cpuid) | 584 | int strcmp_cpuid_str(const char *mapcpuid, const char *cpuid) |
| 590 | { | 585 | { |
| 591 | regex_t re; | 586 | regex_t re; |
| 592 | regmatch_t pmatch[1]; | 587 | regmatch_t pmatch[1]; |
| @@ -668,6 +663,7 @@ static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu) | |||
| 668 | struct pmu_events_map *map; | 663 | struct pmu_events_map *map; |
| 669 | struct pmu_event *pe; | 664 | struct pmu_event *pe; |
| 670 | const char *name = pmu->name; | 665 | const char *name = pmu->name; |
| 666 | const char *pname; | ||
| 671 | 667 | ||
| 672 | map = perf_pmu__find_map(pmu); | 668 | map = perf_pmu__find_map(pmu); |
| 673 | if (!map) | 669 | if (!map) |
| @@ -686,11 +682,9 @@ static void pmu_add_cpu_aliases(struct list_head *head, struct perf_pmu *pmu) | |||
| 686 | break; | 682 | break; |
| 687 | } | 683 | } |
| 688 | 684 | ||
| 689 | if (!is_pmu_core(name)) { | 685 | if (!is_arm_pmu_core(name)) { |
| 690 | /* check for uncore devices */ | 686 | pname = pe->pmu ? pe->pmu : "cpu"; |
| 691 | if (pe->pmu == NULL) | 687 | if (strncmp(pname, name, strlen(pname))) |
| 692 | continue; | ||
| 693 | if (strncmp(pe->pmu, name, strlen(pe->pmu))) | ||
| 694 | continue; | 688 | continue; |
| 695 | } | 689 | } |
| 696 | 690 | ||
