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

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

Pull perf fixes from Ingo Molnar:
"This tree contains various perf fixes on the kernel side, plus three
hw/event-enablement late additions:

- Intel Memory Bandwidth Monitoring events and handling
- the AMD Accumulated Power Mechanism reporting facility
- more IOMMU events

... and a final round of perf tooling updates/fixes"

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: (44 commits)
perf llvm: Use strerror_r instead of the thread unsafe strerror one
perf llvm: Use realpath to canonicalize paths
perf tools: Unexport some methods unused outside strbuf.c
perf probe: No need to use formatting strbuf method
perf help: Use asprintf instead of adhoc equivalents
perf tools: Remove unused perf_pathdup, xstrdup functions
perf tools: Do not include stringify.h from the kernel sources
tools include: Copy linux/stringify.h from the kernel
tools lib traceevent: Remove redundant CPU output
perf tools: Remove needless 'extern' from function prototypes
perf tools: Simplify die() mechanism
perf tools: Remove unused DIE_IF macro
perf script: Remove lots of unused arguments
perf thread: Rename perf_event__preprocess_sample_addr to thread__resolve
perf machine: Rename perf_event__preprocess_sample to machine__resolve
perf tools: Add cpumode to struct perf_sample
perf tests: Forward the perf_sample in the dwarf unwind test
perf tools: Remove misplaced __maybe_unused
perf list: Fix documentation of :ppp
perf bench numa: Fix assertion for nodes bitfield
...

+1330 -628
+9
arch/x86/Kconfig
··· 1210 1210 def_bool y 1211 1211 depends on MICROCODE 1212 1212 1213 + config PERF_EVENTS_AMD_POWER 1214 + depends on PERF_EVENTS && CPU_SUP_AMD 1215 + tristate "AMD Processor Power Reporting Mechanism" 1216 + ---help--- 1217 + Provide power reporting mechanism support for AMD processors. 1218 + Currently, it leverages X86_FEATURE_ACC_POWER 1219 + (CPUID Fn8000_0007_EDX[12]) interface to calculate the 1220 + average power consumption on Family 15h processors. 1221 + 1213 1222 config X86_MSR 1214 1223 tristate "/dev/cpu/*/msr - Model-specific register support" 1215 1224 ---help---
+1
arch/x86/events/Makefile
··· 1 1 obj-y += core.o 2 2 3 3 obj-$(CONFIG_CPU_SUP_AMD) += amd/core.o amd/uncore.o 4 + obj-$(CONFIG_PERF_EVENTS_AMD_POWER) += amd/power.o 4 5 obj-$(CONFIG_X86_LOCAL_APIC) += amd/ibs.o msr.o 5 6 ifdef CONFIG_AMD_IOMMU 6 7 obj-$(CONFIG_CPU_SUP_AMD) += amd/iommu.o
+33 -4
arch/x86/events/amd/ibs.c
··· 376 376 hwc->state = 0; 377 377 378 378 perf_ibs_set_period(perf_ibs, hwc, &period); 379 + /* 380 + * Set STARTED before enabling the hardware, such that 381 + * a subsequent NMI must observe it. Then clear STOPPING 382 + * such that we don't consume NMIs by accident. 383 + */ 379 384 set_bit(IBS_STARTED, pcpu->state); 385 + clear_bit(IBS_STOPPING, pcpu->state); 380 386 perf_ibs_enable_event(perf_ibs, hwc, period >> 4); 381 387 382 388 perf_event_update_userpage(event); ··· 396 390 u64 config; 397 391 int stopping; 398 392 399 - stopping = test_and_clear_bit(IBS_STARTED, pcpu->state); 393 + stopping = test_bit(IBS_STARTED, pcpu->state); 400 394 401 395 if (!stopping && (hwc->state & PERF_HES_UPTODATE)) 402 396 return; ··· 404 398 rdmsrl(hwc->config_base, config); 405 399 406 400 if (stopping) { 401 + /* 402 + * Set STOPPING before disabling the hardware, such that it 403 + * must be visible to NMIs the moment we clear the EN bit, 404 + * at which point we can generate an !VALID sample which 405 + * we need to consume. 406 + */ 407 407 set_bit(IBS_STOPPING, pcpu->state); 408 408 perf_ibs_disable_event(perf_ibs, hwc, config); 409 + /* 410 + * Clear STARTED after disabling the hardware; if it were 411 + * cleared before an NMI hitting after the clear but before 412 + * clearing the EN bit might think it a spurious NMI and not 413 + * handle it. 414 + * 415 + * Clearing it after, however, creates the problem of the NMI 416 + * handler seeing STARTED but not having a valid sample. 417 + */ 418 + clear_bit(IBS_STARTED, pcpu->state); 409 419 WARN_ON_ONCE(hwc->state & PERF_HES_STOPPED); 410 420 hwc->state |= PERF_HES_STOPPED; 411 421 } ··· 549 527 u64 *buf, *config, period; 550 528 551 529 if (!test_bit(IBS_STARTED, pcpu->state)) { 530 + fail: 552 531 /* 553 532 * Catch spurious interrupts after stopping IBS: After 554 533 * disabling IBS there could be still incoming NMIs 555 534 * with samples that even have the valid bit cleared. 556 535 * Mark all this NMIs as handled. 557 536 */ 558 - return test_and_clear_bit(IBS_STOPPING, pcpu->state) ? 1 : 0; 537 + if (test_and_clear_bit(IBS_STOPPING, pcpu->state)) 538 + return 1; 539 + 540 + return 0; 559 541 } 560 542 561 543 msr = hwc->config_base; 562 544 buf = ibs_data.regs; 563 545 rdmsrl(msr, *buf); 564 546 if (!(*buf++ & perf_ibs->valid_mask)) 565 - return 0; 547 + goto fail; 566 548 567 549 config = &ibs_data.regs[0]; 568 550 perf_ibs_event_update(perf_ibs, event, config); ··· 625 599 throttle = perf_event_overflow(event, &data, &regs); 626 600 out: 627 601 if (throttle) 628 - perf_ibs_disable_event(perf_ibs, hwc, *config); 602 + perf_ibs_stop(event, 0); 629 603 else 630 604 perf_ibs_enable_event(perf_ibs, hwc, period >> 4); 631 605 ··· 637 611 static int 638 612 perf_ibs_nmi_handler(unsigned int cmd, struct pt_regs *regs) 639 613 { 614 + u64 stamp = sched_clock(); 640 615 int handled = 0; 641 616 642 617 handled += perf_ibs_handle_irq(&perf_ibs_fetch, regs); ··· 645 618 646 619 if (handled) 647 620 inc_irq_stat(apic_perf_irqs); 621 + 622 + perf_sample_event_took(sched_clock() - stamp); 648 623 649 624 return handled; 650 625 }
+5
arch/x86/events/amd/iommu.c
··· 118 118 AMD_IOMMU_EVENT_DESC(cmd_processed, "csource=0x11"), 119 119 AMD_IOMMU_EVENT_DESC(cmd_processed_inv, "csource=0x12"), 120 120 AMD_IOMMU_EVENT_DESC(tlb_inv, "csource=0x13"), 121 + AMD_IOMMU_EVENT_DESC(ign_rd_wr_mmio_1ff8h, "csource=0x14"), 122 + AMD_IOMMU_EVENT_DESC(vapic_int_non_guest, "csource=0x15"), 123 + AMD_IOMMU_EVENT_DESC(vapic_int_guest, "csource=0x16"), 124 + AMD_IOMMU_EVENT_DESC(smi_recv, "csource=0x17"), 125 + AMD_IOMMU_EVENT_DESC(smi_blk, "csource=0x18"), 121 126 { /* end: all zeroes */ }, 122 127 }; 123 128
+353
arch/x86/events/amd/power.c
··· 1 + /* 2 + * Performance events - AMD Processor Power Reporting Mechanism 3 + * 4 + * Copyright (C) 2016 Advanced Micro Devices, Inc. 5 + * 6 + * Author: Huang Rui <ray.huang@amd.com> 7 + * 8 + * This program is free software; you can redistribute it and/or modify 9 + * it under the terms of the GNU General Public License version 2 as 10 + * published by the Free Software Foundation. 11 + */ 12 + 13 + #include <linux/module.h> 14 + #include <linux/slab.h> 15 + #include <linux/perf_event.h> 16 + #include <asm/cpu_device_id.h> 17 + #include "../perf_event.h" 18 + 19 + #define MSR_F15H_CU_PWR_ACCUMULATOR 0xc001007a 20 + #define MSR_F15H_CU_MAX_PWR_ACCUMULATOR 0xc001007b 21 + #define MSR_F15H_PTSC 0xc0010280 22 + 23 + /* Event code: LSB 8 bits, passed in attr->config any other bit is reserved. */ 24 + #define AMD_POWER_EVENT_MASK 0xFFULL 25 + 26 + /* 27 + * Accumulated power status counters. 28 + */ 29 + #define AMD_POWER_EVENTSEL_PKG 1 30 + 31 + /* 32 + * The ratio of compute unit power accumulator sample period to the 33 + * PTSC period. 34 + */ 35 + static unsigned int cpu_pwr_sample_ratio; 36 + 37 + /* Maximum accumulated power of a compute unit. */ 38 + static u64 max_cu_acc_power; 39 + 40 + static struct pmu pmu_class; 41 + 42 + /* 43 + * Accumulated power represents the sum of each compute unit's (CU) power 44 + * consumption. On any core of each CU we read the total accumulated power from 45 + * MSR_F15H_CU_PWR_ACCUMULATOR. cpu_mask represents CPU bit map of all cores 46 + * which are picked to measure the power for the CUs they belong to. 47 + */ 48 + static cpumask_t cpu_mask; 49 + 50 + static void event_update(struct perf_event *event) 51 + { 52 + struct hw_perf_event *hwc = &event->hw; 53 + u64 prev_pwr_acc, new_pwr_acc, prev_ptsc, new_ptsc; 54 + u64 delta, tdelta; 55 + 56 + prev_pwr_acc = hwc->pwr_acc; 57 + prev_ptsc = hwc->ptsc; 58 + rdmsrl(MSR_F15H_CU_PWR_ACCUMULATOR, new_pwr_acc); 59 + rdmsrl(MSR_F15H_PTSC, new_ptsc); 60 + 61 + /* 62 + * Calculate the CU power consumption over a time period, the unit of 63 + * final value (delta) is micro-Watts. Then add it to the event count. 64 + */ 65 + if (new_pwr_acc < prev_pwr_acc) { 66 + delta = max_cu_acc_power + new_pwr_acc; 67 + delta -= prev_pwr_acc; 68 + } else 69 + delta = new_pwr_acc - prev_pwr_acc; 70 + 71 + delta *= cpu_pwr_sample_ratio * 1000; 72 + tdelta = new_ptsc - prev_ptsc; 73 + 74 + do_div(delta, tdelta); 75 + local64_add(delta, &event->count); 76 + } 77 + 78 + static void __pmu_event_start(struct perf_event *event) 79 + { 80 + if (WARN_ON_ONCE(!(event->hw.state & PERF_HES_STOPPED))) 81 + return; 82 + 83 + event->hw.state = 0; 84 + 85 + rdmsrl(MSR_F15H_PTSC, event->hw.ptsc); 86 + rdmsrl(MSR_F15H_CU_PWR_ACCUMULATOR, event->hw.pwr_acc); 87 + } 88 + 89 + static void pmu_event_start(struct perf_event *event, int mode) 90 + { 91 + __pmu_event_start(event); 92 + } 93 + 94 + static void pmu_event_stop(struct perf_event *event, int mode) 95 + { 96 + struct hw_perf_event *hwc = &event->hw; 97 + 98 + /* Mark event as deactivated and stopped. */ 99 + if (!(hwc->state & PERF_HES_STOPPED)) 100 + hwc->state |= PERF_HES_STOPPED; 101 + 102 + /* Check if software counter update is necessary. */ 103 + if ((mode & PERF_EF_UPDATE) && !(hwc->state & PERF_HES_UPTODATE)) { 104 + /* 105 + * Drain the remaining delta count out of an event 106 + * that we are disabling: 107 + */ 108 + event_update(event); 109 + hwc->state |= PERF_HES_UPTODATE; 110 + } 111 + } 112 + 113 + static int pmu_event_add(struct perf_event *event, int mode) 114 + { 115 + struct hw_perf_event *hwc = &event->hw; 116 + 117 + hwc->state = PERF_HES_UPTODATE | PERF_HES_STOPPED; 118 + 119 + if (mode & PERF_EF_START) 120 + __pmu_event_start(event); 121 + 122 + return 0; 123 + } 124 + 125 + static void pmu_event_del(struct perf_event *event, int flags) 126 + { 127 + pmu_event_stop(event, PERF_EF_UPDATE); 128 + } 129 + 130 + static int pmu_event_init(struct perf_event *event) 131 + { 132 + u64 cfg = event->attr.config & AMD_POWER_EVENT_MASK; 133 + 134 + /* Only look at AMD power events. */ 135 + if (event->attr.type != pmu_class.type) 136 + return -ENOENT; 137 + 138 + /* Unsupported modes and filters. */ 139 + if (event->attr.exclude_user || 140 + event->attr.exclude_kernel || 141 + event->attr.exclude_hv || 142 + event->attr.exclude_idle || 143 + event->attr.exclude_host || 144 + event->attr.exclude_guest || 145 + /* no sampling */ 146 + event->attr.sample_period) 147 + return -EINVAL; 148 + 149 + if (cfg != AMD_POWER_EVENTSEL_PKG) 150 + return -EINVAL; 151 + 152 + return 0; 153 + } 154 + 155 + static void pmu_event_read(struct perf_event *event) 156 + { 157 + event_update(event); 158 + } 159 + 160 + static ssize_t 161 + get_attr_cpumask(struct device *dev, struct device_attribute *attr, char *buf) 162 + { 163 + return cpumap_print_to_pagebuf(true, buf, &cpu_mask); 164 + } 165 + 166 + static DEVICE_ATTR(cpumask, S_IRUGO, get_attr_cpumask, NULL); 167 + 168 + static struct attribute *pmu_attrs[] = { 169 + &dev_attr_cpumask.attr, 170 + NULL, 171 + }; 172 + 173 + static struct attribute_group pmu_attr_group = { 174 + .attrs = pmu_attrs, 175 + }; 176 + 177 + /* 178 + * Currently it only supports to report the power of each 179 + * processor/package. 180 + */ 181 + EVENT_ATTR_STR(power-pkg, power_pkg, "event=0x01"); 182 + 183 + EVENT_ATTR_STR(power-pkg.unit, power_pkg_unit, "mWatts"); 184 + 185 + /* Convert the count from micro-Watts to milli-Watts. */ 186 + EVENT_ATTR_STR(power-pkg.scale, power_pkg_scale, "1.000000e-3"); 187 + 188 + static struct attribute *events_attr[] = { 189 + EVENT_PTR(power_pkg), 190 + EVENT_PTR(power_pkg_unit), 191 + EVENT_PTR(power_pkg_scale), 192 + NULL, 193 + }; 194 + 195 + static struct attribute_group pmu_events_group = { 196 + .name = "events", 197 + .attrs = events_attr, 198 + }; 199 + 200 + PMU_FORMAT_ATTR(event, "config:0-7"); 201 + 202 + static struct attribute *formats_attr[] = { 203 + &format_attr_event.attr, 204 + NULL, 205 + }; 206 + 207 + static struct attribute_group pmu_format_group = { 208 + .name = "format", 209 + .attrs = formats_attr, 210 + }; 211 + 212 + static const struct attribute_group *attr_groups[] = { 213 + &pmu_attr_group, 214 + &pmu_format_group, 215 + &pmu_events_group, 216 + NULL, 217 + }; 218 + 219 + static struct pmu pmu_class = { 220 + .attr_groups = attr_groups, 221 + /* system-wide only */ 222 + .task_ctx_nr = perf_invalid_context, 223 + .event_init = pmu_event_init, 224 + .add = pmu_event_add, 225 + .del = pmu_event_del, 226 + .start = pmu_event_start, 227 + .stop = pmu_event_stop, 228 + .read = pmu_event_read, 229 + }; 230 + 231 + static void power_cpu_exit(int cpu) 232 + { 233 + int target; 234 + 235 + if (!cpumask_test_and_clear_cpu(cpu, &cpu_mask)) 236 + return; 237 + 238 + /* 239 + * Find a new CPU on the same compute unit, if was set in cpumask 240 + * and still some CPUs on compute unit. Then migrate event and 241 + * context to new CPU. 242 + */ 243 + target = cpumask_any_but(topology_sibling_cpumask(cpu), cpu); 244 + if (target < nr_cpumask_bits) { 245 + cpumask_set_cpu(target, &cpu_mask); 246 + perf_pmu_migrate_context(&pmu_class, cpu, target); 247 + } 248 + } 249 + 250 + static void power_cpu_init(int cpu) 251 + { 252 + int target; 253 + 254 + /* 255 + * 1) If any CPU is set at cpu_mask in the same compute unit, do 256 + * nothing. 257 + * 2) If no CPU is set at cpu_mask in the same compute unit, 258 + * set current STARTING CPU. 259 + * 260 + * Note: if there is a CPU aside of the new one already in the 261 + * sibling mask, then it is also in cpu_mask. 262 + */ 263 + target = cpumask_any_but(topology_sibling_cpumask(cpu), cpu); 264 + if (target >= nr_cpumask_bits) 265 + cpumask_set_cpu(cpu, &cpu_mask); 266 + } 267 + 268 + static int 269 + power_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu) 270 + { 271 + unsigned int cpu = (long)hcpu; 272 + 273 + switch (action & ~CPU_TASKS_FROZEN) { 274 + case CPU_DOWN_FAILED: 275 + case CPU_STARTING: 276 + power_cpu_init(cpu); 277 + break; 278 + case CPU_DOWN_PREPARE: 279 + power_cpu_exit(cpu); 280 + break; 281 + default: 282 + break; 283 + } 284 + 285 + return NOTIFY_OK; 286 + } 287 + 288 + static struct notifier_block power_cpu_notifier_nb = { 289 + .notifier_call = power_cpu_notifier, 290 + .priority = CPU_PRI_PERF, 291 + }; 292 + 293 + static const struct x86_cpu_id cpu_match[] = { 294 + { .vendor = X86_VENDOR_AMD, .family = 0x15 }, 295 + {}, 296 + }; 297 + 298 + static int __init amd_power_pmu_init(void) 299 + { 300 + int cpu, target, ret; 301 + 302 + if (!x86_match_cpu(cpu_match)) 303 + return 0; 304 + 305 + if (!boot_cpu_has(X86_FEATURE_ACC_POWER)) 306 + return -ENODEV; 307 + 308 + cpu_pwr_sample_ratio = cpuid_ecx(0x80000007); 309 + 310 + if (rdmsrl_safe(MSR_F15H_CU_MAX_PWR_ACCUMULATOR, &max_cu_acc_power)) { 311 + pr_err("Failed to read max compute unit power accumulator MSR\n"); 312 + return -ENODEV; 313 + } 314 + 315 + cpu_notifier_register_begin(); 316 + 317 + /* Choose one online core of each compute unit. */ 318 + for_each_online_cpu(cpu) { 319 + target = cpumask_first(topology_sibling_cpumask(cpu)); 320 + if (!cpumask_test_cpu(target, &cpu_mask)) 321 + cpumask_set_cpu(target, &cpu_mask); 322 + } 323 + 324 + ret = perf_pmu_register(&pmu_class, "power", -1); 325 + if (WARN_ON(ret)) { 326 + pr_warn("AMD Power PMU registration failed\n"); 327 + goto out; 328 + } 329 + 330 + __register_cpu_notifier(&power_cpu_notifier_nb); 331 + 332 + pr_info("AMD Power PMU detected\n"); 333 + 334 + out: 335 + cpu_notifier_register_done(); 336 + 337 + return ret; 338 + } 339 + module_init(amd_power_pmu_init); 340 + 341 + static void __exit amd_power_pmu_exit(void) 342 + { 343 + cpu_notifier_register_begin(); 344 + __unregister_cpu_notifier(&power_cpu_notifier_nb); 345 + cpu_notifier_register_done(); 346 + 347 + perf_pmu_unregister(&pmu_class); 348 + } 349 + module_exit(amd_power_pmu_exit); 350 + 351 + MODULE_AUTHOR("Huang Rui <ray.huang@amd.com>"); 352 + MODULE_DESCRIPTION("AMD Processor Power Reporting Mechanism"); 353 + MODULE_LICENSE("GPL v2");
+2 -2
arch/x86/events/core.c
··· 1602 1602 return new; 1603 1603 } 1604 1604 1605 - ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, 1606 - char *page) 1605 + ssize_t events_sysfs_show(struct device *dev, struct device_attribute *attr, char *page) 1607 1606 { 1608 1607 struct perf_pmu_events_attr *pmu_attr = \ 1609 1608 container_of(attr, struct perf_pmu_events_attr, attr); ··· 1614 1615 1615 1616 return x86_pmu.events_sysfs_show(page, config); 1616 1617 } 1618 + EXPORT_SYMBOL_GPL(events_sysfs_show); 1617 1619 1618 1620 EVENT_ATTR(cpu-cycles, CPU_CYCLES ); 1619 1621 EVENT_ATTR(instructions, INSTRUCTIONS );
+432 -24
arch/x86/events/intel/cqm.c
··· 13 13 #define MSR_IA32_QM_CTR 0x0c8e 14 14 #define MSR_IA32_QM_EVTSEL 0x0c8d 15 15 16 + #define MBM_CNTR_WIDTH 24 17 + /* 18 + * Guaranteed time in ms as per SDM where MBM counters will not overflow. 19 + */ 20 + #define MBM_CTR_OVERFLOW_TIME 1000 21 + 16 22 static u32 cqm_max_rmid = -1; 17 23 static unsigned int cqm_l3_scale; /* supposedly cacheline size */ 24 + static bool cqm_enabled, mbm_enabled; 25 + unsigned int mbm_socket_max; 18 26 19 27 /** 20 28 * struct intel_pqr_state - State cache for the PQR MSR ··· 50 42 * interrupts disabled, which is sufficient for the protection. 51 43 */ 52 44 static DEFINE_PER_CPU(struct intel_pqr_state, pqr_state); 45 + static struct hrtimer *mbm_timers; 46 + /** 47 + * struct sample - mbm event's (local or total) data 48 + * @total_bytes #bytes since we began monitoring 49 + * @prev_msr previous value of MSR 50 + */ 51 + struct sample { 52 + u64 total_bytes; 53 + u64 prev_msr; 54 + }; 53 55 56 + /* 57 + * samples profiled for total memory bandwidth type events 58 + */ 59 + static struct sample *mbm_total; 60 + /* 61 + * samples profiled for local memory bandwidth type events 62 + */ 63 + static struct sample *mbm_local; 64 + 65 + #define pkg_id topology_physical_package_id(smp_processor_id()) 66 + /* 67 + * rmid_2_index returns the index for the rmid in mbm_local/mbm_total array. 68 + * mbm_total[] and mbm_local[] are linearly indexed by socket# * max number of 69 + * rmids per socket, an example is given below 70 + * RMID1 of Socket0: vrmid = 1 71 + * RMID1 of Socket1: vrmid = 1 * (cqm_max_rmid + 1) + 1 72 + * RMID1 of Socket2: vrmid = 2 * (cqm_max_rmid + 1) + 1 73 + */ 74 + #define rmid_2_index(rmid) ((pkg_id * (cqm_max_rmid + 1)) + rmid) 54 75 /* 55 76 * Protects cache_cgroups and cqm_rmid_free_lru and cqm_rmid_limbo_lru. 56 77 * Also protects event->hw.cqm_rmid ··· 102 65 #define RMID_VAL_ERROR (1ULL << 63) 103 66 #define RMID_VAL_UNAVAIL (1ULL << 62) 104 67 105 - #define QOS_L3_OCCUP_EVENT_ID (1 << 0) 106 - 107 - #define QOS_EVENT_MASK QOS_L3_OCCUP_EVENT_ID 68 + /* 69 + * Event IDs are used to program IA32_QM_EVTSEL before reading event 70 + * counter from IA32_QM_CTR 71 + */ 72 + #define QOS_L3_OCCUP_EVENT_ID 0x01 73 + #define QOS_MBM_TOTAL_EVENT_ID 0x02 74 + #define QOS_MBM_LOCAL_EVENT_ID 0x03 108 75 109 76 /* 110 77 * This is central to the rotation algorithm in __intel_cqm_rmid_rotate(). ··· 252 211 list_add_tail(&entry->list, &cqm_rmid_limbo_lru); 253 212 } 254 213 214 + static void cqm_cleanup(void) 215 + { 216 + int i; 217 + 218 + if (!cqm_rmid_ptrs) 219 + return; 220 + 221 + for (i = 0; i < cqm_max_rmid; i++) 222 + kfree(cqm_rmid_ptrs[i]); 223 + 224 + kfree(cqm_rmid_ptrs); 225 + cqm_rmid_ptrs = NULL; 226 + cqm_enabled = false; 227 + } 228 + 255 229 static int intel_cqm_setup_rmid_cache(void) 256 230 { 257 231 struct cqm_rmid_entry *entry; ··· 274 218 int r = 0; 275 219 276 220 nr_rmids = cqm_max_rmid + 1; 277 - cqm_rmid_ptrs = kmalloc(sizeof(struct cqm_rmid_entry *) * 221 + cqm_rmid_ptrs = kzalloc(sizeof(struct cqm_rmid_entry *) * 278 222 nr_rmids, GFP_KERNEL); 279 223 if (!cqm_rmid_ptrs) 280 224 return -ENOMEM; ··· 305 249 mutex_unlock(&cache_mutex); 306 250 307 251 return 0; 308 - fail: 309 - while (r--) 310 - kfree(cqm_rmid_ptrs[r]); 311 252 312 - kfree(cqm_rmid_ptrs); 253 + fail: 254 + cqm_cleanup(); 313 255 return -ENOMEM; 314 256 } 315 257 ··· 335 281 336 282 /* 337 283 * Events that target same task are placed into the same cache group. 284 + * Mark it as a multi event group, so that we update ->count 285 + * for every event rather than just the group leader later. 338 286 */ 339 - if (a->hw.target == b->hw.target) 287 + if (a->hw.target == b->hw.target) { 288 + b->hw.is_group_event = true; 340 289 return true; 290 + } 341 291 342 292 /* 343 293 * Are we an inherited event? ··· 450 392 451 393 struct rmid_read { 452 394 u32 rmid; 395 + u32 evt_type; 453 396 atomic64_t value; 454 397 }; 455 398 456 399 static void __intel_cqm_event_count(void *info); 400 + static void init_mbm_sample(u32 rmid, u32 evt_type); 401 + static void __intel_mbm_event_count(void *info); 402 + 403 + static bool is_mbm_event(int e) 404 + { 405 + return (e >= QOS_MBM_TOTAL_EVENT_ID && e <= QOS_MBM_LOCAL_EVENT_ID); 406 + } 407 + 408 + static void cqm_mask_call(struct rmid_read *rr) 409 + { 410 + if (is_mbm_event(rr->evt_type)) 411 + on_each_cpu_mask(&cqm_cpumask, __intel_mbm_event_count, rr, 1); 412 + else 413 + on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count, rr, 1); 414 + } 457 415 458 416 /* 459 417 * Exchange the RMID of a group of events. ··· 487 413 */ 488 414 if (__rmid_valid(old_rmid) && !__rmid_valid(rmid)) { 489 415 struct rmid_read rr = { 490 - .value = ATOMIC64_INIT(0), 491 416 .rmid = old_rmid, 417 + .evt_type = group->attr.config, 418 + .value = ATOMIC64_INIT(0), 492 419 }; 493 420 494 - on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count, 495 - &rr, 1); 421 + cqm_mask_call(&rr); 496 422 local64_set(&group->count, atomic64_read(&rr.value)); 497 423 } 498 424 ··· 503 429 event->hw.cqm_rmid = rmid; 504 430 505 431 raw_spin_unlock_irq(&cache_lock); 432 + 433 + /* 434 + * If the allocation is for mbm, init the mbm stats. 435 + * Need to check if each event in the group is mbm event 436 + * because there could be multiple type of events in the same group. 437 + */ 438 + if (__rmid_valid(rmid)) { 439 + event = group; 440 + if (is_mbm_event(event->attr.config)) 441 + init_mbm_sample(rmid, event->attr.config); 442 + 443 + list_for_each_entry(event, head, hw.cqm_group_entry) { 444 + if (is_mbm_event(event->attr.config)) 445 + init_mbm_sample(rmid, event->attr.config); 446 + } 447 + } 506 448 507 449 return old_rmid; 508 450 } ··· 927 837 schedule_delayed_work(&intel_cqm_rmid_work, delay); 928 838 } 929 839 840 + static u64 update_sample(unsigned int rmid, u32 evt_type, int first) 841 + { 842 + struct sample *mbm_current; 843 + u32 vrmid = rmid_2_index(rmid); 844 + u64 val, bytes, shift; 845 + u32 eventid; 846 + 847 + if (evt_type == QOS_MBM_LOCAL_EVENT_ID) { 848 + mbm_current = &mbm_local[vrmid]; 849 + eventid = QOS_MBM_LOCAL_EVENT_ID; 850 + } else { 851 + mbm_current = &mbm_total[vrmid]; 852 + eventid = QOS_MBM_TOTAL_EVENT_ID; 853 + } 854 + 855 + wrmsr(MSR_IA32_QM_EVTSEL, eventid, rmid); 856 + rdmsrl(MSR_IA32_QM_CTR, val); 857 + if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) 858 + return mbm_current->total_bytes; 859 + 860 + if (first) { 861 + mbm_current->prev_msr = val; 862 + mbm_current->total_bytes = 0; 863 + return mbm_current->total_bytes; 864 + } 865 + 866 + /* 867 + * The h/w guarantees that counters will not overflow 868 + * so long as we poll them at least once per second. 869 + */ 870 + shift = 64 - MBM_CNTR_WIDTH; 871 + bytes = (val << shift) - (mbm_current->prev_msr << shift); 872 + bytes >>= shift; 873 + 874 + bytes *= cqm_l3_scale; 875 + 876 + mbm_current->total_bytes += bytes; 877 + mbm_current->prev_msr = val; 878 + 879 + return mbm_current->total_bytes; 880 + } 881 + 882 + static u64 rmid_read_mbm(unsigned int rmid, u32 evt_type) 883 + { 884 + return update_sample(rmid, evt_type, 0); 885 + } 886 + 887 + static void __intel_mbm_event_init(void *info) 888 + { 889 + struct rmid_read *rr = info; 890 + 891 + update_sample(rr->rmid, rr->evt_type, 1); 892 + } 893 + 894 + static void init_mbm_sample(u32 rmid, u32 evt_type) 895 + { 896 + struct rmid_read rr = { 897 + .rmid = rmid, 898 + .evt_type = evt_type, 899 + .value = ATOMIC64_INIT(0), 900 + }; 901 + 902 + /* on each socket, init sample */ 903 + on_each_cpu_mask(&cqm_cpumask, __intel_mbm_event_init, &rr, 1); 904 + } 905 + 930 906 /* 931 907 * Find a group and setup RMID. 932 908 * ··· 1005 849 bool conflict = false; 1006 850 u32 rmid; 1007 851 852 + event->hw.is_group_event = false; 1008 853 list_for_each_entry(iter, &cache_groups, hw.cqm_groups_entry) { 1009 854 rmid = iter->hw.cqm_rmid; 1010 855 ··· 1013 856 /* All tasks in a group share an RMID */ 1014 857 event->hw.cqm_rmid = rmid; 1015 858 *group = iter; 859 + if (is_mbm_event(event->attr.config) && __rmid_valid(rmid)) 860 + init_mbm_sample(rmid, event->attr.config); 1016 861 return; 1017 862 } 1018 863 ··· 1030 871 rmid = INVALID_RMID; 1031 872 else 1032 873 rmid = __get_rmid(); 874 + 875 + if (is_mbm_event(event->attr.config) && __rmid_valid(rmid)) 876 + init_mbm_sample(rmid, event->attr.config); 1033 877 1034 878 event->hw.cqm_rmid = rmid; 1035 879 } ··· 1055 893 if (!__rmid_valid(rmid)) 1056 894 goto out; 1057 895 1058 - val = __rmid_read(rmid); 896 + if (is_mbm_event(event->attr.config)) 897 + val = rmid_read_mbm(rmid, event->attr.config); 898 + else 899 + val = __rmid_read(rmid); 1059 900 1060 901 /* 1061 902 * Ignore this reading on error states and do not update the value. ··· 1089 924 return !list_empty(&event->hw.cqm_groups_entry); 1090 925 } 1091 926 927 + static void __intel_mbm_event_count(void *info) 928 + { 929 + struct rmid_read *rr = info; 930 + u64 val; 931 + 932 + val = rmid_read_mbm(rr->rmid, rr->evt_type); 933 + if (val & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) 934 + return; 935 + atomic64_add(val, &rr->value); 936 + } 937 + 938 + static enum hrtimer_restart mbm_hrtimer_handle(struct hrtimer *hrtimer) 939 + { 940 + struct perf_event *iter, *iter1; 941 + int ret = HRTIMER_RESTART; 942 + struct list_head *head; 943 + unsigned long flags; 944 + u32 grp_rmid; 945 + 946 + /* 947 + * Need to cache_lock as the timer Event Select MSR reads 948 + * can race with the mbm/cqm count() and mbm_init() reads. 949 + */ 950 + raw_spin_lock_irqsave(&cache_lock, flags); 951 + 952 + if (list_empty(&cache_groups)) { 953 + ret = HRTIMER_NORESTART; 954 + goto out; 955 + } 956 + 957 + list_for_each_entry(iter, &cache_groups, hw.cqm_groups_entry) { 958 + grp_rmid = iter->hw.cqm_rmid; 959 + if (!__rmid_valid(grp_rmid)) 960 + continue; 961 + if (is_mbm_event(iter->attr.config)) 962 + update_sample(grp_rmid, iter->attr.config, 0); 963 + 964 + head = &iter->hw.cqm_group_entry; 965 + if (list_empty(head)) 966 + continue; 967 + list_for_each_entry(iter1, head, hw.cqm_group_entry) { 968 + if (!iter1->hw.is_group_event) 969 + break; 970 + if (is_mbm_event(iter1->attr.config)) 971 + update_sample(iter1->hw.cqm_rmid, 972 + iter1->attr.config, 0); 973 + } 974 + } 975 + 976 + hrtimer_forward_now(hrtimer, ms_to_ktime(MBM_CTR_OVERFLOW_TIME)); 977 + out: 978 + raw_spin_unlock_irqrestore(&cache_lock, flags); 979 + 980 + return ret; 981 + } 982 + 983 + static void __mbm_start_timer(void *info) 984 + { 985 + hrtimer_start(&mbm_timers[pkg_id], ms_to_ktime(MBM_CTR_OVERFLOW_TIME), 986 + HRTIMER_MODE_REL_PINNED); 987 + } 988 + 989 + static void __mbm_stop_timer(void *info) 990 + { 991 + hrtimer_cancel(&mbm_timers[pkg_id]); 992 + } 993 + 994 + static void mbm_start_timers(void) 995 + { 996 + on_each_cpu_mask(&cqm_cpumask, __mbm_start_timer, NULL, 1); 997 + } 998 + 999 + static void mbm_stop_timers(void) 1000 + { 1001 + on_each_cpu_mask(&cqm_cpumask, __mbm_stop_timer, NULL, 1); 1002 + } 1003 + 1004 + static void mbm_hrtimer_init(void) 1005 + { 1006 + struct hrtimer *hr; 1007 + int i; 1008 + 1009 + for (i = 0; i < mbm_socket_max; i++) { 1010 + hr = &mbm_timers[i]; 1011 + hrtimer_init(hr, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 1012 + hr->function = mbm_hrtimer_handle; 1013 + } 1014 + } 1015 + 1092 1016 static u64 intel_cqm_event_count(struct perf_event *event) 1093 1017 { 1094 1018 unsigned long flags; 1095 1019 struct rmid_read rr = { 1020 + .evt_type = event->attr.config, 1096 1021 .value = ATOMIC64_INIT(0), 1097 1022 }; 1098 1023 ··· 1195 940 return __perf_event_count(event); 1196 941 1197 942 /* 1198 - * Only the group leader gets to report values. This stops us 943 + * Only the group leader gets to report values except in case of 944 + * multiple events in the same group, we still need to read the 945 + * other events.This stops us 1199 946 * reporting duplicate values to userspace, and gives us a clear 1200 947 * rule for which task gets to report the values. 1201 948 * ··· 1205 948 * specific packages - we forfeit that ability when we create 1206 949 * task events. 1207 950 */ 1208 - if (!cqm_group_leader(event)) 951 + if (!cqm_group_leader(event) && !event->hw.is_group_event) 1209 952 return 0; 1210 953 1211 954 /* ··· 1232 975 if (!__rmid_valid(rr.rmid)) 1233 976 goto out; 1234 977 1235 - on_each_cpu_mask(&cqm_cpumask, __intel_cqm_event_count, &rr, 1); 978 + cqm_mask_call(&rr); 1236 979 1237 980 raw_spin_lock_irqsave(&cache_lock, flags); 1238 981 if (event->hw.cqm_rmid == rr.rmid) ··· 1303 1046 static void intel_cqm_event_destroy(struct perf_event *event) 1304 1047 { 1305 1048 struct perf_event *group_other = NULL; 1049 + unsigned long flags; 1306 1050 1307 1051 mutex_lock(&cache_mutex); 1052 + /* 1053 + * Hold the cache_lock as mbm timer handlers could be 1054 + * scanning the list of events. 1055 + */ 1056 + raw_spin_lock_irqsave(&cache_lock, flags); 1308 1057 1309 1058 /* 1310 1059 * If there's another event in this group... ··· 1342 1079 } 1343 1080 } 1344 1081 1082 + raw_spin_unlock_irqrestore(&cache_lock, flags); 1083 + 1084 + /* 1085 + * Stop the mbm overflow timers when the last event is destroyed. 1086 + */ 1087 + if (mbm_enabled && list_empty(&cache_groups)) 1088 + mbm_stop_timers(); 1089 + 1345 1090 mutex_unlock(&cache_mutex); 1346 1091 } 1347 1092 ··· 1357 1086 { 1358 1087 struct perf_event *group = NULL; 1359 1088 bool rotate = false; 1089 + unsigned long flags; 1360 1090 1361 1091 if (event->attr.type != intel_cqm_pmu.type) 1362 1092 return -ENOENT; 1363 1093 1364 - if (event->attr.config & ~QOS_EVENT_MASK) 1094 + if ((event->attr.config < QOS_L3_OCCUP_EVENT_ID) || 1095 + (event->attr.config > QOS_MBM_LOCAL_EVENT_ID)) 1365 1096 return -EINVAL; 1366 1097 1367 1098 /* unsupported modes and filters */ ··· 1383 1110 1384 1111 mutex_lock(&cache_mutex); 1385 1112 1113 + /* 1114 + * Start the mbm overflow timers when the first event is created. 1115 + */ 1116 + if (mbm_enabled && list_empty(&cache_groups)) 1117 + mbm_start_timers(); 1118 + 1386 1119 /* Will also set rmid */ 1387 1120 intel_cqm_setup_event(event, &group); 1121 + 1122 + /* 1123 + * Hold the cache_lock as mbm timer handlers be 1124 + * scanning the list of events. 1125 + */ 1126 + raw_spin_lock_irqsave(&cache_lock, flags); 1388 1127 1389 1128 if (group) { 1390 1129 list_add_tail(&event->hw.cqm_group_entry, ··· 1416 1131 rotate = true; 1417 1132 } 1418 1133 1134 + raw_spin_unlock_irqrestore(&cache_lock, flags); 1419 1135 mutex_unlock(&cache_mutex); 1420 1136 1421 1137 if (rotate) ··· 1431 1145 EVENT_ATTR_STR(llc_occupancy.scale, intel_cqm_llc_scale, NULL); 1432 1146 EVENT_ATTR_STR(llc_occupancy.snapshot, intel_cqm_llc_snapshot, "1"); 1433 1147 1148 + EVENT_ATTR_STR(total_bytes, intel_cqm_total_bytes, "event=0x02"); 1149 + EVENT_ATTR_STR(total_bytes.per-pkg, intel_cqm_total_bytes_pkg, "1"); 1150 + EVENT_ATTR_STR(total_bytes.unit, intel_cqm_total_bytes_unit, "MB"); 1151 + EVENT_ATTR_STR(total_bytes.scale, intel_cqm_total_bytes_scale, "1e-6"); 1152 + 1153 + EVENT_ATTR_STR(local_bytes, intel_cqm_local_bytes, "event=0x03"); 1154 + EVENT_ATTR_STR(local_bytes.per-pkg, intel_cqm_local_bytes_pkg, "1"); 1155 + EVENT_ATTR_STR(local_bytes.unit, intel_cqm_local_bytes_unit, "MB"); 1156 + EVENT_ATTR_STR(local_bytes.scale, intel_cqm_local_bytes_scale, "1e-6"); 1157 + 1434 1158 static struct attribute *intel_cqm_events_attr[] = { 1435 1159 EVENT_PTR(intel_cqm_llc), 1436 1160 EVENT_PTR(intel_cqm_llc_pkg), ··· 1450 1154 NULL, 1451 1155 }; 1452 1156 1157 + static struct attribute *intel_mbm_events_attr[] = { 1158 + EVENT_PTR(intel_cqm_total_bytes), 1159 + EVENT_PTR(intel_cqm_local_bytes), 1160 + EVENT_PTR(intel_cqm_total_bytes_pkg), 1161 + EVENT_PTR(intel_cqm_local_bytes_pkg), 1162 + EVENT_PTR(intel_cqm_total_bytes_unit), 1163 + EVENT_PTR(intel_cqm_local_bytes_unit), 1164 + EVENT_PTR(intel_cqm_total_bytes_scale), 1165 + EVENT_PTR(intel_cqm_local_bytes_scale), 1166 + NULL, 1167 + }; 1168 + 1169 + static struct attribute *intel_cmt_mbm_events_attr[] = { 1170 + EVENT_PTR(intel_cqm_llc), 1171 + EVENT_PTR(intel_cqm_total_bytes), 1172 + EVENT_PTR(intel_cqm_local_bytes), 1173 + EVENT_PTR(intel_cqm_llc_pkg), 1174 + EVENT_PTR(intel_cqm_total_bytes_pkg), 1175 + EVENT_PTR(intel_cqm_local_bytes_pkg), 1176 + EVENT_PTR(intel_cqm_llc_unit), 1177 + EVENT_PTR(intel_cqm_total_bytes_unit), 1178 + EVENT_PTR(intel_cqm_local_bytes_unit), 1179 + EVENT_PTR(intel_cqm_llc_scale), 1180 + EVENT_PTR(intel_cqm_total_bytes_scale), 1181 + EVENT_PTR(intel_cqm_local_bytes_scale), 1182 + EVENT_PTR(intel_cqm_llc_snapshot), 1183 + NULL, 1184 + }; 1185 + 1453 1186 static struct attribute_group intel_cqm_events_group = { 1454 1187 .name = "events", 1455 - .attrs = intel_cqm_events_attr, 1188 + .attrs = NULL, 1456 1189 }; 1457 1190 1458 1191 PMU_FORMAT_ATTR(event, "config:0-7"); ··· 1628 1303 {} 1629 1304 }; 1630 1305 1306 + static void mbm_cleanup(void) 1307 + { 1308 + if (!mbm_enabled) 1309 + return; 1310 + 1311 + kfree(mbm_local); 1312 + kfree(mbm_total); 1313 + mbm_enabled = false; 1314 + } 1315 + 1316 + static const struct x86_cpu_id intel_mbm_local_match[] = { 1317 + { .vendor = X86_VENDOR_INTEL, .feature = X86_FEATURE_CQM_MBM_LOCAL }, 1318 + {} 1319 + }; 1320 + 1321 + static const struct x86_cpu_id intel_mbm_total_match[] = { 1322 + { .vendor = X86_VENDOR_INTEL, .feature = X86_FEATURE_CQM_MBM_TOTAL }, 1323 + {} 1324 + }; 1325 + 1326 + static int intel_mbm_init(void) 1327 + { 1328 + int ret = 0, array_size, maxid = cqm_max_rmid + 1; 1329 + 1330 + mbm_socket_max = topology_max_packages(); 1331 + array_size = sizeof(struct sample) * maxid * mbm_socket_max; 1332 + mbm_local = kmalloc(array_size, GFP_KERNEL); 1333 + if (!mbm_local) 1334 + return -ENOMEM; 1335 + 1336 + mbm_total = kmalloc(array_size, GFP_KERNEL); 1337 + if (!mbm_total) { 1338 + ret = -ENOMEM; 1339 + goto out; 1340 + } 1341 + 1342 + array_size = sizeof(struct hrtimer) * mbm_socket_max; 1343 + mbm_timers = kmalloc(array_size, GFP_KERNEL); 1344 + if (!mbm_timers) { 1345 + ret = -ENOMEM; 1346 + goto out; 1347 + } 1348 + mbm_hrtimer_init(); 1349 + 1350 + out: 1351 + if (ret) 1352 + mbm_cleanup(); 1353 + 1354 + return ret; 1355 + } 1356 + 1631 1357 static int __init intel_cqm_init(void) 1632 1358 { 1633 - char *str, scale[20]; 1359 + char *str = NULL, scale[20]; 1634 1360 int i, cpu, ret; 1635 1361 1636 - if (!x86_match_cpu(intel_cqm_match)) 1362 + if (x86_match_cpu(intel_cqm_match)) 1363 + cqm_enabled = true; 1364 + 1365 + if (x86_match_cpu(intel_mbm_local_match) && 1366 + x86_match_cpu(intel_mbm_total_match)) 1367 + mbm_enabled = true; 1368 + 1369 + if (!cqm_enabled && !mbm_enabled) 1637 1370 return -ENODEV; 1638 1371 1639 1372 cqm_l3_scale = boot_cpu_data.x86_cache_occ_scale; ··· 1748 1365 cqm_pick_event_reader(i); 1749 1366 } 1750 1367 1751 - __perf_cpu_notifier(intel_cqm_cpu_notifier); 1368 + if (mbm_enabled) 1369 + ret = intel_mbm_init(); 1370 + if (ret && !cqm_enabled) 1371 + goto out; 1372 + 1373 + if (cqm_enabled && mbm_enabled) 1374 + intel_cqm_events_group.attrs = intel_cmt_mbm_events_attr; 1375 + else if (!cqm_enabled && mbm_enabled) 1376 + intel_cqm_events_group.attrs = intel_mbm_events_attr; 1377 + else if (cqm_enabled && !mbm_enabled) 1378 + intel_cqm_events_group.attrs = intel_cqm_events_attr; 1752 1379 1753 1380 ret = perf_pmu_register(&intel_cqm_pmu, "intel_cqm", -1); 1754 - if (ret) 1381 + if (ret) { 1755 1382 pr_err("Intel CQM perf registration failed: %d\n", ret); 1756 - else 1757 - pr_info("Intel CQM monitoring enabled\n"); 1383 + goto out; 1384 + } 1758 1385 1386 + if (cqm_enabled) 1387 + pr_info("Intel CQM monitoring enabled\n"); 1388 + if (mbm_enabled) 1389 + pr_info("Intel MBM enabled\n"); 1390 + 1391 + /* 1392 + * Register the hot cpu notifier once we are sure cqm 1393 + * is enabled to avoid notifier leak. 1394 + */ 1395 + __perf_cpu_notifier(intel_cqm_cpu_notifier); 1759 1396 out: 1760 1397 cpu_notifier_register_done(); 1398 + if (ret) { 1399 + kfree(str); 1400 + cqm_cleanup(); 1401 + mbm_cleanup(); 1402 + } 1761 1403 1762 1404 return ret; 1763 1405 }
+4 -1
arch/x86/events/intel/ds.c
··· 570 570 * We will overwrite the from and to address before we output 571 571 * the sample. 572 572 */ 573 + rcu_read_lock(); 573 574 perf_prepare_sample(&header, &data, event, &regs); 574 575 575 576 if (perf_output_begin(&handle, event, header.size * 576 577 (top - base - skip))) 577 - return 1; 578 + goto unlock; 578 579 579 580 for (at = base; at < top; at++) { 580 581 /* Filter out any records that contain kernel addresses. */ ··· 594 593 /* There's new data available. */ 595 594 event->hw.interrupts++; 596 595 event->pending_kill = POLL_IN; 596 + unlock: 597 + rcu_read_unlock(); 597 598 return 1; 598 599 } 599 600
+2
arch/x86/events/intel/rapl.c
··· 711 711 rapl_pmu_events_group.attrs = rapl_events_cln_attr; 712 712 break; 713 713 case 63: /* Haswell-Server */ 714 + case 79: /* Broadwell-Server */ 714 715 apply_quirk = true; 715 716 rapl_cntr_mask = RAPL_IDX_SRV; 716 717 rapl_pmu_events_group.attrs = rapl_events_srv_attr; ··· 719 718 case 60: /* Haswell */ 720 719 case 69: /* Haswell-Celeron */ 721 720 case 61: /* Broadwell */ 721 + case 71: /* Broadwell-H */ 722 722 rapl_cntr_mask = RAPL_IDX_HSW; 723 723 rapl_pmu_events_group.attrs = rapl_events_hsw_attr; 724 724 break;
+2 -5
arch/x86/events/intel/uncore_snbep.c
··· 46 46 (SNBEP_PMON_CTL_EV_SEL_MASK | \ 47 47 SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ 48 48 SNBEP_PMON_CTL_EDGE_DET | \ 49 - SNBEP_PMON_CTL_EV_SEL_EXT | \ 50 49 SNBEP_PMON_CTL_INVERT | \ 51 50 SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \ 52 51 SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ ··· 147 148 /* IVBEP PCU */ 148 149 #define IVBEP_PCU_MSR_PMON_RAW_EVENT_MASK \ 149 150 (SNBEP_PMON_CTL_EV_SEL_MASK | \ 150 - SNBEP_PMON_CTL_EV_SEL_EXT | \ 151 151 SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ 152 152 SNBEP_PMON_CTL_EDGE_DET | \ 153 153 SNBEP_PCU_MSR_PMON_CTL_TRESH_MASK | \ ··· 256 258 SNBEP_PCU_MSR_PMON_CTL_OCC_SEL_MASK | \ 257 259 SNBEP_PMON_CTL_EDGE_DET | \ 258 260 SNBEP_CBO_PMON_CTL_TID_EN | \ 259 - SNBEP_PMON_CTL_EV_SEL_EXT | \ 260 261 SNBEP_PMON_CTL_INVERT | \ 261 262 KNL_PCU_MSR_PMON_CTL_TRESH_MASK | \ 262 263 SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \ ··· 469 472 }; 470 473 471 474 static struct attribute *snbep_uncore_pcu_formats_attr[] = { 472 - &format_attr_event_ext.attr, 475 + &format_attr_event.attr, 473 476 &format_attr_occ_sel.attr, 474 477 &format_attr_edge.attr, 475 478 &format_attr_inv.attr, ··· 1310 1313 }; 1311 1314 1312 1315 static struct attribute *ivbep_uncore_pcu_formats_attr[] = { 1313 - &format_attr_event_ext.attr, 1316 + &format_attr_event.attr, 1314 1317 &format_attr_occ_sel.attr, 1315 1318 &format_attr_edge.attr, 1316 1319 &format_attr_thresh5.attr,
+3 -1
arch/x86/include/asm/cpufeatures.h
··· 94 94 #define X86_FEATURE_REP_GOOD ( 3*32+16) /* rep microcode works well */ 95 95 #define X86_FEATURE_MFENCE_RDTSC ( 3*32+17) /* "" Mfence synchronizes RDTSC */ 96 96 #define X86_FEATURE_LFENCE_RDTSC ( 3*32+18) /* "" Lfence synchronizes RDTSC */ 97 - /* free, was #define X86_FEATURE_11AP ( 3*32+19) * "" Bad local APIC aka 11AP */ 97 + #define X86_FEATURE_ACC_POWER ( 3*32+19) /* AMD Accumulated Power Mechanism */ 98 98 #define X86_FEATURE_NOPL ( 3*32+20) /* The NOPL (0F 1F) instructions */ 99 99 #define X86_FEATURE_ALWAYS ( 3*32+21) /* "" Always-present feature */ 100 100 #define X86_FEATURE_XTOPOLOGY ( 3*32+22) /* cpu topology enum extensions */ ··· 245 245 246 246 /* Intel-defined CPU QoS Sub-leaf, CPUID level 0x0000000F:1 (edx), word 12 */ 247 247 #define X86_FEATURE_CQM_OCCUP_LLC (12*32+ 0) /* LLC occupancy monitoring if 1 */ 248 + #define X86_FEATURE_CQM_MBM_TOTAL (12*32+ 1) /* LLC Total MBM monitoring */ 249 + #define X86_FEATURE_CQM_MBM_LOCAL (12*32+ 2) /* LLC Local MBM monitoring */ 248 250 249 251 /* AMD-defined CPU features, CPUID level 0x80000008 (ebx), word 13 */ 250 252 #define X86_FEATURE_CLZERO (13*32+0) /* CLZERO instruction */
+16 -2
arch/x86/kernel/cpu/amd.c
··· 309 309 u32 eax, ebx, ecx, edx; 310 310 311 311 cpuid(0x8000001e, &eax, &ebx, &ecx, &edx); 312 - nodes_per_socket = ((ecx >> 8) & 7) + 1; 313 312 node_id = ecx & 7; 314 313 315 314 /* get compute unit information */ ··· 319 320 u64 value; 320 321 321 322 rdmsrl(MSR_FAM10H_NODE_ID, value); 322 - nodes_per_socket = ((value >> 3) & 7) + 1; 323 323 node_id = value & 7; 324 324 } else 325 325 return; ··· 520 522 521 523 if (cpu_has(c, X86_FEATURE_MWAITX)) 522 524 use_mwaitx_delay(); 525 + 526 + if (boot_cpu_has(X86_FEATURE_TOPOEXT)) { 527 + u32 ecx; 528 + 529 + ecx = cpuid_ecx(0x8000001e); 530 + nodes_per_socket = ((ecx >> 8) & 7) + 1; 531 + } else if (boot_cpu_has(X86_FEATURE_NODEID_MSR)) { 532 + u64 value; 533 + 534 + rdmsrl(MSR_FAM10H_NODE_ID, value); 535 + nodes_per_socket = ((value >> 3) & 7) + 1; 536 + } 523 537 } 524 538 525 539 static void early_init_amd(struct cpuinfo_x86 *c) ··· 548 538 if (!check_tsc_unstable()) 549 539 set_sched_clock_stable(); 550 540 } 541 + 542 + /* Bit 12 of 8000_0007 edx is accumulated power mechanism. */ 543 + if (c->x86_power & BIT(12)) 544 + set_cpu_cap(c, X86_FEATURE_ACC_POWER); 551 545 552 546 #ifdef CONFIG_X86_64 553 547 set_cpu_cap(c, X86_FEATURE_SYSCALL32);
+3 -1
arch/x86/kernel/cpu/common.c
··· 692 692 cpuid_count(0x0000000F, 1, &eax, &ebx, &ecx, &edx); 693 693 c->x86_capability[CPUID_F_1_EDX] = edx; 694 694 695 - if (cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC)) { 695 + if ((cpu_has(c, X86_FEATURE_CQM_OCCUP_LLC)) || 696 + ((cpu_has(c, X86_FEATURE_CQM_MBM_TOTAL)) || 697 + (cpu_has(c, X86_FEATURE_CQM_MBM_LOCAL)))) { 696 698 c->x86_cache_max_rmid = ecx; 697 699 c->x86_cache_occ_scale = ebx; 698 700 }
+5
include/linux/perf_event.h
··· 121 121 struct { /* intel_cqm */ 122 122 int cqm_state; 123 123 u32 cqm_rmid; 124 + int is_group_event; 124 125 struct list_head cqm_events_entry; 125 126 struct list_head cqm_groups_entry; 126 127 struct list_head cqm_group_entry; 127 128 }; 128 129 struct { /* itrace */ 129 130 int itrace_started; 131 + }; 132 + struct { /* amd_power */ 133 + u64 pwr_acc; 134 + u64 ptsc; 130 135 }; 131 136 #ifdef CONFIG_HAVE_HW_BREAKPOINT 132 137 struct { /* breakpoint */
+78 -36
kernel/events/core.c
··· 376 376 u64 tmp = perf_sample_period_ns; 377 377 378 378 tmp *= sysctl_perf_cpu_time_max_percent; 379 - do_div(tmp, 100); 380 - ACCESS_ONCE(perf_sample_allowed_ns) = tmp; 379 + tmp = div_u64(tmp, 100); 380 + if (!tmp) 381 + tmp = 1; 382 + 383 + WRITE_ONCE(perf_sample_allowed_ns, tmp); 381 384 } 382 385 383 386 static int perf_rotate_context(struct perf_cpu_context *cpuctx); ··· 412 409 if (ret || !write) 413 410 return ret; 414 411 415 - update_perf_cpu_limits(); 412 + if (sysctl_perf_cpu_time_max_percent == 100) { 413 + printk(KERN_WARNING 414 + "perf: Dynamic interrupt throttling disabled, can hang your system!\n"); 415 + WRITE_ONCE(perf_sample_allowed_ns, 0); 416 + } else { 417 + update_perf_cpu_limits(); 418 + } 416 419 417 420 return 0; 418 421 } ··· 432 423 #define NR_ACCUMULATED_SAMPLES 128 433 424 static DEFINE_PER_CPU(u64, running_sample_length); 434 425 426 + static u64 __report_avg; 427 + static u64 __report_allowed; 428 + 435 429 static void perf_duration_warn(struct irq_work *w) 436 430 { 437 - u64 allowed_ns = ACCESS_ONCE(perf_sample_allowed_ns); 438 - u64 avg_local_sample_len; 439 - u64 local_samples_len; 440 - 441 - local_samples_len = __this_cpu_read(running_sample_length); 442 - avg_local_sample_len = local_samples_len/NR_ACCUMULATED_SAMPLES; 443 - 444 431 printk_ratelimited(KERN_WARNING 445 - "perf interrupt took too long (%lld > %lld), lowering " 446 - "kernel.perf_event_max_sample_rate to %d\n", 447 - avg_local_sample_len, allowed_ns >> 1, 448 - sysctl_perf_event_sample_rate); 432 + "perf: interrupt took too long (%lld > %lld), lowering " 433 + "kernel.perf_event_max_sample_rate to %d\n", 434 + __report_avg, __report_allowed, 435 + sysctl_perf_event_sample_rate); 449 436 } 450 437 451 438 static DEFINE_IRQ_WORK(perf_duration_work, perf_duration_warn); 452 439 453 440 void perf_sample_event_took(u64 sample_len_ns) 454 441 { 455 - u64 allowed_ns = ACCESS_ONCE(perf_sample_allowed_ns); 456 - u64 avg_local_sample_len; 457 - u64 local_samples_len; 442 + u64 max_len = READ_ONCE(perf_sample_allowed_ns); 443 + u64 running_len; 444 + u64 avg_len; 445 + u32 max; 458 446 459 - if (allowed_ns == 0) 447 + if (max_len == 0) 460 448 return; 461 449 462 - /* decay the counter by 1 average sample */ 463 - local_samples_len = __this_cpu_read(running_sample_length); 464 - local_samples_len -= local_samples_len/NR_ACCUMULATED_SAMPLES; 465 - local_samples_len += sample_len_ns; 466 - __this_cpu_write(running_sample_length, local_samples_len); 450 + /* Decay the counter by 1 average sample. */ 451 + running_len = __this_cpu_read(running_sample_length); 452 + running_len -= running_len/NR_ACCUMULATED_SAMPLES; 453 + running_len += sample_len_ns; 454 + __this_cpu_write(running_sample_length, running_len); 467 455 468 456 /* 469 - * note: this will be biased artifically low until we have 470 - * seen NR_ACCUMULATED_SAMPLES. Doing it this way keeps us 457 + * Note: this will be biased artifically low until we have 458 + * seen NR_ACCUMULATED_SAMPLES. Doing it this way keeps us 471 459 * from having to maintain a count. 472 460 */ 473 - avg_local_sample_len = local_samples_len/NR_ACCUMULATED_SAMPLES; 474 - 475 - if (avg_local_sample_len <= allowed_ns) 461 + avg_len = running_len/NR_ACCUMULATED_SAMPLES; 462 + if (avg_len <= max_len) 476 463 return; 477 464 478 - if (max_samples_per_tick <= 1) 479 - return; 465 + __report_avg = avg_len; 466 + __report_allowed = max_len; 480 467 481 - max_samples_per_tick = DIV_ROUND_UP(max_samples_per_tick, 2); 482 - sysctl_perf_event_sample_rate = max_samples_per_tick * HZ; 468 + /* 469 + * Compute a throttle threshold 25% below the current duration. 470 + */ 471 + avg_len += avg_len / 4; 472 + max = (TICK_NSEC / 100) * sysctl_perf_cpu_time_max_percent; 473 + if (avg_len < max) 474 + max /= (u32)avg_len; 475 + else 476 + max = 1; 477 + 478 + WRITE_ONCE(perf_sample_allowed_ns, avg_len); 479 + WRITE_ONCE(max_samples_per_tick, max); 480 + 481 + sysctl_perf_event_sample_rate = max * HZ; 483 482 perf_sample_period_ns = NSEC_PER_SEC / sysctl_perf_event_sample_rate; 484 483 485 - update_perf_cpu_limits(); 486 - 487 484 if (!irq_work_queue(&perf_duration_work)) { 488 - early_printk("perf interrupt took too long (%lld > %lld), lowering " 485 + early_printk("perf: interrupt took too long (%lld > %lld), lowering " 489 486 "kernel.perf_event_max_sample_rate to %d\n", 490 - avg_local_sample_len, allowed_ns >> 1, 487 + __report_avg, __report_allowed, 491 488 sysctl_perf_event_sample_rate); 492 489 } 493 490 } ··· 4225 4210 active = (event->state == PERF_EVENT_STATE_ACTIVE); 4226 4211 if (active) { 4227 4212 perf_pmu_disable(ctx->pmu); 4213 + /* 4214 + * We could be throttled; unthrottle now to avoid the tick 4215 + * trying to unthrottle while we already re-started the event. 4216 + */ 4217 + if (event->hw.interrupts == MAX_INTERRUPTS) { 4218 + event->hw.interrupts = 0; 4219 + perf_log_throttle(event, 1); 4220 + } 4228 4221 event->pmu->stop(event, PERF_EF_UPDATE); 4229 4222 } 4230 4223 ··· 9449 9426 switch (action & ~CPU_TASKS_FROZEN) { 9450 9427 9451 9428 case CPU_UP_PREPARE: 9429 + /* 9430 + * This must be done before the CPU comes alive, because the 9431 + * moment we can run tasks we can encounter (software) events. 9432 + * 9433 + * Specifically, someone can have inherited events on kthreadd 9434 + * or a pre-existing worker thread that gets re-bound. 9435 + */ 9452 9436 perf_event_init_cpu(cpu); 9453 9437 break; 9454 9438 9455 9439 case CPU_DOWN_PREPARE: 9440 + /* 9441 + * This must be done before the CPU dies because after that an 9442 + * active event might want to IPI the CPU and that'll not work 9443 + * so great for dead CPUs. 9444 + * 9445 + * XXX smp_call_function_single() return -ENXIO without a warn 9446 + * so we could possibly deal with this. 9447 + * 9448 + * This is safe against new events arriving because 9449 + * sys_perf_event_open() serializes against hotplug using 9450 + * get_online_cpus(). 9451 + */ 9456 9452 perf_event_exit_cpu(cpu); 9457 9453 break; 9458 9454 default:
+4 -2
kernel/events/ring_buffer.c
··· 746 746 747 747 rb->user_page = all_buf; 748 748 rb->data_pages[0] = all_buf + PAGE_SIZE; 749 - rb->page_order = ilog2(nr_pages); 750 - rb->nr_pages = !!nr_pages; 749 + if (nr_pages) { 750 + rb->nr_pages = 1; 751 + rb->page_order = ilog2(nr_pages); 752 + } 751 753 752 754 ring_buffer_init(rb, watermark, flags); 753 755
+12
tools/include/linux/stringify.h
··· 1 + #ifndef __LINUX_STRINGIFY_H 2 + #define __LINUX_STRINGIFY_H 3 + 4 + /* Indirect stringification. Doing two levels allows the parameter to be a 5 + * macro itself. For example, compile with -DFOO=bar, __stringify(FOO) 6 + * converts to "bar". 7 + */ 8 + 9 + #define __stringify_1(x...) #x 10 + #define __stringify(x...) __stringify_1(x) 11 + 12 + #endif /* !__LINUX_STRINGIFY_H */
+1 -1
tools/lib/api/Makefile
··· 1 1 include ../../scripts/Makefile.include 2 - include ../../perf/config/utilities.mak # QUIET_CLEAN 2 + include ../../scripts/utilities.mak # QUIET_CLEAN 3 3 4 4 ifeq ($(srctree),) 5 5 srctree := $(patsubst %/,%,$(dir $(shell pwd)))
+1 -1
tools/lib/subcmd/Makefile
··· 1 1 include ../../scripts/Makefile.include 2 - include ../../perf/config/utilities.mak # QUIET_CLEAN 2 + include ../../scripts/utilities.mak # QUIET_CLEAN 3 3 4 4 ifeq ($(srctree),) 5 5 srctree := $(patsubst %/,%,$(dir $(shell pwd)))
+1 -3
tools/lib/traceevent/event-parse.c
··· 5427 5427 } 5428 5428 5429 5429 if (pevent->latency_format) { 5430 - trace_seq_printf(s, " %3d", record->cpu); 5431 5430 pevent_data_lat_fmt(pevent, s, record); 5432 - } else 5433 - trace_seq_printf(s, " [%03d]", record->cpu); 5431 + } 5434 5432 5435 5433 if (use_usec_format) { 5436 5434 if (pevent->flags & PEVENT_NSEC_OUTPUT) {
+1 -1
tools/perf/Documentation/Makefile
··· 1 1 include ../../scripts/Makefile.include 2 - include ../config/utilities.mak 2 + include ../../scripts/utilities.mak 3 3 4 4 MAN1_TXT= \ 5 5 $(filter-out $(addsuffix .txt, $(ARTICLES) $(SP_ARTICLES)), \
+4 -2
tools/perf/Documentation/perf-list.txt
··· 40 40 0 - SAMPLE_IP can have arbitrary skid 41 41 1 - SAMPLE_IP must have constant skid 42 42 2 - SAMPLE_IP requested to have 0 skid 43 - 3 - SAMPLE_IP must have 0 skid 43 + 3 - SAMPLE_IP must have 0 skid, or uses randomization to avoid 44 + sample shadowing effects. 44 45 45 46 For Intel systems precise event sampling is implemented with PEBS 46 - which supports up to precise-level 2. 47 + which supports up to precise-level 2, and precise level 3 for 48 + some special cases 47 49 48 50 On AMD systems it is implemented using IBS (up to precise-level 2). 49 51 The precise modifier works with event types 0x76 (cpu-cycles, CPU
+1 -1
tools/perf/Makefile.perf
··· 3 3 # The default target of this Makefile is... 4 4 all: 5 5 6 - include config/utilities.mak 6 + include ../scripts/utilities.mak 7 7 8 8 # Define V to have a more verbose compile. 9 9 #
+1 -3
tools/perf/arch/powerpc/util/header.c
··· 3 3 #include <stdio.h> 4 4 #include <stdlib.h> 5 5 #include <string.h> 6 - 7 - #include "../../util/header.h" 8 - #include "../../util/util.h" 6 + #include <linux/stringify.h> 9 7 10 8 #define mfspr(rn) ({unsigned long rval; \ 11 9 asm volatile("mfspr %0," __stringify(rn) \
+10 -12
tools/perf/bench/bench.h
··· 25 25 # endif 26 26 #endif 27 27 28 - extern int bench_numa(int argc, const char **argv, const char *prefix); 29 - extern int bench_sched_messaging(int argc, const char **argv, const char *prefix); 30 - extern int bench_sched_pipe(int argc, const char **argv, const char *prefix); 31 - extern int bench_mem_memcpy(int argc, const char **argv, 32 - const char *prefix __maybe_unused); 33 - extern int bench_mem_memset(int argc, const char **argv, const char *prefix); 34 - extern int bench_futex_hash(int argc, const char **argv, const char *prefix); 35 - extern int bench_futex_wake(int argc, const char **argv, const char *prefix); 36 - extern int bench_futex_wake_parallel(int argc, const char **argv, 37 - const char *prefix); 38 - extern int bench_futex_requeue(int argc, const char **argv, const char *prefix); 28 + int bench_numa(int argc, const char **argv, const char *prefix); 29 + int bench_sched_messaging(int argc, const char **argv, const char *prefix); 30 + int bench_sched_pipe(int argc, const char **argv, const char *prefix); 31 + int bench_mem_memcpy(int argc, const char **argv, const char *prefix); 32 + int bench_mem_memset(int argc, const char **argv, const char *prefix); 33 + int bench_futex_hash(int argc, const char **argv, const char *prefix); 34 + int bench_futex_wake(int argc, const char **argv, const char *prefix); 35 + int bench_futex_wake_parallel(int argc, const char **argv, const char *prefix); 36 + int bench_futex_requeue(int argc, const char **argv, const char *prefix); 39 37 /* pi futexes */ 40 - extern int bench_futex_lock_pi(int argc, const char **argv, const char *prefix); 38 + int bench_futex_lock_pi(int argc, const char **argv, const char *prefix); 41 39 42 40 #define BENCH_FORMAT_DEFAULT_STR "default" 43 41 #define BENCH_FORMAT_DEFAULT 0
+1 -1
tools/perf/bench/mem-memcpy-arch.h
··· 2 2 #ifdef HAVE_ARCH_X86_64_SUPPORT 3 3 4 4 #define MEMCPY_FN(fn, name, desc) \ 5 - extern void *fn(void *, const void *, size_t); 5 + void *fn(void *, const void *, size_t); 6 6 7 7 #include "mem-memcpy-x86-64-asm-def.h" 8 8
+1 -1
tools/perf/bench/mem-memset-arch.h
··· 2 2 #ifdef HAVE_ARCH_X86_64_SUPPORT 3 3 4 4 #define MEMSET_FN(fn, name, desc) \ 5 - extern void *fn(void *, int, size_t); 5 + void *fn(void *, int, size_t); 6 6 7 7 #include "mem-memset-x86-64-asm-def.h" 8 8
+1 -1
tools/perf/bench/numa.c
··· 293 293 if (node == -1) 294 294 return; 295 295 296 - BUG_ON(g->p.nr_nodes > (int)sizeof(nodemask)); 296 + BUG_ON(g->p.nr_nodes > (int)sizeof(nodemask)*8); 297 297 nodemask = 1L << node; 298 298 299 299 ret = set_mempolicy(MPOL_BIND, &nodemask, sizeof(nodemask)*8);
+1 -1
tools/perf/builtin-annotate.c
··· 94 94 struct addr_location al; 95 95 int ret = 0; 96 96 97 - if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { 97 + if (machine__resolve(machine, &al, sample) < 0) { 98 98 pr_warning("problem processing %d event, skipping it.\n", 99 99 event->header.type); 100 100 return -1;
+1 -1
tools/perf/builtin-diff.c
··· 330 330 struct hists *hists = evsel__hists(evsel); 331 331 int ret = -1; 332 332 333 - if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { 333 + if (machine__resolve(machine, &al, sample) < 0) { 334 334 pr_warning("problem processing %d event, skipping it.\n", 335 335 event->header.type); 336 336 return -1;
+31 -38
tools/perf/builtin-help.c
··· 106 106 107 107 if (!check_emacsclient_version()) { 108 108 /* This works only with emacsclient version >= 22. */ 109 - struct strbuf man_page = STRBUF_INIT; 109 + char *man_page; 110 110 111 111 if (!path) 112 112 path = "emacsclient"; 113 - strbuf_addf(&man_page, "(woman \"%s\")", page); 114 - execlp(path, "emacsclient", "-e", man_page.buf, NULL); 113 + if (asprintf(&man_page, "(woman \"%s\")", page) > 0) { 114 + execlp(path, "emacsclient", "-e", man_page, NULL); 115 + free(man_page); 116 + } 115 117 warning("failed to exec '%s': %s", path, 116 118 strerror_r(errno, sbuf, sizeof(sbuf))); 117 119 } ··· 124 122 const char *display = getenv("DISPLAY"); 125 123 126 124 if (display && *display) { 127 - struct strbuf man_page = STRBUF_INIT; 125 + char *man_page; 128 126 const char *filename = "kfmclient"; 129 127 char sbuf[STRERR_BUFSIZE]; 130 128 ··· 143 141 filename = file; 144 142 } else 145 143 path = "kfmclient"; 146 - strbuf_addf(&man_page, "man:%s(1)", page); 147 - execlp(path, filename, "newTab", man_page.buf, NULL); 144 + if (asprintf(&man_page, "man:%s(1)", page) > 0) { 145 + execlp(path, filename, "newTab", man_page, NULL); 146 + free(man_page); 147 + } 148 148 warning("failed to exec '%s': %s", path, 149 149 strerror_r(errno, sbuf, sizeof(sbuf))); 150 150 } ··· 165 161 166 162 static void exec_man_cmd(const char *cmd, const char *page) 167 163 { 168 - struct strbuf shell_cmd = STRBUF_INIT; 169 164 char sbuf[STRERR_BUFSIZE]; 165 + char *shell_cmd; 170 166 171 - strbuf_addf(&shell_cmd, "%s %s", cmd, page); 172 - execl("/bin/sh", "sh", "-c", shell_cmd.buf, NULL); 167 + if (asprintf(&shell_cmd, "%s %s", cmd, page) > 0) { 168 + execl("/bin/sh", "sh", "-c", shell_cmd, NULL); 169 + free(shell_cmd); 170 + } 173 171 warning("failed to exec '%s': %s", cmd, 174 172 strerror_r(errno, sbuf, sizeof(sbuf))); 175 173 } ··· 305 299 is_in_cmdlist(&other_cmds, s); 306 300 } 307 301 308 - static const char *prepend(const char *prefix, const char *cmd) 309 - { 310 - size_t pre_len = strlen(prefix); 311 - size_t cmd_len = strlen(cmd); 312 - char *p = malloc(pre_len + cmd_len + 1); 313 - memcpy(p, prefix, pre_len); 314 - strcpy(p + pre_len, cmd); 315 - return p; 316 - } 317 - 318 302 static const char *cmd_to_page(const char *perf_cmd) 319 303 { 304 + char *s; 305 + 320 306 if (!perf_cmd) 321 307 return "perf"; 322 308 else if (!prefixcmp(perf_cmd, "perf")) 323 309 return perf_cmd; 324 - else 325 - return prepend("perf-", perf_cmd); 310 + 311 + return asprintf(&s, "perf-%s", perf_cmd) < 0 ? NULL : s; 326 312 } 327 313 328 314 static void setup_man_path(void) 329 315 { 330 - struct strbuf new_path = STRBUF_INIT; 316 + char *new_path; 331 317 const char *old_path = getenv("MANPATH"); 332 318 333 319 /* We should always put ':' after our path. If there is no 334 320 * old_path, the ':' at the end will let 'man' to try 335 321 * system-wide paths after ours to find the manual page. If 336 322 * there is old_path, we need ':' as delimiter. */ 337 - strbuf_addstr(&new_path, system_path(PERF_MAN_PATH)); 338 - strbuf_addch(&new_path, ':'); 339 - if (old_path) 340 - strbuf_addstr(&new_path, old_path); 341 - 342 - setenv("MANPATH", new_path.buf, 1); 343 - 344 - strbuf_release(&new_path); 323 + if (asprintf(&new_path, "%s:%s", system_path(PERF_MAN_PATH), old_path ?: "") > 0) { 324 + setenv("MANPATH", new_path, 1); 325 + free(new_path); 326 + } else { 327 + error("Unable to setup man path"); 328 + } 345 329 } 346 330 347 331 static void exec_viewer(const char *name, const char *page) ··· 376 380 return -1; 377 381 } 378 382 379 - static int get_html_page_path(struct strbuf *page_path, const char *page) 383 + static int get_html_page_path(char **page_path, const char *page) 380 384 { 381 385 struct stat st; 382 386 const char *html_path = system_path(PERF_HTML_PATH); ··· 388 392 return -1; 389 393 } 390 394 391 - strbuf_init(page_path, 0); 392 - strbuf_addf(page_path, "%s/%s.html", html_path, page); 393 - 394 - return 0; 395 + return asprintf(page_path, "%s/%s.html", html_path, page); 395 396 } 396 397 397 398 /* ··· 406 413 static int show_html_page(const char *perf_cmd) 407 414 { 408 415 const char *page = cmd_to_page(perf_cmd); 409 - struct strbuf page_path; /* it leaks but we exec bellow */ 416 + char *page_path; /* it leaks but we exec bellow */ 410 417 411 - if (get_html_page_path(&page_path, page) != 0) 418 + if (get_html_page_path(&page_path, page) < 0) 412 419 return -1; 413 420 414 - open_html(page_path.buf); 421 + open_html(page_path); 415 422 416 423 return 0; 417 424 }
+2 -6
tools/perf/builtin-inject.c
··· 131 131 132 132 static s64 perf_event__repipe_auxtrace(struct perf_tool *tool, 133 133 union perf_event *event, 134 - struct perf_session *session 135 - __maybe_unused) 134 + struct perf_session *session) 136 135 { 137 136 struct perf_inject *inject = container_of(tool, struct perf_inject, 138 137 tool); ··· 416 417 { 417 418 struct addr_location al; 418 419 struct thread *thread; 419 - u8 cpumode; 420 - 421 - cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 422 420 423 421 thread = machine__findnew_thread(machine, sample->pid, sample->tid); 424 422 if (thread == NULL) { ··· 424 428 goto repipe; 425 429 } 426 430 427 - thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->ip, &al); 431 + thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, sample->ip, &al); 428 432 429 433 if (al.map != NULL) { 430 434 if (!al.map->dso->hit) {
+1 -1
tools/perf/builtin-mem.c
··· 131 131 struct addr_location al; 132 132 const char *fmt; 133 133 134 - if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { 134 + if (machine__resolve(machine, &al, sample) < 0) { 135 135 fprintf(stderr, "problem processing %d event, skipping it.\n", 136 136 event->header.type); 137 137 return -1;
+2 -1
tools/perf/builtin-report.c
··· 41 41 42 42 #include <dlfcn.h> 43 43 #include <linux/bitmap.h> 44 + #include <linux/stringify.h> 44 45 45 46 struct report { 46 47 struct perf_tool tool; ··· 155 154 }; 156 155 int ret = 0; 157 156 158 - if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { 157 + if (machine__resolve(machine, &al, sample) < 0) { 159 158 pr_debug("problem processing %d event, skipping it.\n", 160 159 event->header.type); 161 160 return -1;
+18 -28
tools/perf/builtin-script.c
··· 405 405 return 0; 406 406 } 407 407 408 - static void print_sample_iregs(union perf_event *event __maybe_unused, 409 - struct perf_sample *sample, 410 - struct thread *thread __maybe_unused, 408 + static void print_sample_iregs(struct perf_sample *sample, 411 409 struct perf_event_attr *attr) 412 410 { 413 411 struct regs_dump *regs = &sample->intr_regs; ··· 474 476 return br->flags.predicted ? 'P' : 'M'; 475 477 } 476 478 477 - static void print_sample_brstack(union perf_event *event __maybe_unused, 478 - struct perf_sample *sample, 479 - struct thread *thread __maybe_unused, 480 - struct perf_event_attr *attr __maybe_unused) 479 + static void print_sample_brstack(struct perf_sample *sample) 481 480 { 482 481 struct branch_stack *br = sample->branch_stack; 483 482 u64 i; ··· 493 498 } 494 499 } 495 500 496 - static void print_sample_brstacksym(union perf_event *event __maybe_unused, 497 - struct perf_sample *sample, 498 - struct thread *thread __maybe_unused, 499 - struct perf_event_attr *attr __maybe_unused) 501 + static void print_sample_brstacksym(struct perf_sample *sample, 502 + struct thread *thread) 500 503 { 501 504 struct branch_stack *br = sample->branch_stack; 502 505 struct addr_location alf, alt; 503 - u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 504 506 u64 i, from, to; 505 507 506 508 if (!(br && br->nr)) ··· 510 518 from = br->entries[i].from; 511 519 to = br->entries[i].to; 512 520 513 - thread__find_addr_map(thread, cpumode, MAP__FUNCTION, from, &alf); 521 + thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, from, &alf); 514 522 if (alf.map) 515 523 alf.sym = map__find_symbol(alf.map, alf.addr, NULL); 516 524 517 - thread__find_addr_map(thread, cpumode, MAP__FUNCTION, to, &alt); 525 + thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, to, &alt); 518 526 if (alt.map) 519 527 alt.sym = map__find_symbol(alt.map, alt.addr, NULL); 520 528 ··· 530 538 } 531 539 532 540 533 - static void print_sample_addr(union perf_event *event, 534 - struct perf_sample *sample, 541 + static void print_sample_addr(struct perf_sample *sample, 535 542 struct thread *thread, 536 543 struct perf_event_attr *attr) 537 544 { ··· 541 550 if (!sample_addr_correlates_sym(attr)) 542 551 return; 543 552 544 - perf_event__preprocess_sample_addr(event, sample, thread, &al); 553 + thread__resolve(thread, &al, sample); 545 554 546 555 if (PRINT_FIELD(SYM)) { 547 556 printf(" "); ··· 558 567 } 559 568 } 560 569 561 - static void print_sample_bts(union perf_event *event, 562 - struct perf_sample *sample, 570 + static void print_sample_bts(struct perf_sample *sample, 563 571 struct perf_evsel *evsel, 564 572 struct thread *thread, 565 573 struct addr_location *al) ··· 588 598 ((evsel->attr.sample_type & PERF_SAMPLE_ADDR) && 589 599 !output[attr->type].user_set)) { 590 600 printf(" => "); 591 - print_sample_addr(event, sample, thread, attr); 601 + print_sample_addr(sample, thread, attr); 592 602 } 593 603 594 604 if (print_srcline_last) ··· 737 747 return printf("%-*s", maxlen, out); 738 748 } 739 749 740 - static void process_event(struct perf_script *script, union perf_event *event, 750 + static void process_event(struct perf_script *script, 741 751 struct perf_sample *sample, struct perf_evsel *evsel, 742 752 struct addr_location *al) 743 753 { ··· 766 776 print_sample_flags(sample->flags); 767 777 768 778 if (is_bts_event(attr)) { 769 - print_sample_bts(event, sample, evsel, thread, al); 779 + print_sample_bts(sample, evsel, thread, al); 770 780 return; 771 781 } 772 782 ··· 774 784 event_format__print(evsel->tp_format, sample->cpu, 775 785 sample->raw_data, sample->raw_size); 776 786 if (PRINT_FIELD(ADDR)) 777 - print_sample_addr(event, sample, thread, attr); 787 + print_sample_addr(sample, thread, attr); 778 788 779 789 if (PRINT_FIELD(DATA_SRC)) 780 790 data_src__printf(sample->data_src); ··· 794 804 } 795 805 796 806 if (PRINT_FIELD(IREGS)) 797 - print_sample_iregs(event, sample, thread, attr); 807 + print_sample_iregs(sample, attr); 798 808 799 809 if (PRINT_FIELD(BRSTACK)) 800 - print_sample_brstack(event, sample, thread, attr); 810 + print_sample_brstack(sample); 801 811 else if (PRINT_FIELD(BRSTACKSYM)) 802 - print_sample_brstacksym(event, sample, thread, attr); 812 + print_sample_brstacksym(sample, thread); 803 813 804 814 if (perf_evsel__is_bpf_output(evsel) && PRINT_FIELD(BPF_OUTPUT)) 805 815 print_sample_bpf_output(sample); ··· 895 905 return 0; 896 906 } 897 907 898 - if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { 908 + if (machine__resolve(machine, &al, sample) < 0) { 899 909 pr_err("problem processing %d event, skipping it.\n", 900 910 event->header.type); 901 911 return -1; ··· 910 920 if (scripting_ops) 911 921 scripting_ops->process_event(event, sample, evsel, &al); 912 922 else 913 - process_event(scr, event, sample, evsel, &al); 923 + process_event(scr, sample, evsel, &al); 914 924 915 925 out_put: 916 926 addr_location__put(&al);
+1 -1
tools/perf/builtin-timechart.c
··· 489 489 if (!chain) 490 490 goto exit; 491 491 492 - if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) { 492 + if (machine__resolve(machine, &al, sample) < 0) { 493 493 fprintf(stderr, "problem processing %d event, skipping it.\n", 494 494 event->header.type); 495 495 goto exit;
+3 -5
tools/perf/builtin-top.c
··· 67 67 #include <sys/utsname.h> 68 68 #include <sys/mman.h> 69 69 70 + #include <linux/stringify.h> 70 71 #include <linux/types.h> 71 72 72 73 static volatile int done; ··· 729 728 if (event->header.misc & PERF_RECORD_MISC_EXACT_IP) 730 729 top->exact_samples++; 731 730 732 - if (perf_event__preprocess_sample(event, machine, &al, sample) < 0) 731 + if (machine__resolve(machine, &al, sample) < 0) 733 732 return; 734 733 735 734 if (!top->kptr_restrict_warned && ··· 810 809 struct perf_session *session = top->session; 811 810 union perf_event *event; 812 811 struct machine *machine; 813 - u8 origin; 814 812 int ret; 815 813 816 814 while ((event = perf_evlist__mmap_read(top->evlist, idx)) != NULL) { ··· 822 822 evsel = perf_evlist__id2evsel(session->evlist, sample.id); 823 823 assert(evsel != NULL); 824 824 825 - origin = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 826 - 827 825 if (event->header.type == PERF_RECORD_SAMPLE) 828 826 ++top->samples; 829 827 830 - switch (origin) { 828 + switch (sample.cpumode) { 831 829 case PERF_RECORD_MISC_USER: 832 830 ++top->us_samples; 833 831 if (top->hide_user_symbols)
+4 -5
tools/perf/builtin-trace.c
··· 2256 2256 2257 2257 static int trace__pgfault(struct trace *trace, 2258 2258 struct perf_evsel *evsel, 2259 - union perf_event *event, 2259 + union perf_event *event __maybe_unused, 2260 2260 struct perf_sample *sample) 2261 2261 { 2262 2262 struct thread *thread; 2263 - u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 2264 2263 struct addr_location al; 2265 2264 char map_type = 'd'; 2266 2265 struct thread_trace *ttrace; ··· 2278 2279 if (trace->summary_only) 2279 2280 goto out; 2280 2281 2281 - thread__find_addr_location(thread, cpumode, MAP__FUNCTION, 2282 + thread__find_addr_location(thread, sample->cpumode, MAP__FUNCTION, 2282 2283 sample->ip, &al); 2283 2284 2284 2285 trace__fprintf_entry_head(trace, thread, 0, sample->time, trace->output); ··· 2291 2292 2292 2293 fprintf(trace->output, "] => "); 2293 2294 2294 - thread__find_addr_location(thread, cpumode, MAP__VARIABLE, 2295 + thread__find_addr_location(thread, sample->cpumode, MAP__VARIABLE, 2295 2296 sample->addr, &al); 2296 2297 2297 2298 if (!al.map) { 2298 - thread__find_addr_location(thread, cpumode, 2299 + thread__find_addr_location(thread, sample->cpumode, 2299 2300 MAP__FUNCTION, sample->addr, &al); 2300 2301 2301 2302 if (al.map)
+32 -32
tools/perf/builtin.h
··· 7 7 extern const char perf_usage_string[]; 8 8 extern const char perf_more_info_string[]; 9 9 10 - extern void list_common_cmds_help(void); 11 - extern const char *help_unknown_cmd(const char *cmd); 12 - extern void prune_packed_objects(int); 13 - extern int read_line_with_nul(char *buf, int size, FILE *file); 14 - extern int check_pager_config(const char *cmd); 10 + void list_common_cmds_help(void); 11 + const char *help_unknown_cmd(const char *cmd); 12 + void prune_packed_objects(int); 13 + int read_line_with_nul(char *buf, int size, FILE *file); 14 + int check_pager_config(const char *cmd); 15 15 16 - extern int cmd_annotate(int argc, const char **argv, const char *prefix); 17 - extern int cmd_bench(int argc, const char **argv, const char *prefix); 18 - extern int cmd_buildid_cache(int argc, const char **argv, const char *prefix); 19 - extern int cmd_buildid_list(int argc, const char **argv, const char *prefix); 20 - extern int cmd_config(int argc, const char **argv, const char *prefix); 21 - extern int cmd_diff(int argc, const char **argv, const char *prefix); 22 - extern int cmd_evlist(int argc, const char **argv, const char *prefix); 23 - extern int cmd_help(int argc, const char **argv, const char *prefix); 24 - extern int cmd_sched(int argc, const char **argv, const char *prefix); 25 - extern int cmd_list(int argc, const char **argv, const char *prefix); 26 - extern int cmd_record(int argc, const char **argv, const char *prefix); 27 - extern int cmd_report(int argc, const char **argv, const char *prefix); 28 - extern int cmd_stat(int argc, const char **argv, const char *prefix); 29 - extern int cmd_timechart(int argc, const char **argv, const char *prefix); 30 - extern int cmd_top(int argc, const char **argv, const char *prefix); 31 - extern int cmd_script(int argc, const char **argv, const char *prefix); 32 - extern int cmd_version(int argc, const char **argv, const char *prefix); 33 - extern int cmd_probe(int argc, const char **argv, const char *prefix); 34 - extern int cmd_kmem(int argc, const char **argv, const char *prefix); 35 - extern int cmd_lock(int argc, const char **argv, const char *prefix); 36 - extern int cmd_kvm(int argc, const char **argv, const char *prefix); 37 - extern int cmd_test(int argc, const char **argv, const char *prefix); 38 - extern int cmd_trace(int argc, const char **argv, const char *prefix); 39 - extern int cmd_inject(int argc, const char **argv, const char *prefix); 40 - extern int cmd_mem(int argc, const char **argv, const char *prefix); 41 - extern int cmd_data(int argc, const char **argv, const char *prefix); 16 + int cmd_annotate(int argc, const char **argv, const char *prefix); 17 + int cmd_bench(int argc, const char **argv, const char *prefix); 18 + int cmd_buildid_cache(int argc, const char **argv, const char *prefix); 19 + int cmd_buildid_list(int argc, const char **argv, const char *prefix); 20 + int cmd_config(int argc, const char **argv, const char *prefix); 21 + int cmd_diff(int argc, const char **argv, const char *prefix); 22 + int cmd_evlist(int argc, const char **argv, const char *prefix); 23 + int cmd_help(int argc, const char **argv, const char *prefix); 24 + int cmd_sched(int argc, const char **argv, const char *prefix); 25 + int cmd_list(int argc, const char **argv, const char *prefix); 26 + int cmd_record(int argc, const char **argv, const char *prefix); 27 + int cmd_report(int argc, const char **argv, const char *prefix); 28 + int cmd_stat(int argc, const char **argv, const char *prefix); 29 + int cmd_timechart(int argc, const char **argv, const char *prefix); 30 + int cmd_top(int argc, const char **argv, const char *prefix); 31 + int cmd_script(int argc, const char **argv, const char *prefix); 32 + int cmd_version(int argc, const char **argv, const char *prefix); 33 + int cmd_probe(int argc, const char **argv, const char *prefix); 34 + int cmd_kmem(int argc, const char **argv, const char *prefix); 35 + int cmd_lock(int argc, const char **argv, const char *prefix); 36 + int cmd_kvm(int argc, const char **argv, const char *prefix); 37 + int cmd_test(int argc, const char **argv, const char *prefix); 38 + int cmd_trace(int argc, const char **argv, const char *prefix); 39 + int cmd_inject(int argc, const char **argv, const char *prefix); 40 + int cmd_mem(int argc, const char **argv, const char *prefix); 41 + int cmd_data(int argc, const char **argv, const char *prefix); 42 42 43 - extern int find_scripts(char **scripts_array, char **scripts_path_array); 43 + int find_scripts(char **scripts_array, char **scripts_path_array); 44 44 #endif
+1 -1
tools/perf/config/Makefile
··· 109 109 CFLAGS += -DHAVE_ARCH_REGS_QUERY_REGISTER_OFFSET 110 110 endif 111 111 112 - include $(src-perf)/config/utilities.mak 112 + include $(srctree)/tools/scripts/utilities.mak 113 113 114 114 ifeq ($(call get-executable,$(FLEX)),) 115 115 dummy := $(error Error: $(FLEX) is missing on this system, please install it)
tools/perf/config/utilities.mak tools/scripts/utilities.mak
+1 -4
tools/perf/tests/code-reading.c
··· 293 293 { 294 294 struct perf_sample sample; 295 295 struct thread *thread; 296 - u8 cpumode; 297 296 int ret; 298 297 299 298 if (perf_evlist__parse_sample(evlist, event, &sample)) { ··· 306 307 return -1; 307 308 } 308 309 309 - cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 310 - 311 - ret = read_object_code(sample.ip, READLEN, cpumode, thread, state); 310 + ret = read_object_code(sample.ip, READLEN, sample.cpumode, thread, state); 312 311 thread__put(thread); 313 312 return ret; 314 313 }
+2 -2
tools/perf/tests/dwarf-unwind.c
··· 20 20 21 21 static int mmap_handler(struct perf_tool *tool __maybe_unused, 22 22 union perf_event *event, 23 - struct perf_sample *sample __maybe_unused, 23 + struct perf_sample *sample, 24 24 struct machine *machine) 25 25 { 26 - return machine__process_mmap2_event(machine, event, NULL); 26 + return machine__process_mmap2_event(machine, event, sample); 27 27 } 28 28 29 29 static int init_live_machine(struct machine *machine)
+4 -2
tools/perf/tests/hists_common.c
··· 100 100 } 101 101 102 102 for (i = 0; i < ARRAY_SIZE(fake_mmap_info); i++) { 103 + struct perf_sample sample = { 104 + .cpumode = PERF_RECORD_MISC_USER, 105 + }; 103 106 union perf_event fake_mmap_event = { 104 107 .mmap = { 105 - .header = { .misc = PERF_RECORD_MISC_USER, }, 106 108 .pid = fake_mmap_info[i].pid, 107 109 .tid = fake_mmap_info[i].pid, 108 110 .start = fake_mmap_info[i].start, ··· 116 114 strcpy(fake_mmap_event.mmap.filename, 117 115 fake_mmap_info[i].filename); 118 116 119 - machine__process_mmap_event(machine, &fake_mmap_event, NULL); 117 + machine__process_mmap_event(machine, &fake_mmap_event, &sample); 120 118 } 121 119 122 120 for (i = 0; i < ARRAY_SIZE(fake_symbols); i++) {
+2 -7
tools/perf/tests/hists_cumulate.c
··· 81 81 size_t i; 82 82 83 83 for (i = 0; i < ARRAY_SIZE(fake_samples); i++) { 84 - const union perf_event event = { 85 - .header = { 86 - .misc = PERF_RECORD_MISC_USER, 87 - }, 88 - }; 89 84 struct hist_entry_iter iter = { 90 85 .evsel = evsel, 91 86 .sample = &sample, ··· 92 97 else 93 98 iter.ops = &hist_iter_normal; 94 99 100 + sample.cpumode = PERF_RECORD_MISC_USER; 95 101 sample.pid = fake_samples[i].pid; 96 102 sample.tid = fake_samples[i].pid; 97 103 sample.ip = fake_samples[i].ip; 98 104 sample.callchain = (struct ip_callchain *)fake_callchains[i]; 99 105 100 - if (perf_event__preprocess_sample(&event, machine, &al, 101 - &sample) < 0) 106 + if (machine__resolve(machine, &al, &sample) < 0) 102 107 goto out; 103 108 104 109 if (hist_entry_iter__add(&iter, &al, PERF_MAX_STACK_DEPTH,
+2 -7
tools/perf/tests/hists_filter.c
··· 58 58 */ 59 59 evlist__for_each(evlist, evsel) { 60 60 for (i = 0; i < ARRAY_SIZE(fake_samples); i++) { 61 - const union perf_event event = { 62 - .header = { 63 - .misc = PERF_RECORD_MISC_USER, 64 - }, 65 - }; 66 61 struct hist_entry_iter iter = { 67 62 .evsel = evsel, 68 63 .sample = &sample, ··· 71 76 hists->dso_filter = NULL; 72 77 hists->symbol_filter_str = NULL; 73 78 79 + sample.cpumode = PERF_RECORD_MISC_USER; 74 80 sample.pid = fake_samples[i].pid; 75 81 sample.tid = fake_samples[i].pid; 76 82 sample.ip = fake_samples[i].ip; 77 83 78 - if (perf_event__preprocess_sample(&event, machine, &al, 79 - &sample) < 0) 84 + if (machine__resolve(machine, &al, &sample) < 0) 80 85 goto out; 81 86 82 87 al.socket = fake_samples[i].socket;
+4 -16
tools/perf/tests/hists_link.c
··· 76 76 struct hists *hists = evsel__hists(evsel); 77 77 78 78 for (k = 0; k < ARRAY_SIZE(fake_common_samples); k++) { 79 - const union perf_event event = { 80 - .header = { 81 - .misc = PERF_RECORD_MISC_USER, 82 - }, 83 - }; 84 - 79 + sample.cpumode = PERF_RECORD_MISC_USER; 85 80 sample.pid = fake_common_samples[k].pid; 86 81 sample.tid = fake_common_samples[k].pid; 87 82 sample.ip = fake_common_samples[k].ip; 88 - if (perf_event__preprocess_sample(&event, machine, &al, 89 - &sample) < 0) 83 + 84 + if (machine__resolve(machine, &al, &sample) < 0) 90 85 goto out; 91 86 92 87 he = __hists__add_entry(hists, &al, NULL, ··· 97 102 } 98 103 99 104 for (k = 0; k < ARRAY_SIZE(fake_samples[i]); k++) { 100 - const union perf_event event = { 101 - .header = { 102 - .misc = PERF_RECORD_MISC_USER, 103 - }, 104 - }; 105 - 106 105 sample.pid = fake_samples[i][k].pid; 107 106 sample.tid = fake_samples[i][k].pid; 108 107 sample.ip = fake_samples[i][k].ip; 109 - if (perf_event__preprocess_sample(&event, machine, &al, 110 - &sample) < 0) 108 + if (machine__resolve(machine, &al, &sample) < 0) 111 109 goto out; 112 110 113 111 he = __hists__add_entry(hists, &al, NULL,
+2 -7
tools/perf/tests/hists_output.c
··· 51 51 size_t i; 52 52 53 53 for (i = 0; i < ARRAY_SIZE(fake_samples); i++) { 54 - const union perf_event event = { 55 - .header = { 56 - .misc = PERF_RECORD_MISC_USER, 57 - }, 58 - }; 59 54 struct hist_entry_iter iter = { 60 55 .evsel = evsel, 61 56 .sample = &sample, ··· 58 63 .hide_unresolved = false, 59 64 }; 60 65 66 + sample.cpumode = PERF_RECORD_MISC_USER; 61 67 sample.cpu = fake_samples[i].cpu; 62 68 sample.pid = fake_samples[i].pid; 63 69 sample.tid = fake_samples[i].pid; 64 70 sample.ip = fake_samples[i].ip; 65 71 66 - if (perf_event__preprocess_sample(&event, machine, &al, 67 - &sample) < 0) 72 + if (machine__resolve(machine, &al, &sample) < 0) 68 73 goto out; 69 74 70 75 if (hist_entry_iter__add(&iter, &al, PERF_MAX_STACK_DEPTH,
+1 -1
tools/perf/ui/gtk/hists.c
··· 55 55 return he->stat_acc->_field; \ 56 56 } \ 57 57 \ 58 - static int perf_gtk__hpp_color_##_type(struct perf_hpp_fmt *fmt __maybe_unused, \ 58 + static int perf_gtk__hpp_color_##_type(struct perf_hpp_fmt *fmt, \ 59 59 struct perf_hpp *hpp, \ 60 60 struct hist_entry *he) \ 61 61 { \
-1
tools/perf/util/Build
··· 1 - libperf-y += abspath.o 2 1 libperf-y += alias.o 3 2 libperf-y += annotate.o 4 3 libperf-y += build-id.o
-37
tools/perf/util/abspath.c
··· 1 - #include "cache.h" 2 - 3 - static const char *get_pwd_cwd(void) 4 - { 5 - static char cwd[PATH_MAX + 1]; 6 - char *pwd; 7 - struct stat cwd_stat, pwd_stat; 8 - if (getcwd(cwd, PATH_MAX) == NULL) 9 - return NULL; 10 - pwd = getenv("PWD"); 11 - if (pwd && strcmp(pwd, cwd)) { 12 - stat(cwd, &cwd_stat); 13 - if (!stat(pwd, &pwd_stat) && 14 - pwd_stat.st_dev == cwd_stat.st_dev && 15 - pwd_stat.st_ino == cwd_stat.st_ino) { 16 - strlcpy(cwd, pwd, PATH_MAX); 17 - } 18 - } 19 - return cwd; 20 - } 21 - 22 - const char *make_nonrelative_path(const char *path) 23 - { 24 - static char buf[PATH_MAX + 1]; 25 - 26 - if (is_absolute_path(path)) { 27 - if (strlcpy(buf, path, PATH_MAX) >= PATH_MAX) 28 - die("Too long path: %.*s", 60, path); 29 - } else { 30 - const char *cwd = get_pwd_cwd(); 31 - if (!cwd) 32 - die("Cannot determine the current working directory"); 33 - if (snprintf(buf, PATH_MAX, "%s/%s", cwd, path) >= PATH_MAX) 34 - die("Too long path: %.*s", 60, path); 35 - } 36 - return buf; 37 - }
+1 -1
tools/perf/util/annotate.h
··· 158 158 159 159 int hist_entry__annotate(struct hist_entry *he, size_t privsize); 160 160 161 - int symbol__annotate_init(struct map *map __maybe_unused, struct symbol *sym); 161 + int symbol__annotate_init(struct map *map, struct symbol *sym); 162 162 int symbol__annotate_printf(struct symbol *sym, struct map *map, 163 163 struct perf_evsel *evsel, bool full_paths, 164 164 int min_pcnt, int max_lines, int context);
+1 -1
tools/perf/util/auxtrace.h
··· 517 517 518 518 static inline struct auxtrace_record * 519 519 auxtrace_record__init(struct perf_evlist *evlist __maybe_unused, 520 - int *err __maybe_unused) 520 + int *err) 521 521 { 522 522 *err = 0; 523 523 return NULL;
+1 -2
tools/perf/util/build-id.c
··· 28 28 struct machine *machine) 29 29 { 30 30 struct addr_location al; 31 - u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 32 31 struct thread *thread = machine__findnew_thread(machine, sample->pid, 33 32 sample->tid); 34 33 ··· 37 38 return -1; 38 39 } 39 40 40 - thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->ip, &al); 41 + thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, sample->ip, &al); 41 42 42 43 if (al.map != NULL) 43 44 al.map->dso->hit = 1;
+10 -14
tools/perf/util/cache.h
··· 26 26 extern const char *config_exclusive_filename; 27 27 28 28 typedef int (*config_fn_t)(const char *, const char *, void *); 29 - extern int perf_default_config(const char *, const char *, void *); 30 - extern int perf_config(config_fn_t fn, void *); 31 - extern int perf_config_int(const char *, const char *); 32 - extern u64 perf_config_u64(const char *, const char *); 33 - extern int perf_config_bool(const char *, const char *); 34 - extern int config_error_nonbool(const char *); 35 - extern const char *perf_config_dirname(const char *, const char *); 36 - extern const char *perf_etc_perfconfig(void); 29 + int perf_default_config(const char *, const char *, void *); 30 + int perf_config(config_fn_t fn, void *); 31 + int perf_config_int(const char *, const char *); 32 + u64 perf_config_u64(const char *, const char *); 33 + int perf_config_bool(const char *, const char *); 34 + int config_error_nonbool(const char *); 35 + const char *perf_config_dirname(const char *, const char *); 36 + const char *perf_etc_perfconfig(void); 37 37 38 38 char *alias_lookup(const char *alias); 39 39 int split_cmdline(char *cmdline, const char ***argv); ··· 64 64 return path[0] == '/'; 65 65 } 66 66 67 - const char *make_nonrelative_path(const char *path); 68 67 char *strip_path_suffix(const char *path, const char *suffix); 69 68 70 - extern char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2))); 71 - extern char *perf_path(const char *fmt, ...) __attribute__((format (printf, 1, 2))); 72 - 73 - extern char *perf_pathdup(const char *fmt, ...) 74 - __attribute__((format (printf, 1, 2))); 69 + char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2))); 70 + char *perf_path(const char *fmt, ...) __attribute__((format (printf, 1, 2))); 75 71 76 72 #endif /* __PERF_CACHE_H */
+2 -2
tools/perf/util/callchain.h
··· 220 220 bool hide_unresolved); 221 221 222 222 extern const char record_callchain_help[]; 223 - extern int parse_callchain_record(const char *arg, struct callchain_param *param); 223 + int parse_callchain_record(const char *arg, struct callchain_param *param); 224 224 int parse_callchain_record_opt(const char *arg, struct callchain_param *param); 225 225 int parse_callchain_report_opt(const char *arg); 226 226 int parse_callchain_top_opt(const char *arg); ··· 236 236 } 237 237 238 238 #ifdef HAVE_SKIP_CALLCHAIN_IDX 239 - extern int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain); 239 + int arch_skip_callchain_idx(struct thread *thread, struct ip_callchain *chain); 240 240 #else 241 241 static inline int arch_skip_callchain_idx(struct thread *thread __maybe_unused, 242 242 struct ip_callchain *chain __maybe_unused)
+2 -2
tools/perf/util/cgroup.h
··· 13 13 14 14 15 15 extern int nr_cgroups; /* number of explicit cgroups defined */ 16 - extern void close_cgroup(struct cgroup_sel *cgrp); 17 - extern int parse_cgroups(const struct option *opt, const char *str, int unset); 16 + void close_cgroup(struct cgroup_sel *cgrp); 17 + int parse_cgroups(const struct option *opt, const char *str, int unset); 18 18 19 19 #endif /* __CGROUP_H__ */
+1 -1
tools/perf/util/cloexec.h
··· 5 5 6 6 #ifdef __GLIBC_PREREQ 7 7 #if !__GLIBC_PREREQ(2, 6) && !defined(__UCLIBC__) 8 - extern int sched_getcpu(void) __THROW; 8 + int sched_getcpu(void) __THROW; 9 9 #endif 10 10 #endif 11 11
+1 -1
tools/perf/util/data-convert-bt.c
··· 632 632 } 633 633 634 634 static int process_sample_event(struct perf_tool *tool, 635 - union perf_event *_event __maybe_unused, 635 + union perf_event *_event, 636 636 struct perf_sample *sample, 637 637 struct perf_evsel *evsel, 638 638 struct machine *machine __maybe_unused)
+1 -1
tools/perf/util/db-export.c
··· 333 333 sample_addr_correlates_sym(&evsel->attr)) { 334 334 struct addr_location addr_al; 335 335 336 - perf_event__preprocess_sample_addr(event, sample, thread, &addr_al); 336 + thread__resolve(thread, &addr_al, sample); 337 337 err = db_ids_from_al(dbe, &addr_al, &es.addr_dso_db_id, 338 338 &es.addr_sym_db_id, &es.addr_offset); 339 339 if (err)
+2 -1
tools/perf/util/dso.h
··· 162 162 u8 loaded; 163 163 u8 rel; 164 164 u8 build_id[BUILD_ID_SIZE]; 165 + u64 text_offset; 165 166 const char *short_name; 166 167 const char *long_name; 167 168 u16 long_name_len; ··· 302 301 * TODO 303 302 */ 304 303 int dso__data_get_fd(struct dso *dso, struct machine *machine); 305 - void dso__data_put_fd(struct dso *dso __maybe_unused); 304 + void dso__data_put_fd(struct dso *dso); 306 305 void dso__data_close(struct dso *dso); 307 306 308 307 off_t dso__data_size(struct dso *dso, struct machine *machine);
+5 -5
tools/perf/util/dwarf-aux.c
··· 915 915 tmp = "*"; 916 916 else if (tag == DW_TAG_subroutine_type) { 917 917 /* Function pointer */ 918 - strbuf_addf(buf, "(function_type)"); 918 + strbuf_add(buf, "(function_type)", 15); 919 919 return 0; 920 920 } else { 921 921 if (!dwarf_diename(&type)) ··· 932 932 } 933 933 ret = die_get_typename(&type, buf); 934 934 if (ret == 0) 935 - strbuf_addf(buf, "%s", tmp); 935 + strbuf_addstr(buf, tmp); 936 936 937 937 return ret; 938 938 } ··· 951 951 ret = die_get_typename(vr_die, buf); 952 952 if (ret < 0) { 953 953 pr_debug("Failed to get type, make it unknown.\n"); 954 - strbuf_addf(buf, "(unknown_type)"); 954 + strbuf_add(buf, " (unknown_type)", 14); 955 955 } 956 956 957 957 strbuf_addf(buf, "\t%s", dwarf_diename(vr_die)); ··· 1013 1013 } 1014 1014 1015 1015 if (!first) 1016 - strbuf_addf(buf, "]>"); 1016 + strbuf_add(buf, "]>", 2); 1017 1017 1018 1018 out: 1019 1019 free(scopes); ··· 1076 1076 } 1077 1077 1078 1078 if (!first) 1079 - strbuf_addf(buf, "]>"); 1079 + strbuf_add(buf, "]>", 2); 1080 1080 1081 1081 return ret; 1082 1082 }
+35 -37
tools/perf/util/dwarf-aux.h
··· 25 25 #include <elfutils/version.h> 26 26 27 27 /* Find the realpath of the target file */ 28 - extern const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname); 28 + const char *cu_find_realpath(Dwarf_Die *cu_die, const char *fname); 29 29 30 30 /* Get DW_AT_comp_dir (should be NULL with older gcc) */ 31 - extern const char *cu_get_comp_dir(Dwarf_Die *cu_die); 31 + const char *cu_get_comp_dir(Dwarf_Die *cu_die); 32 32 33 33 /* Get a line number and file name for given address */ 34 - extern int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr, 35 - const char **fname, int *lineno); 34 + int cu_find_lineinfo(Dwarf_Die *cudie, unsigned long addr, 35 + const char **fname, int *lineno); 36 36 37 37 /* Walk on funcitons at given address */ 38 - extern int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr, 39 - int (*callback)(Dwarf_Die *, void *), void *data); 38 + int cu_walk_functions_at(Dwarf_Die *cu_die, Dwarf_Addr addr, 39 + int (*callback)(Dwarf_Die *, void *), void *data); 40 40 41 41 /* Ensure that this DIE is a subprogram and definition (not declaration) */ 42 - extern bool die_is_func_def(Dwarf_Die *dw_die); 42 + bool die_is_func_def(Dwarf_Die *dw_die); 43 43 44 44 /* Ensure that this DIE is an instance of a subprogram */ 45 - extern bool die_is_func_instance(Dwarf_Die *dw_die); 45 + bool die_is_func_instance(Dwarf_Die *dw_die); 46 46 47 47 /* Compare diename and tname */ 48 - extern bool die_compare_name(Dwarf_Die *dw_die, const char *tname); 48 + bool die_compare_name(Dwarf_Die *dw_die, const char *tname); 49 49 50 50 /* Matching diename with glob pattern */ 51 - extern bool die_match_name(Dwarf_Die *dw_die, const char *glob); 51 + bool die_match_name(Dwarf_Die *dw_die, const char *glob); 52 52 53 53 /* Get callsite line number of inline-function instance */ 54 - extern int die_get_call_lineno(Dwarf_Die *in_die); 54 + int die_get_call_lineno(Dwarf_Die *in_die); 55 55 56 56 /* Get callsite file name of inlined function instance */ 57 - extern const char *die_get_call_file(Dwarf_Die *in_die); 57 + const char *die_get_call_file(Dwarf_Die *in_die); 58 58 59 59 /* Get type die */ 60 - extern Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem); 60 + Dwarf_Die *die_get_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem); 61 61 62 62 /* Get a type die, but skip qualifiers and typedef */ 63 - extern Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem); 63 + Dwarf_Die *die_get_real_type(Dwarf_Die *vr_die, Dwarf_Die *die_mem); 64 64 65 65 /* Check whether the DIE is signed or not */ 66 - extern bool die_is_signed_type(Dwarf_Die *tp_die); 66 + bool die_is_signed_type(Dwarf_Die *tp_die); 67 67 68 68 /* Get data_member_location offset */ 69 - extern int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs); 69 + int die_get_data_member_location(Dwarf_Die *mb_die, Dwarf_Word *offs); 70 70 71 71 /* Return values for die_find_child() callbacks */ 72 72 enum { ··· 77 77 }; 78 78 79 79 /* Search child DIEs */ 80 - extern Dwarf_Die *die_find_child(Dwarf_Die *rt_die, 81 - int (*callback)(Dwarf_Die *, void *), 82 - void *data, Dwarf_Die *die_mem); 80 + Dwarf_Die *die_find_child(Dwarf_Die *rt_die, 81 + int (*callback)(Dwarf_Die *, void *), 82 + void *data, Dwarf_Die *die_mem); 83 83 84 84 /* Search a non-inlined function including given address */ 85 - extern Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, 86 - Dwarf_Die *die_mem); 85 + Dwarf_Die *die_find_realfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, 86 + Dwarf_Die *die_mem); 87 87 88 88 /* Search a non-inlined function with tail call at given address */ 89 89 Dwarf_Die *die_find_tailfunc(Dwarf_Die *cu_die, Dwarf_Addr addr, 90 90 Dwarf_Die *die_mem); 91 91 92 92 /* Search the top inlined function including given address */ 93 - extern Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, 94 - Dwarf_Die *die_mem); 93 + Dwarf_Die *die_find_top_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, 94 + Dwarf_Die *die_mem); 95 95 96 96 /* Search the deepest inlined function including given address */ 97 - extern Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, 98 - Dwarf_Die *die_mem); 97 + Dwarf_Die *die_find_inlinefunc(Dwarf_Die *sp_die, Dwarf_Addr addr, 98 + Dwarf_Die *die_mem); 99 99 100 100 /* Walk on the instances of given DIE */ 101 - extern int die_walk_instances(Dwarf_Die *in_die, 102 - int (*callback)(Dwarf_Die *, void *), void *data); 101 + int die_walk_instances(Dwarf_Die *in_die, 102 + int (*callback)(Dwarf_Die *, void *), void *data); 103 103 104 104 /* Walker on lines (Note: line number will not be sorted) */ 105 105 typedef int (* line_walk_callback_t) (const char *fname, int lineno, ··· 109 109 * Walk on lines inside given DIE. If the DIE is a subprogram, walk only on 110 110 * the lines inside the subprogram, otherwise the DIE must be a CU DIE. 111 111 */ 112 - extern int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, 113 - void *data); 112 + int die_walk_lines(Dwarf_Die *rt_die, line_walk_callback_t callback, void *data); 114 113 115 114 /* Find a variable called 'name' at given address */ 116 - extern Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name, 117 - Dwarf_Addr addr, Dwarf_Die *die_mem); 115 + Dwarf_Die *die_find_variable_at(Dwarf_Die *sp_die, const char *name, 116 + Dwarf_Addr addr, Dwarf_Die *die_mem); 118 117 119 118 /* Find a member called 'name' */ 120 - extern Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name, 121 - Dwarf_Die *die_mem); 119 + Dwarf_Die *die_find_member(Dwarf_Die *st_die, const char *name, 120 + Dwarf_Die *die_mem); 122 121 123 122 /* Get the name of given variable DIE */ 124 - extern int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf); 123 + int die_get_typename(Dwarf_Die *vr_die, struct strbuf *buf); 125 124 126 125 /* Get the name and type of given variable DIE, stored as "type\tname" */ 127 - extern int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf); 128 - extern int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, 129 - struct strbuf *buf); 126 + int die_get_varname(Dwarf_Die *vr_die, struct strbuf *buf); 127 + int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf); 130 128 #endif
+8 -15
tools/perf/util/event.c
··· 1295 1295 * Callers need to drop the reference to al->thread, obtained in 1296 1296 * machine__findnew_thread() 1297 1297 */ 1298 - int perf_event__preprocess_sample(const union perf_event *event, 1299 - struct machine *machine, 1300 - struct addr_location *al, 1301 - struct perf_sample *sample) 1298 + int machine__resolve(struct machine *machine, struct addr_location *al, 1299 + struct perf_sample *sample) 1302 1300 { 1303 - u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 1304 1301 struct thread *thread = machine__findnew_thread(machine, sample->pid, 1305 1302 sample->tid); 1306 1303 ··· 1312 1315 * events, but for older perf.data files there was no such thing, so do 1313 1316 * it now. 1314 1317 */ 1315 - if (cpumode == PERF_RECORD_MISC_KERNEL && 1318 + if (sample->cpumode == PERF_RECORD_MISC_KERNEL && 1316 1319 machine__kernel_map(machine) == NULL) 1317 1320 machine__create_kernel_maps(machine); 1318 1321 1319 - thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->ip, al); 1322 + thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, sample->ip, al); 1320 1323 dump_printf(" ...... dso: %s\n", 1321 1324 al->map ? al->map->dso->long_name : 1322 1325 al->level == 'H' ? "[hypervisor]" : "<not found>"); ··· 1392 1395 return false; 1393 1396 } 1394 1397 1395 - void perf_event__preprocess_sample_addr(union perf_event *event, 1396 - struct perf_sample *sample, 1397 - struct thread *thread, 1398 - struct addr_location *al) 1398 + void thread__resolve(struct thread *thread, struct addr_location *al, 1399 + struct perf_sample *sample) 1399 1400 { 1400 - u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 1401 - 1402 - thread__find_addr_map(thread, cpumode, MAP__FUNCTION, sample->addr, al); 1401 + thread__find_addr_map(thread, sample->cpumode, MAP__FUNCTION, sample->addr, al); 1403 1402 if (!al->map) 1404 - thread__find_addr_map(thread, cpumode, MAP__VARIABLE, 1403 + thread__find_addr_map(thread, sample->cpumode, MAP__VARIABLE, 1405 1404 sample->addr, al); 1406 1405 1407 1406 al->cpu = sample->cpu;
+5 -8
tools/perf/util/event.h
··· 192 192 u64 data_src; 193 193 u32 flags; 194 194 u16 insn_len; 195 + u8 cpumode; 195 196 void *raw_data; 196 197 struct ip_callchain *callchain; 197 198 struct branch_stack *branch_stack; ··· 598 597 599 598 struct addr_location; 600 599 601 - int perf_event__preprocess_sample(const union perf_event *event, 602 - struct machine *machine, 603 - struct addr_location *al, 604 - struct perf_sample *sample); 600 + int machine__resolve(struct machine *machine, struct addr_location *al, 601 + struct perf_sample *sample); 605 602 606 603 void addr_location__put(struct addr_location *al); 607 604 ··· 607 608 608 609 bool is_bts_event(struct perf_event_attr *attr); 609 610 bool sample_addr_correlates_sym(struct perf_event_attr *attr); 610 - void perf_event__preprocess_sample_addr(union perf_event *event, 611 - struct perf_sample *sample, 612 - struct thread *thread, 613 - struct addr_location *al); 611 + void thread__resolve(struct thread *thread, struct addr_location *al, 612 + struct perf_sample *sample); 614 613 615 614 const char *perf_event__name(unsigned int id); 616 615
+1
tools/perf/util/evsel.c
··· 1643 1643 data->stream_id = data->id = data->time = -1ULL; 1644 1644 data->period = evsel->attr.sample_period; 1645 1645 data->weight = 0; 1646 + data->cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 1646 1647 1647 1648 if (event->header.type != PERF_RECORD_SAMPLE) { 1648 1649 if (!evsel->attr.sample_id_all)
+3 -5
tools/perf/util/genelf.h
··· 2 2 #define __GENELF_H__ 3 3 4 4 /* genelf.c */ 5 - extern int jit_write_elf(int fd, uint64_t code_addr, const char *sym, 6 - const void *code, int csize, 7 - void *debug, int nr_debug_entries); 5 + int jit_write_elf(int fd, uint64_t code_addr, const char *sym, 6 + const void *code, int csize, void *debug, int nr_debug_entries); 8 7 /* genelf_debug.c */ 9 - extern int jit_add_debug_info(Elf *e, uint64_t code_addr, 10 - void *debug, int nr_debug_entries); 8 + int jit_add_debug_info(Elf *e, uint64_t code_addr, void *debug, int nr_debug_entries); 11 9 12 10 #if defined(__arm__) 13 11 #define GEN_ELF_ARCH EM_ARM
-5
tools/perf/util/header.c
··· 1872 1872 if (ph->needs_swap) 1873 1873 nr = bswap_32(nr); 1874 1874 1875 - if (nr > (u32)cpu_nr) { 1876 - pr_debug("core_id number is too big." 1877 - "You may need to upgrade the perf tool.\n"); 1878 - goto free_cpu; 1879 - } 1880 1875 ph->env.cpu[i].core_id = nr; 1881 1876 1882 1877 ret = readn(fd, &nr, sizeof(nr));
+1 -1
tools/perf/util/header.h
··· 121 121 perf_event__handler_t process); 122 122 int perf_event__process_attr(struct perf_tool *tool, union perf_event *event, 123 123 struct perf_evlist **pevlist); 124 - int perf_event__process_event_update(struct perf_tool *tool __maybe_unused, 124 + int perf_event__process_event_update(struct perf_tool *tool, 125 125 union perf_event *event, 126 126 struct perf_evlist **pevlist); 127 127 size_t perf_event__fprintf_event_update(union perf_event *event, FILE *fp);
+1 -1
tools/perf/util/hist.c
··· 670 670 } 671 671 672 672 static int 673 - iter_add_single_branch_entry(struct hist_entry_iter *iter __maybe_unused, 673 + iter_add_single_branch_entry(struct hist_entry_iter *iter, 674 674 struct addr_location *al __maybe_unused) 675 675 { 676 676 /* to avoid calling callback function */
+1 -2
tools/perf/util/hist.h
··· 433 433 struct perf_sample *sample, bool nonany_branch_mode); 434 434 435 435 struct option; 436 - int parse_filter_percentage(const struct option *opt __maybe_unused, 437 - const char *arg, int unset __maybe_unused); 436 + int parse_filter_percentage(const struct option *opt, const char *arg, int unset); 438 437 int perf_hist_config(const char *var, const char *value); 439 438 440 439 void perf_hpp_list__init(struct perf_hpp_list *list);
+1 -1
tools/perf/util/intel-bts.c
··· 678 678 return 0; 679 679 } 680 680 681 - static int intel_bts_flush(struct perf_session *session __maybe_unused, 681 + static int intel_bts_flush(struct perf_session *session, 682 682 struct perf_tool *tool __maybe_unused) 683 683 { 684 684 struct intel_bts *bts = container_of(session->auxtrace, struct intel_bts,
+3 -7
tools/perf/util/jit.h
··· 3 3 4 4 #include <data.h> 5 5 6 - extern int jit_process(struct perf_session *session, 7 - struct perf_data_file *output, 8 - struct machine *machine, 9 - char *filename, 10 - pid_t pid, 11 - u64 *nbytes); 6 + int jit_process(struct perf_session *session, struct perf_data_file *output, 7 + struct machine *machine, char *filename, pid_t pid, u64 *nbytes); 12 8 13 - extern int jit_inject_record(const char *filename); 9 + int jit_inject_record(const char *filename); 14 10 15 11 #endif /* __JIT_H__ */
+16 -8
tools/perf/util/llvm-utils.c
··· 3 3 * Copyright (C) 2015, Huawei Inc. 4 4 */ 5 5 6 + #include <limits.h> 6 7 #include <stdio.h> 7 - #include "util.h" 8 + #include <stdlib.h> 8 9 #include "debug.h" 9 10 #include "llvm-utils.h" 10 - #include "cache.h" 11 11 12 12 #define CLANG_BPF_CMD_DEFAULT_TEMPLATE \ 13 13 "$CLANG_EXEC -D__KERNEL__ -D__NR_CPUS__=$NR_CPUS "\ ··· 98 98 void *buf = NULL; 99 99 FILE *file = NULL; 100 100 size_t read_sz = 0, buf_sz = 0; 101 + char serr[STRERR_BUFSIZE]; 101 102 102 103 file = popen(cmd, "r"); 103 104 if (!file) { 104 105 pr_err("ERROR: unable to popen cmd: %s\n", 105 - strerror(errno)); 106 + strerror_r(errno, serr, sizeof(serr))); 106 107 return -EINVAL; 107 108 } 108 109 ··· 137 136 138 137 if (ferror(file)) { 139 138 pr_err("ERROR: error occurred when reading from pipe: %s\n", 140 - strerror(errno)); 139 + strerror_r(errno, serr, sizeof(serr))); 141 140 err = -EIO; 142 141 goto errout; 143 142 } ··· 335 334 unsigned int kernel_version; 336 335 char linux_version_code_str[64]; 337 336 const char *clang_opt = llvm_param.clang_opt; 338 - char clang_path[PATH_MAX], nr_cpus_avail_str[64]; 337 + char clang_path[PATH_MAX], abspath[PATH_MAX], nr_cpus_avail_str[64]; 338 + char serr[STRERR_BUFSIZE]; 339 339 char *kbuild_dir = NULL, *kbuild_include_opts = NULL; 340 340 const char *template = llvm_param.clang_bpf_cmd_template; 341 + 342 + if (path[0] != '-' && realpath(path, abspath) == NULL) { 343 + err = errno; 344 + pr_err("ERROR: problems with path %s: %s\n", 345 + path, strerror_r(err, serr, sizeof(serr))); 346 + return -err; 347 + } 341 348 342 349 if (!template) 343 350 template = CLANG_BPF_CMD_DEFAULT_TEMPLATE; ··· 371 362 if (nr_cpus_avail <= 0) { 372 363 pr_err( 373 364 "WARNING:\tunable to get available CPUs in this system: %s\n" 374 - " \tUse 128 instead.\n", strerror(errno)); 365 + " \tUse 128 instead.\n", strerror_r(errno, serr, sizeof(serr))); 375 366 nr_cpus_avail = 128; 376 367 } 377 368 snprintf(nr_cpus_avail_str, sizeof(nr_cpus_avail_str), "%d", ··· 396 387 * stdin to be source file (testing). 397 388 */ 398 389 force_set_env("CLANG_SOURCE", 399 - (path[0] == '-') ? path : 400 - make_nonrelative_path(path)); 390 + (path[0] == '-') ? path : abspath); 401 391 402 392 pr_debug("llvm compiling command template: %s\n", template); 403 393 err = read_from_pipe(template, &obj_buf, &obj_buf_sz);
+3 -4
tools/perf/util/llvm-utils.h
··· 39 39 }; 40 40 41 41 extern struct llvm_param llvm_param; 42 - extern int perf_llvm_config(const char *var, const char *value); 42 + int perf_llvm_config(const char *var, const char *value); 43 43 44 - extern int llvm__compile_bpf(const char *path, void **p_obj_buf, 45 - size_t *p_obj_buf_sz); 44 + int llvm__compile_bpf(const char *path, void **p_obj_buf, size_t *p_obj_buf_sz); 46 45 47 46 /* This function is for test__llvm() use only */ 48 - extern int llvm__search_clang(void); 47 + int llvm__search_clang(void); 49 48 #endif
+6 -8
tools/perf/util/machine.c
··· 1301 1301 1302 1302 int machine__process_mmap2_event(struct machine *machine, 1303 1303 union perf_event *event, 1304 - struct perf_sample *sample __maybe_unused) 1304 + struct perf_sample *sample) 1305 1305 { 1306 - u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 1307 1306 struct thread *thread; 1308 1307 struct map *map; 1309 1308 enum map_type type; ··· 1311 1312 if (dump_trace) 1312 1313 perf_event__fprintf_mmap2(event, stdout); 1313 1314 1314 - if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL || 1315 - cpumode == PERF_RECORD_MISC_KERNEL) { 1315 + if (sample->cpumode == PERF_RECORD_MISC_GUEST_KERNEL || 1316 + sample->cpumode == PERF_RECORD_MISC_KERNEL) { 1316 1317 ret = machine__process_kernel_mmap_event(machine, event); 1317 1318 if (ret < 0) 1318 1319 goto out_problem; ··· 1354 1355 } 1355 1356 1356 1357 int machine__process_mmap_event(struct machine *machine, union perf_event *event, 1357 - struct perf_sample *sample __maybe_unused) 1358 + struct perf_sample *sample) 1358 1359 { 1359 - u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 1360 1360 struct thread *thread; 1361 1361 struct map *map; 1362 1362 enum map_type type; ··· 1364 1366 if (dump_trace) 1365 1367 perf_event__fprintf_mmap(event, stdout); 1366 1368 1367 - if (cpumode == PERF_RECORD_MISC_GUEST_KERNEL || 1368 - cpumode == PERF_RECORD_MISC_KERNEL) { 1369 + if (sample->cpumode == PERF_RECORD_MISC_GUEST_KERNEL || 1370 + sample->cpumode == PERF_RECORD_MISC_KERNEL) { 1369 1371 ret = machine__process_kernel_mmap_event(machine, event); 1370 1372 if (ret < 0) 1371 1373 goto out_problem;
+1 -1
tools/perf/util/machine.h
··· 94 94 union perf_event *event); 95 95 int machine__process_itrace_start_event(struct machine *machine, 96 96 union perf_event *event); 97 - int machine__process_switch_event(struct machine *machine __maybe_unused, 97 + int machine__process_switch_event(struct machine *machine, 98 98 union perf_event *event); 99 99 int machine__process_mmap_event(struct machine *machine, union perf_event *event, 100 100 struct perf_sample *sample);
+10 -11
tools/perf/util/parse-events.h
··· 22 22 struct tracepoint_path *next; 23 23 }; 24 24 25 - extern struct tracepoint_path *tracepoint_id_to_path(u64 config); 26 - extern struct tracepoint_path *tracepoint_name_to_path(const char *name); 27 - extern bool have_tracepoints(struct list_head *evlist); 25 + struct tracepoint_path *tracepoint_id_to_path(u64 config); 26 + struct tracepoint_path *tracepoint_name_to_path(const char *name); 27 + bool have_tracepoints(struct list_head *evlist); 28 28 29 29 const char *event_type(int type); 30 30 31 - extern int parse_events_option(const struct option *opt, const char *str, 32 - int unset); 33 - extern int parse_events(struct perf_evlist *evlist, const char *str, 34 - struct parse_events_error *error); 35 - extern int parse_events_terms(struct list_head *terms, const char *str); 36 - extern int parse_filter(const struct option *opt, const char *str, int unset); 37 - extern int exclude_perf(const struct option *opt, const char *arg, int unset); 31 + int parse_events_option(const struct option *opt, const char *str, int unset); 32 + int parse_events(struct perf_evlist *evlist, const char *str, 33 + struct parse_events_error *error); 34 + int parse_events_terms(struct list_head *terms, const char *str); 35 + int parse_filter(const struct option *opt, const char *str, int unset); 36 + int exclude_perf(const struct option *opt, const char *arg, int unset); 38 37 39 38 #define EVENTS_HELP_MAX (128*1024) 40 39 ··· 182 183 void print_tracepoint_events(const char *subsys_glob, const char *event_glob, 183 184 bool name_only); 184 185 int print_hwcache_events(const char *event_glob, bool name_only); 185 - extern int is_valid_tracepoint(const char *event_string); 186 + int is_valid_tracepoint(const char *event_string); 186 187 187 188 int valid_event_mount(const char *eventfs); 188 189 char *parse_events_formats_error_string(char *additional_terms);
-30
tools/perf/util/path.c
··· 41 41 return path; 42 42 } 43 43 44 - static char *perf_vsnpath(char *buf, size_t n, const char *fmt, va_list args) 45 - { 46 - const char *perf_dir = get_perf_dir(); 47 - size_t len; 48 - 49 - len = strlen(perf_dir); 50 - if (n < len + 1) 51 - goto bad; 52 - memcpy(buf, perf_dir, len); 53 - if (len && !is_dir_sep(perf_dir[len-1])) 54 - buf[len++] = '/'; 55 - len += vsnprintf(buf + len, n - len, fmt, args); 56 - if (len >= n) 57 - goto bad; 58 - return cleanup_path(buf); 59 - bad: 60 - strlcpy(buf, bad_path, n); 61 - return buf; 62 - } 63 - 64 - char *perf_pathdup(const char *fmt, ...) 65 - { 66 - char path[PATH_MAX]; 67 - va_list args; 68 - va_start(args, fmt); 69 - (void)perf_vsnpath(path, sizeof(path), fmt, args); 70 - va_end(args); 71 - return xstrdup(path); 72 - } 73 - 74 44 char *mkpath(const char *fmt, ...) 75 45 { 76 46 va_list args;
+1 -1
tools/perf/util/probe-event.c
··· 2179 2179 strbuf_addf(result, " in %s", module); 2180 2180 2181 2181 if (pev->nargs > 0) { 2182 - strbuf_addstr(result, " with"); 2182 + strbuf_add(result, " with", 5); 2183 2183 for (i = 0; i < pev->nargs; i++) { 2184 2184 ret = synthesize_perf_probe_arg(&pev->args[i], 2185 2185 buf, 128);
+24 -29
tools/perf/util/probe-event.h
··· 114 114 void exit_probe_symbol_maps(void); 115 115 116 116 /* Command string to events */ 117 - extern int parse_perf_probe_command(const char *cmd, 118 - struct perf_probe_event *pev); 119 - extern int parse_probe_trace_command(const char *cmd, 120 - struct probe_trace_event *tev); 117 + int parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev); 118 + int parse_probe_trace_command(const char *cmd, struct probe_trace_event *tev); 121 119 122 120 /* Events to command string */ 123 - extern char *synthesize_perf_probe_command(struct perf_probe_event *pev); 124 - extern char *synthesize_probe_trace_command(struct probe_trace_event *tev); 125 - extern int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, 126 - size_t len); 121 + char *synthesize_perf_probe_command(struct perf_probe_event *pev); 122 + char *synthesize_probe_trace_command(struct probe_trace_event *tev); 123 + int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len); 127 124 128 125 /* Check the perf_probe_event needs debuginfo */ 129 - extern bool perf_probe_event_need_dwarf(struct perf_probe_event *pev); 126 + bool perf_probe_event_need_dwarf(struct perf_probe_event *pev); 130 127 131 128 /* Release event contents */ 132 - extern void clear_perf_probe_event(struct perf_probe_event *pev); 133 - extern void clear_probe_trace_event(struct probe_trace_event *tev); 129 + void clear_perf_probe_event(struct perf_probe_event *pev); 130 + void clear_probe_trace_event(struct probe_trace_event *tev); 134 131 135 132 /* Command string to line-range */ 136 - extern int parse_line_range_desc(const char *cmd, struct line_range *lr); 133 + int parse_line_range_desc(const char *cmd, struct line_range *lr); 137 134 138 135 /* Release line range members */ 139 - extern void line_range__clear(struct line_range *lr); 136 + void line_range__clear(struct line_range *lr); 140 137 141 138 /* Initialize line range */ 142 - extern int line_range__init(struct line_range *lr); 139 + int line_range__init(struct line_range *lr); 143 140 144 - extern int add_perf_probe_events(struct perf_probe_event *pevs, int npevs); 145 - extern int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs); 146 - extern int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs); 147 - extern void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs); 148 - extern int del_perf_probe_events(struct strfilter *filter); 141 + int add_perf_probe_events(struct perf_probe_event *pevs, int npevs); 142 + int convert_perf_probe_events(struct perf_probe_event *pevs, int npevs); 143 + int apply_perf_probe_events(struct perf_probe_event *pevs, int npevs); 144 + void cleanup_perf_probe_events(struct perf_probe_event *pevs, int npevs); 145 + int del_perf_probe_events(struct strfilter *filter); 149 146 150 - extern int show_perf_probe_event(const char *group, const char *event, 151 - struct perf_probe_event *pev, 152 - const char *module, bool use_stdout); 153 - extern int show_perf_probe_events(struct strfilter *filter); 154 - extern int show_line_range(struct line_range *lr, const char *module, 155 - bool user); 156 - extern int show_available_vars(struct perf_probe_event *pevs, int npevs, 157 - struct strfilter *filter); 158 - extern int show_available_funcs(const char *module, struct strfilter *filter, 159 - bool user); 147 + int show_perf_probe_event(const char *group, const char *event, 148 + struct perf_probe_event *pev, 149 + const char *module, bool use_stdout); 150 + int show_perf_probe_events(struct strfilter *filter); 151 + int show_line_range(struct line_range *lr, const char *module, bool user); 152 + int show_available_vars(struct perf_probe_event *pevs, int npevs, 153 + struct strfilter *filter); 154 + int show_available_funcs(const char *module, struct strfilter *filter, bool user); 160 155 bool arch__prefers_symtab(void); 161 156 void arch__fix_tev_from_maps(struct perf_probe_event *pev, 162 157 struct probe_trace_event *tev, struct map *map);
+4 -4
tools/perf/util/probe-finder.c
··· 1314 1314 if (probe_conf.show_location_range) { 1315 1315 if (!externs) { 1316 1316 if (ret) 1317 - strbuf_addf(&buf, "[INV]\t"); 1317 + strbuf_add(&buf, "[INV]\t", 6); 1318 1318 else 1319 - strbuf_addf(&buf, "[VAL]\t"); 1319 + strbuf_add(&buf, "[VAL]\t", 6); 1320 1320 } else 1321 - strbuf_addf(&buf, "[EXT]\t"); 1321 + strbuf_add(&buf, "[EXT]\t", 6); 1322 1322 } 1323 1323 1324 1324 ret2 = die_get_varname(die_mem, &buf); 1325 1325 1326 1326 if (!ret2 && probe_conf.show_location_range && 1327 1327 !externs) { 1328 - strbuf_addf(&buf, "\t"); 1328 + strbuf_addch(&buf, '\t'); 1329 1329 ret2 = die_get_var_range(&af->pf.sp_die, 1330 1330 die_mem, &buf); 1331 1331 }
+11 -13
tools/perf/util/probe-finder.h
··· 34 34 }; 35 35 36 36 /* This also tries to open distro debuginfo */ 37 - extern struct debuginfo *debuginfo__new(const char *path); 38 - extern void debuginfo__delete(struct debuginfo *dbg); 37 + struct debuginfo *debuginfo__new(const char *path); 38 + void debuginfo__delete(struct debuginfo *dbg); 39 39 40 40 /* Find probe_trace_events specified by perf_probe_event from debuginfo */ 41 - extern int debuginfo__find_trace_events(struct debuginfo *dbg, 42 - struct perf_probe_event *pev, 43 - struct probe_trace_event **tevs); 41 + int debuginfo__find_trace_events(struct debuginfo *dbg, 42 + struct perf_probe_event *pev, 43 + struct probe_trace_event **tevs); 44 44 45 45 /* Find a perf_probe_point from debuginfo */ 46 - extern int debuginfo__find_probe_point(struct debuginfo *dbg, 47 - unsigned long addr, 48 - struct perf_probe_point *ppt); 46 + int debuginfo__find_probe_point(struct debuginfo *dbg, unsigned long addr, 47 + struct perf_probe_point *ppt); 49 48 50 49 /* Find a line range */ 51 - extern int debuginfo__find_line_range(struct debuginfo *dbg, 52 - struct line_range *lr); 50 + int debuginfo__find_line_range(struct debuginfo *dbg, struct line_range *lr); 53 51 54 52 /* Find available variables */ 55 - extern int debuginfo__find_available_vars_at(struct debuginfo *dbg, 56 - struct perf_probe_event *pev, 57 - struct variable_list **vls); 53 + int debuginfo__find_available_vars_at(struct debuginfo *dbg, 54 + struct perf_probe_event *pev, 55 + struct variable_list **vls); 58 56 59 57 /* Find a src file from a DWARF tag path */ 60 58 int get_real_path(const char *raw_path, const char *comp_dir,
+1 -1
tools/perf/util/quote.h
··· 24 24 * sq_quote() in a real application. 25 25 */ 26 26 27 - extern void sq_quote_argv(struct strbuf *, const char **argv, size_t maxlen); 27 + void sq_quote_argv(struct strbuf *, const char **argv, size_t maxlen); 28 28 29 29 #endif /* __PERF_QUOTE_H */
+2 -3
tools/perf/util/session.c
··· 1107 1107 union perf_event *event, 1108 1108 struct perf_sample *sample) 1109 1109 { 1110 - const u8 cpumode = event->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 1111 1110 struct machine *machine; 1112 1111 1113 1112 if (perf_guest && 1114 - ((cpumode == PERF_RECORD_MISC_GUEST_KERNEL) || 1115 - (cpumode == PERF_RECORD_MISC_GUEST_USER))) { 1113 + ((sample->cpumode == PERF_RECORD_MISC_GUEST_KERNEL) || 1114 + (sample->cpumode == PERF_RECORD_MISC_GUEST_USER))) { 1116 1115 u32 pid; 1117 1116 1118 1117 if (event->header.type == PERF_RECORD_MMAP
+1 -1
tools/perf/util/sort.c
··· 2225 2225 } 2226 2226 2227 2227 static int sort_dimension__add(struct perf_hpp_list *list, const char *tok, 2228 - struct perf_evlist *evlist __maybe_unused, 2228 + struct perf_evlist *evlist, 2229 2229 int level) 2230 2230 { 2231 2231 unsigned int i;
+8 -10
tools/perf/util/stat-shadow.c
··· 152 152 } 153 153 154 154 static void print_stalled_cycles_frontend(int cpu, 155 - struct perf_evsel *evsel 156 - __maybe_unused, double avg, 155 + struct perf_evsel *evsel, double avg, 157 156 struct perf_stat_output_ctx *out) 158 157 { 159 158 double total, ratio = 0.0; ··· 174 175 } 175 176 176 177 static void print_stalled_cycles_backend(int cpu, 177 - struct perf_evsel *evsel 178 - __maybe_unused, double avg, 178 + struct perf_evsel *evsel, double avg, 179 179 struct perf_stat_output_ctx *out) 180 180 { 181 181 double total, ratio = 0.0; ··· 192 194 } 193 195 194 196 static void print_branch_misses(int cpu, 195 - struct perf_evsel *evsel __maybe_unused, 197 + struct perf_evsel *evsel, 196 198 double avg, 197 199 struct perf_stat_output_ctx *out) 198 200 { ··· 211 213 } 212 214 213 215 static void print_l1_dcache_misses(int cpu, 214 - struct perf_evsel *evsel __maybe_unused, 216 + struct perf_evsel *evsel, 215 217 double avg, 216 218 struct perf_stat_output_ctx *out) 217 219 { ··· 230 232 } 231 233 232 234 static void print_l1_icache_misses(int cpu, 233 - struct perf_evsel *evsel __maybe_unused, 235 + struct perf_evsel *evsel, 234 236 double avg, 235 237 struct perf_stat_output_ctx *out) 236 238 { ··· 248 250 } 249 251 250 252 static void print_dtlb_cache_misses(int cpu, 251 - struct perf_evsel *evsel __maybe_unused, 253 + struct perf_evsel *evsel, 252 254 double avg, 253 255 struct perf_stat_output_ctx *out) 254 256 { ··· 266 268 } 267 269 268 270 static void print_itlb_cache_misses(int cpu, 269 - struct perf_evsel *evsel __maybe_unused, 271 + struct perf_evsel *evsel, 270 272 double avg, 271 273 struct perf_stat_output_ctx *out) 272 274 { ··· 284 286 } 285 287 286 288 static void print_ll_cache_misses(int cpu, 287 - struct perf_evsel *evsel __maybe_unused, 289 + struct perf_evsel *evsel, 288 290 double avg, 289 291 struct perf_stat_output_ctx *out) 290 292 {
+8 -1
tools/perf/util/strbuf.c
··· 51 51 ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc); 52 52 } 53 53 54 + void strbuf_addch(struct strbuf *sb, int c) 55 + { 56 + strbuf_grow(sb, 1); 57 + sb->buf[sb->len++] = c; 58 + sb->buf[sb->len] = '\0'; 59 + } 60 + 54 61 void strbuf_add(struct strbuf *sb, const void *data, size_t len) 55 62 { 56 63 strbuf_grow(sb, len); ··· 65 58 strbuf_setlen(sb, sb->len + len); 66 59 } 67 60 68 - void strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap) 61 + static void strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap) 69 62 { 70 63 int len; 71 64 va_list ap_saved;
+8 -13
tools/perf/util/strbuf.h
··· 51 51 #define STRBUF_INIT { 0, 0, strbuf_slopbuf } 52 52 53 53 /*----- strbuf life cycle -----*/ 54 - extern void strbuf_init(struct strbuf *buf, ssize_t hint); 55 - extern void strbuf_release(struct strbuf *); 56 - extern char *strbuf_detach(struct strbuf *, size_t *); 54 + void strbuf_init(struct strbuf *buf, ssize_t hint); 55 + void strbuf_release(struct strbuf *buf); 56 + char *strbuf_detach(struct strbuf *buf, size_t *); 57 57 58 58 /*----- strbuf size related -----*/ 59 59 static inline ssize_t strbuf_avail(const struct strbuf *sb) { 60 60 return sb->alloc ? sb->alloc - sb->len - 1 : 0; 61 61 } 62 62 63 - extern void strbuf_grow(struct strbuf *, size_t); 63 + void strbuf_grow(struct strbuf *buf, size_t); 64 64 65 65 static inline void strbuf_setlen(struct strbuf *sb, size_t len) { 66 66 if (!sb->alloc) ··· 71 71 } 72 72 73 73 /*----- add data in your buffer -----*/ 74 - static inline void strbuf_addch(struct strbuf *sb, int c) { 75 - strbuf_grow(sb, 1); 76 - sb->buf[sb->len++] = c; 77 - sb->buf[sb->len] = '\0'; 78 - } 74 + void strbuf_addch(struct strbuf *sb, int c); 79 75 80 - extern void strbuf_add(struct strbuf *, const void *, size_t); 76 + void strbuf_add(struct strbuf *buf, const void *, size_t); 81 77 static inline void strbuf_addstr(struct strbuf *sb, const char *s) { 82 78 strbuf_add(sb, s, strlen(s)); 83 79 } 84 80 85 81 __attribute__((format(printf,2,3))) 86 - extern void strbuf_addf(struct strbuf *sb, const char *fmt, ...); 87 - extern void strbuf_addv(struct strbuf *sb, const char *fmt, va_list ap); 82 + void strbuf_addf(struct strbuf *sb, const char *fmt, ...); 88 83 89 84 /* XXX: if read fails, any partial read is undone */ 90 - extern ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint); 85 + ssize_t strbuf_read(struct strbuf *, int fd, ssize_t hint); 91 86 92 87 #endif /* __PERF_STRBUF_H */
+21 -22
tools/perf/util/svghelper.h
··· 3 3 4 4 #include <linux/types.h> 5 5 6 - extern void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end); 7 - extern void svg_ubox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges); 8 - extern void svg_lbox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges); 9 - extern void svg_fbox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges); 10 - extern void svg_box(int Yslot, u64 start, u64 end, const char *type); 11 - extern void svg_blocked(int Yslot, int cpu, u64 start, u64 end, const char *backtrace); 12 - extern void svg_running(int Yslot, int cpu, u64 start, u64 end, const char *backtrace); 13 - extern void svg_waiting(int Yslot, int cpu, u64 start, u64 end, const char *backtrace); 14 - extern void svg_cpu_box(int cpu, u64 max_frequency, u64 turbo_frequency); 6 + void open_svg(const char *filename, int cpus, int rows, u64 start, u64 end); 7 + void svg_ubox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges); 8 + void svg_lbox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges); 9 + void svg_fbox(int Yslot, u64 start, u64 end, double height, const char *type, int fd, int err, int merges); 10 + void svg_box(int Yslot, u64 start, u64 end, const char *type); 11 + void svg_blocked(int Yslot, int cpu, u64 start, u64 end, const char *backtrace); 12 + void svg_running(int Yslot, int cpu, u64 start, u64 end, const char *backtrace); 13 + void svg_waiting(int Yslot, int cpu, u64 start, u64 end, const char *backtrace); 14 + void svg_cpu_box(int cpu, u64 max_frequency, u64 turbo_frequency); 15 15 16 16 17 - extern void svg_process(int cpu, u64 start, u64 end, int pid, const char *name, const char *backtrace); 18 - extern void svg_cstate(int cpu, u64 start, u64 end, int type); 19 - extern void svg_pstate(int cpu, u64 start, u64 end, u64 freq); 17 + void svg_process(int cpu, u64 start, u64 end, int pid, const char *name, const char *backtrace); 18 + void svg_cstate(int cpu, u64 start, u64 end, int type); 19 + void svg_pstate(int cpu, u64 start, u64 end, u64 freq); 20 20 21 21 22 - extern void svg_time_grid(double min_thickness); 23 - extern void svg_io_legenda(void); 24 - extern void svg_legenda(void); 25 - extern void svg_wakeline(u64 start, int row1, int row2, const char *backtrace); 26 - extern void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, char *desc2, const char *backtrace); 27 - extern void svg_interrupt(u64 start, int row, const char *backtrace); 28 - extern void svg_text(int Yslot, u64 start, const char *text); 29 - extern void svg_close(void); 30 - extern int svg_build_topology_map(char *sib_core, int sib_core_nr, 31 - char *sib_thr, int sib_thr_nr); 22 + void svg_time_grid(double min_thickness); 23 + void svg_io_legenda(void); 24 + void svg_legenda(void); 25 + void svg_wakeline(u64 start, int row1, int row2, const char *backtrace); 26 + void svg_partial_wakeline(u64 start, int row1, char *desc1, int row2, char *desc2, const char *backtrace); 27 + void svg_interrupt(u64 start, int row, const char *backtrace); 28 + void svg_text(int Yslot, u64 start, const char *text); 29 + void svg_close(void); 30 + int svg_build_topology_map(char *sib_core, int sib_core_nr, char *sib_thr, int sib_thr_nr); 32 31 33 32 extern int svg_page_width; 34 33 extern u64 svg_highlight;
+6 -6
tools/perf/util/symbol-elf.c
··· 793 793 uint32_t idx; 794 794 GElf_Ehdr ehdr; 795 795 GElf_Shdr shdr; 796 + GElf_Shdr tshdr; 796 797 Elf_Data *syms, *opddata = NULL; 797 798 GElf_Sym sym; 798 799 Elf_Scn *sec, *sec_strndx; ··· 832 831 ehdr = syms_ss->ehdr; 833 832 sec = syms_ss->symtab; 834 833 shdr = syms_ss->symshdr; 834 + 835 + if (elf_section_by_name(elf, &ehdr, &tshdr, ".text", NULL)) 836 + dso->text_offset = tshdr.sh_addr - tshdr.sh_offset; 835 837 836 838 if (runtime_ss->opdsec) 837 839 opddata = elf_rawdata(runtime_ss->opdsec, NULL); ··· 884 880 * Handle any relocation of vdso necessary because older kernels 885 881 * attempted to prelink vdso to its virtual address. 886 882 */ 887 - if (dso__is_vdso(dso)) { 888 - GElf_Shdr tshdr; 889 - 890 - if (elf_section_by_name(elf, &ehdr, &tshdr, ".text", NULL)) 891 - map->reloc = map->start - tshdr.sh_addr + tshdr.sh_offset; 892 - } 883 + if (dso__is_vdso(dso)) 884 + map->reloc = map->start - dso->text_offset; 893 885 894 886 dso->adjust_symbols = runtime_ss->adjust_symbols || ref_reloc(kmap); 895 887 /*
+2 -2
tools/perf/util/symbol.h
··· 34 34 #endif 35 35 36 36 #ifdef HAVE_LIBELF_SUPPORT 37 - extern Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, 38 - GElf_Shdr *shp, const char *name, size_t *idx); 37 + Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, 38 + GElf_Shdr *shp, const char *name, size_t *idx); 39 39 #endif 40 40 41 41 #ifndef DMGL_PARAMS
+1 -7
tools/perf/util/usage.c
··· 41 41 /* If we are in a dlopen()ed .so write to a global variable would segfault 42 42 * (ugh), so keep things static. */ 43 43 static void (*usage_routine)(const char *err) NORETURN = usage_builtin; 44 - static void (*die_routine)(const char *err, va_list params) NORETURN = die_builtin; 45 44 static void (*error_routine)(const char *err, va_list params) = error_builtin; 46 45 static void (*warn_routine)(const char *err, va_list params) = warn_builtin; 47 - 48 - void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN) 49 - { 50 - die_routine = routine; 51 - } 52 46 53 47 void set_warning_routine(void (*routine)(const char *err, va_list params)) 54 48 { ··· 59 65 va_list params; 60 66 61 67 va_start(params, err); 62 - die_routine(err, params); 68 + die_builtin(err, params); 63 69 va_end(params); 64 70 } 65 71
+8 -19
tools/perf/util/util.h
··· 133 133 #define PERF_GTK_DSO "libperf-gtk.so" 134 134 135 135 /* General helper functions */ 136 - extern void usage(const char *err) NORETURN; 137 - extern void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); 138 - extern int error(const char *err, ...) __attribute__((format (printf, 1, 2))); 139 - extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2))); 136 + void usage(const char *err) NORETURN; 137 + void die(const char *err, ...) NORETURN __attribute__((format (printf, 1, 2))); 138 + int error(const char *err, ...) __attribute__((format (printf, 1, 2))); 139 + void warning(const char *err, ...) __attribute__((format (printf, 1, 2))); 140 140 141 - #include "../../../include/linux/stringify.h" 141 + void set_warning_routine(void (*routine)(const char *err, va_list params)); 142 142 143 - #define DIE_IF(cnd) \ 144 - do { if (cnd) \ 145 - die(" at (" __FILE__ ":" __stringify(__LINE__) "): " \ 146 - __stringify(cnd) "\n"); \ 147 - } while (0) 148 - 149 - 150 - extern void set_die_routine(void (*routine)(const char *err, va_list params) NORETURN); 151 - extern void set_warning_routine(void (*routine)(const char *err, va_list params)); 152 - 153 - extern int prefixcmp(const char *str, const char *prefix); 154 - extern void set_buildid_dir(const char *dir); 143 + int prefixcmp(const char *str, const char *prefix); 144 + void set_buildid_dir(const char *dir); 155 145 156 146 #ifdef __GLIBC_PREREQ 157 147 #if __GLIBC_PREREQ(2, 1) ··· 162 172 /* 163 173 * Wrappers: 164 174 */ 165 - extern char *xstrdup(const char *str); 166 - extern void *xrealloc(void *ptr, size_t size) __attribute__((weak)); 175 + void *xrealloc(void *ptr, size_t size) __attribute__((weak)); 167 176 168 177 169 178 static inline void *zalloc(size_t size)
-12
tools/perf/util/wrapper.c
··· 12 12 { 13 13 } 14 14 15 - char *xstrdup(const char *str) 16 - { 17 - char *ret = strdup(str); 18 - if (!ret) { 19 - release_pack_memory(strlen(str) + 1, -1); 20 - ret = strdup(str); 21 - if (!ret) 22 - die("Out of memory, strdup failed"); 23 - } 24 - return ret; 25 - } 26 - 27 15 void *xrealloc(void *ptr, size_t size) 28 16 { 29 17 void *ret = realloc(ptr, size);