Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull perf fixes from Ingo Molnar:
"Tooling fixes mostly, plus a build warning fix"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (21 commits)
perf/core: Move inline keyword at the beginning of declaration
tools/headers: Pick up latest kernel ABIs
perf tools: Fix crash caused by accessing feat_ops[HEADER_LAST_FEATURE]
perf script: Fix crash because of missing evsel->priv
perf script: Add missing output fields in a hint
perf bench: Fix numa report output code
perf stat: Remove duplicate event counting
perf alias: Rebuild alias expression string to make it comparable
perf alias: Remove trailing newline when reading sysfs files
perf tools: Fix a clang 7.0 compilation error
tools include uapi: Synchronize bpf.h with the kernel
tools include uapi: Update if_link.h to pick IFLA_{BRPORT_ISOLATED,VXLAN_TTL_INHERIT}
tools include powerpc: Update arch/powerpc/include/uapi/asm/unistd.h copy to get 'rseq' syscall
perf tools: Update x86's syscall_64.tbl, adding 'io_pgetevents' and 'rseq'
tools headers uapi: Synchronize drm/drm.h
perf intel-pt: Fix packet decoding of CYC packets
perf tests: Add valid callback for parse-events test
perf tests: Add event parsing error handling to parse events test
perf report powerpc: Fix crash if callchain is empty
perf test session topology: Fix test on s390
...

+201 -22
+1 -1
kernel/events/core.c
··· 6482 6482 data->phys_addr = perf_virt_to_phys(data->addr); 6483 6483 } 6484 6484 6485 - static void __always_inline 6485 + static __always_inline void 6486 6486 __perf_event_output(struct perf_event *event, 6487 6487 struct perf_sample_data *data, 6488 6488 struct pt_regs *regs,
+1
tools/arch/arm/include/uapi/asm/kvm.h
··· 91 91 #define KVM_VGIC_V3_ADDR_TYPE_DIST 2 92 92 #define KVM_VGIC_V3_ADDR_TYPE_REDIST 3 93 93 #define KVM_VGIC_ITS_ADDR_TYPE 4 94 + #define KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION 5 94 95 95 96 #define KVM_VGIC_V3_DIST_SIZE SZ_64K 96 97 #define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
+1
tools/arch/arm64/include/uapi/asm/kvm.h
··· 91 91 #define KVM_VGIC_V3_ADDR_TYPE_DIST 2 92 92 #define KVM_VGIC_V3_ADDR_TYPE_REDIST 3 93 93 #define KVM_VGIC_ITS_ADDR_TYPE 4 94 + #define KVM_VGIC_V3_ADDR_TYPE_REDIST_REGION 5 94 95 95 96 #define KVM_VGIC_V3_DIST_SIZE SZ_64K 96 97 #define KVM_VGIC_V3_REDIST_SIZE (2 * SZ_64K)
+1
tools/arch/powerpc/include/uapi/asm/kvm.h
··· 633 633 #define KVM_REG_PPC_PSSCR (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbd) 634 634 635 635 #define KVM_REG_PPC_DEC_EXPIRY (KVM_REG_PPC | KVM_REG_SIZE_U64 | 0xbe) 636 + #define KVM_REG_PPC_ONLINE (KVM_REG_PPC | KVM_REG_SIZE_U32 | 0xbf) 636 637 637 638 /* Transactional Memory checkpointed state: 638 639 * This is all GPRs, all VSX regs and a subset of SPRs
+1
tools/arch/powerpc/include/uapi/asm/unistd.h
··· 398 398 #define __NR_pkey_alloc 384 399 399 #define __NR_pkey_free 385 400 400 #define __NR_pkey_mprotect 386 401 + #define __NR_rseq 387 401 402 402 403 #endif /* _UAPI_ASM_POWERPC_UNISTD_H_ */
+2
tools/arch/x86/include/asm/cpufeatures.h
··· 282 282 #define X86_FEATURE_AMD_IBPB (13*32+12) /* "" Indirect Branch Prediction Barrier */ 283 283 #define X86_FEATURE_AMD_IBRS (13*32+14) /* "" Indirect Branch Restricted Speculation */ 284 284 #define X86_FEATURE_AMD_STIBP (13*32+15) /* "" Single Thread Indirect Branch Predictors */ 285 + #define X86_FEATURE_AMD_SSBD (13*32+24) /* "" Speculative Store Bypass Disable */ 285 286 #define X86_FEATURE_VIRT_SSBD (13*32+25) /* Virtualized Speculative Store Bypass Disable */ 287 + #define X86_FEATURE_AMD_SSB_NO (13*32+26) /* "" Speculative Store Bypass is fixed in hardware. */ 286 288 287 289 /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */ 288 290 #define X86_FEATURE_DTHERM (14*32+ 0) /* Digital Thermal Sensor */
+7
tools/include/uapi/drm/drm.h
··· 680 680 */ 681 681 #define DRM_CLIENT_CAP_ATOMIC 3 682 682 683 + /** 684 + * DRM_CLIENT_CAP_ASPECT_RATIO 685 + * 686 + * If set to 1, the DRM core will provide aspect ratio information in modes. 687 + */ 688 + #define DRM_CLIENT_CAP_ASPECT_RATIO 4 689 + 683 690 /** DRM_IOCTL_SET_CLIENT_CAP ioctl argument type */ 684 691 struct drm_set_client_cap { 685 692 __u64 capability;
+1 -1
tools/include/uapi/linux/bpf.h
··· 2630 2630 union { 2631 2631 /* inputs to lookup */ 2632 2632 __u8 tos; /* AF_INET */ 2633 - __be32 flowlabel; /* AF_INET6 */ 2633 + __be32 flowinfo; /* AF_INET6, flow_label + priority */ 2634 2634 2635 2635 /* output: metric of fib result (IPv4/IPv6 only) */ 2636 2636 __u32 rt_metric;
+2
tools/include/uapi/linux/if_link.h
··· 333 333 IFLA_BRPORT_BCAST_FLOOD, 334 334 IFLA_BRPORT_GROUP_FWD_MASK, 335 335 IFLA_BRPORT_NEIGH_SUPPRESS, 336 + IFLA_BRPORT_ISOLATED, 336 337 __IFLA_BRPORT_MAX 337 338 }; 338 339 #define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1) ··· 517 516 IFLA_VXLAN_COLLECT_METADATA, 518 517 IFLA_VXLAN_LABEL, 519 518 IFLA_VXLAN_GPE, 519 + IFLA_VXLAN_TTL_INHERIT, 520 520 __IFLA_VXLAN_MAX 521 521 }; 522 522 #define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
+1
tools/include/uapi/linux/kvm.h
··· 948 948 #define KVM_CAP_S390_BPB 152 949 949 #define KVM_CAP_GET_MSR_FEATURES 153 950 950 #define KVM_CAP_HYPERV_EVENTFD 154 951 + #define KVM_CAP_HYPERV_TLBFLUSH 155 951 952 952 953 #ifdef KVM_CAP_IRQ_ROUTING 953 954
+1 -1
tools/perf/arch/powerpc/util/skip-callchain-idx.c
··· 243 243 u64 ip; 244 244 u64 skip_slot = -1; 245 245 246 - if (chain->nr < 3) 246 + if (!chain || chain->nr < 3) 247 247 return skip_slot; 248 248 249 249 ip = chain->ips[2];
+2
tools/perf/arch/x86/entry/syscalls/syscall_64.tbl
··· 341 341 330 common pkey_alloc __x64_sys_pkey_alloc 342 342 331 common pkey_free __x64_sys_pkey_free 343 343 332 common statx __x64_sys_statx 344 + 333 common io_pgetevents __x64_sys_io_pgetevents 345 + 334 common rseq __x64_sys_rseq 344 346 345 347 # 346 348 # x32-specific system call numbers start at 512 to avoid cache impact
+3 -2
tools/perf/bench/numa.c
··· 1098 1098 u8 *global_data; 1099 1099 u8 *process_data; 1100 1100 u8 *thread_data; 1101 - u64 bytes_done; 1101 + u64 bytes_done, secs; 1102 1102 long work_done; 1103 1103 u32 l; 1104 1104 struct rusage rusage; ··· 1254 1254 timersub(&stop, &start0, &diff); 1255 1255 td->runtime_ns = diff.tv_sec * NSEC_PER_SEC; 1256 1256 td->runtime_ns += diff.tv_usec * NSEC_PER_USEC; 1257 - td->speed_gbs = bytes_done / (td->runtime_ns / NSEC_PER_SEC) / 1e9; 1257 + secs = td->runtime_ns / NSEC_PER_SEC; 1258 + td->speed_gbs = secs ? bytes_done / secs / 1e9 : 0; 1258 1259 1259 1260 getrusage(RUSAGE_THREAD, &rusage); 1260 1261 td->system_time_ns = rusage.ru_stime.tv_sec * NSEC_PER_SEC;
+10 -1
tools/perf/builtin-annotate.c
··· 283 283 return ret; 284 284 } 285 285 286 + static int process_feature_event(struct perf_tool *tool, 287 + union perf_event *event, 288 + struct perf_session *session) 289 + { 290 + if (event->feat.feat_id < HEADER_LAST_FEATURE) 291 + return perf_event__process_feature(tool, event, session); 292 + return 0; 293 + } 294 + 286 295 static int hist_entry__tty_annotate(struct hist_entry *he, 287 296 struct perf_evsel *evsel, 288 297 struct perf_annotate *ann) ··· 480 471 .attr = perf_event__process_attr, 481 472 .build_id = perf_event__process_build_id, 482 473 .tracing_data = perf_event__process_tracing_data, 483 - .feature = perf_event__process_feature, 474 + .feature = process_feature_event, 484 475 .ordered_events = true, 485 476 .ordering_requires_timestamps = true, 486 477 },
+2 -1
tools/perf/builtin-report.c
··· 217 217 } 218 218 219 219 /* 220 - * All features are received, we can force the 220 + * (feat_id = HEADER_LAST_FEATURE) is the end marker which 221 + * means all features are received, now we can force the 221 222 * group if needed. 222 223 */ 223 224 setup_forced_leader(rep, session->evlist);
+27 -3
tools/perf/builtin-script.c
··· 1834 1834 struct perf_evlist *evlist; 1835 1835 struct perf_evsel *evsel, *pos; 1836 1836 int err; 1837 + static struct perf_evsel_script *es; 1837 1838 1838 1839 err = perf_event__process_attr(tool, event, pevlist); 1839 1840 if (err) ··· 1842 1841 1843 1842 evlist = *pevlist; 1844 1843 evsel = perf_evlist__last(*pevlist); 1844 + 1845 + if (!evsel->priv) { 1846 + if (scr->per_event_dump) { 1847 + evsel->priv = perf_evsel_script__new(evsel, 1848 + scr->session->data); 1849 + } else { 1850 + es = zalloc(sizeof(*es)); 1851 + if (!es) 1852 + return -ENOMEM; 1853 + es->fp = stdout; 1854 + evsel->priv = es; 1855 + } 1856 + } 1845 1857 1846 1858 if (evsel->attr.type >= PERF_TYPE_MAX && 1847 1859 evsel->attr.type != PERF_TYPE_SYNTH) ··· 3044 3030 return set_maps(script); 3045 3031 } 3046 3032 3033 + static int process_feature_event(struct perf_tool *tool, 3034 + union perf_event *event, 3035 + struct perf_session *session) 3036 + { 3037 + if (event->feat.feat_id < HEADER_LAST_FEATURE) 3038 + return perf_event__process_feature(tool, event, session); 3039 + return 0; 3040 + } 3041 + 3047 3042 #ifdef HAVE_AUXTRACE_SUPPORT 3048 3043 static int perf_script__process_auxtrace_info(struct perf_tool *tool, 3049 3044 union perf_event *event, ··· 3097 3074 .attr = process_attr, 3098 3075 .event_update = perf_event__process_event_update, 3099 3076 .tracing_data = perf_event__process_tracing_data, 3100 - .feature = perf_event__process_feature, 3077 + .feature = process_feature_event, 3101 3078 .build_id = perf_event__process_build_id, 3102 3079 .id_index = perf_event__process_id_index, 3103 3080 .auxtrace_info = perf_script__process_auxtrace_info, ··· 3148 3125 "+field to add and -field to remove." 3149 3126 "Valid types: hw,sw,trace,raw,synth. " 3150 3127 "Fields: comm,tid,pid,time,cpu,event,trace,ip,sym,dso," 3151 - "addr,symoff,period,iregs,uregs,brstack,brstacksym,flags," 3152 - "bpf-output,callindent,insn,insnlen,brstackinsn,synth,phys_addr", 3128 + "addr,symoff,srcline,period,iregs,uregs,brstack," 3129 + "brstacksym,flags,bpf-output,brstackinsn,brstackoff," 3130 + "callindent,insn,insnlen,synth,phys_addr,metric,misc", 3153 3131 parse_output_fields), 3154 3132 OPT_BOOLEAN('a', "all-cpus", &system_wide, 3155 3133 "system-wide collection from all CPUs"),
+20 -5
tools/perf/tests/parse-events.c
··· 1309 1309 return 0; 1310 1310 } 1311 1311 1312 + static bool test__intel_pt_valid(void) 1313 + { 1314 + return !!perf_pmu__find("intel_pt"); 1315 + } 1316 + 1312 1317 static int test__intel_pt(struct perf_evlist *evlist) 1313 1318 { 1314 1319 struct perf_evsel *evsel = perf_evlist__first(evlist); ··· 1380 1375 const char *name; 1381 1376 __u32 type; 1382 1377 const int id; 1378 + bool (*valid)(void); 1383 1379 int (*check)(struct perf_evlist *evlist); 1384 1380 }; 1385 1381 ··· 1654 1648 }, 1655 1649 { 1656 1650 .name = "intel_pt//u", 1651 + .valid = test__intel_pt_valid, 1657 1652 .check = test__intel_pt, 1658 1653 .id = 52, 1659 1654 }, ··· 1693 1686 1694 1687 static int test_event(struct evlist_test *e) 1695 1688 { 1689 + struct parse_events_error err = { .idx = 0, }; 1696 1690 struct perf_evlist *evlist; 1697 1691 int ret; 1692 + 1693 + if (e->valid && !e->valid()) { 1694 + pr_debug("... SKIP"); 1695 + return 0; 1696 + } 1698 1697 1699 1698 evlist = perf_evlist__new(); 1700 1699 if (evlist == NULL) 1701 1700 return -ENOMEM; 1702 1701 1703 - ret = parse_events(evlist, e->name, NULL); 1702 + ret = parse_events(evlist, e->name, &err); 1704 1703 if (ret) { 1705 - pr_debug("failed to parse event '%s', err %d\n", 1706 - e->name, ret); 1704 + pr_debug("failed to parse event '%s', err %d, str '%s'\n", 1705 + e->name, ret, err.str); 1706 + parse_events_print_error(&err, e->name); 1707 1707 } else { 1708 1708 ret = e->check(evlist); 1709 1709 } ··· 1728 1714 for (i = 0; i < cnt; i++) { 1729 1715 struct evlist_test *e = &events[i]; 1730 1716 1731 - pr_debug("running test %d '%s'\n", e->id, e->name); 1717 + pr_debug("running test %d '%s'", e->id, e->name); 1732 1718 ret1 = test_event(e); 1733 1719 if (ret1) 1734 1720 ret2 = ret1; 1721 + pr_debug("\n"); 1735 1722 } 1736 1723 1737 1724 return ret2; ··· 1814 1799 } 1815 1800 1816 1801 while (!ret && (ent = readdir(dir))) { 1817 - struct evlist_test e; 1802 + struct evlist_test e = { .id = 0, }; 1818 1803 char name[2 * NAME_MAX + 1 + 12 + 3]; 1819 1804 1820 1805 /* Names containing . are special and cannot be used directly */
+1
tools/perf/tests/topology.c
··· 45 45 46 46 perf_header__set_feat(&session->header, HEADER_CPU_TOPOLOGY); 47 47 perf_header__set_feat(&session->header, HEADER_NRCPUS); 48 + perf_header__set_feat(&session->header, HEADER_ARCH); 48 49 49 50 session->header.data_size += DATA_SIZE; 50 51
+9 -2
tools/perf/util/c++/clang.cpp
··· 146 146 raw_svector_ostream ostream(*Buffer); 147 147 148 148 legacy::PassManager PM; 149 - if (TargetMachine->addPassesToEmitFile(PM, ostream, 150 - TargetMachine::CGFT_ObjectFile)) { 149 + bool NotAdded; 150 + #if CLANG_VERSION_MAJOR < 7 151 + NotAdded = TargetMachine->addPassesToEmitFile(PM, ostream, 152 + TargetMachine::CGFT_ObjectFile); 153 + #else 154 + NotAdded = TargetMachine->addPassesToEmitFile(PM, ostream, nullptr, 155 + TargetMachine::CGFT_ObjectFile); 156 + #endif 157 + if (NotAdded) { 151 158 llvm::errs() << "TargetMachine can't emit a file of this type\n"; 152 159 return std::unique_ptr<llvm::SmallVectorImpl<char>>(nullptr);; 153 160 }
+10 -2
tools/perf/util/header.c
··· 2129 2129 int cpu_nr = ff->ph->env.nr_cpus_avail; 2130 2130 u64 size = 0; 2131 2131 struct perf_header *ph = ff->ph; 2132 + bool do_core_id_test = true; 2132 2133 2133 2134 ph->env.cpu = calloc(cpu_nr, sizeof(*ph->env.cpu)); 2134 2135 if (!ph->env.cpu) ··· 2184 2183 return 0; 2185 2184 } 2186 2185 2186 + /* On s390 the socket_id number is not related to the numbers of cpus. 2187 + * The socket_id number might be higher than the numbers of cpus. 2188 + * This depends on the configuration. 2189 + */ 2190 + if (ph->env.arch && !strncmp(ph->env.arch, "s390", 4)) 2191 + do_core_id_test = false; 2192 + 2187 2193 for (i = 0; i < (u32)cpu_nr; i++) { 2188 2194 if (do_read_u32(ff, &nr)) 2189 2195 goto free_cpu; ··· 2200 2192 if (do_read_u32(ff, &nr)) 2201 2193 goto free_cpu; 2202 2194 2203 - if (nr != (u32)-1 && nr > (u32)cpu_nr) { 2195 + if (do_core_id_test && nr != (u32)-1 && nr > (u32)cpu_nr) { 2204 2196 pr_debug("socket_id number is too big." 2205 2197 "You may need to upgrade the perf tool.\n"); 2206 2198 goto free_cpu; ··· 3464 3456 pr_warning("invalid record type %d in pipe-mode\n", type); 3465 3457 return 0; 3466 3458 } 3467 - if (feat == HEADER_RESERVED || feat > HEADER_LAST_FEATURE) { 3459 + if (feat == HEADER_RESERVED || feat >= HEADER_LAST_FEATURE) { 3468 3460 pr_warning("invalid record type %d in pipe-mode\n", type); 3469 3461 return -1; 3470 3462 }
+1 -1
tools/perf/util/intel-pt-decoder/intel-pt-pkt-decoder.c
··· 366 366 if (len < offs) 367 367 return INTEL_PT_NEED_MORE_BYTES; 368 368 byte = buf[offs++]; 369 - payload |= (byte >> 1) << shift; 369 + payload |= ((uint64_t)byte >> 1) << shift; 370 370 } 371 371 372 372 packet->type = INTEL_PT_CYC;
+97 -2
tools/perf/util/pmu.c
··· 234 234 return 0; 235 235 } 236 236 237 + static void perf_pmu_assign_str(char *name, const char *field, char **old_str, 238 + char **new_str) 239 + { 240 + if (!*old_str) 241 + goto set_new; 242 + 243 + if (*new_str) { /* Have new string, check with old */ 244 + if (strcasecmp(*old_str, *new_str)) 245 + pr_debug("alias %s differs in field '%s'\n", 246 + name, field); 247 + zfree(old_str); 248 + } else /* Nothing new --> keep old string */ 249 + return; 250 + set_new: 251 + *old_str = *new_str; 252 + *new_str = NULL; 253 + } 254 + 255 + static void perf_pmu_update_alias(struct perf_pmu_alias *old, 256 + struct perf_pmu_alias *newalias) 257 + { 258 + perf_pmu_assign_str(old->name, "desc", &old->desc, &newalias->desc); 259 + perf_pmu_assign_str(old->name, "long_desc", &old->long_desc, 260 + &newalias->long_desc); 261 + perf_pmu_assign_str(old->name, "topic", &old->topic, &newalias->topic); 262 + perf_pmu_assign_str(old->name, "metric_expr", &old->metric_expr, 263 + &newalias->metric_expr); 264 + perf_pmu_assign_str(old->name, "metric_name", &old->metric_name, 265 + &newalias->metric_name); 266 + perf_pmu_assign_str(old->name, "value", &old->str, &newalias->str); 267 + old->scale = newalias->scale; 268 + old->per_pkg = newalias->per_pkg; 269 + old->snapshot = newalias->snapshot; 270 + memcpy(old->unit, newalias->unit, sizeof(old->unit)); 271 + } 272 + 273 + /* Delete an alias entry. */ 274 + static void perf_pmu_free_alias(struct perf_pmu_alias *newalias) 275 + { 276 + zfree(&newalias->name); 277 + zfree(&newalias->desc); 278 + zfree(&newalias->long_desc); 279 + zfree(&newalias->topic); 280 + zfree(&newalias->str); 281 + zfree(&newalias->metric_expr); 282 + zfree(&newalias->metric_name); 283 + parse_events_terms__purge(&newalias->terms); 284 + free(newalias); 285 + } 286 + 287 + /* Merge an alias, search in alias list. If this name is already 288 + * present merge both of them to combine all information. 289 + */ 290 + static bool perf_pmu_merge_alias(struct perf_pmu_alias *newalias, 291 + struct list_head *alist) 292 + { 293 + struct perf_pmu_alias *a; 294 + 295 + list_for_each_entry(a, alist, list) { 296 + if (!strcasecmp(newalias->name, a->name)) { 297 + perf_pmu_update_alias(a, newalias); 298 + perf_pmu_free_alias(newalias); 299 + return true; 300 + } 301 + } 302 + return false; 303 + } 304 + 237 305 static int __perf_pmu__new_alias(struct list_head *list, char *dir, char *name, 238 306 char *desc, char *val, 239 307 char *long_desc, char *topic, ··· 309 241 char *metric_expr, 310 242 char *metric_name) 311 243 { 244 + struct parse_events_term *term; 312 245 struct perf_pmu_alias *alias; 313 246 int ret; 314 247 int num; 248 + char newval[256]; 315 249 316 250 alias = malloc(sizeof(*alias)); 317 251 if (!alias) ··· 330 260 pr_err("Cannot parse alias %s: %d\n", val, ret); 331 261 free(alias); 332 262 return ret; 263 + } 264 + 265 + /* Scan event and remove leading zeroes, spaces, newlines, some 266 + * platforms have terms specified as 267 + * event=0x0091 (read from files ../<PMU>/events/<FILE> 268 + * and terms specified as event=0x91 (read from JSON files). 269 + * 270 + * Rebuild string to make alias->str member comparable. 271 + */ 272 + memset(newval, 0, sizeof(newval)); 273 + ret = 0; 274 + list_for_each_entry(term, &alias->terms, list) { 275 + if (ret) 276 + ret += scnprintf(newval + ret, sizeof(newval) - ret, 277 + ","); 278 + if (term->type_val == PARSE_EVENTS__TERM_TYPE_NUM) 279 + ret += scnprintf(newval + ret, sizeof(newval) - ret, 280 + "%s=%#x", term->config, term->val.num); 281 + else if (term->type_val == PARSE_EVENTS__TERM_TYPE_STR) 282 + ret += scnprintf(newval + ret, sizeof(newval) - ret, 283 + "%s=%s", term->config, term->val.str); 333 284 } 334 285 335 286 alias->name = strdup(name); ··· 376 285 snprintf(alias->unit, sizeof(alias->unit), "%s", unit); 377 286 } 378 287 alias->per_pkg = perpkg && sscanf(perpkg, "%d", &num) == 1 && num == 1; 379 - alias->str = strdup(val); 288 + alias->str = strdup(newval); 380 289 381 - list_add_tail(&alias->list, list); 290 + if (!perf_pmu_merge_alias(alias, list)) 291 + list_add_tail(&alias->list, list); 382 292 383 293 return 0; 384 294 } ··· 394 302 return -EINVAL; 395 303 396 304 buf[ret] = 0; 305 + 306 + /* Remove trailing newline from sysfs file */ 307 + rtrim(buf); 397 308 398 309 return __perf_pmu__new_alias(list, dir, name, NULL, buf, NULL, NULL, NULL, 399 310 NULL, NULL, NULL);