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

Changed files
+129 -78
arch
x86
events
intel
tools
+6 -3
arch/x86/events/intel/core.c
··· 3339 3339 3340 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 3345 if (!cpuc->shared_regs) 3345 3346 return; ··· 3503 3502 .cpu_dying = intel_pmu_cpu_dying, 3504 3503 }; 3505 3504 3505 + static struct attribute *intel_pmu_attrs[]; 3506 + 3506 3507 static __initconst const struct x86_pmu intel_pmu = { 3507 3508 .name = "Intel", 3508 3509 .handle_irq = intel_pmu_handle_irq, ··· 3535 3532 3536 3533 .format_attrs = intel_arch3_formats_attr, 3537 3534 .events_sysfs_show = intel_event_sysfs_show, 3535 + 3536 + .attrs = intel_pmu_attrs, 3538 3537 3539 3538 .cpu_prepare = intel_pmu_cpu_prepare, 3540 3539 .cpu_starting = intel_pmu_cpu_starting, ··· 3916 3911 3917 3912 x86_pmu.max_pebs_events = min_t(unsigned, MAX_PEBS_EVENTS, x86_pmu.num_counters); 3918 3913 3919 - 3920 - x86_pmu.attrs = intel_pmu_attrs; 3921 3914 /* 3922 3915 * Quirk: v2 perfmon does not report fixed-purpose events, so 3923 3916 * assume at least 3 events, when not running in a hypervisor:
+29 -12
tools/perf/Documentation/perf-mem.txt
··· 28 28 <command>...:: 29 29 Any command you can specify in a shell. 30 30 31 + -i:: 32 + --input=<file>:: 33 + Input file name. 34 + 31 35 -f:: 32 36 --force:: 33 37 Don't do ownership validation 34 38 35 39 -t:: 36 - --type=:: 40 + --type=<type>:: 37 41 Select the memory operation type: load or store (default: load,store) 38 42 39 43 -D:: 40 - --dump-raw-samples=:: 44 + --dump-raw-samples:: 41 45 Dump the raw decoded samples on the screen in a format that is easy to parse with 42 46 one sample per line. 43 47 44 48 -x:: 45 - --field-separator:: 49 + --field-separator=<separator>:: 46 50 Specify the field separator used when dump raw samples (-D option). By default, 47 51 The separator is the space character. 48 52 49 53 -C:: 50 - --cpu-list:: 51 - Restrict dump of raw samples to those provided via this option. Note that the same 52 - option can be passed in record mode. It will be interpreted the same way as perf 53 - record. 54 + --cpu=<cpu>:: 55 + Monitor only on the list of CPUs provided. Multiple CPUs can be provided as a 56 + comma-separated list with no space: 0,1. Ranges of CPUs are specified with -: 0-2. Default 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 72 -K:: 56 73 --all-kernel:: ··· 77 60 --all-user:: 78 61 Configure all used events to run in user space. 79 62 80 - --ldload:: 81 - Specify desired latency for loads event. 63 + -v:: 64 + --verbose:: 65 + Be more verbose (show counter open errors, etc) 82 66 83 - -p:: 84 - --phys-data:: 85 - Record/Report sample physical addresses 67 + --ldlat <n>:: 68 + Specify desired latency for loads event. 86 69 87 70 In addition, for report all perf report options are valid, and for record 88 71 all perf record options.
+1
tools/perf/arch/s390/util/auxtrace.c
··· 87 87 struct perf_evsel *pos; 88 88 int diagnose = 0; 89 89 90 + *err = 0; 90 91 if (evlist->nr_entries == 0) 91 92 return NULL; 92 93
-18
tools/perf/arch/s390/util/header.c
··· 146 146 zfree(&buf); 147 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 - }
+38 -2
tools/perf/builtin-stat.c
··· 172 172 static const char *output_name; 173 173 static int output_fd; 174 174 static int print_free_counters_hint; 175 + static int print_mixed_hw_group_error; 175 176 176 177 struct perf_stat { 177 178 bool record; ··· 1127 1126 fprintf(output, "%s%s", csv_sep, evsel->cgrp->name); 1128 1127 } 1129 1128 1129 + static bool is_mixed_hw_group(struct perf_evsel *counter) 1130 + { 1131 + struct perf_evlist *evlist = counter->evlist; 1132 + u32 pmu_type = counter->attr.type; 1133 + struct perf_evsel *pos; 1134 + 1135 + if (counter->nr_members < 2) 1136 + return false; 1137 + 1138 + evlist__for_each_entry(evlist, pos) { 1139 + /* software events can be part of any hardware group */ 1140 + if (pos->attr.type == PERF_TYPE_SOFTWARE) 1141 + continue; 1142 + if (pmu_type == PERF_TYPE_SOFTWARE) { 1143 + pmu_type = pos->attr.type; 1144 + continue; 1145 + } 1146 + if (pmu_type != pos->attr.type) 1147 + return true; 1148 + } 1149 + 1150 + return false; 1151 + } 1152 + 1130 1153 static void printout(int id, int nr, struct perf_evsel *counter, double uval, 1131 1154 char *prefix, u64 run, u64 ena, double noise, 1132 1155 struct runtime_stat *st) ··· 1203 1178 counter->supported ? CNTR_NOT_COUNTED : CNTR_NOT_SUPPORTED, 1204 1179 csv_sep); 1205 1180 1206 - if (counter->supported) 1181 + if (counter->supported) { 1207 1182 print_free_counters_hint = 1; 1183 + if (is_mixed_hw_group(counter)) 1184 + print_mixed_hw_group_error = 1; 1185 + } 1208 1186 1209 1187 fprintf(stat_config.output, "%-*s%s", 1210 1188 csv_output ? 0 : unit_width, ··· 1284 1256 char *new_name; 1285 1257 char *config; 1286 1258 1287 - if (!counter->pmu_name || !strncmp(counter->name, counter->pmu_name, 1259 + if (counter->uniquified_name || 1260 + !counter->pmu_name || !strncmp(counter->name, counter->pmu_name, 1288 1261 strlen(counter->pmu_name))) 1289 1262 return; 1290 1263 ··· 1303 1274 counter->name = new_name; 1304 1275 } 1305 1276 } 1277 + 1278 + counter->uniquified_name = true; 1306 1279 } 1307 1280 1308 1281 static void collect_all_aliases(struct perf_evsel *counter, ··· 1788 1757 " echo 0 > /proc/sys/kernel/nmi_watchdog\n" 1789 1758 " perf stat ...\n" 1790 1759 " echo 1 > /proc/sys/kernel/nmi_watchdog\n"); 1760 + 1761 + if (print_mixed_hw_group_error) 1762 + fprintf(output, 1763 + "The events in group usually have to be from " 1764 + "the same PMU. Try reorganizing the group.\n"); 1791 1765 } 1792 1766 1793 1767 static void print_counters(struct timespec *ts, int argc, const char **argv)
+5 -5
tools/perf/pmu-events/arch/s390/mapfile.csv
··· 1 1 Family-model,Version,Filename,EventType 2 - 209[78],1,cf_z10,core 3 - 281[78],1,cf_z196,core 4 - 282[78],1,cf_zec12,core 5 - 296[45],1,cf_z13,core 6 - 3906,3,cf_z14,core 2 + ^IBM.209[78].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_z10,core 3 + ^IBM.281[78].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_z196,core 4 + ^IBM.282[78].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_zec12,core 5 + ^IBM.296[45].*[13]\.[1-5].[[:xdigit:]]+$,1,cf_z13,core 6 + ^IBM.390[67].*[13]\.[1-5].[[:xdigit:]]+$,3,cf_z14,core
+3
tools/perf/tests/attr/test-record-group-sampling
··· 35 35 # sampling disabled 36 36 sample_freq=0 37 37 sample_period=0 38 + freq=0 39 + write_backward=0 40 + sample_id_all=0
+2 -4
tools/perf/tests/shell/record+probe_libc_inet_pton.sh
··· 19 19 expected[1]=".*inet_pton[[:space:]]\($libc\)$" 20 20 case "$(uname -m)" in 21 21 s390x) 22 - eventattr='call-graph=dwarf' 22 + eventattr='call-graph=dwarf,max-stack=4' 23 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 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 28 eventattr='max-stack=3'
+14 -4
tools/perf/util/evsel.c
··· 930 930 * than leader in case leader 'leads' the sampling. 931 931 */ 932 932 if ((leader != evsel) && leader->sample_read) { 933 - attr->sample_freq = 0; 934 - attr->sample_period = 0; 933 + attr->freq = 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 940 if (opts->no_samples) ··· 1925 1922 goto fallback_missing_features; 1926 1923 } else if (!perf_missing_features.group_read && 1927 1924 evsel->attr.inherit && 1928 - (evsel->attr.read_format & PERF_FORMAT_GROUP)) { 1925 + (evsel->attr.read_format & PERF_FORMAT_GROUP) && 1926 + perf_evsel__is_group_leader(evsel)) { 1929 1927 perf_missing_features.group_read = true; 1930 1928 pr_debug2("switching off group read\n"); 1931 1929 goto fallback_missing_features; ··· 2758 2754 (paranoid = perf_event_paranoid()) > 1) { 2759 2755 const char *name = perf_evsel__name(evsel); 2760 2756 char *new_name; 2757 + const char *sep = ":"; 2761 2758 2762 - if (asprintf(&new_name, "%s%su", name, strchr(name, ':') ? "" : ":") < 0) 2759 + /* Is there already the separator in the name. */ 2760 + if (strchr(name, '/') || 2761 + strchr(name, ':')) 2762 + sep = ""; 2763 + 2764 + if (asprintf(&new_name, "%s%su", name, sep) < 0) 2763 2765 return false; 2764 2766 2765 2767 if (evsel->name)
+1
tools/perf/util/evsel.h
··· 115 115 unsigned int sample_size; 116 116 int id_pos; 117 117 int is_pos; 118 + bool uniquified_name; 118 119 bool snapshot; 119 120 bool supported; 120 121 bool needs_swap;
+18 -12
tools/perf/util/machine.c
··· 1019 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 1022 static char *get_kernel_version(const char *root_dir) 1030 1023 { 1031 1024 char version[PATH_MAX]; ··· 1226 1233 { 1227 1234 struct dso *kernel = machine__get_kernel(machine); 1228 1235 const char *name = NULL; 1236 + struct map *map; 1229 1237 u64 addr = 0; 1230 1238 int ret; 1231 1239 ··· 1253 1259 machine__destroy_kernel_maps(machine); 1254 1260 return -1; 1255 1261 } 1256 - machine__set_kernel_mmap(machine, addr, 0); 1262 + 1263 + /* we have a real start address now, so re-order the kmaps */ 1264 + map = machine__kernel_map(machine); 1265 + 1266 + map__get(map); 1267 + map_groups__remove(&machine->kmaps, map); 1268 + 1269 + /* assume it's the last in the kmaps */ 1270 + machine__set_kernel_mmap(machine, addr, ~0ULL); 1271 + 1272 + map_groups__insert(&machine->kmaps, map); 1273 + map__put(map); 1257 1274 } 1258 1275 1259 - /* 1260 - * Now that we have all the maps created, just set the ->end of them: 1261 - */ 1262 - map_groups__fixup_end(&machine->kmaps); 1276 + /* update end address of the kernel map using adjacent module address */ 1277 + map = map__next(machine__kernel_map(machine)); 1278 + if (map) 1279 + machine__set_kernel_mmap(machine, addr, map->start); 1280 + 1263 1281 return 0; 1264 1282 } 1265 1283
+4 -4
tools/perf/util/parse-events.y
··· 224 224 event_bpf_file 225 225 226 226 event_pmu: 227 - PE_NAME opt_event_config 227 + PE_NAME '/' event_config '/' 228 228 { 229 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 232 YYABORT; 233 233 234 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 236 struct perf_pmu *pmu = NULL; 237 237 int ok = 0; 238 238 char *pattern; ··· 262 262 if (!ok) 263 263 YYABORT; 264 264 } 265 - parse_events_terms__delete($2); 265 + parse_events_terms__delete($3); 266 266 parse_events_terms__delete(orig_terms); 267 267 $$ = list; 268 268 }
+8 -14
tools/perf/util/pmu.c
··· 539 539 540 540 /* 541 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 547 struct stat st; 547 548 char path[PATH_MAX]; ··· 550 549 551 550 if (!sysfs) 552 551 return 0; 553 - 554 - /* Look for cpu sysfs (x86 and others) */ 555 - scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/cpu", sysfs); 556 - if ((stat(path, &st) == 0) && 557 - (strncmp(name, "cpu", strlen("cpu")) == 0)) 558 - return 1; 559 552 560 553 /* Look for cpu sysfs (specific to arm) */ 561 554 scnprintf(path, PATH_MAX, "%s/bus/event_source/devices/%s/cpus", ··· 581 586 * cpuid string generated on this platform. 582 587 * Otherwise return non-zero. 583 588 */ 584 - int __weak strcmp_cpuid_str(const char *mapcpuid, const char *cpuid) 589 + int strcmp_cpuid_str(const char *mapcpuid, const char *cpuid) 585 590 { 586 591 regex_t re; 587 592 regmatch_t pmatch[1]; ··· 663 668 struct pmu_events_map *map; 664 669 struct pmu_event *pe; 665 670 const char *name = pmu->name; 671 + const char *pname; 666 672 667 673 map = perf_pmu__find_map(pmu); 668 674 if (!map) ··· 682 686 break; 683 687 } 684 688 685 - if (!is_pmu_core(name)) { 686 - /* check for uncore devices */ 687 - if (pe->pmu == NULL) 688 - continue; 689 - if (strncmp(pe->pmu, name, strlen(pe->pmu))) 689 + if (!is_arm_pmu_core(name)) { 690 + pname = pe->pmu ? pe->pmu : "cpu"; 691 + if (strncmp(pname, name, strlen(pname))) 690 692 continue; 691 693 } 692 694