History

Merge branch 'perfcounters-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip

* 'perfcounters-fixes-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip: perf_counter: Report the cloning task as parent on perf_counter_fork() perf_counter: Fix an ipi-deadlock perf: Rework/fix the whole read vs group stuff perf_counter: Fix swcounter context invariance perf report: Don't show unresolved DSOs and symbols when -S/-d is used perf tools: Add a general option to enable raw sample records perf tools: Add a per tracepoint counter attribute to get raw sample perf_counter: Provide hw_perf_counter_setup_online() APIs perf list: Fix large list output by using the pager perf_counter, x86: Fix/improve apic fallback perf record: Add missing -C option support for specifying profile cpu perf tools: Fix dso__new handle() to handle deleted DSOs perf tools: Fix fallback to cplus_demangle() when bfd_demangle() is not available perf report: Show the tid too in -D perf record: Fix .tid and .pid fill-in when synthesizing events perf_counter, x86: Fix generic cache events on P6-mobile CPUs perf_counter, x86: Fix lapic printk message

Linus Torvalds committed 17 years ago

Commit 3493e842 parents 919aa96 94d5d1b11 files · +429 −190Browse files

Unified · Split

11 files
  1. arch/x86/Kconfig +1 −1
  2. arch/x86/kernel/cpu/perf_counter.c +33 −7
  3. include/linux/perf_counter.h +38 −11
  4. kernel/perf_counter.c +236 −102
  5. tools/perf/Makefile +18 −11
  6. tools/perf/builtin-list.c +2 −1
  7. tools/perf/builtin-record.c +58 −37
  8. tools/perf/builtin-report.c +7 −5
  9. tools/perf/util/parse-events.c +10 −0
  10. tools/perf/util/symbol.c +2 −15
  11. tools/perf/util/symbol.h +24 −0
arch/x86/Kconfig+1−1
@@ -24,6 +24,7 @@ config X86 · 23 unmodified lines
2424 select HAVE_UNSTABLE_SCHED_CLOCK
2525 select HAVE_IDE
2626 select HAVE_OPROFILE
27+ select HAVE_PERF_COUNTERS if (!M386 && !M486)
2728 select HAVE_IOREMAP_PROT
2829 select HAVE_KPROBES
2930 select ARCH_WANT_OPTIONAL_GPIOLIB
@@ -742,7 +743,6 @@ config X86_UP_IOAPIC · 712 unmodified lines
742743 config X86_LOCAL_APIC
743744 def_bool y
744745 depends on X86_64 || SMP || X86_32_NON_STANDARD || X86_UP_APIC
745− select HAVE_PERF_COUNTERS if (!M386 && !M486)
746746
747747 config X86_IO_APIC
748748 def_bool y
arch/x86/kernel/cpu/perf_counter.c+33−7
@@ -55,6 +55,7 @@ struct x86_pmu { · 54 unmodified lines
5555 int num_counters_fixed;
5656 int counter_bits;
5757 u64 counter_mask;
58+ int apic;
5859 u64 max_period;
5960 u64 intel_ctrl;
6061 };
@@ -72,8 +73,8 @@ static const u64 p6_perfmon_event_map[] = · 11 unmodified lines
7273 {
7374 [PERF_COUNT_HW_CPU_CYCLES] = 0x0079,
7475 [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
75− [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0000,
76− [PERF_COUNT_HW_CACHE_MISSES] = 0x0000,
76+ [PERF_COUNT_HW_CACHE_REFERENCES] = 0x0f2e,
77+ [PERF_COUNT_HW_CACHE_MISSES] = 0x012e,
7778 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4,
7879 [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5,
7980 [PERF_COUNT_HW_BUS_CYCLES] = 0x0062,
@@ -613,6 +614,7 @@ static DEFINE_MUTEX(pmc_reserve_mutex); · 533 unmodified lines
613614
614615 static bool reserve_pmc_hardware(void)
615616 {
617+#ifdef CONFIG_X86_LOCAL_APIC
616618 int i;
617619
618620 if (nmi_watchdog == NMI_LOCAL_APIC)
@@ -627,9 +629,11 @@ static bool reserve_pmc_hardware(void) · 8 unmodified lines
627629 if (!reserve_evntsel_nmi(x86_pmu.eventsel + i))
628630 goto eventsel_fail;
629631 }
632+#endif
630633
631634 return true;
632635
636+#ifdef CONFIG_X86_LOCAL_APIC
633637 eventsel_fail:
634638 for (i--; i >= 0; i--)
635639 release_evntsel_nmi(x86_pmu.eventsel + i);
@@ -644,10 +648,12 @@ perfctr_fail: · 8 unmodified lines
644648 enable_lapic_nmi_watchdog();
645649
646650 return false;
651+#endif
647652 }
648653
649654 static void release_pmc_hardware(void)
650655 {
656+#ifdef CONFIG_X86_LOCAL_APIC
651657 int i;
652658
653659 for (i = 0; i < x86_pmu.num_counters; i++) {
@@ -657,6 +663,7 @@ static void release_pmc_hardware(void) · 3 unmodified lines
657663
658664 if (nmi_watchdog == NMI_LOCAL_APIC)
659665 enable_lapic_nmi_watchdog();
666+#endif
660667 }
661668
662669 static void hw_perf_counter_destroy(struct perf_counter *counter)
@@ -748,6 +755,15 @@ static int __hw_perf_counter_init(struct perf_counter *counter) · 85 unmodified lines
748755 hwc->sample_period = x86_pmu.max_period;
749756 hwc->last_period = hwc->sample_period;
750757 atomic64_set(&hwc->period_left, hwc->sample_period);
758+ } else {
759+ /*
760+ * If we have a PMU initialized but no APIC
761+ * interrupts, we cannot sample hardware
762+ * counters (user-space has to fall back and
763+ * sample via a hrtimer based software counter):
764+ */
765+ if (!x86_pmu.apic)
766+ return -EOPNOTSUPP;
751767 }
752768
753769 counter->destroy = hw_perf_counter_destroy;
@@ -1449,18 +1465,22 @@ void smp_perf_pending_interrupt(struct pt_regs *regs) · 695 unmodified lines
14491465
14501466 void set_perf_counter_pending(void)
14511467 {
1468+#ifdef CONFIG_X86_LOCAL_APIC
14521469 apic->send_IPI_self(LOCAL_PENDING_VECTOR);
1470+#endif
14531471 }
14541472
14551473 void perf_counters_lapic_init(void)
14561474 {
1457− if (!x86_pmu_initialized())
1475+#ifdef CONFIG_X86_LOCAL_APIC
1476+ if (!x86_pmu.apic || !x86_pmu_initialized())
14581477 return;
14591478
14601479 /*
14611480 * Always use NMI for PMU
14621481 */
14631482 apic_write(APIC_LVTPC, APIC_DM_NMI);
1483+#endif
14641484 }
14651485
14661486 static int __kprobes
@@ -1484,7 +1504,9 @@ perf_counter_nmi_handler(struct notifier_block *self, · 17 unmodified lines
14841504
14851505 regs = args->regs;
14861506
1507+#ifdef CONFIG_X86_LOCAL_APIC
14871508 apic_write(APIC_LVTPC, APIC_DM_NMI);
1509+#endif
14881510 /*
14891511 * Can't rely on the handled return value to say it was our NMI, two
14901512 * counters could trigger 'simultaneously' raising two back-to-back NMIs.
@@ -1515,6 +1537,7 @@ static struct x86_pmu p6_pmu = { · 24 unmodified lines
15151537 .event_map = p6_pmu_event_map,
15161538 .raw_event = p6_pmu_raw_event,
15171539 .max_events = ARRAY_SIZE(p6_perfmon_event_map),
1540+ .apic = 1,
15181541 .max_period = (1ULL << 31) - 1,
15191542 .version = 0,
15201543 .num_counters = 2,
@@ -1541,6 +1564,7 @@ static struct x86_pmu intel_pmu = { · 20 unmodified lines
15411564 .event_map = intel_pmu_event_map,
15421565 .raw_event = intel_pmu_raw_event,
15431566 .max_events = ARRAY_SIZE(intel_perfmon_event_map),
1567+ .apic = 1,
15441568 /*
15451569 * Intel PMCs cannot be accessed sanely above 32 bit width,
15461570 * so we install an artificial 1<<31 period regardless of
@@ -1564,6 +1588,7 @@ static struct x86_pmu amd_pmu = { · 17 unmodified lines
15641588 .num_counters = 4,
15651589 .counter_bits = 48,
15661590 .counter_mask = (1ULL << 48) - 1,
1591+ .apic = 1,
15671592 /* use highest bit to detect overflow */
15681593 .max_period = (1ULL << 47) - 1,
15691594 };
@@ -1589,13 +1614,14 @@ static int p6_pmu_init(void) · 19 unmodified lines
15891614 return -ENODEV;
15901615 }
15911616
1617+ x86_pmu = p6_pmu;
1618+
15921619 if (!cpu_has_apic) {
1593− pr_info("no Local APIC, try rebooting with lapic");
1594− return -ENODEV;
1620+ pr_info("no APIC, boot with the \"lapic\" boot parameter to force-enable it.\n");
1621+ pr_info("no hardware sampling interrupt available.\n");
1622+ x86_pmu.apic = 0;
15951623 }
15961624
1597− x86_pmu = p6_pmu;
1598−
15991625 return 0;
16001626 }
16011627
include/linux/perf_counter.h+38−11
@@ -115,7 +115,7 @@ enum perf_counter_sample_format { · 114 unmodified lines
115115 PERF_SAMPLE_TID = 1U << 1,
116116 PERF_SAMPLE_TIME = 1U << 2,
117117 PERF_SAMPLE_ADDR = 1U << 3,
118− PERF_SAMPLE_GROUP = 1U << 4,
118+ PERF_SAMPLE_READ = 1U << 4,
119119 PERF_SAMPLE_CALLCHAIN = 1U << 5,
120120 PERF_SAMPLE_ID = 1U << 6,
121121 PERF_SAMPLE_CPU = 1U << 7,
@@ -127,16 +127,32 @@ enum perf_counter_sample_format { · 5 unmodified lines
127127 };
128128
129129 /*
130− * Bits that can be set in attr.read_format to request that
131− * reads on the counter should return the indicated quantities,
132− * in increasing order of bit value, after the counter value.
130+ * The format of the data returned by read() on a perf counter fd,
131+ * as specified by attr.read_format:
132+ *
133+ * struct read_format {
134+ * { u64 value;
135+ * { u64 time_enabled; } && PERF_FORMAT_ENABLED
136+ * { u64 time_running; } && PERF_FORMAT_RUNNING
137+ * { u64 id; } && PERF_FORMAT_ID
138+ * } && !PERF_FORMAT_GROUP
139+ *
140+ * { u64 nr;
141+ * { u64 time_enabled; } && PERF_FORMAT_ENABLED
142+ * { u64 time_running; } && PERF_FORMAT_RUNNING
143+ * { u64 value;
144+ * { u64 id; } && PERF_FORMAT_ID
145+ * } cntr[nr];
146+ * } && PERF_FORMAT_GROUP
147+ * };
133148 */
134149 enum perf_counter_read_format {
135150 PERF_FORMAT_TOTAL_TIME_ENABLED = 1U << 0,
136151 PERF_FORMAT_TOTAL_TIME_RUNNING = 1U << 1,
137152 PERF_FORMAT_ID = 1U << 2,
153+ PERF_FORMAT_GROUP = 1U << 3,
138154
139− PERF_FORMAT_MAX = 1U << 3, /* non-ABI */
155+ PERF_FORMAT_MAX = 1U << 4, /* non-ABI */
140156 };
141157
142158 #define PERF_ATTR_SIZE_VER0 64 /* sizeof first published struct */
@@ -343,10 +359,8 @@ enum perf_event_type { · 200 unmodified lines
343359 * struct {
344360 * struct perf_event_header header;
345361 * u32 pid, tid;
346− * u64 value;
347− * { u64 time_enabled; } && PERF_FORMAT_ENABLED
348− * { u64 time_running; } && PERF_FORMAT_RUNNING
349− * { u64 parent_id; } && PERF_FORMAT_ID
362+ *
363+ * struct read_format values;
350364 * };
351365 */
352366 PERF_EVENT_READ = 8,
@@ -364,11 +378,22 @@ enum perf_event_type { · 11 unmodified lines
364378 * { u32 cpu, res; } && PERF_SAMPLE_CPU
365379 * { u64 period; } && PERF_SAMPLE_PERIOD
366380 *
367− * { u64 nr;
368− * { u64 id, val; } cnt[nr]; } && PERF_SAMPLE_GROUP
381+ * { struct read_format values; } && PERF_SAMPLE_READ
369382 *
370383 * { u64 nr,
371384 * u64 ips[nr]; } && PERF_SAMPLE_CALLCHAIN
385+ *
386+ * #
387+ * # The RAW record below is opaque data wrt the ABI
388+ * #
389+ * # That is, the ABI doesn't make any promises wrt to
390+ * # the stability of its content, it may vary depending
391+ * # on event, hardware, kernel version and phase of
392+ * # the moon.
393+ * #
394+ * # In other words, PERF_SAMPLE_RAW contents are not an ABI.
395+ * #
396+ *
372397 * { u32 size;
373398 * char data[size];}&& PERF_SAMPLE_RAW
374399 * };
@@ -694,6 +719,8 @@ struct perf_sample_data { · 319 unmodified lines
694719
695720 extern int perf_counter_overflow(struct perf_counter *counter, int nmi,
696721 struct perf_sample_data *data);
722+extern void perf_counter_output(struct perf_counter *counter, int nmi,
723+ struct perf_sample_data *data);
697724
698725 /*
699726 * Return 1 for a software counter, 0 for a hardware counter
kernel/perf_counter.c+236−102
@@ -88,6 +88,7 @@ void __weak hw_perf_disable(void) { barrier(); } · 87 unmodified lines
8888 void __weak hw_perf_enable(void) { barrier(); }
8989
9090 void __weak hw_perf_counter_setup(int cpu) { barrier(); }
91+void __weak hw_perf_counter_setup_online(int cpu) { barrier(); }
9192
9293 int __weak
9394 hw_perf_group_sched_in(struct perf_counter *group_leader,
@@ -306,6 +307,10 @@ counter_sched_out(struct perf_counter *counter, · 212 unmodified lines
306307 return;
307308
308309 counter->state = PERF_COUNTER_STATE_INACTIVE;
310+ if (counter->pending_disable) {
311+ counter->pending_disable = 0;
312+ counter->state = PERF_COUNTER_STATE_OFF;
313+ }
309314 counter->tstamp_stopped = ctx->time;
310315 counter->pmu->disable(counter);
311316 counter->oncpu = -1;
@@ -1691,7 +1696,32 @@ static int perf_release(struct inode *inode, struct file *file) · 1379 unmodified lines
16911696 return 0;
16921697 }
16931698
1694−static u64 perf_counter_read_tree(struct perf_counter *counter)
1699+static int perf_counter_read_size(struct perf_counter *counter)
1700+{
1701+ int entry = sizeof(u64); /* value */
1702+ int size = 0;
1703+ int nr = 1;
1704+
1705+ if (counter->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
1706+ size += sizeof(u64);
1707+
1708+ if (counter->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
1709+ size += sizeof(u64);
1710+
1711+ if (counter->attr.read_format & PERF_FORMAT_ID)
1712+ entry += sizeof(u64);
1713+
1714+ if (counter->attr.read_format & PERF_FORMAT_GROUP) {
1715+ nr += counter->group_leader->nr_siblings;
1716+ size += sizeof(u64);
1717+ }
1718+
1719+ size += entry * nr;
1720+
1721+ return size;
1722+}
1723+
1724+static u64 perf_counter_read_value(struct perf_counter *counter)
16951725 {
16961726 struct perf_counter *child;
16971727 u64 total = 0;
@@ -1703,14 +1733,96 @@ static u64 perf_counter_read_tree(struct perf_counter *counter) · 5 unmodified lines
17031733 return total;
17041734 }
17051735
1736+static int perf_counter_read_entry(struct perf_counter *counter,
1737+ u64 read_format, char __user *buf)
1738+{
1739+ int n = 0, count = 0;
1740+ u64 values[2];
1741+
1742+ values[n++] = perf_counter_read_value(counter);
1743+ if (read_format & PERF_FORMAT_ID)
1744+ values[n++] = primary_counter_id(counter);
1745+
1746+ count = n * sizeof(u64);
1747+
1748+ if (copy_to_user(buf, values, count))
1749+ return -EFAULT;
1750+
1751+ return count;
1752+}
1753+
1754+static int perf_counter_read_group(struct perf_counter *counter,
1755+ u64 read_format, char __user *buf)
1756+{
1757+ struct perf_counter *leader = counter->group_leader, *sub;
1758+ int n = 0, size = 0, err = -EFAULT;
1759+ u64 values[3];
1760+
1761+ values[n++] = 1 + leader->nr_siblings;
1762+ if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
1763+ values[n++] = leader->total_time_enabled +
1764+ atomic64_read(&leader->child_total_time_enabled);
1765+ }
1766+ if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
1767+ values[n++] = leader->total_time_running +
1768+ atomic64_read(&leader->child_total_time_running);
1769+ }
1770+
1771+ size = n * sizeof(u64);
1772+
1773+ if (copy_to_user(buf, values, size))
1774+ return -EFAULT;
1775+
1776+ err = perf_counter_read_entry(leader, read_format, buf + size);
1777+ if (err < 0)
1778+ return err;
1779+
1780+ size += err;
1781+
1782+ list_for_each_entry(sub, &leader->sibling_list, list_entry) {
1783+ err = perf_counter_read_entry(counter, read_format,
1784+ buf + size);
1785+ if (err < 0)
1786+ return err;
1787+
1788+ size += err;
1789+ }
1790+
1791+ return size;
1792+}
1793+
1794+static int perf_counter_read_one(struct perf_counter *counter,
1795+ u64 read_format, char __user *buf)
1796+{
1797+ u64 values[4];
1798+ int n = 0;
1799+
1800+ values[n++] = perf_counter_read_value(counter);
1801+ if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
1802+ values[n++] = counter->total_time_enabled +
1803+ atomic64_read(&counter->child_total_time_enabled);
1804+ }
1805+ if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
1806+ values[n++] = counter->total_time_running +
1807+ atomic64_read(&counter->child_total_time_running);
1808+ }
1809+ if (read_format & PERF_FORMAT_ID)
1810+ values[n++] = primary_counter_id(counter);
1811+
1812+ if (copy_to_user(buf, values, n * sizeof(u64)))
1813+ return -EFAULT;
1814+
1815+ return n * sizeof(u64);
1816+}
1817+
17061818 /*
17071819 * Read the performance counter - simple non blocking version for now
17081820 */
17091821 static ssize_t
17101822 perf_read_hw(struct perf_counter *counter, char __user *buf, size_t count)
17111823 {
1712− u64 values[4];
1713− int n;
1824+ u64 read_format = counter->attr.read_format;
1825+ int ret;
17141826
17151827 /*
17161828 * Return end-of-file for a read on a counter that is in
@@ -1720,28 +1832,18 @@ perf_read_hw(struct perf_counter *counter, char __user *buf, size_t count) · 3 unmodified lines
17201832 if (counter->state == PERF_COUNTER_STATE_ERROR)
17211833 return 0;
17221834
1835+ if (count < perf_counter_read_size(counter))
1836+ return -ENOSPC;
1837+
17231838 WARN_ON_ONCE(counter->ctx->parent_ctx);
17241839 mutex_lock(&counter->child_mutex);
1725− values[0] = perf_counter_read_tree(counter);
1726− n = 1;
1727− if (counter->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
1728− values[n++] = counter->total_time_enabled +
1729− atomic64_read(&counter->child_total_time_enabled);
1730− if (counter->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
1731− values[n++] = counter->total_time_running +
1732− atomic64_read(&counter->child_total_time_running);
1733− if (counter->attr.read_format & PERF_FORMAT_ID)
1734− values[n++] = primary_counter_id(counter);
1840+ if (read_format & PERF_FORMAT_GROUP)
1841+ ret = perf_counter_read_group(counter, read_format, buf);
1842+ else
1843+ ret = perf_counter_read_one(counter, read_format, buf);
17351844 mutex_unlock(&counter->child_mutex);
17361845
1737− if (count < n * sizeof(u64))
1738− return -EINVAL;
1739− count = n * sizeof(u64);
1740−
1741− if (copy_to_user(buf, values, count))
1742− return -EFAULT;
1743−
1744− return count;
1846+ return ret;
17451847 }
17461848
17471849 static ssize_t
@@ -2245,7 +2347,7 @@ static void perf_pending_counter(struct perf_pending_entry *entry) · 497 unmodified lines
22452347
22462348 if (counter->pending_disable) {
22472349 counter->pending_disable = 0;
2248− perf_counter_disable(counter);
2350+ __perf_counter_disable(counter);
22492351 }
22502352
22512353 if (counter->pending_wakeup) {
@@ -2630,7 +2732,80 @@ static u32 perf_counter_tid(struct perf_counter *counter, struct task_struct *p) · 378 unmodified lines
26302732 return task_pid_nr_ns(p, counter->ns);
26312733 }
26322734
2633−static void perf_counter_output(struct perf_counter *counter, int nmi,
2735+static void perf_output_read_one(struct perf_output_handle *handle,
2736+ struct perf_counter *counter)
2737+{
2738+ u64 read_format = counter->attr.read_format;
2739+ u64 values[4];
2740+ int n = 0;
2741+
2742+ values[n++] = atomic64_read(&counter->count);
2743+ if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
2744+ values[n++] = counter->total_time_enabled +
2745+ atomic64_read(&counter->child_total_time_enabled);
2746+ }
2747+ if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
2748+ values[n++] = counter->total_time_running +
2749+ atomic64_read(&counter->child_total_time_running);
2750+ }
2751+ if (read_format & PERF_FORMAT_ID)
2752+ values[n++] = primary_counter_id(counter);
2753+
2754+ perf_output_copy(handle, values, n * sizeof(u64));
2755+}
2756+
2757+/*
2758+ * XXX PERF_FORMAT_GROUP vs inherited counters seems difficult.
2759+ */
2760+static void perf_output_read_group(struct perf_output_handle *handle,
2761+ struct perf_counter *counter)
2762+{
2763+ struct perf_counter *leader = counter->group_leader, *sub;
2764+ u64 read_format = counter->attr.read_format;
2765+ u64 values[5];
2766+ int n = 0;
2767+
2768+ values[n++] = 1 + leader->nr_siblings;
2769+
2770+ if (read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
2771+ values[n++] = leader->total_time_enabled;
2772+
2773+ if (read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
2774+ values[n++] = leader->total_time_running;
2775+
2776+ if (leader != counter)
2777+ leader->pmu->read(leader);
2778+
2779+ values[n++] = atomic64_read(&leader->count);
2780+ if (read_format & PERF_FORMAT_ID)
2781+ values[n++] = primary_counter_id(leader);
2782+
2783+ perf_output_copy(handle, values, n * sizeof(u64));
2784+
2785+ list_for_each_entry(sub, &leader->sibling_list, list_entry) {
2786+ n = 0;
2787+
2788+ if (sub != counter)
2789+ sub->pmu->read(sub);
2790+
2791+ values[n++] = atomic64_read(&sub->count);
2792+ if (read_format & PERF_FORMAT_ID)
2793+ values[n++] = primary_counter_id(sub);
2794+
2795+ perf_output_copy(handle, values, n * sizeof(u64));
2796+ }
2797+}
2798+
2799+static void perf_output_read(struct perf_output_handle *handle,
2800+ struct perf_counter *counter)
2801+{
2802+ if (counter->attr.read_format & PERF_FORMAT_GROUP)
2803+ perf_output_read_group(handle, counter);
2804+ else
2805+ perf_output_read_one(handle, counter);
2806+}
2807+
2808+void perf_counter_output(struct perf_counter *counter, int nmi,
26342809 struct perf_sample_data *data)
26352810 {
26362811 int ret;
@@ -2641,10 +2816,6 @@ static void perf_counter_output(struct perf_counter *counter, int nmi, · 4 unmodified lines
26412816 struct {
26422817 u32 pid, tid;
26432818 } tid_entry;
2644− struct {
2645− u64 id;
2646− u64 counter;
2647− } group_entry;
26482819 struct perf_callchain_entry *callchain = NULL;
26492820 int callchain_size = 0;
26502821 u64 time;
@@ -2699,10 +2870,8 @@ static void perf_counter_output(struct perf_counter *counter, int nmi, · 48 unmodified lines
26992870 if (sample_type & PERF_SAMPLE_PERIOD)
27002871 header.size += sizeof(u64);
27012872
2702− if (sample_type & PERF_SAMPLE_GROUP) {
2703− header.size += sizeof(u64) +
2704− counter->nr_siblings * sizeof(group_entry);
2705− }
2873+ if (sample_type & PERF_SAMPLE_READ)
2874+ header.size += perf_counter_read_size(counter);
27062875
27072876 if (sample_type & PERF_SAMPLE_CALLCHAIN) {
27082877 callchain = perf_callchain(data->regs);
@@ -2759,26 +2928,8 @@ static void perf_counter_output(struct perf_counter *counter, int nmi, · 50 unmodified lines
27592928 if (sample_type & PERF_SAMPLE_PERIOD)
27602929 perf_output_put(&handle, data->period);
27612930
2762− /*
2763− * XXX PERF_SAMPLE_GROUP vs inherited counters seems difficult.
2764− */
2765− if (sample_type & PERF_SAMPLE_GROUP) {
2766− struct perf_counter *leader, *sub;
2767− u64 nr = counter->nr_siblings;
2768−
2769− perf_output_put(&handle, nr);
2770−
2771− leader = counter->group_leader;
2772− list_for_each_entry(sub, &leader->sibling_list, list_entry) {
2773− if (sub != counter)
2774− sub->pmu->read(sub);
2775−
2776− group_entry.id = primary_counter_id(sub);
2777− group_entry.counter = atomic64_read(&sub->count);
2778−
2779− perf_output_put(&handle, group_entry);
2780− }
2781− }
2931+ if (sample_type & PERF_SAMPLE_READ)
2932+ perf_output_read(&handle, counter);
27822933
27832934 if (sample_type & PERF_SAMPLE_CALLCHAIN) {
27842935 if (callchain)
@@ -2817,8 +2968,6 @@ struct perf_read_event { · 32 unmodified lines
28172968
28182969 u32 pid;
28192970 u32 tid;
2820− u64 value;
2821− u64 format[3];
28222971 };
28232972
28242973 static void
@@ -2830,34 +2979,20 @@ perf_counter_read_event(struct perf_counter *counter, · 5 unmodified lines
28302979 .header = {
28312980 .type = PERF_EVENT_READ,
28322981 .misc = 0,
2833− .size = sizeof(event) - sizeof(event.format),
2982+ .size = sizeof(event) + perf_counter_read_size(counter),
28342983 },
28352984 .pid = perf_counter_pid(counter, task),
28362985 .tid = perf_counter_tid(counter, task),
2837− .value = atomic64_read(&counter->count),
28382986 };
2839− int ret, i = 0;
2840−
2841− if (counter->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) {
2842− event.header.size += sizeof(u64);
2843− event.format[i++] = counter->total_time_enabled;
2844− }
2845−
2846− if (counter->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) {
2847− event.header.size += sizeof(u64);
2848− event.format[i++] = counter->total_time_running;
2849− }
2850−
2851− if (counter->attr.read_format & PERF_FORMAT_ID) {
2852− event.header.size += sizeof(u64);
2853− event.format[i++] = primary_counter_id(counter);
2854− }
2987+ int ret;
28552988
28562989 ret = perf_output_begin(&handle, counter, event.header.size, 0, 0);
28572990 if (ret)
28582991 return;
28592992
2860− perf_output_copy(&handle, &event, event.header.size);
2993+ perf_output_put(&handle, event);
2994+ perf_output_read(&handle, counter);
2995+
28612996 perf_output_end(&handle);
28622997 }
28632998
@@ -2893,10 +3028,10 @@ static void perf_counter_task_output(struct perf_counter *counter, · 29 unmodified lines
28933028 return;
28943029
28953030 task_event->event.pid = perf_counter_pid(counter, task);
2896− task_event->event.ppid = perf_counter_pid(counter, task->real_parent);
3031+ task_event->event.ppid = perf_counter_pid(counter, current);
28973032
28983033 task_event->event.tid = perf_counter_tid(counter, task);
2899− task_event->event.ptid = perf_counter_tid(counter, task->real_parent);
3034+ task_event->event.ptid = perf_counter_tid(counter, current);
29003035
29013036 perf_output_put(&handle, task_event->event);
29023037 perf_output_end(&handle);
@@ -3443,40 +3578,32 @@ static void perf_swcounter_add(struct perf_counter *counter, u64 nr, · 540 unmodified lines
34433578
34443579 static int perf_swcounter_is_counting(struct perf_counter *counter)
34453580 {
3446− struct perf_counter_context *ctx;
3447− unsigned long flags;
3448− int count;
3449−
3581+ /*
3582+ * The counter is active, we're good!
3583+ */
34503584 if (counter->state == PERF_COUNTER_STATE_ACTIVE)
34513585 return 1;
34523586
3587+ /*
3588+ * The counter is off/error, not counting.
3589+ */
34533590 if (counter->state != PERF_COUNTER_STATE_INACTIVE)
34543591 return 0;
34553592
34563593 /*
3457− * If the counter is inactive, it could be just because
3458− * its task is scheduled out, or because it's in a group
3459− * which could not go on the PMU. We want to count in
3460− * the first case but not the second. If the context is
3461− * currently active then an inactive software counter must
3462− * be the second case. If it's not currently active then
3463− * we need to know whether the counter was active when the
3464− * context was last active, which we can determine by
3465− * comparing counter->tstamp_stopped with ctx->time.
3466− *
3467− * We are within an RCU read-side critical section,
3468− * which protects the existence of *ctx.
3594+ * The counter is inactive, if the context is active
3595+ * we're part of a group that didn't make it on the 'pmu',
3596+ * not counting.
34693597 */
3470− ctx = counter->ctx;
3471− spin_lock_irqsave(&ctx->lock, flags);
3472− count = 1;
3473− /* Re-check state now we have the lock */
3474− if (counter->state < PERF_COUNTER_STATE_INACTIVE ||
3475− counter->ctx->is_active ||
3476− counter->tstamp_stopped < ctx->time)
3477− count = 0;
3478− spin_unlock_irqrestore(&ctx->lock, flags);
3479− return count;
3598+ if (counter->ctx->is_active)
3599+ return 0;
3600+
3601+ /*
3602+ * We're inactive and the context is too, this means the
3603+ * task is scheduled out, we're counting events that happen
3604+ * to us, like migration events.
3605+ */
3606+ return 1;
34803607 }
34813608
34823609 static int perf_swcounter_match(struct perf_counter *counter,
@@ -3928,9 +4055,9 @@ perf_counter_alloc(struct perf_counter_attr *attr, · 445 unmodified lines
39284055 atomic64_set(&hwc->period_left, hwc->sample_period);
39294056
39304057 /*
3931− * we currently do not support PERF_SAMPLE_GROUP on inherited counters
4058+ * we currently do not support PERF_FORMAT_GROUP on inherited counters
39324059 */
3933− if (attr->inherit && (attr->sample_type & PERF_SAMPLE_GROUP))
4060+ if (attr->inherit && (attr->read_format & PERF_FORMAT_GROUP))
39344061 goto done;
39354062
39364063 switch (attr->type) {
@@ -4592,6 +4719,11 @@ perf_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) · 655 unmodified lines
45924719 perf_counter_init_cpu(cpu);
45934720 break;
45944721
4722+ case CPU_ONLINE:
4723+ case CPU_ONLINE_FROZEN:
4724+ hw_perf_counter_setup_online(cpu);
4725+ break;
4726+
45954727 case CPU_DOWN_PREPARE:
45964728 case CPU_DOWN_PREPARE_FROZEN:
45974729 perf_counter_exit_cpu(cpu);
@@ -4616,6 +4748,8 @@ void __init perf_counter_init(void) · 18 unmodified lines
46164748 {
46174749 perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_UP_PREPARE,
46184750 (void *)(long)smp_processor_id());
4751+ perf_cpu_notify(&perf_cpu_nb, (unsigned long)CPU_ONLINE,
4752+ (void *)(long)smp_processor_id());
46194753 register_cpu_notifier(&perf_cpu_nb);
46204754 }
46214755
tools/perf/Makefile+18−11
@@ -382,22 +382,29 @@ endif · 381 unmodified lines
382382 ifdef NO_DEMANGLE
383383 BASIC_CFLAGS += -DNO_DEMANGLE
384384 else
385−
386385 has_bfd := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd > /dev/null 2>&1 && echo y")
387386
388− has_bfd_iberty := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd -liberty > /dev/null 2>&1 && echo y")
389−
390− has_bfd_iberty_z := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd -liberty -lz > /dev/null 2>&1 && echo y")
391−
392387 ifeq ($(has_bfd),y)
393388 EXTLIBS += -lbfd
394− else ifeq ($(has_bfd_iberty),y)
395− EXTLIBS += -lbfd -liberty
396− else ifeq ($(has_bfd_iberty_z),y)
397− EXTLIBS += -lbfd -liberty -lz
398389 else
399− msg := $(warning No bfd.h/libbfd found, install binutils-dev[el] to gain symbol demangling)
400− BASIC_CFLAGS += -DNO_DEMANGLE
390+ has_bfd_iberty := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd -liberty > /dev/null 2>&1 && echo y")
391+ ifeq ($(has_bfd_iberty),y)
392+ EXTLIBS += -lbfd -liberty
393+ else
394+ has_bfd_iberty_z := $(shell sh -c "(echo '\#include <bfd.h>'; echo 'int main(void) { bfd_demangle(0, 0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -lbfd -liberty -lz > /dev/null 2>&1 && echo y")
395+ ifeq ($(has_bfd_iberty_z),y)
396+ EXTLIBS += -lbfd -liberty -lz
397+ else
398+ has_cplus_demangle := $(shell sh -c "(echo 'extern char *cplus_demangle(const char *, int);'; echo 'int main(void) { cplus_demangle(0, 0); return 0; }') | $(CC) -x c - $(ALL_CFLAGS) -o /dev/null $(ALL_LDFLAGS) -liberty > /dev/null 2>&1 && echo y")
399+ ifeq ($(has_cplus_demangle),y)
400+ EXTLIBS += -liberty
401+ BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
402+ else
403+ msg := $(warning No bfd.h/libbfd found, install binutils-dev[el] to gain symbol demangling)
404+ BASIC_CFLAGS += -DNO_DEMANGLE
405+ endif
406+ endif
407+ endif
401408 endif
402409 endif
403410
tools/perf/builtin-list.c+2−1
@@ -10,11 +10,12 @@ · 9 unmodified lines
1010
1111 #include "perf.h"
1212
13−#include "util/parse-options.h"
1413 #include "util/parse-events.h"
14+#include "util/cache.h"
1515
1616 int cmd_list(int argc __used, const char **argv __used, const char *prefix __used)
1717 {
18+ setup_pager();
1819 print_events();
1920 return 0;
2021 }
tools/perf/builtin-record.c+58−37
@@ -34,7 +34,9 @@ static int output; · 33 unmodified lines
3434 static const char *output_name = "perf.data";
3535 static int group = 0;
3636 static unsigned int realtime_prio = 0;
37+static int raw_samples = 0;
3738 static int system_wide = 0;
39+static int profile_cpu = -1;
3840 static pid_t target_pid = -1;
3941 static int inherit = 1;
4042 static int force = 0;
@@ -203,46 +205,48 @@ static void sig_atexit(void) · 162 unmodified lines
203205 kill(getpid(), signr);
204206 }
205207
206−static void pid_synthesize_comm_event(pid_t pid, int full)
208+static pid_t pid_synthesize_comm_event(pid_t pid, int full)
207209 {
208210 struct comm_event comm_ev;
209211 char filename[PATH_MAX];
210212 char bf[BUFSIZ];
211− int fd;
212− size_t size;
213− char *field, *sep;
213+ FILE *fp;
214+ size_t size = 0;
214215 DIR *tasks;
215216 struct dirent dirent, *next;
217+ pid_t tgid = 0;
216218
217− snprintf(filename, sizeof(filename), "/proc/%d/stat", pid);
219+ snprintf(filename, sizeof(filename), "/proc/%d/status", pid);
218220
219− fd = open(filename, O_RDONLY);
220− if (fd < 0) {
221+ fp = fopen(filename, "r");
222+ if (fd == NULL) {
221223 /*
222224 * We raced with a task exiting - just return:
223225 */
224226 if (verbose)
225227 fprintf(stderr, "couldn't open %s\n", filename);
226− return;
227− }
228− if (read(fd, bf, sizeof(bf)) < 0) {
229− fprintf(stderr, "couldn't read %s\n", filename);
230− exit(EXIT_FAILURE);
228+ return 0;
231229 }
232− close(fd);
233230
234− /* 9027 (cat) R 6747 9027 6747 34816 9027 ... */
235231 memset(&comm_ev, 0, sizeof(comm_ev));
236− field = strchr(bf, '(');
237− if (field == NULL)
238− goto out_failure;
239− sep = strchr(++field, ')');
240− if (sep == NULL)
241− goto out_failure;
242− size = sep - field;
243− memcpy(comm_ev.comm, field, size++);
244−
245− comm_ev.pid = pid;
232+ while (!comm_ev.comm[0] || !comm_ev.pid) {
233+ if (fgets(bf, sizeof(bf), fp) == NULL)
234+ goto out_failure;
235+
236+ if (memcmp(bf, "Name:", 5) == 0) {
237+ char *name = bf + 5;
238+ while (*name && isspace(*name))
239+ ++name;
240+ size = strlen(name) - 1;
241+ memcpy(comm_ev.comm, name, size++);
242+ } else if (memcmp(bf, "Tgid:", 5) == 0) {
243+ char *tgids = bf + 5;
244+ while (*tgids && isspace(*tgids))
245+ ++tgids;
246+ tgid = comm_ev.pid = atoi(tgids);
247+ }
248+ }
249+
246250 comm_ev.header.type = PERF_EVENT_COMM;
247251 size = ALIGN(size, sizeof(u64));
248252 comm_ev.header.size = sizeof(comm_ev) - (sizeof(comm_ev.comm) - size);
@@ -251,7 +255,7 @@ static void pid_synthesize_comm_event(pid_t pid, int full) · 2 unmodified lines
251255 comm_ev.tid = pid;
252256
253257 write_output(&comm_ev, comm_ev.header.size);
254− return;
258+ goto out_fclose;
255259 }
256260
257261 snprintf(filename, sizeof(filename), "/proc/%d/task", pid);
@@ -268,7 +272,10 @@ static void pid_synthesize_comm_event(pid_t pid, int full) · 10 unmodified lines
268272 write_output(&comm_ev, comm_ev.header.size);
269273 }
270274 closedir(tasks);
271− return;
275+
276+out_fclose:
277+ fclose(fp);
278+ return tgid;
272279
273280 out_failure:
274281 fprintf(stderr, "couldn't get COMM and pgid, malformed %s\n",
@@ -276,7 +283,7 @@ out_failure: · 1 unmodified line
276283 exit(EXIT_FAILURE);
277284 }
278285
279−static void pid_synthesize_mmap_samples(pid_t pid)
286+static void pid_synthesize_mmap_samples(pid_t pid, pid_t tgid)
280287 {
281288 char filename[PATH_MAX];
282289 FILE *fp;
@@ -328,7 +335,7 @@ static void pid_synthesize_mmap_samples(pid_t pid) · 45 unmodified lines
328335 mmap_ev.len -= mmap_ev.start;
329336 mmap_ev.header.size = (sizeof(mmap_ev) -
330337 (sizeof(mmap_ev.filename) - size));
331− mmap_ev.pid = pid;
338+ mmap_ev.pid = tgid;
332339 mmap_ev.tid = pid;
333340
334341 write_output(&mmap_ev, mmap_ev.header.size);
@@ -347,14 +354,14 @@ static void synthesize_all(void) · 12 unmodified lines
347354
348355 while (!readdir_r(proc, &dirent, &next) && next) {
349356 char *end;
350− pid_t pid;
357+ pid_t pid, tgid;
351358
352359 pid = strtol(dirent.d_name, &end, 10);
353360 if (*end) /* only interested in proper numerical dirents */
354361 continue;
355362
356− pid_synthesize_comm_event(pid, 1);
357− pid_synthesize_mmap_samples(pid);
363+ tgid = pid_synthesize_comm_event(pid, 1);
364+ pid_synthesize_mmap_samples(pid, tgid);
358365 }
359366
360367 closedir(proc);
@@ -392,7 +399,7 @@ static void create_counter(int counter, int cpu, pid_t pid) · 31 unmodified lines
392399 PERF_FORMAT_TOTAL_TIME_RUNNING |
393400 PERF_FORMAT_ID;
394401
395− attr->sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID;
402+ attr->sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID;
396403
397404 if (freq) {
398405 attr->sample_type |= PERF_SAMPLE_PERIOD;
@@ -412,6 +419,8 @@ static void create_counter(int counter, int cpu, pid_t pid) · 13 unmodified lines
412419 if (call_graph)
413420 attr->sample_type |= PERF_SAMPLE_CALLCHAIN;
414421
422+ if (raw_samples)
423+ attr->sample_type |= PERF_SAMPLE_RAW;
415424
416425 attr->mmap = track;
417426 attr->comm = track;
@@ -426,6 +435,8 @@ try_again: · 8 unmodified lines
426435
427436 if (err == EPERM)
428437 die("Permission error - are you root?\n");
438+ else if (err == ENODEV && profile_cpu != -1)
439+ die("No such device - did you specify an out-of-range profile CPU?\n");
429440
430441 /*
431442 * If it's cycles then fall back to hrtimer
@@ -559,16 +570,22 @@ static int __cmd_record(int argc, const char **argv) · 127 unmodified lines
559570 if (pid == -1)
560571 pid = getpid();
561572
562− open_counters(-1, pid);
563− } else for (i = 0; i < nr_cpus; i++)
564− open_counters(i, target_pid);
573+ open_counters(profile_cpu, pid);
574+ } else {
575+ if (profile_cpu != -1) {
576+ open_counters(profile_cpu, target_pid);
577+ } else {
578+ for (i = 0; i < nr_cpus; i++)
579+ open_counters(i, target_pid);
580+ }
581+ }
565582
566583 if (file_new)
567584 perf_header__write(header, output);
568585
569586 if (!system_wide) {
570− pid_synthesize_comm_event(pid, 0);
571− pid_synthesize_mmap_samples(pid);
587+ pid_t tgid = pid_synthesize_comm_event(pid, 0);
588+ pid_synthesize_mmap_samples(pid, tgid);
572589 } else
573590 synthesize_all();
574591
@@ -636,10 +653,14 @@ static const struct option options[] = { · 61 unmodified lines
636653 "record events on existing pid"),
637654 OPT_INTEGER('r', "realtime", &realtime_prio,
638655 "collect data with this RT SCHED_FIFO priority"),
656+ OPT_BOOLEAN('R', "raw-samples", &raw_samples,
657+ "collect raw sample records from all opened counters"),
639658 OPT_BOOLEAN('a', "all-cpus", &system_wide,
640659 "system-wide collection from all CPUs"),
641660 OPT_BOOLEAN('A', "append", &append_file,
642661 "append to the output file to do incremental profiling"),
662+ OPT_INTEGER('C', "profile_cpu", &profile_cpu,
663+ "CPU to profile on"),
643664 OPT_BOOLEAN('f', "force", &force,
644665 "overwrite existing data file"),
645666 OPT_LONG('c', "count", &default_interval,
tools/perf/builtin-report.c+7−5
@@ -1526,11 +1526,11 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) · 1525 unmodified lines
15261526 more_data += sizeof(u64);
15271527 }
15281528
1529− dprintf("%p [%p]: PERF_EVENT_SAMPLE (IP, %d): %d: %p period: %Ld\n",
1529+ dprintf("%p [%p]: PERF_EVENT_SAMPLE (IP, %d): %d/%d: %p period: %Ld\n",
15301530 (void *)(offset + head),
15311531 (void *)(long)(event->header.size),
15321532 event->header.misc,
1533− event->ip.pid,
1533+ event->ip.pid, event->ip.tid,
15341534 (void *)(long)ip,
15351535 (long long)period);
15361536
@@ -1590,10 +1590,11 @@ process_sample_event(event_t *event, unsigned long offset, unsigned long head) · 53 unmodified lines
15901590 if (show & show_mask) {
15911591 struct symbol *sym = resolve_symbol(thread, &map, &dso, &ip);
15921592
1593− if (dso_list && dso && dso->name && !strlist__has_entry(dso_list, dso->name))
1593+ if (dso_list && (!dso || !dso->name ||
1594+ !strlist__has_entry(dso_list, dso->name)))
15941595 return 0;
15951596
1596− if (sym_list && sym && !strlist__has_entry(sym_list, sym->name))
1597+ if (sym_list && (!sym || !strlist__has_entry(sym_list, sym->name)))
15971598 return 0;
15981599
15991600 if (hist_entry__add(thread, map, dso, sym, ip, chain, level, period)) {
@@ -1612,10 +1613,11 @@ process_mmap_event(event_t *event, unsigned long offset, unsigned long head) · 12 unmodified lines
16121613 struct thread *thread = threads__findnew(event->mmap.pid);
16131614 struct map *map = map__new(&event->mmap);
16141615
1615− dprintf("%p [%p]: PERF_EVENT_MMAP %d: [%p(%p) @ %p]: %s\n",
1616+ dprintf("%p [%p]: PERF_EVENT_MMAP %d/%d: [%p(%p) @ %p]: %s\n",
16161617 (void *)(offset + head),
16171618 (void *)(long)(event->header.size),
16181619 event->mmap.pid,
1620+ event->mmap.tid,
16191621 (void *)(long)event->mmap.start,
16201622 (void *)(long)event->mmap.len,
16211623 (void *)(long)event->mmap.pgoff,
tools/perf/util/parse-events.c+10−0
@@ -379,6 +379,7 @@ static int parse_tracepoint_event(const char **strp, · 378 unmodified lines
379379 struct perf_counter_attr *attr)
380380 {
381381 const char *evt_name;
382+ char *flags;
382383 char sys_name[MAX_EVENT_LENGTH];
383384 char id_buf[4];
384385 int fd;
@@ -400,6 +401,15 @@ static int parse_tracepoint_event(const char **strp, · 15 unmodified lines
400401 strncpy(sys_name, *strp, sys_length);
401402 sys_name[sys_length] = '\0';
402403 evt_name = evt_name + 1;
404+
405+ flags = strchr(evt_name, ':');
406+ if (flags) {
407+ *flags = '\0';
408+ flags++;
409+ if (!strncmp(flags, "record", strlen(flags)))
410+ attr->sample_type |= PERF_SAMPLE_RAW;
411+ }
412+
403413 evt_length = strlen(evt_name);
404414 if (evt_length >= MAX_EVENT_LENGTH)
405415 return 0;
tools/perf/util/symbol.c+2−15
@@ -7,23 +7,8 @@ · 6 unmodified lines
77 #include <gelf.h>
88 #include <elf.h>
99
10−#ifndef NO_DEMANGLE
11−#include <bfd.h>
12−#else
13−static inline
14−char *bfd_demangle(void __used *v, const char __used *c, int __used i)
15−{
16− return NULL;
17−}
18−#endif
19−
2010 const char *sym_hist_filter;
2111
22−#ifndef DMGL_PARAMS
23−#define DMGL_PARAMS (1 << 0) /* Include function args */
24−#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
25−#endif
26−
2712 enum dso_origin {
2813 DSO__ORIG_KERNEL = 0,
2914 DSO__ORIG_JAVA_JIT,
@@ -816,6 +801,8 @@ more: · 786 unmodified lines
816801 }
817802 out:
818803 free(name);
804+ if (ret < 0 && strstr(self->name, " (deleted)") != NULL)
805+ return 0;
819806 return ret;
820807 }
821808
tools/perf/util/symbol.h+24−0
@@ -7,6 +7,30 @@ · 6 unmodified lines
77 #include <linux/rbtree.h>
88 #include "module.h"
99
10+#ifdef HAVE_CPLUS_DEMANGLE
11+extern char *cplus_demangle(const char *, int);
12+
13+static inline char *bfd_demangle(void __used *v, const char *c, int i)
14+{
15+ return cplus_demangle(c, i);
16+}
17+#else
18+#ifdef NO_DEMANGLE
19+static inline char *bfd_demangle(void __used *v, const char __used *c,
20+ int __used i)
21+{
22+ return NULL;
23+}
24+#else
25+#include <bfd.h>
26+#endif
27+#endif
28+
29+#ifndef DMGL_PARAMS
30+#define DMGL_PARAMS (1 << 0) /* Include function args */
31+#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
32+#endif
33+
1034 struct symbol {
1135 struct rb_node rb_node;
1236 u64 start;