Commit 1d229d54dbc26971142f61c3d271a68db236d178

Authored by Linus Torvalds

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

…l/git/tip/linux-2.6-tip

* 'perf-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  perf symbols: Check '/tmp/perf-' symbol file ownership
  perf sched: Usage leftover from trace -> script rename
  perf sched: Do not delete session object prematurely
  perf tools: Check $HOME/.perfconfig ownership
  perf, x86: Add model 45 SandyBridge support
  perf tools: Add support to install perf python extension
  perf tools: do not look at ./config for configuration
  perf tools: Make clean leaves some files
  perf lock: Dropping unsupported ':r' modifier
  perf probe: Fix coredump introduced by probe module option
  jump label: Reduce the cycle count by changing the link order
  perf report: Use ui__warning in some more places
  perf python: Add PERF_RECORD_{LOST,READ,SAMPLE} routine tables
  perf evlist: Introduce 'disable' method
  trace events: Update version number reference to new 3.x scheme for EVENT_POWER_TRACING_DEPRECATED
  perf buildid-cache: Zero out buffer of filenames when adding/removing buildid

Showing 16 changed files Inline Diff

arch/x86/kernel/cpu/perf_event_intel.c
1 #ifdef CONFIG_CPU_SUP_INTEL 1 #ifdef CONFIG_CPU_SUP_INTEL
2 2
3 /* 3 /*
4 * Per core/cpu state 4 * Per core/cpu state
5 * 5 *
6 * Used to coordinate shared registers between HT threads or 6 * Used to coordinate shared registers between HT threads or
7 * among events on a single PMU. 7 * among events on a single PMU.
8 */ 8 */
9 struct intel_shared_regs { 9 struct intel_shared_regs {
10 struct er_account regs[EXTRA_REG_MAX]; 10 struct er_account regs[EXTRA_REG_MAX];
11 int refcnt; /* per-core: #HT threads */ 11 int refcnt; /* per-core: #HT threads */
12 unsigned core_id; /* per-core: core id */ 12 unsigned core_id; /* per-core: core id */
13 }; 13 };
14 14
15 /* 15 /*
16 * Intel PerfMon, used on Core and later. 16 * Intel PerfMon, used on Core and later.
17 */ 17 */
18 static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX] __read_mostly = 18 static u64 intel_perfmon_event_map[PERF_COUNT_HW_MAX] __read_mostly =
19 { 19 {
20 [PERF_COUNT_HW_CPU_CYCLES] = 0x003c, 20 [PERF_COUNT_HW_CPU_CYCLES] = 0x003c,
21 [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0, 21 [PERF_COUNT_HW_INSTRUCTIONS] = 0x00c0,
22 [PERF_COUNT_HW_CACHE_REFERENCES] = 0x4f2e, 22 [PERF_COUNT_HW_CACHE_REFERENCES] = 0x4f2e,
23 [PERF_COUNT_HW_CACHE_MISSES] = 0x412e, 23 [PERF_COUNT_HW_CACHE_MISSES] = 0x412e,
24 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4, 24 [PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = 0x00c4,
25 [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5, 25 [PERF_COUNT_HW_BRANCH_MISSES] = 0x00c5,
26 [PERF_COUNT_HW_BUS_CYCLES] = 0x013c, 26 [PERF_COUNT_HW_BUS_CYCLES] = 0x013c,
27 }; 27 };
28 28
29 static struct event_constraint intel_core_event_constraints[] __read_mostly = 29 static struct event_constraint intel_core_event_constraints[] __read_mostly =
30 { 30 {
31 INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */ 31 INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */
32 INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */ 32 INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
33 INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */ 33 INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */
34 INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */ 34 INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */
35 INTEL_EVENT_CONSTRAINT(0x19, 0x2), /* DELAYED_BYPASS */ 35 INTEL_EVENT_CONSTRAINT(0x19, 0x2), /* DELAYED_BYPASS */
36 INTEL_EVENT_CONSTRAINT(0xc1, 0x1), /* FP_COMP_INSTR_RET */ 36 INTEL_EVENT_CONSTRAINT(0xc1, 0x1), /* FP_COMP_INSTR_RET */
37 EVENT_CONSTRAINT_END 37 EVENT_CONSTRAINT_END
38 }; 38 };
39 39
40 static struct event_constraint intel_core2_event_constraints[] __read_mostly = 40 static struct event_constraint intel_core2_event_constraints[] __read_mostly =
41 { 41 {
42 FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ 42 FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
43 FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ 43 FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
44 /* 44 /*
45 * Core2 has Fixed Counter 2 listed as CPU_CLK_UNHALTED.REF and event 45 * Core2 has Fixed Counter 2 listed as CPU_CLK_UNHALTED.REF and event
46 * 0x013c as CPU_CLK_UNHALTED.BUS and specifies there is a fixed 46 * 0x013c as CPU_CLK_UNHALTED.BUS and specifies there is a fixed
47 * ratio between these counters. 47 * ratio between these counters.
48 */ 48 */
49 /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */ 49 /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */
50 INTEL_EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */ 50 INTEL_EVENT_CONSTRAINT(0x10, 0x1), /* FP_COMP_OPS_EXE */
51 INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */ 51 INTEL_EVENT_CONSTRAINT(0x11, 0x2), /* FP_ASSIST */
52 INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */ 52 INTEL_EVENT_CONSTRAINT(0x12, 0x2), /* MUL */
53 INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */ 53 INTEL_EVENT_CONSTRAINT(0x13, 0x2), /* DIV */
54 INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */ 54 INTEL_EVENT_CONSTRAINT(0x14, 0x1), /* CYCLES_DIV_BUSY */
55 INTEL_EVENT_CONSTRAINT(0x18, 0x1), /* IDLE_DURING_DIV */ 55 INTEL_EVENT_CONSTRAINT(0x18, 0x1), /* IDLE_DURING_DIV */
56 INTEL_EVENT_CONSTRAINT(0x19, 0x2), /* DELAYED_BYPASS */ 56 INTEL_EVENT_CONSTRAINT(0x19, 0x2), /* DELAYED_BYPASS */
57 INTEL_EVENT_CONSTRAINT(0xa1, 0x1), /* RS_UOPS_DISPATCH_CYCLES */ 57 INTEL_EVENT_CONSTRAINT(0xa1, 0x1), /* RS_UOPS_DISPATCH_CYCLES */
58 INTEL_EVENT_CONSTRAINT(0xc9, 0x1), /* ITLB_MISS_RETIRED (T30-9) */ 58 INTEL_EVENT_CONSTRAINT(0xc9, 0x1), /* ITLB_MISS_RETIRED (T30-9) */
59 INTEL_EVENT_CONSTRAINT(0xcb, 0x1), /* MEM_LOAD_RETIRED */ 59 INTEL_EVENT_CONSTRAINT(0xcb, 0x1), /* MEM_LOAD_RETIRED */
60 EVENT_CONSTRAINT_END 60 EVENT_CONSTRAINT_END
61 }; 61 };
62 62
63 static struct event_constraint intel_nehalem_event_constraints[] __read_mostly = 63 static struct event_constraint intel_nehalem_event_constraints[] __read_mostly =
64 { 64 {
65 FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ 65 FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
66 FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ 66 FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
67 /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */ 67 /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */
68 INTEL_EVENT_CONSTRAINT(0x40, 0x3), /* L1D_CACHE_LD */ 68 INTEL_EVENT_CONSTRAINT(0x40, 0x3), /* L1D_CACHE_LD */
69 INTEL_EVENT_CONSTRAINT(0x41, 0x3), /* L1D_CACHE_ST */ 69 INTEL_EVENT_CONSTRAINT(0x41, 0x3), /* L1D_CACHE_ST */
70 INTEL_EVENT_CONSTRAINT(0x42, 0x3), /* L1D_CACHE_LOCK */ 70 INTEL_EVENT_CONSTRAINT(0x42, 0x3), /* L1D_CACHE_LOCK */
71 INTEL_EVENT_CONSTRAINT(0x43, 0x3), /* L1D_ALL_REF */ 71 INTEL_EVENT_CONSTRAINT(0x43, 0x3), /* L1D_ALL_REF */
72 INTEL_EVENT_CONSTRAINT(0x48, 0x3), /* L1D_PEND_MISS */ 72 INTEL_EVENT_CONSTRAINT(0x48, 0x3), /* L1D_PEND_MISS */
73 INTEL_EVENT_CONSTRAINT(0x4e, 0x3), /* L1D_PREFETCH */ 73 INTEL_EVENT_CONSTRAINT(0x4e, 0x3), /* L1D_PREFETCH */
74 INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */ 74 INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */
75 INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */ 75 INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */
76 EVENT_CONSTRAINT_END 76 EVENT_CONSTRAINT_END
77 }; 77 };
78 78
79 static struct extra_reg intel_nehalem_extra_regs[] __read_mostly = 79 static struct extra_reg intel_nehalem_extra_regs[] __read_mostly =
80 { 80 {
81 INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0), 81 INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0),
82 EVENT_EXTRA_END 82 EVENT_EXTRA_END
83 }; 83 };
84 84
85 static struct event_constraint intel_westmere_event_constraints[] __read_mostly = 85 static struct event_constraint intel_westmere_event_constraints[] __read_mostly =
86 { 86 {
87 FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ 87 FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
88 FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ 88 FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
89 /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */ 89 /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */
90 INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */ 90 INTEL_EVENT_CONSTRAINT(0x51, 0x3), /* L1D */
91 INTEL_EVENT_CONSTRAINT(0x60, 0x1), /* OFFCORE_REQUESTS_OUTSTANDING */ 91 INTEL_EVENT_CONSTRAINT(0x60, 0x1), /* OFFCORE_REQUESTS_OUTSTANDING */
92 INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */ 92 INTEL_EVENT_CONSTRAINT(0x63, 0x3), /* CACHE_LOCK_CYCLES */
93 INTEL_EVENT_CONSTRAINT(0xb3, 0x1), /* SNOOPQ_REQUEST_OUTSTANDING */ 93 INTEL_EVENT_CONSTRAINT(0xb3, 0x1), /* SNOOPQ_REQUEST_OUTSTANDING */
94 EVENT_CONSTRAINT_END 94 EVENT_CONSTRAINT_END
95 }; 95 };
96 96
97 static struct event_constraint intel_snb_event_constraints[] __read_mostly = 97 static struct event_constraint intel_snb_event_constraints[] __read_mostly =
98 { 98 {
99 FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ 99 FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
100 FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ 100 FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
101 /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */ 101 /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */
102 INTEL_EVENT_CONSTRAINT(0x48, 0x4), /* L1D_PEND_MISS.PENDING */ 102 INTEL_EVENT_CONSTRAINT(0x48, 0x4), /* L1D_PEND_MISS.PENDING */
103 INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */ 103 INTEL_UEVENT_CONSTRAINT(0x01c0, 0x2), /* INST_RETIRED.PREC_DIST */
104 INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */ 104 INTEL_EVENT_CONSTRAINT(0xcd, 0x8), /* MEM_TRANS_RETIRED.LOAD_LATENCY */
105 EVENT_CONSTRAINT_END 105 EVENT_CONSTRAINT_END
106 }; 106 };
107 107
108 static struct extra_reg intel_westmere_extra_regs[] __read_mostly = 108 static struct extra_reg intel_westmere_extra_regs[] __read_mostly =
109 { 109 {
110 INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0), 110 INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0xffff, RSP_0),
111 INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0xffff, RSP_1), 111 INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0xffff, RSP_1),
112 EVENT_EXTRA_END 112 EVENT_EXTRA_END
113 }; 113 };
114 114
115 static struct event_constraint intel_v1_event_constraints[] __read_mostly = 115 static struct event_constraint intel_v1_event_constraints[] __read_mostly =
116 { 116 {
117 EVENT_CONSTRAINT_END 117 EVENT_CONSTRAINT_END
118 }; 118 };
119 119
120 static struct event_constraint intel_gen_event_constraints[] __read_mostly = 120 static struct event_constraint intel_gen_event_constraints[] __read_mostly =
121 { 121 {
122 FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */ 122 FIXED_EVENT_CONSTRAINT(0x00c0, 0), /* INST_RETIRED.ANY */
123 FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */ 123 FIXED_EVENT_CONSTRAINT(0x003c, 1), /* CPU_CLK_UNHALTED.CORE */
124 /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */ 124 /* FIXED_EVENT_CONSTRAINT(0x013c, 2), CPU_CLK_UNHALTED.REF */
125 EVENT_CONSTRAINT_END 125 EVENT_CONSTRAINT_END
126 }; 126 };
127 127
128 static struct extra_reg intel_snb_extra_regs[] __read_mostly = { 128 static struct extra_reg intel_snb_extra_regs[] __read_mostly = {
129 INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3fffffffffull, RSP_0), 129 INTEL_EVENT_EXTRA_REG(0xb7, MSR_OFFCORE_RSP_0, 0x3fffffffffull, RSP_0),
130 INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3fffffffffull, RSP_1), 130 INTEL_EVENT_EXTRA_REG(0xbb, MSR_OFFCORE_RSP_1, 0x3fffffffffull, RSP_1),
131 EVENT_EXTRA_END 131 EVENT_EXTRA_END
132 }; 132 };
133 133
134 static u64 intel_pmu_event_map(int hw_event) 134 static u64 intel_pmu_event_map(int hw_event)
135 { 135 {
136 return intel_perfmon_event_map[hw_event]; 136 return intel_perfmon_event_map[hw_event];
137 } 137 }
138 138
139 static __initconst const u64 snb_hw_cache_event_ids 139 static __initconst const u64 snb_hw_cache_event_ids
140 [PERF_COUNT_HW_CACHE_MAX] 140 [PERF_COUNT_HW_CACHE_MAX]
141 [PERF_COUNT_HW_CACHE_OP_MAX] 141 [PERF_COUNT_HW_CACHE_OP_MAX]
142 [PERF_COUNT_HW_CACHE_RESULT_MAX] = 142 [PERF_COUNT_HW_CACHE_RESULT_MAX] =
143 { 143 {
144 [ C(L1D) ] = { 144 [ C(L1D) ] = {
145 [ C(OP_READ) ] = { 145 [ C(OP_READ) ] = {
146 [ C(RESULT_ACCESS) ] = 0xf1d0, /* MEM_UOP_RETIRED.LOADS */ 146 [ C(RESULT_ACCESS) ] = 0xf1d0, /* MEM_UOP_RETIRED.LOADS */
147 [ C(RESULT_MISS) ] = 0x0151, /* L1D.REPLACEMENT */ 147 [ C(RESULT_MISS) ] = 0x0151, /* L1D.REPLACEMENT */
148 }, 148 },
149 [ C(OP_WRITE) ] = { 149 [ C(OP_WRITE) ] = {
150 [ C(RESULT_ACCESS) ] = 0xf2d0, /* MEM_UOP_RETIRED.STORES */ 150 [ C(RESULT_ACCESS) ] = 0xf2d0, /* MEM_UOP_RETIRED.STORES */
151 [ C(RESULT_MISS) ] = 0x0851, /* L1D.ALL_M_REPLACEMENT */ 151 [ C(RESULT_MISS) ] = 0x0851, /* L1D.ALL_M_REPLACEMENT */
152 }, 152 },
153 [ C(OP_PREFETCH) ] = { 153 [ C(OP_PREFETCH) ] = {
154 [ C(RESULT_ACCESS) ] = 0x0, 154 [ C(RESULT_ACCESS) ] = 0x0,
155 [ C(RESULT_MISS) ] = 0x024e, /* HW_PRE_REQ.DL1_MISS */ 155 [ C(RESULT_MISS) ] = 0x024e, /* HW_PRE_REQ.DL1_MISS */
156 }, 156 },
157 }, 157 },
158 [ C(L1I ) ] = { 158 [ C(L1I ) ] = {
159 [ C(OP_READ) ] = { 159 [ C(OP_READ) ] = {
160 [ C(RESULT_ACCESS) ] = 0x0, 160 [ C(RESULT_ACCESS) ] = 0x0,
161 [ C(RESULT_MISS) ] = 0x0280, /* ICACHE.MISSES */ 161 [ C(RESULT_MISS) ] = 0x0280, /* ICACHE.MISSES */
162 }, 162 },
163 [ C(OP_WRITE) ] = { 163 [ C(OP_WRITE) ] = {
164 [ C(RESULT_ACCESS) ] = -1, 164 [ C(RESULT_ACCESS) ] = -1,
165 [ C(RESULT_MISS) ] = -1, 165 [ C(RESULT_MISS) ] = -1,
166 }, 166 },
167 [ C(OP_PREFETCH) ] = { 167 [ C(OP_PREFETCH) ] = {
168 [ C(RESULT_ACCESS) ] = 0x0, 168 [ C(RESULT_ACCESS) ] = 0x0,
169 [ C(RESULT_MISS) ] = 0x0, 169 [ C(RESULT_MISS) ] = 0x0,
170 }, 170 },
171 }, 171 },
172 [ C(LL ) ] = { 172 [ C(LL ) ] = {
173 [ C(OP_READ) ] = { 173 [ C(OP_READ) ] = {
174 /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */ 174 /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
175 [ C(RESULT_ACCESS) ] = 0x01b7, 175 [ C(RESULT_ACCESS) ] = 0x01b7,
176 /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */ 176 /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
177 [ C(RESULT_MISS) ] = 0x01b7, 177 [ C(RESULT_MISS) ] = 0x01b7,
178 }, 178 },
179 [ C(OP_WRITE) ] = { 179 [ C(OP_WRITE) ] = {
180 /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */ 180 /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
181 [ C(RESULT_ACCESS) ] = 0x01b7, 181 [ C(RESULT_ACCESS) ] = 0x01b7,
182 /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */ 182 /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
183 [ C(RESULT_MISS) ] = 0x01b7, 183 [ C(RESULT_MISS) ] = 0x01b7,
184 }, 184 },
185 [ C(OP_PREFETCH) ] = { 185 [ C(OP_PREFETCH) ] = {
186 /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */ 186 /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
187 [ C(RESULT_ACCESS) ] = 0x01b7, 187 [ C(RESULT_ACCESS) ] = 0x01b7,
188 /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */ 188 /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
189 [ C(RESULT_MISS) ] = 0x01b7, 189 [ C(RESULT_MISS) ] = 0x01b7,
190 }, 190 },
191 }, 191 },
192 [ C(DTLB) ] = { 192 [ C(DTLB) ] = {
193 [ C(OP_READ) ] = { 193 [ C(OP_READ) ] = {
194 [ C(RESULT_ACCESS) ] = 0x81d0, /* MEM_UOP_RETIRED.ALL_LOADS */ 194 [ C(RESULT_ACCESS) ] = 0x81d0, /* MEM_UOP_RETIRED.ALL_LOADS */
195 [ C(RESULT_MISS) ] = 0x0108, /* DTLB_LOAD_MISSES.CAUSES_A_WALK */ 195 [ C(RESULT_MISS) ] = 0x0108, /* DTLB_LOAD_MISSES.CAUSES_A_WALK */
196 }, 196 },
197 [ C(OP_WRITE) ] = { 197 [ C(OP_WRITE) ] = {
198 [ C(RESULT_ACCESS) ] = 0x82d0, /* MEM_UOP_RETIRED.ALL_STORES */ 198 [ C(RESULT_ACCESS) ] = 0x82d0, /* MEM_UOP_RETIRED.ALL_STORES */
199 [ C(RESULT_MISS) ] = 0x0149, /* DTLB_STORE_MISSES.MISS_CAUSES_A_WALK */ 199 [ C(RESULT_MISS) ] = 0x0149, /* DTLB_STORE_MISSES.MISS_CAUSES_A_WALK */
200 }, 200 },
201 [ C(OP_PREFETCH) ] = { 201 [ C(OP_PREFETCH) ] = {
202 [ C(RESULT_ACCESS) ] = 0x0, 202 [ C(RESULT_ACCESS) ] = 0x0,
203 [ C(RESULT_MISS) ] = 0x0, 203 [ C(RESULT_MISS) ] = 0x0,
204 }, 204 },
205 }, 205 },
206 [ C(ITLB) ] = { 206 [ C(ITLB) ] = {
207 [ C(OP_READ) ] = { 207 [ C(OP_READ) ] = {
208 [ C(RESULT_ACCESS) ] = 0x1085, /* ITLB_MISSES.STLB_HIT */ 208 [ C(RESULT_ACCESS) ] = 0x1085, /* ITLB_MISSES.STLB_HIT */
209 [ C(RESULT_MISS) ] = 0x0185, /* ITLB_MISSES.CAUSES_A_WALK */ 209 [ C(RESULT_MISS) ] = 0x0185, /* ITLB_MISSES.CAUSES_A_WALK */
210 }, 210 },
211 [ C(OP_WRITE) ] = { 211 [ C(OP_WRITE) ] = {
212 [ C(RESULT_ACCESS) ] = -1, 212 [ C(RESULT_ACCESS) ] = -1,
213 [ C(RESULT_MISS) ] = -1, 213 [ C(RESULT_MISS) ] = -1,
214 }, 214 },
215 [ C(OP_PREFETCH) ] = { 215 [ C(OP_PREFETCH) ] = {
216 [ C(RESULT_ACCESS) ] = -1, 216 [ C(RESULT_ACCESS) ] = -1,
217 [ C(RESULT_MISS) ] = -1, 217 [ C(RESULT_MISS) ] = -1,
218 }, 218 },
219 }, 219 },
220 [ C(BPU ) ] = { 220 [ C(BPU ) ] = {
221 [ C(OP_READ) ] = { 221 [ C(OP_READ) ] = {
222 [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */ 222 [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
223 [ C(RESULT_MISS) ] = 0x00c5, /* BR_MISP_RETIRED.ALL_BRANCHES */ 223 [ C(RESULT_MISS) ] = 0x00c5, /* BR_MISP_RETIRED.ALL_BRANCHES */
224 }, 224 },
225 [ C(OP_WRITE) ] = { 225 [ C(OP_WRITE) ] = {
226 [ C(RESULT_ACCESS) ] = -1, 226 [ C(RESULT_ACCESS) ] = -1,
227 [ C(RESULT_MISS) ] = -1, 227 [ C(RESULT_MISS) ] = -1,
228 }, 228 },
229 [ C(OP_PREFETCH) ] = { 229 [ C(OP_PREFETCH) ] = {
230 [ C(RESULT_ACCESS) ] = -1, 230 [ C(RESULT_ACCESS) ] = -1,
231 [ C(RESULT_MISS) ] = -1, 231 [ C(RESULT_MISS) ] = -1,
232 }, 232 },
233 }, 233 },
234 [ C(NODE) ] = { 234 [ C(NODE) ] = {
235 [ C(OP_READ) ] = { 235 [ C(OP_READ) ] = {
236 [ C(RESULT_ACCESS) ] = -1, 236 [ C(RESULT_ACCESS) ] = -1,
237 [ C(RESULT_MISS) ] = -1, 237 [ C(RESULT_MISS) ] = -1,
238 }, 238 },
239 [ C(OP_WRITE) ] = { 239 [ C(OP_WRITE) ] = {
240 [ C(RESULT_ACCESS) ] = -1, 240 [ C(RESULT_ACCESS) ] = -1,
241 [ C(RESULT_MISS) ] = -1, 241 [ C(RESULT_MISS) ] = -1,
242 }, 242 },
243 [ C(OP_PREFETCH) ] = { 243 [ C(OP_PREFETCH) ] = {
244 [ C(RESULT_ACCESS) ] = -1, 244 [ C(RESULT_ACCESS) ] = -1,
245 [ C(RESULT_MISS) ] = -1, 245 [ C(RESULT_MISS) ] = -1,
246 }, 246 },
247 }, 247 },
248 248
249 }; 249 };
250 250
251 static __initconst const u64 westmere_hw_cache_event_ids 251 static __initconst const u64 westmere_hw_cache_event_ids
252 [PERF_COUNT_HW_CACHE_MAX] 252 [PERF_COUNT_HW_CACHE_MAX]
253 [PERF_COUNT_HW_CACHE_OP_MAX] 253 [PERF_COUNT_HW_CACHE_OP_MAX]
254 [PERF_COUNT_HW_CACHE_RESULT_MAX] = 254 [PERF_COUNT_HW_CACHE_RESULT_MAX] =
255 { 255 {
256 [ C(L1D) ] = { 256 [ C(L1D) ] = {
257 [ C(OP_READ) ] = { 257 [ C(OP_READ) ] = {
258 [ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS */ 258 [ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS */
259 [ C(RESULT_MISS) ] = 0x0151, /* L1D.REPL */ 259 [ C(RESULT_MISS) ] = 0x0151, /* L1D.REPL */
260 }, 260 },
261 [ C(OP_WRITE) ] = { 261 [ C(OP_WRITE) ] = {
262 [ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES */ 262 [ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES */
263 [ C(RESULT_MISS) ] = 0x0251, /* L1D.M_REPL */ 263 [ C(RESULT_MISS) ] = 0x0251, /* L1D.M_REPL */
264 }, 264 },
265 [ C(OP_PREFETCH) ] = { 265 [ C(OP_PREFETCH) ] = {
266 [ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS */ 266 [ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS */
267 [ C(RESULT_MISS) ] = 0x024e, /* L1D_PREFETCH.MISS */ 267 [ C(RESULT_MISS) ] = 0x024e, /* L1D_PREFETCH.MISS */
268 }, 268 },
269 }, 269 },
270 [ C(L1I ) ] = { 270 [ C(L1I ) ] = {
271 [ C(OP_READ) ] = { 271 [ C(OP_READ) ] = {
272 [ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS */ 272 [ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS */
273 [ C(RESULT_MISS) ] = 0x0280, /* L1I.MISSES */ 273 [ C(RESULT_MISS) ] = 0x0280, /* L1I.MISSES */
274 }, 274 },
275 [ C(OP_WRITE) ] = { 275 [ C(OP_WRITE) ] = {
276 [ C(RESULT_ACCESS) ] = -1, 276 [ C(RESULT_ACCESS) ] = -1,
277 [ C(RESULT_MISS) ] = -1, 277 [ C(RESULT_MISS) ] = -1,
278 }, 278 },
279 [ C(OP_PREFETCH) ] = { 279 [ C(OP_PREFETCH) ] = {
280 [ C(RESULT_ACCESS) ] = 0x0, 280 [ C(RESULT_ACCESS) ] = 0x0,
281 [ C(RESULT_MISS) ] = 0x0, 281 [ C(RESULT_MISS) ] = 0x0,
282 }, 282 },
283 }, 283 },
284 [ C(LL ) ] = { 284 [ C(LL ) ] = {
285 [ C(OP_READ) ] = { 285 [ C(OP_READ) ] = {
286 /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */ 286 /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
287 [ C(RESULT_ACCESS) ] = 0x01b7, 287 [ C(RESULT_ACCESS) ] = 0x01b7,
288 /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */ 288 /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
289 [ C(RESULT_MISS) ] = 0x01b7, 289 [ C(RESULT_MISS) ] = 0x01b7,
290 }, 290 },
291 /* 291 /*
292 * Use RFO, not WRITEBACK, because a write miss would typically occur 292 * Use RFO, not WRITEBACK, because a write miss would typically occur
293 * on RFO. 293 * on RFO.
294 */ 294 */
295 [ C(OP_WRITE) ] = { 295 [ C(OP_WRITE) ] = {
296 /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */ 296 /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
297 [ C(RESULT_ACCESS) ] = 0x01b7, 297 [ C(RESULT_ACCESS) ] = 0x01b7,
298 /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */ 298 /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
299 [ C(RESULT_MISS) ] = 0x01b7, 299 [ C(RESULT_MISS) ] = 0x01b7,
300 }, 300 },
301 [ C(OP_PREFETCH) ] = { 301 [ C(OP_PREFETCH) ] = {
302 /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */ 302 /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
303 [ C(RESULT_ACCESS) ] = 0x01b7, 303 [ C(RESULT_ACCESS) ] = 0x01b7,
304 /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */ 304 /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
305 [ C(RESULT_MISS) ] = 0x01b7, 305 [ C(RESULT_MISS) ] = 0x01b7,
306 }, 306 },
307 }, 307 },
308 [ C(DTLB) ] = { 308 [ C(DTLB) ] = {
309 [ C(OP_READ) ] = { 309 [ C(OP_READ) ] = {
310 [ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS */ 310 [ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS */
311 [ C(RESULT_MISS) ] = 0x0108, /* DTLB_LOAD_MISSES.ANY */ 311 [ C(RESULT_MISS) ] = 0x0108, /* DTLB_LOAD_MISSES.ANY */
312 }, 312 },
313 [ C(OP_WRITE) ] = { 313 [ C(OP_WRITE) ] = {
314 [ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES */ 314 [ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES */
315 [ C(RESULT_MISS) ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS */ 315 [ C(RESULT_MISS) ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS */
316 }, 316 },
317 [ C(OP_PREFETCH) ] = { 317 [ C(OP_PREFETCH) ] = {
318 [ C(RESULT_ACCESS) ] = 0x0, 318 [ C(RESULT_ACCESS) ] = 0x0,
319 [ C(RESULT_MISS) ] = 0x0, 319 [ C(RESULT_MISS) ] = 0x0,
320 }, 320 },
321 }, 321 },
322 [ C(ITLB) ] = { 322 [ C(ITLB) ] = {
323 [ C(OP_READ) ] = { 323 [ C(OP_READ) ] = {
324 [ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P */ 324 [ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P */
325 [ C(RESULT_MISS) ] = 0x0185, /* ITLB_MISSES.ANY */ 325 [ C(RESULT_MISS) ] = 0x0185, /* ITLB_MISSES.ANY */
326 }, 326 },
327 [ C(OP_WRITE) ] = { 327 [ C(OP_WRITE) ] = {
328 [ C(RESULT_ACCESS) ] = -1, 328 [ C(RESULT_ACCESS) ] = -1,
329 [ C(RESULT_MISS) ] = -1, 329 [ C(RESULT_MISS) ] = -1,
330 }, 330 },
331 [ C(OP_PREFETCH) ] = { 331 [ C(OP_PREFETCH) ] = {
332 [ C(RESULT_ACCESS) ] = -1, 332 [ C(RESULT_ACCESS) ] = -1,
333 [ C(RESULT_MISS) ] = -1, 333 [ C(RESULT_MISS) ] = -1,
334 }, 334 },
335 }, 335 },
336 [ C(BPU ) ] = { 336 [ C(BPU ) ] = {
337 [ C(OP_READ) ] = { 337 [ C(OP_READ) ] = {
338 [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */ 338 [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
339 [ C(RESULT_MISS) ] = 0x03e8, /* BPU_CLEARS.ANY */ 339 [ C(RESULT_MISS) ] = 0x03e8, /* BPU_CLEARS.ANY */
340 }, 340 },
341 [ C(OP_WRITE) ] = { 341 [ C(OP_WRITE) ] = {
342 [ C(RESULT_ACCESS) ] = -1, 342 [ C(RESULT_ACCESS) ] = -1,
343 [ C(RESULT_MISS) ] = -1, 343 [ C(RESULT_MISS) ] = -1,
344 }, 344 },
345 [ C(OP_PREFETCH) ] = { 345 [ C(OP_PREFETCH) ] = {
346 [ C(RESULT_ACCESS) ] = -1, 346 [ C(RESULT_ACCESS) ] = -1,
347 [ C(RESULT_MISS) ] = -1, 347 [ C(RESULT_MISS) ] = -1,
348 }, 348 },
349 }, 349 },
350 [ C(NODE) ] = { 350 [ C(NODE) ] = {
351 [ C(OP_READ) ] = { 351 [ C(OP_READ) ] = {
352 [ C(RESULT_ACCESS) ] = 0x01b7, 352 [ C(RESULT_ACCESS) ] = 0x01b7,
353 [ C(RESULT_MISS) ] = 0x01b7, 353 [ C(RESULT_MISS) ] = 0x01b7,
354 }, 354 },
355 [ C(OP_WRITE) ] = { 355 [ C(OP_WRITE) ] = {
356 [ C(RESULT_ACCESS) ] = 0x01b7, 356 [ C(RESULT_ACCESS) ] = 0x01b7,
357 [ C(RESULT_MISS) ] = 0x01b7, 357 [ C(RESULT_MISS) ] = 0x01b7,
358 }, 358 },
359 [ C(OP_PREFETCH) ] = { 359 [ C(OP_PREFETCH) ] = {
360 [ C(RESULT_ACCESS) ] = 0x01b7, 360 [ C(RESULT_ACCESS) ] = 0x01b7,
361 [ C(RESULT_MISS) ] = 0x01b7, 361 [ C(RESULT_MISS) ] = 0x01b7,
362 }, 362 },
363 }, 363 },
364 }; 364 };
365 365
366 /* 366 /*
367 * Nehalem/Westmere MSR_OFFCORE_RESPONSE bits; 367 * Nehalem/Westmere MSR_OFFCORE_RESPONSE bits;
368 * See IA32 SDM Vol 3B 30.6.1.3 368 * See IA32 SDM Vol 3B 30.6.1.3
369 */ 369 */
370 370
371 #define NHM_DMND_DATA_RD (1 << 0) 371 #define NHM_DMND_DATA_RD (1 << 0)
372 #define NHM_DMND_RFO (1 << 1) 372 #define NHM_DMND_RFO (1 << 1)
373 #define NHM_DMND_IFETCH (1 << 2) 373 #define NHM_DMND_IFETCH (1 << 2)
374 #define NHM_DMND_WB (1 << 3) 374 #define NHM_DMND_WB (1 << 3)
375 #define NHM_PF_DATA_RD (1 << 4) 375 #define NHM_PF_DATA_RD (1 << 4)
376 #define NHM_PF_DATA_RFO (1 << 5) 376 #define NHM_PF_DATA_RFO (1 << 5)
377 #define NHM_PF_IFETCH (1 << 6) 377 #define NHM_PF_IFETCH (1 << 6)
378 #define NHM_OFFCORE_OTHER (1 << 7) 378 #define NHM_OFFCORE_OTHER (1 << 7)
379 #define NHM_UNCORE_HIT (1 << 8) 379 #define NHM_UNCORE_HIT (1 << 8)
380 #define NHM_OTHER_CORE_HIT_SNP (1 << 9) 380 #define NHM_OTHER_CORE_HIT_SNP (1 << 9)
381 #define NHM_OTHER_CORE_HITM (1 << 10) 381 #define NHM_OTHER_CORE_HITM (1 << 10)
382 /* reserved */ 382 /* reserved */
383 #define NHM_REMOTE_CACHE_FWD (1 << 12) 383 #define NHM_REMOTE_CACHE_FWD (1 << 12)
384 #define NHM_REMOTE_DRAM (1 << 13) 384 #define NHM_REMOTE_DRAM (1 << 13)
385 #define NHM_LOCAL_DRAM (1 << 14) 385 #define NHM_LOCAL_DRAM (1 << 14)
386 #define NHM_NON_DRAM (1 << 15) 386 #define NHM_NON_DRAM (1 << 15)
387 387
388 #define NHM_ALL_DRAM (NHM_REMOTE_DRAM|NHM_LOCAL_DRAM) 388 #define NHM_ALL_DRAM (NHM_REMOTE_DRAM|NHM_LOCAL_DRAM)
389 389
390 #define NHM_DMND_READ (NHM_DMND_DATA_RD) 390 #define NHM_DMND_READ (NHM_DMND_DATA_RD)
391 #define NHM_DMND_WRITE (NHM_DMND_RFO|NHM_DMND_WB) 391 #define NHM_DMND_WRITE (NHM_DMND_RFO|NHM_DMND_WB)
392 #define NHM_DMND_PREFETCH (NHM_PF_DATA_RD|NHM_PF_DATA_RFO) 392 #define NHM_DMND_PREFETCH (NHM_PF_DATA_RD|NHM_PF_DATA_RFO)
393 393
394 #define NHM_L3_HIT (NHM_UNCORE_HIT|NHM_OTHER_CORE_HIT_SNP|NHM_OTHER_CORE_HITM) 394 #define NHM_L3_HIT (NHM_UNCORE_HIT|NHM_OTHER_CORE_HIT_SNP|NHM_OTHER_CORE_HITM)
395 #define NHM_L3_MISS (NHM_NON_DRAM|NHM_ALL_DRAM|NHM_REMOTE_CACHE_FWD) 395 #define NHM_L3_MISS (NHM_NON_DRAM|NHM_ALL_DRAM|NHM_REMOTE_CACHE_FWD)
396 #define NHM_L3_ACCESS (NHM_L3_HIT|NHM_L3_MISS) 396 #define NHM_L3_ACCESS (NHM_L3_HIT|NHM_L3_MISS)
397 397
398 static __initconst const u64 nehalem_hw_cache_extra_regs 398 static __initconst const u64 nehalem_hw_cache_extra_regs
399 [PERF_COUNT_HW_CACHE_MAX] 399 [PERF_COUNT_HW_CACHE_MAX]
400 [PERF_COUNT_HW_CACHE_OP_MAX] 400 [PERF_COUNT_HW_CACHE_OP_MAX]
401 [PERF_COUNT_HW_CACHE_RESULT_MAX] = 401 [PERF_COUNT_HW_CACHE_RESULT_MAX] =
402 { 402 {
403 [ C(LL ) ] = { 403 [ C(LL ) ] = {
404 [ C(OP_READ) ] = { 404 [ C(OP_READ) ] = {
405 [ C(RESULT_ACCESS) ] = NHM_DMND_READ|NHM_L3_ACCESS, 405 [ C(RESULT_ACCESS) ] = NHM_DMND_READ|NHM_L3_ACCESS,
406 [ C(RESULT_MISS) ] = NHM_DMND_READ|NHM_L3_MISS, 406 [ C(RESULT_MISS) ] = NHM_DMND_READ|NHM_L3_MISS,
407 }, 407 },
408 [ C(OP_WRITE) ] = { 408 [ C(OP_WRITE) ] = {
409 [ C(RESULT_ACCESS) ] = NHM_DMND_WRITE|NHM_L3_ACCESS, 409 [ C(RESULT_ACCESS) ] = NHM_DMND_WRITE|NHM_L3_ACCESS,
410 [ C(RESULT_MISS) ] = NHM_DMND_WRITE|NHM_L3_MISS, 410 [ C(RESULT_MISS) ] = NHM_DMND_WRITE|NHM_L3_MISS,
411 }, 411 },
412 [ C(OP_PREFETCH) ] = { 412 [ C(OP_PREFETCH) ] = {
413 [ C(RESULT_ACCESS) ] = NHM_DMND_PREFETCH|NHM_L3_ACCESS, 413 [ C(RESULT_ACCESS) ] = NHM_DMND_PREFETCH|NHM_L3_ACCESS,
414 [ C(RESULT_MISS) ] = NHM_DMND_PREFETCH|NHM_L3_MISS, 414 [ C(RESULT_MISS) ] = NHM_DMND_PREFETCH|NHM_L3_MISS,
415 }, 415 },
416 }, 416 },
417 [ C(NODE) ] = { 417 [ C(NODE) ] = {
418 [ C(OP_READ) ] = { 418 [ C(OP_READ) ] = {
419 [ C(RESULT_ACCESS) ] = NHM_DMND_READ|NHM_ALL_DRAM, 419 [ C(RESULT_ACCESS) ] = NHM_DMND_READ|NHM_ALL_DRAM,
420 [ C(RESULT_MISS) ] = NHM_DMND_READ|NHM_REMOTE_DRAM, 420 [ C(RESULT_MISS) ] = NHM_DMND_READ|NHM_REMOTE_DRAM,
421 }, 421 },
422 [ C(OP_WRITE) ] = { 422 [ C(OP_WRITE) ] = {
423 [ C(RESULT_ACCESS) ] = NHM_DMND_WRITE|NHM_ALL_DRAM, 423 [ C(RESULT_ACCESS) ] = NHM_DMND_WRITE|NHM_ALL_DRAM,
424 [ C(RESULT_MISS) ] = NHM_DMND_WRITE|NHM_REMOTE_DRAM, 424 [ C(RESULT_MISS) ] = NHM_DMND_WRITE|NHM_REMOTE_DRAM,
425 }, 425 },
426 [ C(OP_PREFETCH) ] = { 426 [ C(OP_PREFETCH) ] = {
427 [ C(RESULT_ACCESS) ] = NHM_DMND_PREFETCH|NHM_ALL_DRAM, 427 [ C(RESULT_ACCESS) ] = NHM_DMND_PREFETCH|NHM_ALL_DRAM,
428 [ C(RESULT_MISS) ] = NHM_DMND_PREFETCH|NHM_REMOTE_DRAM, 428 [ C(RESULT_MISS) ] = NHM_DMND_PREFETCH|NHM_REMOTE_DRAM,
429 }, 429 },
430 }, 430 },
431 }; 431 };
432 432
433 static __initconst const u64 nehalem_hw_cache_event_ids 433 static __initconst const u64 nehalem_hw_cache_event_ids
434 [PERF_COUNT_HW_CACHE_MAX] 434 [PERF_COUNT_HW_CACHE_MAX]
435 [PERF_COUNT_HW_CACHE_OP_MAX] 435 [PERF_COUNT_HW_CACHE_OP_MAX]
436 [PERF_COUNT_HW_CACHE_RESULT_MAX] = 436 [PERF_COUNT_HW_CACHE_RESULT_MAX] =
437 { 437 {
438 [ C(L1D) ] = { 438 [ C(L1D) ] = {
439 [ C(OP_READ) ] = { 439 [ C(OP_READ) ] = {
440 [ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS */ 440 [ C(RESULT_ACCESS) ] = 0x010b, /* MEM_INST_RETIRED.LOADS */
441 [ C(RESULT_MISS) ] = 0x0151, /* L1D.REPL */ 441 [ C(RESULT_MISS) ] = 0x0151, /* L1D.REPL */
442 }, 442 },
443 [ C(OP_WRITE) ] = { 443 [ C(OP_WRITE) ] = {
444 [ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES */ 444 [ C(RESULT_ACCESS) ] = 0x020b, /* MEM_INST_RETURED.STORES */
445 [ C(RESULT_MISS) ] = 0x0251, /* L1D.M_REPL */ 445 [ C(RESULT_MISS) ] = 0x0251, /* L1D.M_REPL */
446 }, 446 },
447 [ C(OP_PREFETCH) ] = { 447 [ C(OP_PREFETCH) ] = {
448 [ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS */ 448 [ C(RESULT_ACCESS) ] = 0x014e, /* L1D_PREFETCH.REQUESTS */
449 [ C(RESULT_MISS) ] = 0x024e, /* L1D_PREFETCH.MISS */ 449 [ C(RESULT_MISS) ] = 0x024e, /* L1D_PREFETCH.MISS */
450 }, 450 },
451 }, 451 },
452 [ C(L1I ) ] = { 452 [ C(L1I ) ] = {
453 [ C(OP_READ) ] = { 453 [ C(OP_READ) ] = {
454 [ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS */ 454 [ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS */
455 [ C(RESULT_MISS) ] = 0x0280, /* L1I.MISSES */ 455 [ C(RESULT_MISS) ] = 0x0280, /* L1I.MISSES */
456 }, 456 },
457 [ C(OP_WRITE) ] = { 457 [ C(OP_WRITE) ] = {
458 [ C(RESULT_ACCESS) ] = -1, 458 [ C(RESULT_ACCESS) ] = -1,
459 [ C(RESULT_MISS) ] = -1, 459 [ C(RESULT_MISS) ] = -1,
460 }, 460 },
461 [ C(OP_PREFETCH) ] = { 461 [ C(OP_PREFETCH) ] = {
462 [ C(RESULT_ACCESS) ] = 0x0, 462 [ C(RESULT_ACCESS) ] = 0x0,
463 [ C(RESULT_MISS) ] = 0x0, 463 [ C(RESULT_MISS) ] = 0x0,
464 }, 464 },
465 }, 465 },
466 [ C(LL ) ] = { 466 [ C(LL ) ] = {
467 [ C(OP_READ) ] = { 467 [ C(OP_READ) ] = {
468 /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */ 468 /* OFFCORE_RESPONSE.ANY_DATA.LOCAL_CACHE */
469 [ C(RESULT_ACCESS) ] = 0x01b7, 469 [ C(RESULT_ACCESS) ] = 0x01b7,
470 /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */ 470 /* OFFCORE_RESPONSE.ANY_DATA.ANY_LLC_MISS */
471 [ C(RESULT_MISS) ] = 0x01b7, 471 [ C(RESULT_MISS) ] = 0x01b7,
472 }, 472 },
473 /* 473 /*
474 * Use RFO, not WRITEBACK, because a write miss would typically occur 474 * Use RFO, not WRITEBACK, because a write miss would typically occur
475 * on RFO. 475 * on RFO.
476 */ 476 */
477 [ C(OP_WRITE) ] = { 477 [ C(OP_WRITE) ] = {
478 /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */ 478 /* OFFCORE_RESPONSE.ANY_RFO.LOCAL_CACHE */
479 [ C(RESULT_ACCESS) ] = 0x01b7, 479 [ C(RESULT_ACCESS) ] = 0x01b7,
480 /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */ 480 /* OFFCORE_RESPONSE.ANY_RFO.ANY_LLC_MISS */
481 [ C(RESULT_MISS) ] = 0x01b7, 481 [ C(RESULT_MISS) ] = 0x01b7,
482 }, 482 },
483 [ C(OP_PREFETCH) ] = { 483 [ C(OP_PREFETCH) ] = {
484 /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */ 484 /* OFFCORE_RESPONSE.PREFETCH.LOCAL_CACHE */
485 [ C(RESULT_ACCESS) ] = 0x01b7, 485 [ C(RESULT_ACCESS) ] = 0x01b7,
486 /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */ 486 /* OFFCORE_RESPONSE.PREFETCH.ANY_LLC_MISS */
487 [ C(RESULT_MISS) ] = 0x01b7, 487 [ C(RESULT_MISS) ] = 0x01b7,
488 }, 488 },
489 }, 489 },
490 [ C(DTLB) ] = { 490 [ C(DTLB) ] = {
491 [ C(OP_READ) ] = { 491 [ C(OP_READ) ] = {
492 [ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI (alias) */ 492 [ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI (alias) */
493 [ C(RESULT_MISS) ] = 0x0108, /* DTLB_LOAD_MISSES.ANY */ 493 [ C(RESULT_MISS) ] = 0x0108, /* DTLB_LOAD_MISSES.ANY */
494 }, 494 },
495 [ C(OP_WRITE) ] = { 495 [ C(OP_WRITE) ] = {
496 [ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI (alias) */ 496 [ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI (alias) */
497 [ C(RESULT_MISS) ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS */ 497 [ C(RESULT_MISS) ] = 0x010c, /* MEM_STORE_RETIRED.DTLB_MISS */
498 }, 498 },
499 [ C(OP_PREFETCH) ] = { 499 [ C(OP_PREFETCH) ] = {
500 [ C(RESULT_ACCESS) ] = 0x0, 500 [ C(RESULT_ACCESS) ] = 0x0,
501 [ C(RESULT_MISS) ] = 0x0, 501 [ C(RESULT_MISS) ] = 0x0,
502 }, 502 },
503 }, 503 },
504 [ C(ITLB) ] = { 504 [ C(ITLB) ] = {
505 [ C(OP_READ) ] = { 505 [ C(OP_READ) ] = {
506 [ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P */ 506 [ C(RESULT_ACCESS) ] = 0x01c0, /* INST_RETIRED.ANY_P */
507 [ C(RESULT_MISS) ] = 0x20c8, /* ITLB_MISS_RETIRED */ 507 [ C(RESULT_MISS) ] = 0x20c8, /* ITLB_MISS_RETIRED */
508 }, 508 },
509 [ C(OP_WRITE) ] = { 509 [ C(OP_WRITE) ] = {
510 [ C(RESULT_ACCESS) ] = -1, 510 [ C(RESULT_ACCESS) ] = -1,
511 [ C(RESULT_MISS) ] = -1, 511 [ C(RESULT_MISS) ] = -1,
512 }, 512 },
513 [ C(OP_PREFETCH) ] = { 513 [ C(OP_PREFETCH) ] = {
514 [ C(RESULT_ACCESS) ] = -1, 514 [ C(RESULT_ACCESS) ] = -1,
515 [ C(RESULT_MISS) ] = -1, 515 [ C(RESULT_MISS) ] = -1,
516 }, 516 },
517 }, 517 },
518 [ C(BPU ) ] = { 518 [ C(BPU ) ] = {
519 [ C(OP_READ) ] = { 519 [ C(OP_READ) ] = {
520 [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */ 520 [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ALL_BRANCHES */
521 [ C(RESULT_MISS) ] = 0x03e8, /* BPU_CLEARS.ANY */ 521 [ C(RESULT_MISS) ] = 0x03e8, /* BPU_CLEARS.ANY */
522 }, 522 },
523 [ C(OP_WRITE) ] = { 523 [ C(OP_WRITE) ] = {
524 [ C(RESULT_ACCESS) ] = -1, 524 [ C(RESULT_ACCESS) ] = -1,
525 [ C(RESULT_MISS) ] = -1, 525 [ C(RESULT_MISS) ] = -1,
526 }, 526 },
527 [ C(OP_PREFETCH) ] = { 527 [ C(OP_PREFETCH) ] = {
528 [ C(RESULT_ACCESS) ] = -1, 528 [ C(RESULT_ACCESS) ] = -1,
529 [ C(RESULT_MISS) ] = -1, 529 [ C(RESULT_MISS) ] = -1,
530 }, 530 },
531 }, 531 },
532 [ C(NODE) ] = { 532 [ C(NODE) ] = {
533 [ C(OP_READ) ] = { 533 [ C(OP_READ) ] = {
534 [ C(RESULT_ACCESS) ] = 0x01b7, 534 [ C(RESULT_ACCESS) ] = 0x01b7,
535 [ C(RESULT_MISS) ] = 0x01b7, 535 [ C(RESULT_MISS) ] = 0x01b7,
536 }, 536 },
537 [ C(OP_WRITE) ] = { 537 [ C(OP_WRITE) ] = {
538 [ C(RESULT_ACCESS) ] = 0x01b7, 538 [ C(RESULT_ACCESS) ] = 0x01b7,
539 [ C(RESULT_MISS) ] = 0x01b7, 539 [ C(RESULT_MISS) ] = 0x01b7,
540 }, 540 },
541 [ C(OP_PREFETCH) ] = { 541 [ C(OP_PREFETCH) ] = {
542 [ C(RESULT_ACCESS) ] = 0x01b7, 542 [ C(RESULT_ACCESS) ] = 0x01b7,
543 [ C(RESULT_MISS) ] = 0x01b7, 543 [ C(RESULT_MISS) ] = 0x01b7,
544 }, 544 },
545 }, 545 },
546 }; 546 };
547 547
548 static __initconst const u64 core2_hw_cache_event_ids 548 static __initconst const u64 core2_hw_cache_event_ids
549 [PERF_COUNT_HW_CACHE_MAX] 549 [PERF_COUNT_HW_CACHE_MAX]
550 [PERF_COUNT_HW_CACHE_OP_MAX] 550 [PERF_COUNT_HW_CACHE_OP_MAX]
551 [PERF_COUNT_HW_CACHE_RESULT_MAX] = 551 [PERF_COUNT_HW_CACHE_RESULT_MAX] =
552 { 552 {
553 [ C(L1D) ] = { 553 [ C(L1D) ] = {
554 [ C(OP_READ) ] = { 554 [ C(OP_READ) ] = {
555 [ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI */ 555 [ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI */
556 [ C(RESULT_MISS) ] = 0x0140, /* L1D_CACHE_LD.I_STATE */ 556 [ C(RESULT_MISS) ] = 0x0140, /* L1D_CACHE_LD.I_STATE */
557 }, 557 },
558 [ C(OP_WRITE) ] = { 558 [ C(OP_WRITE) ] = {
559 [ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI */ 559 [ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI */
560 [ C(RESULT_MISS) ] = 0x0141, /* L1D_CACHE_ST.I_STATE */ 560 [ C(RESULT_MISS) ] = 0x0141, /* L1D_CACHE_ST.I_STATE */
561 }, 561 },
562 [ C(OP_PREFETCH) ] = { 562 [ C(OP_PREFETCH) ] = {
563 [ C(RESULT_ACCESS) ] = 0x104e, /* L1D_PREFETCH.REQUESTS */ 563 [ C(RESULT_ACCESS) ] = 0x104e, /* L1D_PREFETCH.REQUESTS */
564 [ C(RESULT_MISS) ] = 0, 564 [ C(RESULT_MISS) ] = 0,
565 }, 565 },
566 }, 566 },
567 [ C(L1I ) ] = { 567 [ C(L1I ) ] = {
568 [ C(OP_READ) ] = { 568 [ C(OP_READ) ] = {
569 [ C(RESULT_ACCESS) ] = 0x0080, /* L1I.READS */ 569 [ C(RESULT_ACCESS) ] = 0x0080, /* L1I.READS */
570 [ C(RESULT_MISS) ] = 0x0081, /* L1I.MISSES */ 570 [ C(RESULT_MISS) ] = 0x0081, /* L1I.MISSES */
571 }, 571 },
572 [ C(OP_WRITE) ] = { 572 [ C(OP_WRITE) ] = {
573 [ C(RESULT_ACCESS) ] = -1, 573 [ C(RESULT_ACCESS) ] = -1,
574 [ C(RESULT_MISS) ] = -1, 574 [ C(RESULT_MISS) ] = -1,
575 }, 575 },
576 [ C(OP_PREFETCH) ] = { 576 [ C(OP_PREFETCH) ] = {
577 [ C(RESULT_ACCESS) ] = 0, 577 [ C(RESULT_ACCESS) ] = 0,
578 [ C(RESULT_MISS) ] = 0, 578 [ C(RESULT_MISS) ] = 0,
579 }, 579 },
580 }, 580 },
581 [ C(LL ) ] = { 581 [ C(LL ) ] = {
582 [ C(OP_READ) ] = { 582 [ C(OP_READ) ] = {
583 [ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI */ 583 [ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI */
584 [ C(RESULT_MISS) ] = 0x4129, /* L2_LD.ISTATE */ 584 [ C(RESULT_MISS) ] = 0x4129, /* L2_LD.ISTATE */
585 }, 585 },
586 [ C(OP_WRITE) ] = { 586 [ C(OP_WRITE) ] = {
587 [ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI */ 587 [ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI */
588 [ C(RESULT_MISS) ] = 0x412A, /* L2_ST.ISTATE */ 588 [ C(RESULT_MISS) ] = 0x412A, /* L2_ST.ISTATE */
589 }, 589 },
590 [ C(OP_PREFETCH) ] = { 590 [ C(OP_PREFETCH) ] = {
591 [ C(RESULT_ACCESS) ] = 0, 591 [ C(RESULT_ACCESS) ] = 0,
592 [ C(RESULT_MISS) ] = 0, 592 [ C(RESULT_MISS) ] = 0,
593 }, 593 },
594 }, 594 },
595 [ C(DTLB) ] = { 595 [ C(DTLB) ] = {
596 [ C(OP_READ) ] = { 596 [ C(OP_READ) ] = {
597 [ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI (alias) */ 597 [ C(RESULT_ACCESS) ] = 0x0f40, /* L1D_CACHE_LD.MESI (alias) */
598 [ C(RESULT_MISS) ] = 0x0208, /* DTLB_MISSES.MISS_LD */ 598 [ C(RESULT_MISS) ] = 0x0208, /* DTLB_MISSES.MISS_LD */
599 }, 599 },
600 [ C(OP_WRITE) ] = { 600 [ C(OP_WRITE) ] = {
601 [ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI (alias) */ 601 [ C(RESULT_ACCESS) ] = 0x0f41, /* L1D_CACHE_ST.MESI (alias) */
602 [ C(RESULT_MISS) ] = 0x0808, /* DTLB_MISSES.MISS_ST */ 602 [ C(RESULT_MISS) ] = 0x0808, /* DTLB_MISSES.MISS_ST */
603 }, 603 },
604 [ C(OP_PREFETCH) ] = { 604 [ C(OP_PREFETCH) ] = {
605 [ C(RESULT_ACCESS) ] = 0, 605 [ C(RESULT_ACCESS) ] = 0,
606 [ C(RESULT_MISS) ] = 0, 606 [ C(RESULT_MISS) ] = 0,
607 }, 607 },
608 }, 608 },
609 [ C(ITLB) ] = { 609 [ C(ITLB) ] = {
610 [ C(OP_READ) ] = { 610 [ C(OP_READ) ] = {
611 [ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P */ 611 [ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P */
612 [ C(RESULT_MISS) ] = 0x1282, /* ITLBMISSES */ 612 [ C(RESULT_MISS) ] = 0x1282, /* ITLBMISSES */
613 }, 613 },
614 [ C(OP_WRITE) ] = { 614 [ C(OP_WRITE) ] = {
615 [ C(RESULT_ACCESS) ] = -1, 615 [ C(RESULT_ACCESS) ] = -1,
616 [ C(RESULT_MISS) ] = -1, 616 [ C(RESULT_MISS) ] = -1,
617 }, 617 },
618 [ C(OP_PREFETCH) ] = { 618 [ C(OP_PREFETCH) ] = {
619 [ C(RESULT_ACCESS) ] = -1, 619 [ C(RESULT_ACCESS) ] = -1,
620 [ C(RESULT_MISS) ] = -1, 620 [ C(RESULT_MISS) ] = -1,
621 }, 621 },
622 }, 622 },
623 [ C(BPU ) ] = { 623 [ C(BPU ) ] = {
624 [ C(OP_READ) ] = { 624 [ C(OP_READ) ] = {
625 [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY */ 625 [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY */
626 [ C(RESULT_MISS) ] = 0x00c5, /* BP_INST_RETIRED.MISPRED */ 626 [ C(RESULT_MISS) ] = 0x00c5, /* BP_INST_RETIRED.MISPRED */
627 }, 627 },
628 [ C(OP_WRITE) ] = { 628 [ C(OP_WRITE) ] = {
629 [ C(RESULT_ACCESS) ] = -1, 629 [ C(RESULT_ACCESS) ] = -1,
630 [ C(RESULT_MISS) ] = -1, 630 [ C(RESULT_MISS) ] = -1,
631 }, 631 },
632 [ C(OP_PREFETCH) ] = { 632 [ C(OP_PREFETCH) ] = {
633 [ C(RESULT_ACCESS) ] = -1, 633 [ C(RESULT_ACCESS) ] = -1,
634 [ C(RESULT_MISS) ] = -1, 634 [ C(RESULT_MISS) ] = -1,
635 }, 635 },
636 }, 636 },
637 }; 637 };
638 638
639 static __initconst const u64 atom_hw_cache_event_ids 639 static __initconst const u64 atom_hw_cache_event_ids
640 [PERF_COUNT_HW_CACHE_MAX] 640 [PERF_COUNT_HW_CACHE_MAX]
641 [PERF_COUNT_HW_CACHE_OP_MAX] 641 [PERF_COUNT_HW_CACHE_OP_MAX]
642 [PERF_COUNT_HW_CACHE_RESULT_MAX] = 642 [PERF_COUNT_HW_CACHE_RESULT_MAX] =
643 { 643 {
644 [ C(L1D) ] = { 644 [ C(L1D) ] = {
645 [ C(OP_READ) ] = { 645 [ C(OP_READ) ] = {
646 [ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE.LD */ 646 [ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE.LD */
647 [ C(RESULT_MISS) ] = 0, 647 [ C(RESULT_MISS) ] = 0,
648 }, 648 },
649 [ C(OP_WRITE) ] = { 649 [ C(OP_WRITE) ] = {
650 [ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE.ST */ 650 [ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE.ST */
651 [ C(RESULT_MISS) ] = 0, 651 [ C(RESULT_MISS) ] = 0,
652 }, 652 },
653 [ C(OP_PREFETCH) ] = { 653 [ C(OP_PREFETCH) ] = {
654 [ C(RESULT_ACCESS) ] = 0x0, 654 [ C(RESULT_ACCESS) ] = 0x0,
655 [ C(RESULT_MISS) ] = 0, 655 [ C(RESULT_MISS) ] = 0,
656 }, 656 },
657 }, 657 },
658 [ C(L1I ) ] = { 658 [ C(L1I ) ] = {
659 [ C(OP_READ) ] = { 659 [ C(OP_READ) ] = {
660 [ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS */ 660 [ C(RESULT_ACCESS) ] = 0x0380, /* L1I.READS */
661 [ C(RESULT_MISS) ] = 0x0280, /* L1I.MISSES */ 661 [ C(RESULT_MISS) ] = 0x0280, /* L1I.MISSES */
662 }, 662 },
663 [ C(OP_WRITE) ] = { 663 [ C(OP_WRITE) ] = {
664 [ C(RESULT_ACCESS) ] = -1, 664 [ C(RESULT_ACCESS) ] = -1,
665 [ C(RESULT_MISS) ] = -1, 665 [ C(RESULT_MISS) ] = -1,
666 }, 666 },
667 [ C(OP_PREFETCH) ] = { 667 [ C(OP_PREFETCH) ] = {
668 [ C(RESULT_ACCESS) ] = 0, 668 [ C(RESULT_ACCESS) ] = 0,
669 [ C(RESULT_MISS) ] = 0, 669 [ C(RESULT_MISS) ] = 0,
670 }, 670 },
671 }, 671 },
672 [ C(LL ) ] = { 672 [ C(LL ) ] = {
673 [ C(OP_READ) ] = { 673 [ C(OP_READ) ] = {
674 [ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI */ 674 [ C(RESULT_ACCESS) ] = 0x4f29, /* L2_LD.MESI */
675 [ C(RESULT_MISS) ] = 0x4129, /* L2_LD.ISTATE */ 675 [ C(RESULT_MISS) ] = 0x4129, /* L2_LD.ISTATE */
676 }, 676 },
677 [ C(OP_WRITE) ] = { 677 [ C(OP_WRITE) ] = {
678 [ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI */ 678 [ C(RESULT_ACCESS) ] = 0x4f2A, /* L2_ST.MESI */
679 [ C(RESULT_MISS) ] = 0x412A, /* L2_ST.ISTATE */ 679 [ C(RESULT_MISS) ] = 0x412A, /* L2_ST.ISTATE */
680 }, 680 },
681 [ C(OP_PREFETCH) ] = { 681 [ C(OP_PREFETCH) ] = {
682 [ C(RESULT_ACCESS) ] = 0, 682 [ C(RESULT_ACCESS) ] = 0,
683 [ C(RESULT_MISS) ] = 0, 683 [ C(RESULT_MISS) ] = 0,
684 }, 684 },
685 }, 685 },
686 [ C(DTLB) ] = { 686 [ C(DTLB) ] = {
687 [ C(OP_READ) ] = { 687 [ C(OP_READ) ] = {
688 [ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE_LD.MESI (alias) */ 688 [ C(RESULT_ACCESS) ] = 0x2140, /* L1D_CACHE_LD.MESI (alias) */
689 [ C(RESULT_MISS) ] = 0x0508, /* DTLB_MISSES.MISS_LD */ 689 [ C(RESULT_MISS) ] = 0x0508, /* DTLB_MISSES.MISS_LD */
690 }, 690 },
691 [ C(OP_WRITE) ] = { 691 [ C(OP_WRITE) ] = {
692 [ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE_ST.MESI (alias) */ 692 [ C(RESULT_ACCESS) ] = 0x2240, /* L1D_CACHE_ST.MESI (alias) */
693 [ C(RESULT_MISS) ] = 0x0608, /* DTLB_MISSES.MISS_ST */ 693 [ C(RESULT_MISS) ] = 0x0608, /* DTLB_MISSES.MISS_ST */
694 }, 694 },
695 [ C(OP_PREFETCH) ] = { 695 [ C(OP_PREFETCH) ] = {
696 [ C(RESULT_ACCESS) ] = 0, 696 [ C(RESULT_ACCESS) ] = 0,
697 [ C(RESULT_MISS) ] = 0, 697 [ C(RESULT_MISS) ] = 0,
698 }, 698 },
699 }, 699 },
700 [ C(ITLB) ] = { 700 [ C(ITLB) ] = {
701 [ C(OP_READ) ] = { 701 [ C(OP_READ) ] = {
702 [ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P */ 702 [ C(RESULT_ACCESS) ] = 0x00c0, /* INST_RETIRED.ANY_P */
703 [ C(RESULT_MISS) ] = 0x0282, /* ITLB.MISSES */ 703 [ C(RESULT_MISS) ] = 0x0282, /* ITLB.MISSES */
704 }, 704 },
705 [ C(OP_WRITE) ] = { 705 [ C(OP_WRITE) ] = {
706 [ C(RESULT_ACCESS) ] = -1, 706 [ C(RESULT_ACCESS) ] = -1,
707 [ C(RESULT_MISS) ] = -1, 707 [ C(RESULT_MISS) ] = -1,
708 }, 708 },
709 [ C(OP_PREFETCH) ] = { 709 [ C(OP_PREFETCH) ] = {
710 [ C(RESULT_ACCESS) ] = -1, 710 [ C(RESULT_ACCESS) ] = -1,
711 [ C(RESULT_MISS) ] = -1, 711 [ C(RESULT_MISS) ] = -1,
712 }, 712 },
713 }, 713 },
714 [ C(BPU ) ] = { 714 [ C(BPU ) ] = {
715 [ C(OP_READ) ] = { 715 [ C(OP_READ) ] = {
716 [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY */ 716 [ C(RESULT_ACCESS) ] = 0x00c4, /* BR_INST_RETIRED.ANY */
717 [ C(RESULT_MISS) ] = 0x00c5, /* BP_INST_RETIRED.MISPRED */ 717 [ C(RESULT_MISS) ] = 0x00c5, /* BP_INST_RETIRED.MISPRED */
718 }, 718 },
719 [ C(OP_WRITE) ] = { 719 [ C(OP_WRITE) ] = {
720 [ C(RESULT_ACCESS) ] = -1, 720 [ C(RESULT_ACCESS) ] = -1,
721 [ C(RESULT_MISS) ] = -1, 721 [ C(RESULT_MISS) ] = -1,
722 }, 722 },
723 [ C(OP_PREFETCH) ] = { 723 [ C(OP_PREFETCH) ] = {
724 [ C(RESULT_ACCESS) ] = -1, 724 [ C(RESULT_ACCESS) ] = -1,
725 [ C(RESULT_MISS) ] = -1, 725 [ C(RESULT_MISS) ] = -1,
726 }, 726 },
727 }, 727 },
728 }; 728 };
729 729
730 static void intel_pmu_disable_all(void) 730 static void intel_pmu_disable_all(void)
731 { 731 {
732 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 732 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
733 733
734 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0); 734 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0);
735 735
736 if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) 736 if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask))
737 intel_pmu_disable_bts(); 737 intel_pmu_disable_bts();
738 738
739 intel_pmu_pebs_disable_all(); 739 intel_pmu_pebs_disable_all();
740 intel_pmu_lbr_disable_all(); 740 intel_pmu_lbr_disable_all();
741 } 741 }
742 742
743 static void intel_pmu_enable_all(int added) 743 static void intel_pmu_enable_all(int added)
744 { 744 {
745 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 745 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
746 746
747 intel_pmu_pebs_enable_all(); 747 intel_pmu_pebs_enable_all();
748 intel_pmu_lbr_enable_all(); 748 intel_pmu_lbr_enable_all();
749 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl); 749 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, x86_pmu.intel_ctrl);
750 750
751 if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) { 751 if (test_bit(X86_PMC_IDX_FIXED_BTS, cpuc->active_mask)) {
752 struct perf_event *event = 752 struct perf_event *event =
753 cpuc->events[X86_PMC_IDX_FIXED_BTS]; 753 cpuc->events[X86_PMC_IDX_FIXED_BTS];
754 754
755 if (WARN_ON_ONCE(!event)) 755 if (WARN_ON_ONCE(!event))
756 return; 756 return;
757 757
758 intel_pmu_enable_bts(event->hw.config); 758 intel_pmu_enable_bts(event->hw.config);
759 } 759 }
760 } 760 }
761 761
762 /* 762 /*
763 * Workaround for: 763 * Workaround for:
764 * Intel Errata AAK100 (model 26) 764 * Intel Errata AAK100 (model 26)
765 * Intel Errata AAP53 (model 30) 765 * Intel Errata AAP53 (model 30)
766 * Intel Errata BD53 (model 44) 766 * Intel Errata BD53 (model 44)
767 * 767 *
768 * The official story: 768 * The official story:
769 * These chips need to be 'reset' when adding counters by programming the 769 * These chips need to be 'reset' when adding counters by programming the
770 * magic three (non-counting) events 0x4300B5, 0x4300D2, and 0x4300B1 either 770 * magic three (non-counting) events 0x4300B5, 0x4300D2, and 0x4300B1 either
771 * in sequence on the same PMC or on different PMCs. 771 * in sequence on the same PMC or on different PMCs.
772 * 772 *
773 * In practise it appears some of these events do in fact count, and 773 * In practise it appears some of these events do in fact count, and
774 * we need to programm all 4 events. 774 * we need to programm all 4 events.
775 */ 775 */
776 static void intel_pmu_nhm_workaround(void) 776 static void intel_pmu_nhm_workaround(void)
777 { 777 {
778 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events); 778 struct cpu_hw_events *cpuc = &__get_cpu_var(cpu_hw_events);
779 static const unsigned long nhm_magic[4] = { 779 static const unsigned long nhm_magic[4] = {
780 0x4300B5, 780 0x4300B5,
781 0x4300D2, 781 0x4300D2,
782 0x4300B1, 782 0x4300B1,
783 0x4300B1 783 0x4300B1
784 }; 784 };
785 struct perf_event *event; 785 struct perf_event *event;
786 int i; 786 int i;
787 787
788 /* 788 /*
789 * The Errata requires below steps: 789 * The Errata requires below steps:
790 * 1) Clear MSR_IA32_PEBS_ENABLE and MSR_CORE_PERF_GLOBAL_CTRL; 790 * 1) Clear MSR_IA32_PEBS_ENABLE and MSR_CORE_PERF_GLOBAL_CTRL;
791 * 2) Configure 4 PERFEVTSELx with the magic events and clear 791 * 2) Configure 4 PERFEVTSELx with the magic events and clear
792 * the corresponding PMCx; 792 * the corresponding PMCx;
793 * 3) set bit0~bit3 of MSR_CORE_PERF_GLOBAL_CTRL; 793 * 3) set bit0~bit3 of MSR_CORE_PERF_GLOBAL_CTRL;
794 * 4) Clear MSR_CORE_PERF_GLOBAL_CTRL; 794 * 4) Clear MSR_CORE_PERF_GLOBAL_CTRL;
795 * 5) Clear 4 pairs of ERFEVTSELx and PMCx; 795 * 5) Clear 4 pairs of ERFEVTSELx and PMCx;
796 */ 796 */
797 797
798 /* 798 /*
799 * The real steps we choose are a little different from above. 799 * The real steps we choose are a little different from above.
800 * A) To reduce MSR operations, we don't run step 1) as they 800 * A) To reduce MSR operations, we don't run step 1) as they
801 * are already cleared before this function is called; 801 * are already cleared before this function is called;
802 * B) Call x86_perf_event_update to save PMCx before configuring 802 * B) Call x86_perf_event_update to save PMCx before configuring
803 * PERFEVTSELx with magic number; 803 * PERFEVTSELx with magic number;
804 * C) With step 5), we do clear only when the PERFEVTSELx is 804 * C) With step 5), we do clear only when the PERFEVTSELx is
805 * not used currently. 805 * not used currently.
806 * D) Call x86_perf_event_set_period to restore PMCx; 806 * D) Call x86_perf_event_set_period to restore PMCx;
807 */ 807 */
808 808
809 /* We always operate 4 pairs of PERF Counters */ 809 /* We always operate 4 pairs of PERF Counters */
810 for (i = 0; i < 4; i++) { 810 for (i = 0; i < 4; i++) {
811 event = cpuc->events[i]; 811 event = cpuc->events[i];
812 if (event) 812 if (event)
813 x86_perf_event_update(event); 813 x86_perf_event_update(event);
814 } 814 }
815 815
816 for (i = 0; i < 4; i++) { 816 for (i = 0; i < 4; i++) {
817 wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + i, nhm_magic[i]); 817 wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + i, nhm_magic[i]);
818 wrmsrl(MSR_ARCH_PERFMON_PERFCTR0 + i, 0x0); 818 wrmsrl(MSR_ARCH_PERFMON_PERFCTR0 + i, 0x0);
819 } 819 }
820 820
821 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0xf); 821 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0xf);
822 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x0); 822 wrmsrl(MSR_CORE_PERF_GLOBAL_CTRL, 0x0);
823 823
824 for (i = 0; i < 4; i++) { 824 for (i = 0; i < 4; i++) {
825 event = cpuc->events[i]; 825 event = cpuc->events[i];
826 826
827 if (event) { 827 if (event) {
828 x86_perf_event_set_period(event); 828 x86_perf_event_set_period(event);
829 __x86_pmu_enable_event(&event->hw, 829 __x86_pmu_enable_event(&event->hw,
830 ARCH_PERFMON_EVENTSEL_ENABLE); 830 ARCH_PERFMON_EVENTSEL_ENABLE);
831 } else 831 } else
832 wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + i, 0x0); 832 wrmsrl(MSR_ARCH_PERFMON_EVENTSEL0 + i, 0x0);
833 } 833 }
834 } 834 }
835 835
836 static void intel_pmu_nhm_enable_all(int added) 836 static void intel_pmu_nhm_enable_all(int added)
837 { 837 {
838 if (added) 838 if (added)
839 intel_pmu_nhm_workaround(); 839 intel_pmu_nhm_workaround();
840 intel_pmu_enable_all(added); 840 intel_pmu_enable_all(added);
841 } 841 }
842 842
843 static inline u64 intel_pmu_get_status(void) 843 static inline u64 intel_pmu_get_status(void)
844 { 844 {
845 u64 status; 845 u64 status;
846 846
847 rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status); 847 rdmsrl(MSR_CORE_PERF_GLOBAL_STATUS, status);
848 848
849 return status; 849 return status;
850 } 850 }
851 851
852 static inline void intel_pmu_ack_status(u64 ack) 852 static inline void intel_pmu_ack_status(u64 ack)
853 { 853 {
854 wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack); 854 wrmsrl(MSR_CORE_PERF_GLOBAL_OVF_CTRL, ack);
855 } 855 }
856 856
857 static void intel_pmu_disable_fixed(struct hw_perf_event *hwc) 857 static void intel_pmu_disable_fixed(struct hw_perf_event *hwc)
858 { 858 {
859 int idx = hwc->idx - X86_PMC_IDX_FIXED; 859 int idx = hwc->idx - X86_PMC_IDX_FIXED;
860 u64 ctrl_val, mask; 860 u64 ctrl_val, mask;
861 861
862 mask = 0xfULL << (idx * 4); 862 mask = 0xfULL << (idx * 4);
863 863
864 rdmsrl(hwc->config_base, ctrl_val); 864 rdmsrl(hwc->config_base, ctrl_val);
865 ctrl_val &= ~mask; 865 ctrl_val &= ~mask;
866 wrmsrl(hwc->config_base, ctrl_val); 866 wrmsrl(hwc->config_base, ctrl_val);
867 } 867 }
868 868
869 static void intel_pmu_disable_event(struct perf_event *event) 869 static void intel_pmu_disable_event(struct perf_event *event)
870 { 870 {
871 struct hw_perf_event *hwc = &event->hw; 871 struct hw_perf_event *hwc = &event->hw;
872 872
873 if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) { 873 if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) {
874 intel_pmu_disable_bts(); 874 intel_pmu_disable_bts();
875 intel_pmu_drain_bts_buffer(); 875 intel_pmu_drain_bts_buffer();
876 return; 876 return;
877 } 877 }
878 878
879 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { 879 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
880 intel_pmu_disable_fixed(hwc); 880 intel_pmu_disable_fixed(hwc);
881 return; 881 return;
882 } 882 }
883 883
884 x86_pmu_disable_event(event); 884 x86_pmu_disable_event(event);
885 885
886 if (unlikely(event->attr.precise_ip)) 886 if (unlikely(event->attr.precise_ip))
887 intel_pmu_pebs_disable(event); 887 intel_pmu_pebs_disable(event);
888 } 888 }
889 889
890 static void intel_pmu_enable_fixed(struct hw_perf_event *hwc) 890 static void intel_pmu_enable_fixed(struct hw_perf_event *hwc)
891 { 891 {
892 int idx = hwc->idx - X86_PMC_IDX_FIXED; 892 int idx = hwc->idx - X86_PMC_IDX_FIXED;
893 u64 ctrl_val, bits, mask; 893 u64 ctrl_val, bits, mask;
894 894
895 /* 895 /*
896 * Enable IRQ generation (0x8), 896 * Enable IRQ generation (0x8),
897 * and enable ring-3 counting (0x2) and ring-0 counting (0x1) 897 * and enable ring-3 counting (0x2) and ring-0 counting (0x1)
898 * if requested: 898 * if requested:
899 */ 899 */
900 bits = 0x8ULL; 900 bits = 0x8ULL;
901 if (hwc->config & ARCH_PERFMON_EVENTSEL_USR) 901 if (hwc->config & ARCH_PERFMON_EVENTSEL_USR)
902 bits |= 0x2; 902 bits |= 0x2;
903 if (hwc->config & ARCH_PERFMON_EVENTSEL_OS) 903 if (hwc->config & ARCH_PERFMON_EVENTSEL_OS)
904 bits |= 0x1; 904 bits |= 0x1;
905 905
906 /* 906 /*
907 * ANY bit is supported in v3 and up 907 * ANY bit is supported in v3 and up
908 */ 908 */
909 if (x86_pmu.version > 2 && hwc->config & ARCH_PERFMON_EVENTSEL_ANY) 909 if (x86_pmu.version > 2 && hwc->config & ARCH_PERFMON_EVENTSEL_ANY)
910 bits |= 0x4; 910 bits |= 0x4;
911 911
912 bits <<= (idx * 4); 912 bits <<= (idx * 4);
913 mask = 0xfULL << (idx * 4); 913 mask = 0xfULL << (idx * 4);
914 914
915 rdmsrl(hwc->config_base, ctrl_val); 915 rdmsrl(hwc->config_base, ctrl_val);
916 ctrl_val &= ~mask; 916 ctrl_val &= ~mask;
917 ctrl_val |= bits; 917 ctrl_val |= bits;
918 wrmsrl(hwc->config_base, ctrl_val); 918 wrmsrl(hwc->config_base, ctrl_val);
919 } 919 }
920 920
921 static void intel_pmu_enable_event(struct perf_event *event) 921 static void intel_pmu_enable_event(struct perf_event *event)
922 { 922 {
923 struct hw_perf_event *hwc = &event->hw; 923 struct hw_perf_event *hwc = &event->hw;
924 924
925 if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) { 925 if (unlikely(hwc->idx == X86_PMC_IDX_FIXED_BTS)) {
926 if (!__this_cpu_read(cpu_hw_events.enabled)) 926 if (!__this_cpu_read(cpu_hw_events.enabled))
927 return; 927 return;
928 928
929 intel_pmu_enable_bts(hwc->config); 929 intel_pmu_enable_bts(hwc->config);
930 return; 930 return;
931 } 931 }
932 932
933 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) { 933 if (unlikely(hwc->config_base == MSR_ARCH_PERFMON_FIXED_CTR_CTRL)) {
934 intel_pmu_enable_fixed(hwc); 934 intel_pmu_enable_fixed(hwc);
935 return; 935 return;
936 } 936 }
937 937
938 if (unlikely(event->attr.precise_ip)) 938 if (unlikely(event->attr.precise_ip))
939 intel_pmu_pebs_enable(event); 939 intel_pmu_pebs_enable(event);
940 940
941 __x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE); 941 __x86_pmu_enable_event(hwc, ARCH_PERFMON_EVENTSEL_ENABLE);
942 } 942 }
943 943
944 /* 944 /*
945 * Save and restart an expired event. Called by NMI contexts, 945 * Save and restart an expired event. Called by NMI contexts,
946 * so it has to be careful about preempting normal event ops: 946 * so it has to be careful about preempting normal event ops:
947 */ 947 */
948 static int intel_pmu_save_and_restart(struct perf_event *event) 948 static int intel_pmu_save_and_restart(struct perf_event *event)
949 { 949 {
950 x86_perf_event_update(event); 950 x86_perf_event_update(event);
951 return x86_perf_event_set_period(event); 951 return x86_perf_event_set_period(event);
952 } 952 }
953 953
954 static void intel_pmu_reset(void) 954 static void intel_pmu_reset(void)
955 { 955 {
956 struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds); 956 struct debug_store *ds = __this_cpu_read(cpu_hw_events.ds);
957 unsigned long flags; 957 unsigned long flags;
958 int idx; 958 int idx;
959 959
960 if (!x86_pmu.num_counters) 960 if (!x86_pmu.num_counters)
961 return; 961 return;
962 962
963 local_irq_save(flags); 963 local_irq_save(flags);
964 964
965 printk("clearing PMU state on CPU#%d\n", smp_processor_id()); 965 printk("clearing PMU state on CPU#%d\n", smp_processor_id());
966 966
967 for (idx = 0; idx < x86_pmu.num_counters; idx++) { 967 for (idx = 0; idx < x86_pmu.num_counters; idx++) {
968 checking_wrmsrl(x86_pmu_config_addr(idx), 0ull); 968 checking_wrmsrl(x86_pmu_config_addr(idx), 0ull);
969 checking_wrmsrl(x86_pmu_event_addr(idx), 0ull); 969 checking_wrmsrl(x86_pmu_event_addr(idx), 0ull);
970 } 970 }
971 for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++) 971 for (idx = 0; idx < x86_pmu.num_counters_fixed; idx++)
972 checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull); 972 checking_wrmsrl(MSR_ARCH_PERFMON_FIXED_CTR0 + idx, 0ull);
973 973
974 if (ds) 974 if (ds)
975 ds->bts_index = ds->bts_buffer_base; 975 ds->bts_index = ds->bts_buffer_base;
976 976
977 local_irq_restore(flags); 977 local_irq_restore(flags);
978 } 978 }
979 979
980 /* 980 /*
981 * This handler is triggered by the local APIC, so the APIC IRQ handling 981 * This handler is triggered by the local APIC, so the APIC IRQ handling
982 * rules apply: 982 * rules apply:
983 */ 983 */
984 static int intel_pmu_handle_irq(struct pt_regs *regs) 984 static int intel_pmu_handle_irq(struct pt_regs *regs)
985 { 985 {
986 struct perf_sample_data data; 986 struct perf_sample_data data;
987 struct cpu_hw_events *cpuc; 987 struct cpu_hw_events *cpuc;
988 int bit, loops; 988 int bit, loops;
989 u64 status; 989 u64 status;
990 int handled; 990 int handled;
991 991
992 perf_sample_data_init(&data, 0); 992 perf_sample_data_init(&data, 0);
993 993
994 cpuc = &__get_cpu_var(cpu_hw_events); 994 cpuc = &__get_cpu_var(cpu_hw_events);
995 995
996 /* 996 /*
997 * Some chipsets need to unmask the LVTPC in a particular spot 997 * Some chipsets need to unmask the LVTPC in a particular spot
998 * inside the nmi handler. As a result, the unmasking was pushed 998 * inside the nmi handler. As a result, the unmasking was pushed
999 * into all the nmi handlers. 999 * into all the nmi handlers.
1000 * 1000 *
1001 * This handler doesn't seem to have any issues with the unmasking 1001 * This handler doesn't seem to have any issues with the unmasking
1002 * so it was left at the top. 1002 * so it was left at the top.
1003 */ 1003 */
1004 apic_write(APIC_LVTPC, APIC_DM_NMI); 1004 apic_write(APIC_LVTPC, APIC_DM_NMI);
1005 1005
1006 intel_pmu_disable_all(); 1006 intel_pmu_disable_all();
1007 handled = intel_pmu_drain_bts_buffer(); 1007 handled = intel_pmu_drain_bts_buffer();
1008 status = intel_pmu_get_status(); 1008 status = intel_pmu_get_status();
1009 if (!status) { 1009 if (!status) {
1010 intel_pmu_enable_all(0); 1010 intel_pmu_enable_all(0);
1011 return handled; 1011 return handled;
1012 } 1012 }
1013 1013
1014 loops = 0; 1014 loops = 0;
1015 again: 1015 again:
1016 intel_pmu_ack_status(status); 1016 intel_pmu_ack_status(status);
1017 if (++loops > 100) { 1017 if (++loops > 100) {
1018 WARN_ONCE(1, "perfevents: irq loop stuck!\n"); 1018 WARN_ONCE(1, "perfevents: irq loop stuck!\n");
1019 perf_event_print_debug(); 1019 perf_event_print_debug();
1020 intel_pmu_reset(); 1020 intel_pmu_reset();
1021 goto done; 1021 goto done;
1022 } 1022 }
1023 1023
1024 inc_irq_stat(apic_perf_irqs); 1024 inc_irq_stat(apic_perf_irqs);
1025 1025
1026 intel_pmu_lbr_read(); 1026 intel_pmu_lbr_read();
1027 1027
1028 /* 1028 /*
1029 * PEBS overflow sets bit 62 in the global status register 1029 * PEBS overflow sets bit 62 in the global status register
1030 */ 1030 */
1031 if (__test_and_clear_bit(62, (unsigned long *)&status)) { 1031 if (__test_and_clear_bit(62, (unsigned long *)&status)) {
1032 handled++; 1032 handled++;
1033 x86_pmu.drain_pebs(regs); 1033 x86_pmu.drain_pebs(regs);
1034 } 1034 }
1035 1035
1036 for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) { 1036 for_each_set_bit(bit, (unsigned long *)&status, X86_PMC_IDX_MAX) {
1037 struct perf_event *event = cpuc->events[bit]; 1037 struct perf_event *event = cpuc->events[bit];
1038 1038
1039 handled++; 1039 handled++;
1040 1040
1041 if (!test_bit(bit, cpuc->active_mask)) 1041 if (!test_bit(bit, cpuc->active_mask))
1042 continue; 1042 continue;
1043 1043
1044 if (!intel_pmu_save_and_restart(event)) 1044 if (!intel_pmu_save_and_restart(event))
1045 continue; 1045 continue;
1046 1046
1047 data.period = event->hw.last_period; 1047 data.period = event->hw.last_period;
1048 1048
1049 if (perf_event_overflow(event, &data, regs)) 1049 if (perf_event_overflow(event, &data, regs))
1050 x86_pmu_stop(event, 0); 1050 x86_pmu_stop(event, 0);
1051 } 1051 }
1052 1052
1053 /* 1053 /*
1054 * Repeat if there is more work to be done: 1054 * Repeat if there is more work to be done:
1055 */ 1055 */
1056 status = intel_pmu_get_status(); 1056 status = intel_pmu_get_status();
1057 if (status) 1057 if (status)
1058 goto again; 1058 goto again;
1059 1059
1060 done: 1060 done:
1061 intel_pmu_enable_all(0); 1061 intel_pmu_enable_all(0);
1062 return handled; 1062 return handled;
1063 } 1063 }
1064 1064
1065 static struct event_constraint * 1065 static struct event_constraint *
1066 intel_bts_constraints(struct perf_event *event) 1066 intel_bts_constraints(struct perf_event *event)
1067 { 1067 {
1068 struct hw_perf_event *hwc = &event->hw; 1068 struct hw_perf_event *hwc = &event->hw;
1069 unsigned int hw_event, bts_event; 1069 unsigned int hw_event, bts_event;
1070 1070
1071 if (event->attr.freq) 1071 if (event->attr.freq)
1072 return NULL; 1072 return NULL;
1073 1073
1074 hw_event = hwc->config & INTEL_ARCH_EVENT_MASK; 1074 hw_event = hwc->config & INTEL_ARCH_EVENT_MASK;
1075 bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS); 1075 bts_event = x86_pmu.event_map(PERF_COUNT_HW_BRANCH_INSTRUCTIONS);
1076 1076
1077 if (unlikely(hw_event == bts_event && hwc->sample_period == 1)) 1077 if (unlikely(hw_event == bts_event && hwc->sample_period == 1))
1078 return &bts_constraint; 1078 return &bts_constraint;
1079 1079
1080 return NULL; 1080 return NULL;
1081 } 1081 }
1082 1082
1083 static bool intel_try_alt_er(struct perf_event *event, int orig_idx) 1083 static bool intel_try_alt_er(struct perf_event *event, int orig_idx)
1084 { 1084 {
1085 if (!(x86_pmu.er_flags & ERF_HAS_RSP_1)) 1085 if (!(x86_pmu.er_flags & ERF_HAS_RSP_1))
1086 return false; 1086 return false;
1087 1087
1088 if (event->hw.extra_reg.idx == EXTRA_REG_RSP_0) { 1088 if (event->hw.extra_reg.idx == EXTRA_REG_RSP_0) {
1089 event->hw.config &= ~INTEL_ARCH_EVENT_MASK; 1089 event->hw.config &= ~INTEL_ARCH_EVENT_MASK;
1090 event->hw.config |= 0x01bb; 1090 event->hw.config |= 0x01bb;
1091 event->hw.extra_reg.idx = EXTRA_REG_RSP_1; 1091 event->hw.extra_reg.idx = EXTRA_REG_RSP_1;
1092 event->hw.extra_reg.reg = MSR_OFFCORE_RSP_1; 1092 event->hw.extra_reg.reg = MSR_OFFCORE_RSP_1;
1093 } else if (event->hw.extra_reg.idx == EXTRA_REG_RSP_1) { 1093 } else if (event->hw.extra_reg.idx == EXTRA_REG_RSP_1) {
1094 event->hw.config &= ~INTEL_ARCH_EVENT_MASK; 1094 event->hw.config &= ~INTEL_ARCH_EVENT_MASK;
1095 event->hw.config |= 0x01b7; 1095 event->hw.config |= 0x01b7;
1096 event->hw.extra_reg.idx = EXTRA_REG_RSP_0; 1096 event->hw.extra_reg.idx = EXTRA_REG_RSP_0;
1097 event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0; 1097 event->hw.extra_reg.reg = MSR_OFFCORE_RSP_0;
1098 } 1098 }
1099 1099
1100 if (event->hw.extra_reg.idx == orig_idx) 1100 if (event->hw.extra_reg.idx == orig_idx)
1101 return false; 1101 return false;
1102 1102
1103 return true; 1103 return true;
1104 } 1104 }
1105 1105
1106 /* 1106 /*
1107 * manage allocation of shared extra msr for certain events 1107 * manage allocation of shared extra msr for certain events
1108 * 1108 *
1109 * sharing can be: 1109 * sharing can be:
1110 * per-cpu: to be shared between the various events on a single PMU 1110 * per-cpu: to be shared between the various events on a single PMU
1111 * per-core: per-cpu + shared by HT threads 1111 * per-core: per-cpu + shared by HT threads
1112 */ 1112 */
1113 static struct event_constraint * 1113 static struct event_constraint *
1114 __intel_shared_reg_get_constraints(struct cpu_hw_events *cpuc, 1114 __intel_shared_reg_get_constraints(struct cpu_hw_events *cpuc,
1115 struct perf_event *event) 1115 struct perf_event *event)
1116 { 1116 {
1117 struct event_constraint *c = &emptyconstraint; 1117 struct event_constraint *c = &emptyconstraint;
1118 struct hw_perf_event_extra *reg = &event->hw.extra_reg; 1118 struct hw_perf_event_extra *reg = &event->hw.extra_reg;
1119 struct er_account *era; 1119 struct er_account *era;
1120 unsigned long flags; 1120 unsigned long flags;
1121 int orig_idx = reg->idx; 1121 int orig_idx = reg->idx;
1122 1122
1123 /* already allocated shared msr */ 1123 /* already allocated shared msr */
1124 if (reg->alloc) 1124 if (reg->alloc)
1125 return &unconstrained; 1125 return &unconstrained;
1126 1126
1127 again: 1127 again:
1128 era = &cpuc->shared_regs->regs[reg->idx]; 1128 era = &cpuc->shared_regs->regs[reg->idx];
1129 /* 1129 /*
1130 * we use spin_lock_irqsave() to avoid lockdep issues when 1130 * we use spin_lock_irqsave() to avoid lockdep issues when
1131 * passing a fake cpuc 1131 * passing a fake cpuc
1132 */ 1132 */
1133 raw_spin_lock_irqsave(&era->lock, flags); 1133 raw_spin_lock_irqsave(&era->lock, flags);
1134 1134
1135 if (!atomic_read(&era->ref) || era->config == reg->config) { 1135 if (!atomic_read(&era->ref) || era->config == reg->config) {
1136 1136
1137 /* lock in msr value */ 1137 /* lock in msr value */
1138 era->config = reg->config; 1138 era->config = reg->config;
1139 era->reg = reg->reg; 1139 era->reg = reg->reg;
1140 1140
1141 /* one more user */ 1141 /* one more user */
1142 atomic_inc(&era->ref); 1142 atomic_inc(&era->ref);
1143 1143
1144 /* no need to reallocate during incremental event scheduling */ 1144 /* no need to reallocate during incremental event scheduling */
1145 reg->alloc = 1; 1145 reg->alloc = 1;
1146 1146
1147 /* 1147 /*
1148 * All events using extra_reg are unconstrained. 1148 * All events using extra_reg are unconstrained.
1149 * Avoids calling x86_get_event_constraints() 1149 * Avoids calling x86_get_event_constraints()
1150 * 1150 *
1151 * Must revisit if extra_reg controlling events 1151 * Must revisit if extra_reg controlling events
1152 * ever have constraints. Worst case we go through 1152 * ever have constraints. Worst case we go through
1153 * the regular event constraint table. 1153 * the regular event constraint table.
1154 */ 1154 */
1155 c = &unconstrained; 1155 c = &unconstrained;
1156 } else if (intel_try_alt_er(event, orig_idx)) { 1156 } else if (intel_try_alt_er(event, orig_idx)) {
1157 raw_spin_unlock(&era->lock); 1157 raw_spin_unlock(&era->lock);
1158 goto again; 1158 goto again;
1159 } 1159 }
1160 raw_spin_unlock_irqrestore(&era->lock, flags); 1160 raw_spin_unlock_irqrestore(&era->lock, flags);
1161 1161
1162 return c; 1162 return c;
1163 } 1163 }
1164 1164
1165 static void 1165 static void
1166 __intel_shared_reg_put_constraints(struct cpu_hw_events *cpuc, 1166 __intel_shared_reg_put_constraints(struct cpu_hw_events *cpuc,
1167 struct hw_perf_event_extra *reg) 1167 struct hw_perf_event_extra *reg)
1168 { 1168 {
1169 struct er_account *era; 1169 struct er_account *era;
1170 1170
1171 /* 1171 /*
1172 * only put constraint if extra reg was actually 1172 * only put constraint if extra reg was actually
1173 * allocated. Also takes care of event which do 1173 * allocated. Also takes care of event which do
1174 * not use an extra shared reg 1174 * not use an extra shared reg
1175 */ 1175 */
1176 if (!reg->alloc) 1176 if (!reg->alloc)
1177 return; 1177 return;
1178 1178
1179 era = &cpuc->shared_regs->regs[reg->idx]; 1179 era = &cpuc->shared_regs->regs[reg->idx];
1180 1180
1181 /* one fewer user */ 1181 /* one fewer user */
1182 atomic_dec(&era->ref); 1182 atomic_dec(&era->ref);
1183 1183
1184 /* allocate again next time */ 1184 /* allocate again next time */
1185 reg->alloc = 0; 1185 reg->alloc = 0;
1186 } 1186 }
1187 1187
1188 static struct event_constraint * 1188 static struct event_constraint *
1189 intel_shared_regs_constraints(struct cpu_hw_events *cpuc, 1189 intel_shared_regs_constraints(struct cpu_hw_events *cpuc,
1190 struct perf_event *event) 1190 struct perf_event *event)
1191 { 1191 {
1192 struct event_constraint *c = NULL; 1192 struct event_constraint *c = NULL;
1193 1193
1194 if (event->hw.extra_reg.idx != EXTRA_REG_NONE) 1194 if (event->hw.extra_reg.idx != EXTRA_REG_NONE)
1195 c = __intel_shared_reg_get_constraints(cpuc, event); 1195 c = __intel_shared_reg_get_constraints(cpuc, event);
1196 1196
1197 return c; 1197 return c;
1198 } 1198 }
1199 1199
1200 static struct event_constraint * 1200 static struct event_constraint *
1201 intel_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event) 1201 intel_get_event_constraints(struct cpu_hw_events *cpuc, struct perf_event *event)
1202 { 1202 {
1203 struct event_constraint *c; 1203 struct event_constraint *c;
1204 1204
1205 c = intel_bts_constraints(event); 1205 c = intel_bts_constraints(event);
1206 if (c) 1206 if (c)
1207 return c; 1207 return c;
1208 1208
1209 c = intel_pebs_constraints(event); 1209 c = intel_pebs_constraints(event);
1210 if (c) 1210 if (c)
1211 return c; 1211 return c;
1212 1212
1213 c = intel_shared_regs_constraints(cpuc, event); 1213 c = intel_shared_regs_constraints(cpuc, event);
1214 if (c) 1214 if (c)
1215 return c; 1215 return c;
1216 1216
1217 return x86_get_event_constraints(cpuc, event); 1217 return x86_get_event_constraints(cpuc, event);
1218 } 1218 }
1219 1219
1220 static void 1220 static void
1221 intel_put_shared_regs_event_constraints(struct cpu_hw_events *cpuc, 1221 intel_put_shared_regs_event_constraints(struct cpu_hw_events *cpuc,
1222 struct perf_event *event) 1222 struct perf_event *event)
1223 { 1223 {
1224 struct hw_perf_event_extra *reg; 1224 struct hw_perf_event_extra *reg;
1225 1225
1226 reg = &event->hw.extra_reg; 1226 reg = &event->hw.extra_reg;
1227 if (reg->idx != EXTRA_REG_NONE) 1227 if (reg->idx != EXTRA_REG_NONE)
1228 __intel_shared_reg_put_constraints(cpuc, reg); 1228 __intel_shared_reg_put_constraints(cpuc, reg);
1229 } 1229 }
1230 1230
1231 static void intel_put_event_constraints(struct cpu_hw_events *cpuc, 1231 static void intel_put_event_constraints(struct cpu_hw_events *cpuc,
1232 struct perf_event *event) 1232 struct perf_event *event)
1233 { 1233 {
1234 intel_put_shared_regs_event_constraints(cpuc, event); 1234 intel_put_shared_regs_event_constraints(cpuc, event);
1235 } 1235 }
1236 1236
1237 static int intel_pmu_hw_config(struct perf_event *event) 1237 static int intel_pmu_hw_config(struct perf_event *event)
1238 { 1238 {
1239 int ret = x86_pmu_hw_config(event); 1239 int ret = x86_pmu_hw_config(event);
1240 1240
1241 if (ret) 1241 if (ret)
1242 return ret; 1242 return ret;
1243 1243
1244 if (event->attr.precise_ip && 1244 if (event->attr.precise_ip &&
1245 (event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) { 1245 (event->hw.config & X86_RAW_EVENT_MASK) == 0x003c) {
1246 /* 1246 /*
1247 * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P 1247 * Use an alternative encoding for CPU_CLK_UNHALTED.THREAD_P
1248 * (0x003c) so that we can use it with PEBS. 1248 * (0x003c) so that we can use it with PEBS.
1249 * 1249 *
1250 * The regular CPU_CLK_UNHALTED.THREAD_P event (0x003c) isn't 1250 * The regular CPU_CLK_UNHALTED.THREAD_P event (0x003c) isn't
1251 * PEBS capable. However we can use INST_RETIRED.ANY_P 1251 * PEBS capable. However we can use INST_RETIRED.ANY_P
1252 * (0x00c0), which is a PEBS capable event, to get the same 1252 * (0x00c0), which is a PEBS capable event, to get the same
1253 * count. 1253 * count.
1254 * 1254 *
1255 * INST_RETIRED.ANY_P counts the number of cycles that retires 1255 * INST_RETIRED.ANY_P counts the number of cycles that retires
1256 * CNTMASK instructions. By setting CNTMASK to a value (16) 1256 * CNTMASK instructions. By setting CNTMASK to a value (16)
1257 * larger than the maximum number of instructions that can be 1257 * larger than the maximum number of instructions that can be
1258 * retired per cycle (4) and then inverting the condition, we 1258 * retired per cycle (4) and then inverting the condition, we
1259 * count all cycles that retire 16 or less instructions, which 1259 * count all cycles that retire 16 or less instructions, which
1260 * is every cycle. 1260 * is every cycle.
1261 * 1261 *
1262 * Thereby we gain a PEBS capable cycle counter. 1262 * Thereby we gain a PEBS capable cycle counter.
1263 */ 1263 */
1264 u64 alt_config = 0x108000c0; /* INST_RETIRED.TOTAL_CYCLES */ 1264 u64 alt_config = 0x108000c0; /* INST_RETIRED.TOTAL_CYCLES */
1265 1265
1266 alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK); 1266 alt_config |= (event->hw.config & ~X86_RAW_EVENT_MASK);
1267 event->hw.config = alt_config; 1267 event->hw.config = alt_config;
1268 } 1268 }
1269 1269
1270 if (event->attr.type != PERF_TYPE_RAW) 1270 if (event->attr.type != PERF_TYPE_RAW)
1271 return 0; 1271 return 0;
1272 1272
1273 if (!(event->attr.config & ARCH_PERFMON_EVENTSEL_ANY)) 1273 if (!(event->attr.config & ARCH_PERFMON_EVENTSEL_ANY))
1274 return 0; 1274 return 0;
1275 1275
1276 if (x86_pmu.version < 3) 1276 if (x86_pmu.version < 3)
1277 return -EINVAL; 1277 return -EINVAL;
1278 1278
1279 if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN)) 1279 if (perf_paranoid_cpu() && !capable(CAP_SYS_ADMIN))
1280 return -EACCES; 1280 return -EACCES;
1281 1281
1282 event->hw.config |= ARCH_PERFMON_EVENTSEL_ANY; 1282 event->hw.config |= ARCH_PERFMON_EVENTSEL_ANY;
1283 1283
1284 return 0; 1284 return 0;
1285 } 1285 }
1286 1286
1287 static __initconst const struct x86_pmu core_pmu = { 1287 static __initconst const struct x86_pmu core_pmu = {
1288 .name = "core", 1288 .name = "core",
1289 .handle_irq = x86_pmu_handle_irq, 1289 .handle_irq = x86_pmu_handle_irq,
1290 .disable_all = x86_pmu_disable_all, 1290 .disable_all = x86_pmu_disable_all,
1291 .enable_all = x86_pmu_enable_all, 1291 .enable_all = x86_pmu_enable_all,
1292 .enable = x86_pmu_enable_event, 1292 .enable = x86_pmu_enable_event,
1293 .disable = x86_pmu_disable_event, 1293 .disable = x86_pmu_disable_event,
1294 .hw_config = x86_pmu_hw_config, 1294 .hw_config = x86_pmu_hw_config,
1295 .schedule_events = x86_schedule_events, 1295 .schedule_events = x86_schedule_events,
1296 .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, 1296 .eventsel = MSR_ARCH_PERFMON_EVENTSEL0,
1297 .perfctr = MSR_ARCH_PERFMON_PERFCTR0, 1297 .perfctr = MSR_ARCH_PERFMON_PERFCTR0,
1298 .event_map = intel_pmu_event_map, 1298 .event_map = intel_pmu_event_map,
1299 .max_events = ARRAY_SIZE(intel_perfmon_event_map), 1299 .max_events = ARRAY_SIZE(intel_perfmon_event_map),
1300 .apic = 1, 1300 .apic = 1,
1301 /* 1301 /*
1302 * Intel PMCs cannot be accessed sanely above 32 bit width, 1302 * Intel PMCs cannot be accessed sanely above 32 bit width,
1303 * so we install an artificial 1<<31 period regardless of 1303 * so we install an artificial 1<<31 period regardless of
1304 * the generic event period: 1304 * the generic event period:
1305 */ 1305 */
1306 .max_period = (1ULL << 31) - 1, 1306 .max_period = (1ULL << 31) - 1,
1307 .get_event_constraints = intel_get_event_constraints, 1307 .get_event_constraints = intel_get_event_constraints,
1308 .put_event_constraints = intel_put_event_constraints, 1308 .put_event_constraints = intel_put_event_constraints,
1309 .event_constraints = intel_core_event_constraints, 1309 .event_constraints = intel_core_event_constraints,
1310 }; 1310 };
1311 1311
1312 static struct intel_shared_regs *allocate_shared_regs(int cpu) 1312 static struct intel_shared_regs *allocate_shared_regs(int cpu)
1313 { 1313 {
1314 struct intel_shared_regs *regs; 1314 struct intel_shared_regs *regs;
1315 int i; 1315 int i;
1316 1316
1317 regs = kzalloc_node(sizeof(struct intel_shared_regs), 1317 regs = kzalloc_node(sizeof(struct intel_shared_regs),
1318 GFP_KERNEL, cpu_to_node(cpu)); 1318 GFP_KERNEL, cpu_to_node(cpu));
1319 if (regs) { 1319 if (regs) {
1320 /* 1320 /*
1321 * initialize the locks to keep lockdep happy 1321 * initialize the locks to keep lockdep happy
1322 */ 1322 */
1323 for (i = 0; i < EXTRA_REG_MAX; i++) 1323 for (i = 0; i < EXTRA_REG_MAX; i++)
1324 raw_spin_lock_init(&regs->regs[i].lock); 1324 raw_spin_lock_init(&regs->regs[i].lock);
1325 1325
1326 regs->core_id = -1; 1326 regs->core_id = -1;
1327 } 1327 }
1328 return regs; 1328 return regs;
1329 } 1329 }
1330 1330
1331 static int intel_pmu_cpu_prepare(int cpu) 1331 static int intel_pmu_cpu_prepare(int cpu)
1332 { 1332 {
1333 struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu); 1333 struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
1334 1334
1335 if (!x86_pmu.extra_regs) 1335 if (!x86_pmu.extra_regs)
1336 return NOTIFY_OK; 1336 return NOTIFY_OK;
1337 1337
1338 cpuc->shared_regs = allocate_shared_regs(cpu); 1338 cpuc->shared_regs = allocate_shared_regs(cpu);
1339 if (!cpuc->shared_regs) 1339 if (!cpuc->shared_regs)
1340 return NOTIFY_BAD; 1340 return NOTIFY_BAD;
1341 1341
1342 return NOTIFY_OK; 1342 return NOTIFY_OK;
1343 } 1343 }
1344 1344
1345 static void intel_pmu_cpu_starting(int cpu) 1345 static void intel_pmu_cpu_starting(int cpu)
1346 { 1346 {
1347 struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu); 1347 struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
1348 int core_id = topology_core_id(cpu); 1348 int core_id = topology_core_id(cpu);
1349 int i; 1349 int i;
1350 1350
1351 init_debug_store_on_cpu(cpu); 1351 init_debug_store_on_cpu(cpu);
1352 /* 1352 /*
1353 * Deal with CPUs that don't clear their LBRs on power-up. 1353 * Deal with CPUs that don't clear their LBRs on power-up.
1354 */ 1354 */
1355 intel_pmu_lbr_reset(); 1355 intel_pmu_lbr_reset();
1356 1356
1357 if (!cpuc->shared_regs || (x86_pmu.er_flags & ERF_NO_HT_SHARING)) 1357 if (!cpuc->shared_regs || (x86_pmu.er_flags & ERF_NO_HT_SHARING))
1358 return; 1358 return;
1359 1359
1360 for_each_cpu(i, topology_thread_cpumask(cpu)) { 1360 for_each_cpu(i, topology_thread_cpumask(cpu)) {
1361 struct intel_shared_regs *pc; 1361 struct intel_shared_regs *pc;
1362 1362
1363 pc = per_cpu(cpu_hw_events, i).shared_regs; 1363 pc = per_cpu(cpu_hw_events, i).shared_regs;
1364 if (pc && pc->core_id == core_id) { 1364 if (pc && pc->core_id == core_id) {
1365 kfree(cpuc->shared_regs); 1365 kfree(cpuc->shared_regs);
1366 cpuc->shared_regs = pc; 1366 cpuc->shared_regs = pc;
1367 break; 1367 break;
1368 } 1368 }
1369 } 1369 }
1370 1370
1371 cpuc->shared_regs->core_id = core_id; 1371 cpuc->shared_regs->core_id = core_id;
1372 cpuc->shared_regs->refcnt++; 1372 cpuc->shared_regs->refcnt++;
1373 } 1373 }
1374 1374
1375 static void intel_pmu_cpu_dying(int cpu) 1375 static void intel_pmu_cpu_dying(int cpu)
1376 { 1376 {
1377 struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu); 1377 struct cpu_hw_events *cpuc = &per_cpu(cpu_hw_events, cpu);
1378 struct intel_shared_regs *pc; 1378 struct intel_shared_regs *pc;
1379 1379
1380 pc = cpuc->shared_regs; 1380 pc = cpuc->shared_regs;
1381 if (pc) { 1381 if (pc) {
1382 if (pc->core_id == -1 || --pc->refcnt == 0) 1382 if (pc->core_id == -1 || --pc->refcnt == 0)
1383 kfree(pc); 1383 kfree(pc);
1384 cpuc->shared_regs = NULL; 1384 cpuc->shared_regs = NULL;
1385 } 1385 }
1386 1386
1387 fini_debug_store_on_cpu(cpu); 1387 fini_debug_store_on_cpu(cpu);
1388 } 1388 }
1389 1389
1390 static __initconst const struct x86_pmu intel_pmu = { 1390 static __initconst const struct x86_pmu intel_pmu = {
1391 .name = "Intel", 1391 .name = "Intel",
1392 .handle_irq = intel_pmu_handle_irq, 1392 .handle_irq = intel_pmu_handle_irq,
1393 .disable_all = intel_pmu_disable_all, 1393 .disable_all = intel_pmu_disable_all,
1394 .enable_all = intel_pmu_enable_all, 1394 .enable_all = intel_pmu_enable_all,
1395 .enable = intel_pmu_enable_event, 1395 .enable = intel_pmu_enable_event,
1396 .disable = intel_pmu_disable_event, 1396 .disable = intel_pmu_disable_event,
1397 .hw_config = intel_pmu_hw_config, 1397 .hw_config = intel_pmu_hw_config,
1398 .schedule_events = x86_schedule_events, 1398 .schedule_events = x86_schedule_events,
1399 .eventsel = MSR_ARCH_PERFMON_EVENTSEL0, 1399 .eventsel = MSR_ARCH_PERFMON_EVENTSEL0,
1400 .perfctr = MSR_ARCH_PERFMON_PERFCTR0, 1400 .perfctr = MSR_ARCH_PERFMON_PERFCTR0,
1401 .event_map = intel_pmu_event_map, 1401 .event_map = intel_pmu_event_map,
1402 .max_events = ARRAY_SIZE(intel_perfmon_event_map), 1402 .max_events = ARRAY_SIZE(intel_perfmon_event_map),
1403 .apic = 1, 1403 .apic = 1,
1404 /* 1404 /*
1405 * Intel PMCs cannot be accessed sanely above 32 bit width, 1405 * Intel PMCs cannot be accessed sanely above 32 bit width,
1406 * so we install an artificial 1<<31 period regardless of 1406 * so we install an artificial 1<<31 period regardless of
1407 * the generic event period: 1407 * the generic event period:
1408 */ 1408 */
1409 .max_period = (1ULL << 31) - 1, 1409 .max_period = (1ULL << 31) - 1,
1410 .get_event_constraints = intel_get_event_constraints, 1410 .get_event_constraints = intel_get_event_constraints,
1411 .put_event_constraints = intel_put_event_constraints, 1411 .put_event_constraints = intel_put_event_constraints,
1412 1412
1413 .cpu_prepare = intel_pmu_cpu_prepare, 1413 .cpu_prepare = intel_pmu_cpu_prepare,
1414 .cpu_starting = intel_pmu_cpu_starting, 1414 .cpu_starting = intel_pmu_cpu_starting,
1415 .cpu_dying = intel_pmu_cpu_dying, 1415 .cpu_dying = intel_pmu_cpu_dying,
1416 }; 1416 };
1417 1417
1418 static void intel_clovertown_quirks(void) 1418 static void intel_clovertown_quirks(void)
1419 { 1419 {
1420 /* 1420 /*
1421 * PEBS is unreliable due to: 1421 * PEBS is unreliable due to:
1422 * 1422 *
1423 * AJ67 - PEBS may experience CPL leaks 1423 * AJ67 - PEBS may experience CPL leaks
1424 * AJ68 - PEBS PMI may be delayed by one event 1424 * AJ68 - PEBS PMI may be delayed by one event
1425 * AJ69 - GLOBAL_STATUS[62] will only be set when DEBUGCTL[12] 1425 * AJ69 - GLOBAL_STATUS[62] will only be set when DEBUGCTL[12]
1426 * AJ106 - FREEZE_LBRS_ON_PMI doesn't work in combination with PEBS 1426 * AJ106 - FREEZE_LBRS_ON_PMI doesn't work in combination with PEBS
1427 * 1427 *
1428 * AJ67 could be worked around by restricting the OS/USR flags. 1428 * AJ67 could be worked around by restricting the OS/USR flags.
1429 * AJ69 could be worked around by setting PMU_FREEZE_ON_PMI. 1429 * AJ69 could be worked around by setting PMU_FREEZE_ON_PMI.
1430 * 1430 *
1431 * AJ106 could possibly be worked around by not allowing LBR 1431 * AJ106 could possibly be worked around by not allowing LBR
1432 * usage from PEBS, including the fixup. 1432 * usage from PEBS, including the fixup.
1433 * AJ68 could possibly be worked around by always programming 1433 * AJ68 could possibly be worked around by always programming
1434 * a pebs_event_reset[0] value and coping with the lost events. 1434 * a pebs_event_reset[0] value and coping with the lost events.
1435 * 1435 *
1436 * But taken together it might just make sense to not enable PEBS on 1436 * But taken together it might just make sense to not enable PEBS on
1437 * these chips. 1437 * these chips.
1438 */ 1438 */
1439 printk(KERN_WARNING "PEBS disabled due to CPU errata.\n"); 1439 printk(KERN_WARNING "PEBS disabled due to CPU errata.\n");
1440 x86_pmu.pebs = 0; 1440 x86_pmu.pebs = 0;
1441 x86_pmu.pebs_constraints = NULL; 1441 x86_pmu.pebs_constraints = NULL;
1442 } 1442 }
1443 1443
1444 static __init int intel_pmu_init(void) 1444 static __init int intel_pmu_init(void)
1445 { 1445 {
1446 union cpuid10_edx edx; 1446 union cpuid10_edx edx;
1447 union cpuid10_eax eax; 1447 union cpuid10_eax eax;
1448 unsigned int unused; 1448 unsigned int unused;
1449 unsigned int ebx; 1449 unsigned int ebx;
1450 int version; 1450 int version;
1451 1451
1452 if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) { 1452 if (!cpu_has(&boot_cpu_data, X86_FEATURE_ARCH_PERFMON)) {
1453 switch (boot_cpu_data.x86) { 1453 switch (boot_cpu_data.x86) {
1454 case 0x6: 1454 case 0x6:
1455 return p6_pmu_init(); 1455 return p6_pmu_init();
1456 case 0xf: 1456 case 0xf:
1457 return p4_pmu_init(); 1457 return p4_pmu_init();
1458 } 1458 }
1459 return -ENODEV; 1459 return -ENODEV;
1460 } 1460 }
1461 1461
1462 /* 1462 /*
1463 * Check whether the Architectural PerfMon supports 1463 * Check whether the Architectural PerfMon supports
1464 * Branch Misses Retired hw_event or not. 1464 * Branch Misses Retired hw_event or not.
1465 */ 1465 */
1466 cpuid(10, &eax.full, &ebx, &unused, &edx.full); 1466 cpuid(10, &eax.full, &ebx, &unused, &edx.full);
1467 if (eax.split.mask_length <= ARCH_PERFMON_BRANCH_MISSES_RETIRED) 1467 if (eax.split.mask_length <= ARCH_PERFMON_BRANCH_MISSES_RETIRED)
1468 return -ENODEV; 1468 return -ENODEV;
1469 1469
1470 version = eax.split.version_id; 1470 version = eax.split.version_id;
1471 if (version < 2) 1471 if (version < 2)
1472 x86_pmu = core_pmu; 1472 x86_pmu = core_pmu;
1473 else 1473 else
1474 x86_pmu = intel_pmu; 1474 x86_pmu = intel_pmu;
1475 1475
1476 x86_pmu.version = version; 1476 x86_pmu.version = version;
1477 x86_pmu.num_counters = eax.split.num_counters; 1477 x86_pmu.num_counters = eax.split.num_counters;
1478 x86_pmu.cntval_bits = eax.split.bit_width; 1478 x86_pmu.cntval_bits = eax.split.bit_width;
1479 x86_pmu.cntval_mask = (1ULL << eax.split.bit_width) - 1; 1479 x86_pmu.cntval_mask = (1ULL << eax.split.bit_width) - 1;
1480 1480
1481 /* 1481 /*
1482 * Quirk: v2 perfmon does not report fixed-purpose events, so 1482 * Quirk: v2 perfmon does not report fixed-purpose events, so
1483 * assume at least 3 events: 1483 * assume at least 3 events:
1484 */ 1484 */
1485 if (version > 1) 1485 if (version > 1)
1486 x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3); 1486 x86_pmu.num_counters_fixed = max((int)edx.split.num_counters_fixed, 3);
1487 1487
1488 /* 1488 /*
1489 * v2 and above have a perf capabilities MSR 1489 * v2 and above have a perf capabilities MSR
1490 */ 1490 */
1491 if (version > 1) { 1491 if (version > 1) {
1492 u64 capabilities; 1492 u64 capabilities;
1493 1493
1494 rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities); 1494 rdmsrl(MSR_IA32_PERF_CAPABILITIES, capabilities);
1495 x86_pmu.intel_cap.capabilities = capabilities; 1495 x86_pmu.intel_cap.capabilities = capabilities;
1496 } 1496 }
1497 1497
1498 intel_ds_init(); 1498 intel_ds_init();
1499 1499
1500 /* 1500 /*
1501 * Install the hw-cache-events table: 1501 * Install the hw-cache-events table:
1502 */ 1502 */
1503 switch (boot_cpu_data.x86_model) { 1503 switch (boot_cpu_data.x86_model) {
1504 case 14: /* 65 nm core solo/duo, "Yonah" */ 1504 case 14: /* 65 nm core solo/duo, "Yonah" */
1505 pr_cont("Core events, "); 1505 pr_cont("Core events, ");
1506 break; 1506 break;
1507 1507
1508 case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */ 1508 case 15: /* original 65 nm celeron/pentium/core2/xeon, "Merom"/"Conroe" */
1509 x86_pmu.quirks = intel_clovertown_quirks; 1509 x86_pmu.quirks = intel_clovertown_quirks;
1510 case 22: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */ 1510 case 22: /* single-core 65 nm celeron/core2solo "Merom-L"/"Conroe-L" */
1511 case 23: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */ 1511 case 23: /* current 45 nm celeron/core2/xeon "Penryn"/"Wolfdale" */
1512 case 29: /* six-core 45 nm xeon "Dunnington" */ 1512 case 29: /* six-core 45 nm xeon "Dunnington" */
1513 memcpy(hw_cache_event_ids, core2_hw_cache_event_ids, 1513 memcpy(hw_cache_event_ids, core2_hw_cache_event_ids,
1514 sizeof(hw_cache_event_ids)); 1514 sizeof(hw_cache_event_ids));
1515 1515
1516 intel_pmu_lbr_init_core(); 1516 intel_pmu_lbr_init_core();
1517 1517
1518 x86_pmu.event_constraints = intel_core2_event_constraints; 1518 x86_pmu.event_constraints = intel_core2_event_constraints;
1519 x86_pmu.pebs_constraints = intel_core2_pebs_event_constraints; 1519 x86_pmu.pebs_constraints = intel_core2_pebs_event_constraints;
1520 pr_cont("Core2 events, "); 1520 pr_cont("Core2 events, ");
1521 break; 1521 break;
1522 1522
1523 case 26: /* 45 nm nehalem, "Bloomfield" */ 1523 case 26: /* 45 nm nehalem, "Bloomfield" */
1524 case 30: /* 45 nm nehalem, "Lynnfield" */ 1524 case 30: /* 45 nm nehalem, "Lynnfield" */
1525 case 46: /* 45 nm nehalem-ex, "Beckton" */ 1525 case 46: /* 45 nm nehalem-ex, "Beckton" */
1526 memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids, 1526 memcpy(hw_cache_event_ids, nehalem_hw_cache_event_ids,
1527 sizeof(hw_cache_event_ids)); 1527 sizeof(hw_cache_event_ids));
1528 memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs, 1528 memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
1529 sizeof(hw_cache_extra_regs)); 1529 sizeof(hw_cache_extra_regs));
1530 1530
1531 intel_pmu_lbr_init_nhm(); 1531 intel_pmu_lbr_init_nhm();
1532 1532
1533 x86_pmu.event_constraints = intel_nehalem_event_constraints; 1533 x86_pmu.event_constraints = intel_nehalem_event_constraints;
1534 x86_pmu.pebs_constraints = intel_nehalem_pebs_event_constraints; 1534 x86_pmu.pebs_constraints = intel_nehalem_pebs_event_constraints;
1535 x86_pmu.enable_all = intel_pmu_nhm_enable_all; 1535 x86_pmu.enable_all = intel_pmu_nhm_enable_all;
1536 x86_pmu.extra_regs = intel_nehalem_extra_regs; 1536 x86_pmu.extra_regs = intel_nehalem_extra_regs;
1537 1537
1538 /* UOPS_ISSUED.STALLED_CYCLES */ 1538 /* UOPS_ISSUED.STALLED_CYCLES */
1539 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x180010e; 1539 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x180010e;
1540 /* UOPS_EXECUTED.CORE_ACTIVE_CYCLES,c=1,i=1 */ 1540 /* UOPS_EXECUTED.CORE_ACTIVE_CYCLES,c=1,i=1 */
1541 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x1803fb1; 1541 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x1803fb1;
1542 1542
1543 if (ebx & 0x40) { 1543 if (ebx & 0x40) {
1544 /* 1544 /*
1545 * Erratum AAJ80 detected, we work it around by using 1545 * Erratum AAJ80 detected, we work it around by using
1546 * the BR_MISP_EXEC.ANY event. This will over-count 1546 * the BR_MISP_EXEC.ANY event. This will over-count
1547 * branch-misses, but it's still much better than the 1547 * branch-misses, but it's still much better than the
1548 * architectural event which is often completely bogus: 1548 * architectural event which is often completely bogus:
1549 */ 1549 */
1550 intel_perfmon_event_map[PERF_COUNT_HW_BRANCH_MISSES] = 0x7f89; 1550 intel_perfmon_event_map[PERF_COUNT_HW_BRANCH_MISSES] = 0x7f89;
1551 1551
1552 pr_cont("erratum AAJ80 worked around, "); 1552 pr_cont("erratum AAJ80 worked around, ");
1553 } 1553 }
1554 pr_cont("Nehalem events, "); 1554 pr_cont("Nehalem events, ");
1555 break; 1555 break;
1556 1556
1557 case 28: /* Atom */ 1557 case 28: /* Atom */
1558 memcpy(hw_cache_event_ids, atom_hw_cache_event_ids, 1558 memcpy(hw_cache_event_ids, atom_hw_cache_event_ids,
1559 sizeof(hw_cache_event_ids)); 1559 sizeof(hw_cache_event_ids));
1560 1560
1561 intel_pmu_lbr_init_atom(); 1561 intel_pmu_lbr_init_atom();
1562 1562
1563 x86_pmu.event_constraints = intel_gen_event_constraints; 1563 x86_pmu.event_constraints = intel_gen_event_constraints;
1564 x86_pmu.pebs_constraints = intel_atom_pebs_event_constraints; 1564 x86_pmu.pebs_constraints = intel_atom_pebs_event_constraints;
1565 pr_cont("Atom events, "); 1565 pr_cont("Atom events, ");
1566 break; 1566 break;
1567 1567
1568 case 37: /* 32 nm nehalem, "Clarkdale" */ 1568 case 37: /* 32 nm nehalem, "Clarkdale" */
1569 case 44: /* 32 nm nehalem, "Gulftown" */ 1569 case 44: /* 32 nm nehalem, "Gulftown" */
1570 case 47: /* 32 nm Xeon E7 */ 1570 case 47: /* 32 nm Xeon E7 */
1571 memcpy(hw_cache_event_ids, westmere_hw_cache_event_ids, 1571 memcpy(hw_cache_event_ids, westmere_hw_cache_event_ids,
1572 sizeof(hw_cache_event_ids)); 1572 sizeof(hw_cache_event_ids));
1573 memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs, 1573 memcpy(hw_cache_extra_regs, nehalem_hw_cache_extra_regs,
1574 sizeof(hw_cache_extra_regs)); 1574 sizeof(hw_cache_extra_regs));
1575 1575
1576 intel_pmu_lbr_init_nhm(); 1576 intel_pmu_lbr_init_nhm();
1577 1577
1578 x86_pmu.event_constraints = intel_westmere_event_constraints; 1578 x86_pmu.event_constraints = intel_westmere_event_constraints;
1579 x86_pmu.enable_all = intel_pmu_nhm_enable_all; 1579 x86_pmu.enable_all = intel_pmu_nhm_enable_all;
1580 x86_pmu.pebs_constraints = intel_westmere_pebs_event_constraints; 1580 x86_pmu.pebs_constraints = intel_westmere_pebs_event_constraints;
1581 x86_pmu.extra_regs = intel_westmere_extra_regs; 1581 x86_pmu.extra_regs = intel_westmere_extra_regs;
1582 x86_pmu.er_flags |= ERF_HAS_RSP_1; 1582 x86_pmu.er_flags |= ERF_HAS_RSP_1;
1583 1583
1584 /* UOPS_ISSUED.STALLED_CYCLES */ 1584 /* UOPS_ISSUED.STALLED_CYCLES */
1585 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x180010e; 1585 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x180010e;
1586 /* UOPS_EXECUTED.CORE_ACTIVE_CYCLES,c=1,i=1 */ 1586 /* UOPS_EXECUTED.CORE_ACTIVE_CYCLES,c=1,i=1 */
1587 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x1803fb1; 1587 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x1803fb1;
1588 1588
1589 pr_cont("Westmere events, "); 1589 pr_cont("Westmere events, ");
1590 break; 1590 break;
1591 1591
1592 case 42: /* SandyBridge */ 1592 case 42: /* SandyBridge */
1593 case 45: /* SandyBridge, "Romely-EP" */
1593 memcpy(hw_cache_event_ids, snb_hw_cache_event_ids, 1594 memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
1594 sizeof(hw_cache_event_ids)); 1595 sizeof(hw_cache_event_ids));
1595 1596
1596 intel_pmu_lbr_init_nhm(); 1597 intel_pmu_lbr_init_nhm();
1597 1598
1598 x86_pmu.event_constraints = intel_snb_event_constraints; 1599 x86_pmu.event_constraints = intel_snb_event_constraints;
1599 x86_pmu.pebs_constraints = intel_snb_pebs_events; 1600 x86_pmu.pebs_constraints = intel_snb_pebs_events;
1600 x86_pmu.extra_regs = intel_snb_extra_regs; 1601 x86_pmu.extra_regs = intel_snb_extra_regs;
1601 /* all extra regs are per-cpu when HT is on */ 1602 /* all extra regs are per-cpu when HT is on */
1602 x86_pmu.er_flags |= ERF_HAS_RSP_1; 1603 x86_pmu.er_flags |= ERF_HAS_RSP_1;
1603 x86_pmu.er_flags |= ERF_NO_HT_SHARING; 1604 x86_pmu.er_flags |= ERF_NO_HT_SHARING;
1604 1605
1605 /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */ 1606 /* UOPS_ISSUED.ANY,c=1,i=1 to count stall cycles */
1606 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x180010e; 1607 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_FRONTEND] = 0x180010e;
1607 /* UOPS_DISPATCHED.THREAD,c=1,i=1 to count stall cycles*/ 1608 /* UOPS_DISPATCHED.THREAD,c=1,i=1 to count stall cycles*/
1608 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x18001b1; 1609 intel_perfmon_event_map[PERF_COUNT_HW_STALLED_CYCLES_BACKEND] = 0x18001b1;
1609 1610
1610 pr_cont("SandyBridge events, "); 1611 pr_cont("SandyBridge events, ");
1611 break; 1612 break;
1612 1613
1613 default: 1614 default:
1614 switch (x86_pmu.version) { 1615 switch (x86_pmu.version) {
1615 case 1: 1616 case 1:
1616 x86_pmu.event_constraints = intel_v1_event_constraints; 1617 x86_pmu.event_constraints = intel_v1_event_constraints;
1617 pr_cont("generic architected perfmon v1, "); 1618 pr_cont("generic architected perfmon v1, ");
1618 break; 1619 break;
1619 default: 1620 default:
1620 /* 1621 /*
1621 * default constraints for v2 and up 1622 * default constraints for v2 and up
1622 */ 1623 */
1623 x86_pmu.event_constraints = intel_gen_event_constraints; 1624 x86_pmu.event_constraints = intel_gen_event_constraints;
1624 pr_cont("generic architected perfmon, "); 1625 pr_cont("generic architected perfmon, ");
1625 break; 1626 break;
1626 } 1627 }
1627 } 1628 }
1628 return 0; 1629 return 0;
1629 } 1630 }
1630 1631
1631 #else /* CONFIG_CPU_SUP_INTEL */ 1632 #else /* CONFIG_CPU_SUP_INTEL */
1632 1633
1633 static int intel_pmu_init(void) 1634 static int intel_pmu_init(void)
1634 { 1635 {
1635 return 0; 1636 return 0;
1636 } 1637 }
1637 1638
1638 static struct intel_shared_regs *allocate_shared_regs(int cpu) 1639 static struct intel_shared_regs *allocate_shared_regs(int cpu)
1639 { 1640 {
1640 return NULL; 1641 return NULL;
1641 } 1642 }
1642 #endif /* CONFIG_CPU_SUP_INTEL */ 1643 #endif /* CONFIG_CPU_SUP_INTEL */
1643 1644
1 # 1 #
2 # Makefile for the linux kernel. 2 # Makefile for the linux kernel.
3 # 3 #
4 4
5 obj-y = sched.o fork.o exec_domain.o panic.o printk.o \ 5 obj-y = sched.o fork.o exec_domain.o panic.o printk.o \
6 cpu.o exit.o itimer.o time.o softirq.o resource.o \ 6 cpu.o exit.o itimer.o time.o softirq.o resource.o \
7 sysctl.o sysctl_binary.o capability.o ptrace.o timer.o user.o \ 7 sysctl.o sysctl_binary.o capability.o ptrace.o timer.o user.o \
8 signal.o sys.o kmod.o workqueue.o pid.o \ 8 signal.o sys.o kmod.o workqueue.o pid.o \
9 rcupdate.o extable.o params.o posix-timers.o \ 9 rcupdate.o extable.o params.o posix-timers.o \
10 kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \ 10 kthread.o wait.o kfifo.o sys_ni.o posix-cpu-timers.o mutex.o \
11 hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \ 11 hrtimer.o rwsem.o nsproxy.o srcu.o semaphore.o \
12 notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \ 12 notifier.o ksysfs.o pm_qos_params.o sched_clock.o cred.o \
13 async.o range.o jump_label.o 13 async.o range.o
14 obj-y += groups.o 14 obj-y += groups.o
15 15
16 ifdef CONFIG_FUNCTION_TRACER 16 ifdef CONFIG_FUNCTION_TRACER
17 # Do not trace debug files and internal ftrace files 17 # Do not trace debug files and internal ftrace files
18 CFLAGS_REMOVE_lockdep.o = -pg 18 CFLAGS_REMOVE_lockdep.o = -pg
19 CFLAGS_REMOVE_lockdep_proc.o = -pg 19 CFLAGS_REMOVE_lockdep_proc.o = -pg
20 CFLAGS_REMOVE_mutex-debug.o = -pg 20 CFLAGS_REMOVE_mutex-debug.o = -pg
21 CFLAGS_REMOVE_rtmutex-debug.o = -pg 21 CFLAGS_REMOVE_rtmutex-debug.o = -pg
22 CFLAGS_REMOVE_cgroup-debug.o = -pg 22 CFLAGS_REMOVE_cgroup-debug.o = -pg
23 CFLAGS_REMOVE_sched_clock.o = -pg 23 CFLAGS_REMOVE_sched_clock.o = -pg
24 CFLAGS_REMOVE_irq_work.o = -pg 24 CFLAGS_REMOVE_irq_work.o = -pg
25 endif 25 endif
26 26
27 obj-$(CONFIG_FREEZER) += freezer.o 27 obj-$(CONFIG_FREEZER) += freezer.o
28 obj-$(CONFIG_PROFILING) += profile.o 28 obj-$(CONFIG_PROFILING) += profile.o
29 obj-$(CONFIG_SYSCTL_SYSCALL_CHECK) += sysctl_check.o 29 obj-$(CONFIG_SYSCTL_SYSCALL_CHECK) += sysctl_check.o
30 obj-$(CONFIG_STACKTRACE) += stacktrace.o 30 obj-$(CONFIG_STACKTRACE) += stacktrace.o
31 obj-y += time/ 31 obj-y += time/
32 obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o 32 obj-$(CONFIG_DEBUG_MUTEXES) += mutex-debug.o
33 obj-$(CONFIG_LOCKDEP) += lockdep.o 33 obj-$(CONFIG_LOCKDEP) += lockdep.o
34 ifeq ($(CONFIG_PROC_FS),y) 34 ifeq ($(CONFIG_PROC_FS),y)
35 obj-$(CONFIG_LOCKDEP) += lockdep_proc.o 35 obj-$(CONFIG_LOCKDEP) += lockdep_proc.o
36 endif 36 endif
37 obj-$(CONFIG_FUTEX) += futex.o 37 obj-$(CONFIG_FUTEX) += futex.o
38 ifeq ($(CONFIG_COMPAT),y) 38 ifeq ($(CONFIG_COMPAT),y)
39 obj-$(CONFIG_FUTEX) += futex_compat.o 39 obj-$(CONFIG_FUTEX) += futex_compat.o
40 endif 40 endif
41 obj-$(CONFIG_RT_MUTEXES) += rtmutex.o 41 obj-$(CONFIG_RT_MUTEXES) += rtmutex.o
42 obj-$(CONFIG_DEBUG_RT_MUTEXES) += rtmutex-debug.o 42 obj-$(CONFIG_DEBUG_RT_MUTEXES) += rtmutex-debug.o
43 obj-$(CONFIG_RT_MUTEX_TESTER) += rtmutex-tester.o 43 obj-$(CONFIG_RT_MUTEX_TESTER) += rtmutex-tester.o
44 obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o 44 obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
45 obj-$(CONFIG_SMP) += smp.o 45 obj-$(CONFIG_SMP) += smp.o
46 ifneq ($(CONFIG_SMP),y) 46 ifneq ($(CONFIG_SMP),y)
47 obj-y += up.o 47 obj-y += up.o
48 endif 48 endif
49 obj-$(CONFIG_SMP) += spinlock.o 49 obj-$(CONFIG_SMP) += spinlock.o
50 obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o 50 obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o
51 obj-$(CONFIG_PROVE_LOCKING) += spinlock.o 51 obj-$(CONFIG_PROVE_LOCKING) += spinlock.o
52 obj-$(CONFIG_UID16) += uid16.o 52 obj-$(CONFIG_UID16) += uid16.o
53 obj-$(CONFIG_MODULES) += module.o 53 obj-$(CONFIG_MODULES) += module.o
54 obj-$(CONFIG_KALLSYMS) += kallsyms.o 54 obj-$(CONFIG_KALLSYMS) += kallsyms.o
55 obj-$(CONFIG_PM) += power/ 55 obj-$(CONFIG_PM) += power/
56 obj-$(CONFIG_FREEZER) += power/ 56 obj-$(CONFIG_FREEZER) += power/
57 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o 57 obj-$(CONFIG_BSD_PROCESS_ACCT) += acct.o
58 obj-$(CONFIG_KEXEC) += kexec.o 58 obj-$(CONFIG_KEXEC) += kexec.o
59 obj-$(CONFIG_BACKTRACE_SELF_TEST) += backtracetest.o 59 obj-$(CONFIG_BACKTRACE_SELF_TEST) += backtracetest.o
60 obj-$(CONFIG_COMPAT) += compat.o 60 obj-$(CONFIG_COMPAT) += compat.o
61 obj-$(CONFIG_CGROUPS) += cgroup.o 61 obj-$(CONFIG_CGROUPS) += cgroup.o
62 obj-$(CONFIG_CGROUP_FREEZER) += cgroup_freezer.o 62 obj-$(CONFIG_CGROUP_FREEZER) += cgroup_freezer.o
63 obj-$(CONFIG_CPUSETS) += cpuset.o 63 obj-$(CONFIG_CPUSETS) += cpuset.o
64 obj-$(CONFIG_UTS_NS) += utsname.o 64 obj-$(CONFIG_UTS_NS) += utsname.o
65 obj-$(CONFIG_USER_NS) += user_namespace.o 65 obj-$(CONFIG_USER_NS) += user_namespace.o
66 obj-$(CONFIG_PID_NS) += pid_namespace.o 66 obj-$(CONFIG_PID_NS) += pid_namespace.o
67 obj-$(CONFIG_IKCONFIG) += configs.o 67 obj-$(CONFIG_IKCONFIG) += configs.o
68 obj-$(CONFIG_RESOURCE_COUNTERS) += res_counter.o 68 obj-$(CONFIG_RESOURCE_COUNTERS) += res_counter.o
69 obj-$(CONFIG_SMP) += stop_machine.o 69 obj-$(CONFIG_SMP) += stop_machine.o
70 obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o 70 obj-$(CONFIG_KPROBES_SANITY_TEST) += test_kprobes.o
71 obj-$(CONFIG_AUDIT) += audit.o auditfilter.o 71 obj-$(CONFIG_AUDIT) += audit.o auditfilter.o
72 obj-$(CONFIG_AUDITSYSCALL) += auditsc.o 72 obj-$(CONFIG_AUDITSYSCALL) += auditsc.o
73 obj-$(CONFIG_AUDIT_WATCH) += audit_watch.o 73 obj-$(CONFIG_AUDIT_WATCH) += audit_watch.o
74 obj-$(CONFIG_AUDIT_TREE) += audit_tree.o 74 obj-$(CONFIG_AUDIT_TREE) += audit_tree.o
75 obj-$(CONFIG_GCOV_KERNEL) += gcov/ 75 obj-$(CONFIG_GCOV_KERNEL) += gcov/
76 obj-$(CONFIG_KPROBES) += kprobes.o 76 obj-$(CONFIG_KPROBES) += kprobes.o
77 obj-$(CONFIG_KGDB) += debug/ 77 obj-$(CONFIG_KGDB) += debug/
78 obj-$(CONFIG_DETECT_HUNG_TASK) += hung_task.o 78 obj-$(CONFIG_DETECT_HUNG_TASK) += hung_task.o
79 obj-$(CONFIG_LOCKUP_DETECTOR) += watchdog.o 79 obj-$(CONFIG_LOCKUP_DETECTOR) += watchdog.o
80 obj-$(CONFIG_GENERIC_HARDIRQS) += irq/ 80 obj-$(CONFIG_GENERIC_HARDIRQS) += irq/
81 obj-$(CONFIG_SECCOMP) += seccomp.o 81 obj-$(CONFIG_SECCOMP) += seccomp.o
82 obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o 82 obj-$(CONFIG_RCU_TORTURE_TEST) += rcutorture.o
83 obj-$(CONFIG_TREE_RCU) += rcutree.o 83 obj-$(CONFIG_TREE_RCU) += rcutree.o
84 obj-$(CONFIG_TREE_PREEMPT_RCU) += rcutree.o 84 obj-$(CONFIG_TREE_PREEMPT_RCU) += rcutree.o
85 obj-$(CONFIG_TREE_RCU_TRACE) += rcutree_trace.o 85 obj-$(CONFIG_TREE_RCU_TRACE) += rcutree_trace.o
86 obj-$(CONFIG_TINY_RCU) += rcutiny.o 86 obj-$(CONFIG_TINY_RCU) += rcutiny.o
87 obj-$(CONFIG_TINY_PREEMPT_RCU) += rcutiny.o 87 obj-$(CONFIG_TINY_PREEMPT_RCU) += rcutiny.o
88 obj-$(CONFIG_RELAY) += relay.o 88 obj-$(CONFIG_RELAY) += relay.o
89 obj-$(CONFIG_SYSCTL) += utsname_sysctl.o 89 obj-$(CONFIG_SYSCTL) += utsname_sysctl.o
90 obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o 90 obj-$(CONFIG_TASK_DELAY_ACCT) += delayacct.o
91 obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o 91 obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o
92 obj-$(CONFIG_TRACEPOINTS) += tracepoint.o 92 obj-$(CONFIG_TRACEPOINTS) += tracepoint.o
93 obj-$(CONFIG_LATENCYTOP) += latencytop.o 93 obj-$(CONFIG_LATENCYTOP) += latencytop.o
94 obj-$(CONFIG_BINFMT_ELF) += elfcore.o 94 obj-$(CONFIG_BINFMT_ELF) += elfcore.o
95 obj-$(CONFIG_COMPAT_BINFMT_ELF) += elfcore.o 95 obj-$(CONFIG_COMPAT_BINFMT_ELF) += elfcore.o
96 obj-$(CONFIG_BINFMT_ELF_FDPIC) += elfcore.o 96 obj-$(CONFIG_BINFMT_ELF_FDPIC) += elfcore.o
97 obj-$(CONFIG_FUNCTION_TRACER) += trace/ 97 obj-$(CONFIG_FUNCTION_TRACER) += trace/
98 obj-$(CONFIG_TRACING) += trace/ 98 obj-$(CONFIG_TRACING) += trace/
99 obj-$(CONFIG_X86_DS) += trace/ 99 obj-$(CONFIG_X86_DS) += trace/
100 obj-$(CONFIG_RING_BUFFER) += trace/ 100 obj-$(CONFIG_RING_BUFFER) += trace/
101 obj-$(CONFIG_TRACEPOINTS) += trace/ 101 obj-$(CONFIG_TRACEPOINTS) += trace/
102 obj-$(CONFIG_SMP) += sched_cpupri.o 102 obj-$(CONFIG_SMP) += sched_cpupri.o
103 obj-$(CONFIG_IRQ_WORK) += irq_work.o 103 obj-$(CONFIG_IRQ_WORK) += irq_work.o
104 104
105 obj-$(CONFIG_PERF_EVENTS) += events/ 105 obj-$(CONFIG_PERF_EVENTS) += events/
106 106
107 obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o 107 obj-$(CONFIG_USER_RETURN_NOTIFIER) += user-return-notifier.o
108 obj-$(CONFIG_PADATA) += padata.o 108 obj-$(CONFIG_PADATA) += padata.o
109 obj-$(CONFIG_CRASH_DUMP) += crash_dump.o 109 obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
110 obj-$(CONFIG_JUMP_LABEL) += jump_label.o
110 111
111 ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y) 112 ifneq ($(CONFIG_SCHED_OMIT_FRAME_POINTER),y)
112 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is 113 # According to Alan Modra <alan@linuxcare.com.au>, the -fno-omit-frame-pointer is
113 # needed for x86 only. Why this used to be enabled for all architectures is beyond 114 # needed for x86 only. Why this used to be enabled for all architectures is beyond
114 # me. I suspect most platforms don't need this, but until we know that for sure 115 # me. I suspect most platforms don't need this, but until we know that for sure
115 # I turn this off for IA-64 only. Andreas Schwab says it's also needed on m68k 116 # I turn this off for IA-64 only. Andreas Schwab says it's also needed on m68k
116 # to get a correct value for the wait-channel (WCHAN in ps). --davidm 117 # to get a correct value for the wait-channel (WCHAN in ps). --davidm
117 CFLAGS_sched.o := $(PROFILING) -fno-omit-frame-pointer 118 CFLAGS_sched.o := $(PROFILING) -fno-omit-frame-pointer
118 endif 119 endif
119 120
120 $(obj)/configs.o: $(obj)/config_data.h 121 $(obj)/configs.o: $(obj)/config_data.h
121 122
122 # config_data.h contains the same information as ikconfig.h but gzipped. 123 # config_data.h contains the same information as ikconfig.h but gzipped.
123 # Info from config_data can be extracted from /proc/config* 124 # Info from config_data can be extracted from /proc/config*
124 targets += config_data.gz 125 targets += config_data.gz
125 $(obj)/config_data.gz: $(KCONFIG_CONFIG) FORCE 126 $(obj)/config_data.gz: $(KCONFIG_CONFIG) FORCE
126 $(call if_changed,gzip) 127 $(call if_changed,gzip)
127 128
128 filechk_ikconfiggz = (echo "static const char kernel_config_data[] __used = MAGIC_START"; cat $< | scripts/bin2c; echo "MAGIC_END;") 129 filechk_ikconfiggz = (echo "static const char kernel_config_data[] __used = MAGIC_START"; cat $< | scripts/bin2c; echo "MAGIC_END;")
129 targets += config_data.h 130 targets += config_data.h
130 $(obj)/config_data.h: $(obj)/config_data.gz FORCE 131 $(obj)/config_data.h: $(obj)/config_data.gz FORCE
131 $(call filechk,ikconfiggz) 132 $(call filechk,ikconfiggz)
132 133
133 $(obj)/time.o: $(obj)/timeconst.h 134 $(obj)/time.o: $(obj)/timeconst.h
134 135
135 quiet_cmd_timeconst = TIMEC $@ 136 quiet_cmd_timeconst = TIMEC $@
136 cmd_timeconst = $(PERL) $< $(CONFIG_HZ) > $@ 137 cmd_timeconst = $(PERL) $< $(CONFIG_HZ) > $@
137 targets += timeconst.h 138 targets += timeconst.h
138 $(obj)/timeconst.h: $(src)/timeconst.pl FORCE 139 $(obj)/timeconst.h: $(src)/timeconst.pl FORCE
139 $(call if_changed,timeconst) 140 $(call if_changed,timeconst)
140 141
kernel/trace/Kconfig
1 # 1 #
2 # Architectures that offer an FUNCTION_TRACER implementation should 2 # Architectures that offer an FUNCTION_TRACER implementation should
3 # select HAVE_FUNCTION_TRACER: 3 # select HAVE_FUNCTION_TRACER:
4 # 4 #
5 5
6 config USER_STACKTRACE_SUPPORT 6 config USER_STACKTRACE_SUPPORT
7 bool 7 bool
8 8
9 config NOP_TRACER 9 config NOP_TRACER
10 bool 10 bool
11 11
12 config HAVE_FTRACE_NMI_ENTER 12 config HAVE_FTRACE_NMI_ENTER
13 bool 13 bool
14 help 14 help
15 See Documentation/trace/ftrace-design.txt 15 See Documentation/trace/ftrace-design.txt
16 16
17 config HAVE_FUNCTION_TRACER 17 config HAVE_FUNCTION_TRACER
18 bool 18 bool
19 help 19 help
20 See Documentation/trace/ftrace-design.txt 20 See Documentation/trace/ftrace-design.txt
21 21
22 config HAVE_FUNCTION_GRAPH_TRACER 22 config HAVE_FUNCTION_GRAPH_TRACER
23 bool 23 bool
24 help 24 help
25 See Documentation/trace/ftrace-design.txt 25 See Documentation/trace/ftrace-design.txt
26 26
27 config HAVE_FUNCTION_GRAPH_FP_TEST 27 config HAVE_FUNCTION_GRAPH_FP_TEST
28 bool 28 bool
29 help 29 help
30 See Documentation/trace/ftrace-design.txt 30 See Documentation/trace/ftrace-design.txt
31 31
32 config HAVE_FUNCTION_TRACE_MCOUNT_TEST 32 config HAVE_FUNCTION_TRACE_MCOUNT_TEST
33 bool 33 bool
34 help 34 help
35 See Documentation/trace/ftrace-design.txt 35 See Documentation/trace/ftrace-design.txt
36 36
37 config HAVE_DYNAMIC_FTRACE 37 config HAVE_DYNAMIC_FTRACE
38 bool 38 bool
39 help 39 help
40 See Documentation/trace/ftrace-design.txt 40 See Documentation/trace/ftrace-design.txt
41 41
42 config HAVE_FTRACE_MCOUNT_RECORD 42 config HAVE_FTRACE_MCOUNT_RECORD
43 bool 43 bool
44 help 44 help
45 See Documentation/trace/ftrace-design.txt 45 See Documentation/trace/ftrace-design.txt
46 46
47 config HAVE_SYSCALL_TRACEPOINTS 47 config HAVE_SYSCALL_TRACEPOINTS
48 bool 48 bool
49 help 49 help
50 See Documentation/trace/ftrace-design.txt 50 See Documentation/trace/ftrace-design.txt
51 51
52 config HAVE_C_RECORDMCOUNT 52 config HAVE_C_RECORDMCOUNT
53 bool 53 bool
54 help 54 help
55 C version of recordmcount available? 55 C version of recordmcount available?
56 56
57 config TRACER_MAX_TRACE 57 config TRACER_MAX_TRACE
58 bool 58 bool
59 59
60 config RING_BUFFER 60 config RING_BUFFER
61 bool 61 bool
62 62
63 config FTRACE_NMI_ENTER 63 config FTRACE_NMI_ENTER
64 bool 64 bool
65 depends on HAVE_FTRACE_NMI_ENTER 65 depends on HAVE_FTRACE_NMI_ENTER
66 default y 66 default y
67 67
68 config EVENT_TRACING 68 config EVENT_TRACING
69 select CONTEXT_SWITCH_TRACER 69 select CONTEXT_SWITCH_TRACER
70 bool 70 bool
71 71
72 config EVENT_POWER_TRACING_DEPRECATED 72 config EVENT_POWER_TRACING_DEPRECATED
73 depends on EVENT_TRACING 73 depends on EVENT_TRACING
74 bool "Deprecated power event trace API, to be removed" 74 bool "Deprecated power event trace API, to be removed"
75 default y 75 default y
76 help 76 help
77 Provides old power event types: 77 Provides old power event types:
78 C-state/idle accounting events: 78 C-state/idle accounting events:
79 power:power_start 79 power:power_start
80 power:power_end 80 power:power_end
81 and old cpufreq accounting event: 81 and old cpufreq accounting event:
82 power:power_frequency 82 power:power_frequency
83 This is for userspace compatibility 83 This is for userspace compatibility
84 and will vanish after 5 kernel iterations, 84 and will vanish after 5 kernel iterations,
85 namely 2.6.41. 85 namely 3.1.
86 86
87 config CONTEXT_SWITCH_TRACER 87 config CONTEXT_SWITCH_TRACER
88 bool 88 bool
89 89
90 config RING_BUFFER_ALLOW_SWAP 90 config RING_BUFFER_ALLOW_SWAP
91 bool 91 bool
92 help 92 help
93 Allow the use of ring_buffer_swap_cpu. 93 Allow the use of ring_buffer_swap_cpu.
94 Adds a very slight overhead to tracing when enabled. 94 Adds a very slight overhead to tracing when enabled.
95 95
96 # All tracer options should select GENERIC_TRACER. For those options that are 96 # All tracer options should select GENERIC_TRACER. For those options that are
97 # enabled by all tracers (context switch and event tracer) they select TRACING. 97 # enabled by all tracers (context switch and event tracer) they select TRACING.
98 # This allows those options to appear when no other tracer is selected. But the 98 # This allows those options to appear when no other tracer is selected. But the
99 # options do not appear when something else selects it. We need the two options 99 # options do not appear when something else selects it. We need the two options
100 # GENERIC_TRACER and TRACING to avoid circular dependencies to accomplish the 100 # GENERIC_TRACER and TRACING to avoid circular dependencies to accomplish the
101 # hiding of the automatic options. 101 # hiding of the automatic options.
102 102
103 config TRACING 103 config TRACING
104 bool 104 bool
105 select DEBUG_FS 105 select DEBUG_FS
106 select RING_BUFFER 106 select RING_BUFFER
107 select STACKTRACE if STACKTRACE_SUPPORT 107 select STACKTRACE if STACKTRACE_SUPPORT
108 select TRACEPOINTS 108 select TRACEPOINTS
109 select NOP_TRACER 109 select NOP_TRACER
110 select BINARY_PRINTF 110 select BINARY_PRINTF
111 select EVENT_TRACING 111 select EVENT_TRACING
112 112
113 config GENERIC_TRACER 113 config GENERIC_TRACER
114 bool 114 bool
115 select TRACING 115 select TRACING
116 116
117 # 117 #
118 # Minimum requirements an architecture has to meet for us to 118 # Minimum requirements an architecture has to meet for us to
119 # be able to offer generic tracing facilities: 119 # be able to offer generic tracing facilities:
120 # 120 #
121 config TRACING_SUPPORT 121 config TRACING_SUPPORT
122 bool 122 bool
123 # PPC32 has no irqflags tracing support, but it can use most of the 123 # PPC32 has no irqflags tracing support, but it can use most of the
124 # tracers anyway, they were tested to build and work. Note that new 124 # tracers anyway, they were tested to build and work. Note that new
125 # exceptions to this list aren't welcomed, better implement the 125 # exceptions to this list aren't welcomed, better implement the
126 # irqflags tracing for your architecture. 126 # irqflags tracing for your architecture.
127 depends on TRACE_IRQFLAGS_SUPPORT || PPC32 127 depends on TRACE_IRQFLAGS_SUPPORT || PPC32
128 depends on STACKTRACE_SUPPORT 128 depends on STACKTRACE_SUPPORT
129 default y 129 default y
130 130
131 if TRACING_SUPPORT 131 if TRACING_SUPPORT
132 132
133 menuconfig FTRACE 133 menuconfig FTRACE
134 bool "Tracers" 134 bool "Tracers"
135 default y if DEBUG_KERNEL 135 default y if DEBUG_KERNEL
136 help 136 help
137 Enable the kernel tracing infrastructure. 137 Enable the kernel tracing infrastructure.
138 138
139 if FTRACE 139 if FTRACE
140 140
141 config FUNCTION_TRACER 141 config FUNCTION_TRACER
142 bool "Kernel Function Tracer" 142 bool "Kernel Function Tracer"
143 depends on HAVE_FUNCTION_TRACER 143 depends on HAVE_FUNCTION_TRACER
144 select FRAME_POINTER if !ARM_UNWIND && !S390 && !MICROBLAZE 144 select FRAME_POINTER if !ARM_UNWIND && !S390 && !MICROBLAZE
145 select KALLSYMS 145 select KALLSYMS
146 select GENERIC_TRACER 146 select GENERIC_TRACER
147 select CONTEXT_SWITCH_TRACER 147 select CONTEXT_SWITCH_TRACER
148 help 148 help
149 Enable the kernel to trace every kernel function. This is done 149 Enable the kernel to trace every kernel function. This is done
150 by using a compiler feature to insert a small, 5-byte No-Operation 150 by using a compiler feature to insert a small, 5-byte No-Operation
151 instruction at the beginning of every kernel function, which NOP 151 instruction at the beginning of every kernel function, which NOP
152 sequence is then dynamically patched into a tracer call when 152 sequence is then dynamically patched into a tracer call when
153 tracing is enabled by the administrator. If it's runtime disabled 153 tracing is enabled by the administrator. If it's runtime disabled
154 (the bootup default), then the overhead of the instructions is very 154 (the bootup default), then the overhead of the instructions is very
155 small and not measurable even in micro-benchmarks. 155 small and not measurable even in micro-benchmarks.
156 156
157 config FUNCTION_GRAPH_TRACER 157 config FUNCTION_GRAPH_TRACER
158 bool "Kernel Function Graph Tracer" 158 bool "Kernel Function Graph Tracer"
159 depends on HAVE_FUNCTION_GRAPH_TRACER 159 depends on HAVE_FUNCTION_GRAPH_TRACER
160 depends on FUNCTION_TRACER 160 depends on FUNCTION_TRACER
161 depends on !X86_32 || !CC_OPTIMIZE_FOR_SIZE 161 depends on !X86_32 || !CC_OPTIMIZE_FOR_SIZE
162 default y 162 default y
163 help 163 help
164 Enable the kernel to trace a function at both its return 164 Enable the kernel to trace a function at both its return
165 and its entry. 165 and its entry.
166 Its first purpose is to trace the duration of functions and 166 Its first purpose is to trace the duration of functions and
167 draw a call graph for each thread with some information like 167 draw a call graph for each thread with some information like
168 the return value. This is done by setting the current return 168 the return value. This is done by setting the current return
169 address on the current task structure into a stack of calls. 169 address on the current task structure into a stack of calls.
170 170
171 171
172 config IRQSOFF_TRACER 172 config IRQSOFF_TRACER
173 bool "Interrupts-off Latency Tracer" 173 bool "Interrupts-off Latency Tracer"
174 default n 174 default n
175 depends on TRACE_IRQFLAGS_SUPPORT 175 depends on TRACE_IRQFLAGS_SUPPORT
176 depends on !ARCH_USES_GETTIMEOFFSET 176 depends on !ARCH_USES_GETTIMEOFFSET
177 select TRACE_IRQFLAGS 177 select TRACE_IRQFLAGS
178 select GENERIC_TRACER 178 select GENERIC_TRACER
179 select TRACER_MAX_TRACE 179 select TRACER_MAX_TRACE
180 select RING_BUFFER_ALLOW_SWAP 180 select RING_BUFFER_ALLOW_SWAP
181 help 181 help
182 This option measures the time spent in irqs-off critical 182 This option measures the time spent in irqs-off critical
183 sections, with microsecond accuracy. 183 sections, with microsecond accuracy.
184 184
185 The default measurement method is a maximum search, which is 185 The default measurement method is a maximum search, which is
186 disabled by default and can be runtime (re-)started 186 disabled by default and can be runtime (re-)started
187 via: 187 via:
188 188
189 echo 0 > /sys/kernel/debug/tracing/tracing_max_latency 189 echo 0 > /sys/kernel/debug/tracing/tracing_max_latency
190 190
191 (Note that kernel size and overhead increase with this option 191 (Note that kernel size and overhead increase with this option
192 enabled. This option and the preempt-off timing option can be 192 enabled. This option and the preempt-off timing option can be
193 used together or separately.) 193 used together or separately.)
194 194
195 config PREEMPT_TRACER 195 config PREEMPT_TRACER
196 bool "Preemption-off Latency Tracer" 196 bool "Preemption-off Latency Tracer"
197 default n 197 default n
198 depends on !ARCH_USES_GETTIMEOFFSET 198 depends on !ARCH_USES_GETTIMEOFFSET
199 depends on PREEMPT 199 depends on PREEMPT
200 select GENERIC_TRACER 200 select GENERIC_TRACER
201 select TRACER_MAX_TRACE 201 select TRACER_MAX_TRACE
202 select RING_BUFFER_ALLOW_SWAP 202 select RING_BUFFER_ALLOW_SWAP
203 help 203 help
204 This option measures the time spent in preemption-off critical 204 This option measures the time spent in preemption-off critical
205 sections, with microsecond accuracy. 205 sections, with microsecond accuracy.
206 206
207 The default measurement method is a maximum search, which is 207 The default measurement method is a maximum search, which is
208 disabled by default and can be runtime (re-)started 208 disabled by default and can be runtime (re-)started
209 via: 209 via:
210 210
211 echo 0 > /sys/kernel/debug/tracing/tracing_max_latency 211 echo 0 > /sys/kernel/debug/tracing/tracing_max_latency
212 212
213 (Note that kernel size and overhead increase with this option 213 (Note that kernel size and overhead increase with this option
214 enabled. This option and the irqs-off timing option can be 214 enabled. This option and the irqs-off timing option can be
215 used together or separately.) 215 used together or separately.)
216 216
217 config SCHED_TRACER 217 config SCHED_TRACER
218 bool "Scheduling Latency Tracer" 218 bool "Scheduling Latency Tracer"
219 select GENERIC_TRACER 219 select GENERIC_TRACER
220 select CONTEXT_SWITCH_TRACER 220 select CONTEXT_SWITCH_TRACER
221 select TRACER_MAX_TRACE 221 select TRACER_MAX_TRACE
222 help 222 help
223 This tracer tracks the latency of the highest priority task 223 This tracer tracks the latency of the highest priority task
224 to be scheduled in, starting from the point it has woken up. 224 to be scheduled in, starting from the point it has woken up.
225 225
226 config ENABLE_DEFAULT_TRACERS 226 config ENABLE_DEFAULT_TRACERS
227 bool "Trace process context switches and events" 227 bool "Trace process context switches and events"
228 depends on !GENERIC_TRACER 228 depends on !GENERIC_TRACER
229 select TRACING 229 select TRACING
230 help 230 help
231 This tracer hooks to various trace points in the kernel, 231 This tracer hooks to various trace points in the kernel,
232 allowing the user to pick and choose which trace point they 232 allowing the user to pick and choose which trace point they
233 want to trace. It also includes the sched_switch tracer plugin. 233 want to trace. It also includes the sched_switch tracer plugin.
234 234
235 config FTRACE_SYSCALLS 235 config FTRACE_SYSCALLS
236 bool "Trace syscalls" 236 bool "Trace syscalls"
237 depends on HAVE_SYSCALL_TRACEPOINTS 237 depends on HAVE_SYSCALL_TRACEPOINTS
238 select GENERIC_TRACER 238 select GENERIC_TRACER
239 select KALLSYMS 239 select KALLSYMS
240 help 240 help
241 Basic tracer to catch the syscall entry and exit events. 241 Basic tracer to catch the syscall entry and exit events.
242 242
243 config TRACE_BRANCH_PROFILING 243 config TRACE_BRANCH_PROFILING
244 bool 244 bool
245 select GENERIC_TRACER 245 select GENERIC_TRACER
246 246
247 choice 247 choice
248 prompt "Branch Profiling" 248 prompt "Branch Profiling"
249 default BRANCH_PROFILE_NONE 249 default BRANCH_PROFILE_NONE
250 help 250 help
251 The branch profiling is a software profiler. It will add hooks 251 The branch profiling is a software profiler. It will add hooks
252 into the C conditionals to test which path a branch takes. 252 into the C conditionals to test which path a branch takes.
253 253
254 The likely/unlikely profiler only looks at the conditions that 254 The likely/unlikely profiler only looks at the conditions that
255 are annotated with a likely or unlikely macro. 255 are annotated with a likely or unlikely macro.
256 256
257 The "all branch" profiler will profile every if-statement in the 257 The "all branch" profiler will profile every if-statement in the
258 kernel. This profiler will also enable the likely/unlikely 258 kernel. This profiler will also enable the likely/unlikely
259 profiler. 259 profiler.
260 260
261 Either of the above profilers adds a bit of overhead to the system. 261 Either of the above profilers adds a bit of overhead to the system.
262 If unsure, choose "No branch profiling". 262 If unsure, choose "No branch profiling".
263 263
264 config BRANCH_PROFILE_NONE 264 config BRANCH_PROFILE_NONE
265 bool "No branch profiling" 265 bool "No branch profiling"
266 help 266 help
267 No branch profiling. Branch profiling adds a bit of overhead. 267 No branch profiling. Branch profiling adds a bit of overhead.
268 Only enable it if you want to analyse the branching behavior. 268 Only enable it if you want to analyse the branching behavior.
269 Otherwise keep it disabled. 269 Otherwise keep it disabled.
270 270
271 config PROFILE_ANNOTATED_BRANCHES 271 config PROFILE_ANNOTATED_BRANCHES
272 bool "Trace likely/unlikely profiler" 272 bool "Trace likely/unlikely profiler"
273 select TRACE_BRANCH_PROFILING 273 select TRACE_BRANCH_PROFILING
274 help 274 help
275 This tracer profiles all the the likely and unlikely macros 275 This tracer profiles all the the likely and unlikely macros
276 in the kernel. It will display the results in: 276 in the kernel. It will display the results in:
277 277
278 /sys/kernel/debug/tracing/trace_stat/branch_annotated 278 /sys/kernel/debug/tracing/trace_stat/branch_annotated
279 279
280 Note: this will add a significant overhead; only turn this 280 Note: this will add a significant overhead; only turn this
281 on if you need to profile the system's use of these macros. 281 on if you need to profile the system's use of these macros.
282 282
283 config PROFILE_ALL_BRANCHES 283 config PROFILE_ALL_BRANCHES
284 bool "Profile all if conditionals" 284 bool "Profile all if conditionals"
285 select TRACE_BRANCH_PROFILING 285 select TRACE_BRANCH_PROFILING
286 help 286 help
287 This tracer profiles all branch conditions. Every if () 287 This tracer profiles all branch conditions. Every if ()
288 taken in the kernel is recorded whether it hit or miss. 288 taken in the kernel is recorded whether it hit or miss.
289 The results will be displayed in: 289 The results will be displayed in:
290 290
291 /sys/kernel/debug/tracing/trace_stat/branch_all 291 /sys/kernel/debug/tracing/trace_stat/branch_all
292 292
293 This option also enables the likely/unlikely profiler. 293 This option also enables the likely/unlikely profiler.
294 294
295 This configuration, when enabled, will impose a great overhead 295 This configuration, when enabled, will impose a great overhead
296 on the system. This should only be enabled when the system 296 on the system. This should only be enabled when the system
297 is to be analyzed in much detail. 297 is to be analyzed in much detail.
298 endchoice 298 endchoice
299 299
300 config TRACING_BRANCHES 300 config TRACING_BRANCHES
301 bool 301 bool
302 help 302 help
303 Selected by tracers that will trace the likely and unlikely 303 Selected by tracers that will trace the likely and unlikely
304 conditions. This prevents the tracers themselves from being 304 conditions. This prevents the tracers themselves from being
305 profiled. Profiling the tracing infrastructure can only happen 305 profiled. Profiling the tracing infrastructure can only happen
306 when the likelys and unlikelys are not being traced. 306 when the likelys and unlikelys are not being traced.
307 307
308 config BRANCH_TRACER 308 config BRANCH_TRACER
309 bool "Trace likely/unlikely instances" 309 bool "Trace likely/unlikely instances"
310 depends on TRACE_BRANCH_PROFILING 310 depends on TRACE_BRANCH_PROFILING
311 select TRACING_BRANCHES 311 select TRACING_BRANCHES
312 help 312 help
313 This traces the events of likely and unlikely condition 313 This traces the events of likely and unlikely condition
314 calls in the kernel. The difference between this and the 314 calls in the kernel. The difference between this and the
315 "Trace likely/unlikely profiler" is that this is not a 315 "Trace likely/unlikely profiler" is that this is not a
316 histogram of the callers, but actually places the calling 316 histogram of the callers, but actually places the calling
317 events into a running trace buffer to see when and where the 317 events into a running trace buffer to see when and where the
318 events happened, as well as their results. 318 events happened, as well as their results.
319 319
320 Say N if unsure. 320 Say N if unsure.
321 321
322 config STACK_TRACER 322 config STACK_TRACER
323 bool "Trace max stack" 323 bool "Trace max stack"
324 depends on HAVE_FUNCTION_TRACER 324 depends on HAVE_FUNCTION_TRACER
325 select FUNCTION_TRACER 325 select FUNCTION_TRACER
326 select STACKTRACE 326 select STACKTRACE
327 select KALLSYMS 327 select KALLSYMS
328 help 328 help
329 This special tracer records the maximum stack footprint of the 329 This special tracer records the maximum stack footprint of the
330 kernel and displays it in /sys/kernel/debug/tracing/stack_trace. 330 kernel and displays it in /sys/kernel/debug/tracing/stack_trace.
331 331
332 This tracer works by hooking into every function call that the 332 This tracer works by hooking into every function call that the
333 kernel executes, and keeping a maximum stack depth value and 333 kernel executes, and keeping a maximum stack depth value and
334 stack-trace saved. If this is configured with DYNAMIC_FTRACE 334 stack-trace saved. If this is configured with DYNAMIC_FTRACE
335 then it will not have any overhead while the stack tracer 335 then it will not have any overhead while the stack tracer
336 is disabled. 336 is disabled.
337 337
338 To enable the stack tracer on bootup, pass in 'stacktrace' 338 To enable the stack tracer on bootup, pass in 'stacktrace'
339 on the kernel command line. 339 on the kernel command line.
340 340
341 The stack tracer can also be enabled or disabled via the 341 The stack tracer can also be enabled or disabled via the
342 sysctl kernel.stack_tracer_enabled 342 sysctl kernel.stack_tracer_enabled
343 343
344 Say N if unsure. 344 Say N if unsure.
345 345
346 config BLK_DEV_IO_TRACE 346 config BLK_DEV_IO_TRACE
347 bool "Support for tracing block IO actions" 347 bool "Support for tracing block IO actions"
348 depends on SYSFS 348 depends on SYSFS
349 depends on BLOCK 349 depends on BLOCK
350 select RELAY 350 select RELAY
351 select DEBUG_FS 351 select DEBUG_FS
352 select TRACEPOINTS 352 select TRACEPOINTS
353 select GENERIC_TRACER 353 select GENERIC_TRACER
354 select STACKTRACE 354 select STACKTRACE
355 help 355 help
356 Say Y here if you want to be able to trace the block layer actions 356 Say Y here if you want to be able to trace the block layer actions
357 on a given queue. Tracing allows you to see any traffic happening 357 on a given queue. Tracing allows you to see any traffic happening
358 on a block device queue. For more information (and the userspace 358 on a block device queue. For more information (and the userspace
359 support tools needed), fetch the blktrace tools from: 359 support tools needed), fetch the blktrace tools from:
360 360
361 git://git.kernel.dk/blktrace.git 361 git://git.kernel.dk/blktrace.git
362 362
363 Tracing also is possible using the ftrace interface, e.g.: 363 Tracing also is possible using the ftrace interface, e.g.:
364 364
365 echo 1 > /sys/block/sda/sda1/trace/enable 365 echo 1 > /sys/block/sda/sda1/trace/enable
366 echo blk > /sys/kernel/debug/tracing/current_tracer 366 echo blk > /sys/kernel/debug/tracing/current_tracer
367 cat /sys/kernel/debug/tracing/trace_pipe 367 cat /sys/kernel/debug/tracing/trace_pipe
368 368
369 If unsure, say N. 369 If unsure, say N.
370 370
371 config KPROBE_EVENT 371 config KPROBE_EVENT
372 depends on KPROBES 372 depends on KPROBES
373 depends on HAVE_REGS_AND_STACK_ACCESS_API 373 depends on HAVE_REGS_AND_STACK_ACCESS_API
374 bool "Enable kprobes-based dynamic events" 374 bool "Enable kprobes-based dynamic events"
375 select TRACING 375 select TRACING
376 default y 376 default y
377 help 377 help
378 This allows the user to add tracing events (similar to tracepoints) 378 This allows the user to add tracing events (similar to tracepoints)
379 on the fly via the ftrace interface. See 379 on the fly via the ftrace interface. See
380 Documentation/trace/kprobetrace.txt for more details. 380 Documentation/trace/kprobetrace.txt for more details.
381 381
382 Those events can be inserted wherever kprobes can probe, and record 382 Those events can be inserted wherever kprobes can probe, and record
383 various register and memory values. 383 various register and memory values.
384 384
385 This option is also required by perf-probe subcommand of perf tools. 385 This option is also required by perf-probe subcommand of perf tools.
386 If you want to use perf tools, this option is strongly recommended. 386 If you want to use perf tools, this option is strongly recommended.
387 387
388 config DYNAMIC_FTRACE 388 config DYNAMIC_FTRACE
389 bool "enable/disable ftrace tracepoints dynamically" 389 bool "enable/disable ftrace tracepoints dynamically"
390 depends on FUNCTION_TRACER 390 depends on FUNCTION_TRACER
391 depends on HAVE_DYNAMIC_FTRACE 391 depends on HAVE_DYNAMIC_FTRACE
392 default y 392 default y
393 help 393 help
394 This option will modify all the calls to ftrace dynamically 394 This option will modify all the calls to ftrace dynamically
395 (will patch them out of the binary image and replace them 395 (will patch them out of the binary image and replace them
396 with a No-Op instruction) as they are called. A table is 396 with a No-Op instruction) as they are called. A table is
397 created to dynamically enable them again. 397 created to dynamically enable them again.
398 398
399 This way a CONFIG_FUNCTION_TRACER kernel is slightly larger, but 399 This way a CONFIG_FUNCTION_TRACER kernel is slightly larger, but
400 otherwise has native performance as long as no tracing is active. 400 otherwise has native performance as long as no tracing is active.
401 401
402 The changes to the code are done by a kernel thread that 402 The changes to the code are done by a kernel thread that
403 wakes up once a second and checks to see if any ftrace calls 403 wakes up once a second and checks to see if any ftrace calls
404 were made. If so, it runs stop_machine (stops all CPUS) 404 were made. If so, it runs stop_machine (stops all CPUS)
405 and modifies the code to jump over the call to ftrace. 405 and modifies the code to jump over the call to ftrace.
406 406
407 config FUNCTION_PROFILER 407 config FUNCTION_PROFILER
408 bool "Kernel function profiler" 408 bool "Kernel function profiler"
409 depends on FUNCTION_TRACER 409 depends on FUNCTION_TRACER
410 default n 410 default n
411 help 411 help
412 This option enables the kernel function profiler. A file is created 412 This option enables the kernel function profiler. A file is created
413 in debugfs called function_profile_enabled which defaults to zero. 413 in debugfs called function_profile_enabled which defaults to zero.
414 When a 1 is echoed into this file profiling begins, and when a 414 When a 1 is echoed into this file profiling begins, and when a
415 zero is entered, profiling stops. A "functions" file is created in 415 zero is entered, profiling stops. A "functions" file is created in
416 the trace_stats directory; this file shows the list of functions that 416 the trace_stats directory; this file shows the list of functions that
417 have been hit and their counters. 417 have been hit and their counters.
418 418
419 If in doubt, say N. 419 If in doubt, say N.
420 420
421 config FTRACE_MCOUNT_RECORD 421 config FTRACE_MCOUNT_RECORD
422 def_bool y 422 def_bool y
423 depends on DYNAMIC_FTRACE 423 depends on DYNAMIC_FTRACE
424 depends on HAVE_FTRACE_MCOUNT_RECORD 424 depends on HAVE_FTRACE_MCOUNT_RECORD
425 425
426 config FTRACE_SELFTEST 426 config FTRACE_SELFTEST
427 bool 427 bool
428 428
429 config FTRACE_STARTUP_TEST 429 config FTRACE_STARTUP_TEST
430 bool "Perform a startup test on ftrace" 430 bool "Perform a startup test on ftrace"
431 depends on GENERIC_TRACER 431 depends on GENERIC_TRACER
432 select FTRACE_SELFTEST 432 select FTRACE_SELFTEST
433 help 433 help
434 This option performs a series of startup tests on ftrace. On bootup 434 This option performs a series of startup tests on ftrace. On bootup
435 a series of tests are made to verify that the tracer is 435 a series of tests are made to verify that the tracer is
436 functioning properly. It will do tests on all the configured 436 functioning properly. It will do tests on all the configured
437 tracers of ftrace. 437 tracers of ftrace.
438 438
439 config EVENT_TRACE_TEST_SYSCALLS 439 config EVENT_TRACE_TEST_SYSCALLS
440 bool "Run selftest on syscall events" 440 bool "Run selftest on syscall events"
441 depends on FTRACE_STARTUP_TEST 441 depends on FTRACE_STARTUP_TEST
442 help 442 help
443 This option will also enable testing every syscall event. 443 This option will also enable testing every syscall event.
444 It only enables the event and disables it and runs various loads 444 It only enables the event and disables it and runs various loads
445 with the event enabled. This adds a bit more time for kernel boot 445 with the event enabled. This adds a bit more time for kernel boot
446 up since it runs this on every system call defined. 446 up since it runs this on every system call defined.
447 447
448 TBD - enable a way to actually call the syscalls as we test their 448 TBD - enable a way to actually call the syscalls as we test their
449 events 449 events
450 450
451 config MMIOTRACE 451 config MMIOTRACE
452 bool "Memory mapped IO tracing" 452 bool "Memory mapped IO tracing"
453 depends on HAVE_MMIOTRACE_SUPPORT && PCI 453 depends on HAVE_MMIOTRACE_SUPPORT && PCI
454 select GENERIC_TRACER 454 select GENERIC_TRACER
455 help 455 help
456 Mmiotrace traces Memory Mapped I/O access and is meant for 456 Mmiotrace traces Memory Mapped I/O access and is meant for
457 debugging and reverse engineering. It is called from the ioremap 457 debugging and reverse engineering. It is called from the ioremap
458 implementation and works via page faults. Tracing is disabled by 458 implementation and works via page faults. Tracing is disabled by
459 default and can be enabled at run-time. 459 default and can be enabled at run-time.
460 460
461 See Documentation/trace/mmiotrace.txt. 461 See Documentation/trace/mmiotrace.txt.
462 If you are not helping to develop drivers, say N. 462 If you are not helping to develop drivers, say N.
463 463
464 config MMIOTRACE_TEST 464 config MMIOTRACE_TEST
465 tristate "Test module for mmiotrace" 465 tristate "Test module for mmiotrace"
466 depends on MMIOTRACE && m 466 depends on MMIOTRACE && m
467 help 467 help
468 This is a dumb module for testing mmiotrace. It is very dangerous 468 This is a dumb module for testing mmiotrace. It is very dangerous
469 as it will write garbage to IO memory starting at a given address. 469 as it will write garbage to IO memory starting at a given address.
470 However, it should be safe to use on e.g. unused portion of VRAM. 470 However, it should be safe to use on e.g. unused portion of VRAM.
471 471
472 Say N, unless you absolutely know what you are doing. 472 Say N, unless you absolutely know what you are doing.
473 473
474 config RING_BUFFER_BENCHMARK 474 config RING_BUFFER_BENCHMARK
475 tristate "Ring buffer benchmark stress tester" 475 tristate "Ring buffer benchmark stress tester"
476 depends on RING_BUFFER 476 depends on RING_BUFFER
477 help 477 help
478 This option creates a test to stress the ring buffer and benchmark it. 478 This option creates a test to stress the ring buffer and benchmark it.
479 It creates its own ring buffer such that it will not interfere with 479 It creates its own ring buffer such that it will not interfere with
480 any other users of the ring buffer (such as ftrace). It then creates 480 any other users of the ring buffer (such as ftrace). It then creates
481 a producer and consumer that will run for 10 seconds and sleep for 481 a producer and consumer that will run for 10 seconds and sleep for
482 10 seconds. Each interval it will print out the number of events 482 10 seconds. Each interval it will print out the number of events
483 it recorded and give a rough estimate of how long each iteration took. 483 it recorded and give a rough estimate of how long each iteration took.
484 484
485 It does not disable interrupts or raise its priority, so it may be 485 It does not disable interrupts or raise its priority, so it may be
486 affected by processes that are running. 486 affected by processes that are running.
487 487
488 If unsure, say N. 488 If unsure, say N.
489 489
490 endif # FTRACE 490 endif # FTRACE
491 491
492 endif # TRACING_SUPPORT 492 endif # TRACING_SUPPORT
493 493
494 494
1 ifeq ("$(origin O)", "command line") 1 ifeq ("$(origin O)", "command line")
2 OUTPUT := $(O)/ 2 OUTPUT := $(O)/
3 endif 3 endif
4 4
5 # The default target of this Makefile is... 5 # The default target of this Makefile is...
6 all: 6 all:
7 7
8 include config/utilities.mak 8 include config/utilities.mak
9 9
10 ifneq ($(OUTPUT),) 10 ifneq ($(OUTPUT),)
11 # check that the output directory actually exists 11 # check that the output directory actually exists
12 OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd) 12 OUTDIR := $(shell cd $(OUTPUT) && /bin/pwd)
13 $(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist)) 13 $(if $(OUTDIR),, $(error output directory "$(OUTPUT)" does not exist))
14 endif 14 endif
15 15
16 # Define V to have a more verbose compile. 16 # Define V to have a more verbose compile.
17 # 17 #
18 # Define PYTHON to point to the python binary if the default 18 # Define PYTHON to point to the python binary if the default
19 # `python' is not correct; for example: PYTHON=python2 19 # `python' is not correct; for example: PYTHON=python2
20 # 20 #
21 # Define PYTHON_CONFIG to point to the python-config binary if 21 # Define PYTHON_CONFIG to point to the python-config binary if
22 # the default `$(PYTHON)-config' is not correct. 22 # the default `$(PYTHON)-config' is not correct.
23 # 23 #
24 # Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8 24 # Define ASCIIDOC8 if you want to format documentation with AsciiDoc 8
25 # 25 #
26 # Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72. 26 # Define DOCBOOK_XSL_172 if you want to format man pages with DocBook XSL v1.72.
27 # 27 #
28 # Define LDFLAGS=-static to build a static binary. 28 # Define LDFLAGS=-static to build a static binary.
29 # 29 #
30 # Define EXTRA_CFLAGS=-m64 or EXTRA_CFLAGS=-m32 as appropriate for cross-builds. 30 # Define EXTRA_CFLAGS=-m64 or EXTRA_CFLAGS=-m32 as appropriate for cross-builds.
31 # 31 #
32 # Define NO_DWARF if you do not want debug-info analysis feature at all. 32 # Define NO_DWARF if you do not want debug-info analysis feature at all.
33 33
34 $(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE 34 $(OUTPUT)PERF-VERSION-FILE: .FORCE-PERF-VERSION-FILE
35 @$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT) 35 @$(SHELL_PATH) util/PERF-VERSION-GEN $(OUTPUT)
36 -include $(OUTPUT)PERF-VERSION-FILE 36 -include $(OUTPUT)PERF-VERSION-FILE
37 37
38 uname_M := $(shell uname -m 2>/dev/null || echo not) 38 uname_M := $(shell uname -m 2>/dev/null || echo not)
39 39
40 ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \ 40 ARCH ?= $(shell echo $(uname_M) | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
41 -e s/arm.*/arm/ -e s/sa110/arm/ \ 41 -e s/arm.*/arm/ -e s/sa110/arm/ \
42 -e s/s390x/s390/ -e s/parisc64/parisc/ \ 42 -e s/s390x/s390/ -e s/parisc64/parisc/ \
43 -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \ 43 -e s/ppc.*/powerpc/ -e s/mips.*/mips/ \
44 -e s/sh[234].*/sh/ ) 44 -e s/sh[234].*/sh/ )
45 45
46 CC = $(CROSS_COMPILE)gcc 46 CC = $(CROSS_COMPILE)gcc
47 AR = $(CROSS_COMPILE)ar 47 AR = $(CROSS_COMPILE)ar
48 48
49 # Additional ARCH settings for x86 49 # Additional ARCH settings for x86
50 ifeq ($(ARCH),i386) 50 ifeq ($(ARCH),i386)
51 ARCH := x86 51 ARCH := x86
52 endif 52 endif
53 ifeq ($(ARCH),x86_64) 53 ifeq ($(ARCH),x86_64)
54 ARCH := x86 54 ARCH := x86
55 IS_X86_64 := 0 55 IS_X86_64 := 0
56 ifeq (, $(findstring m32,$(EXTRA_CFLAGS))) 56 ifeq (, $(findstring m32,$(EXTRA_CFLAGS)))
57 IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -xc - | tail -n 1) 57 IS_X86_64 := $(shell echo __x86_64__ | ${CC} -E -xc - | tail -n 1)
58 endif 58 endif
59 ifeq (${IS_X86_64}, 1) 59 ifeq (${IS_X86_64}, 1)
60 RAW_ARCH := x86_64 60 RAW_ARCH := x86_64
61 ARCH_CFLAGS := -DARCH_X86_64 61 ARCH_CFLAGS := -DARCH_X86_64
62 ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S 62 ARCH_INCLUDE = ../../arch/x86/lib/memcpy_64.S
63 endif 63 endif
64 endif 64 endif
65 65
66 # 66 #
67 # Include saner warnings here, which can catch bugs: 67 # Include saner warnings here, which can catch bugs:
68 # 68 #
69 69
70 EXTRA_WARNINGS := -Wformat 70 EXTRA_WARNINGS := -Wformat
71 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wformat-security 71 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wformat-security
72 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wformat-y2k 72 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wformat-y2k
73 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wshadow 73 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wshadow
74 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Winit-self 74 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Winit-self
75 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wpacked 75 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wpacked
76 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wredundant-decls 76 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wredundant-decls
77 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wstrict-aliasing=3 77 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wstrict-aliasing=3
78 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wswitch-default 78 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wswitch-default
79 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wswitch-enum 79 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wswitch-enum
80 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wno-system-headers 80 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wno-system-headers
81 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wundef 81 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wundef
82 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wwrite-strings 82 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wwrite-strings
83 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wbad-function-cast 83 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wbad-function-cast
84 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wmissing-declarations 84 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wmissing-declarations
85 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wmissing-prototypes 85 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wmissing-prototypes
86 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wnested-externs 86 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wnested-externs
87 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wold-style-definition 87 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wold-style-definition
88 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wstrict-prototypes 88 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wstrict-prototypes
89 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wdeclaration-after-statement 89 EXTRA_WARNINGS := $(EXTRA_WARNINGS) -Wdeclaration-after-statement
90 90
91 ifeq ("$(origin DEBUG)", "command line") 91 ifeq ("$(origin DEBUG)", "command line")
92 PERF_DEBUG = $(DEBUG) 92 PERF_DEBUG = $(DEBUG)
93 endif 93 endif
94 ifndef PERF_DEBUG 94 ifndef PERF_DEBUG
95 CFLAGS_OPTIMIZE = -O6 95 CFLAGS_OPTIMIZE = -O6
96 endif 96 endif
97 97
98 CFLAGS = -fno-omit-frame-pointer -ggdb3 -Wall -Wextra -std=gnu99 -Werror $(CFLAGS_OPTIMIZE) -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) 98 CFLAGS = -fno-omit-frame-pointer -ggdb3 -Wall -Wextra -std=gnu99 -Werror $(CFLAGS_OPTIMIZE) -D_FORTIFY_SOURCE=2 $(EXTRA_WARNINGS) $(EXTRA_CFLAGS)
99 EXTLIBS = -lpthread -lrt -lelf -lm 99 EXTLIBS = -lpthread -lrt -lelf -lm
100 ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 100 ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
101 ALL_LDFLAGS = $(LDFLAGS) 101 ALL_LDFLAGS = $(LDFLAGS)
102 STRIP ?= strip 102 STRIP ?= strip
103 103
104 # Among the variables below, these: 104 # Among the variables below, these:
105 # perfexecdir 105 # perfexecdir
106 # template_dir 106 # template_dir
107 # mandir 107 # mandir
108 # infodir 108 # infodir
109 # htmldir 109 # htmldir
110 # ETC_PERFCONFIG (but not sysconfdir) 110 # ETC_PERFCONFIG (but not sysconfdir)
111 # can be specified as a relative path some/where/else; 111 # can be specified as a relative path some/where/else;
112 # this is interpreted as relative to $(prefix) and "perf" at 112 # this is interpreted as relative to $(prefix) and "perf" at
113 # runtime figures out where they are based on the path to the executable. 113 # runtime figures out where they are based on the path to the executable.
114 # This can help installing the suite in a relocatable way. 114 # This can help installing the suite in a relocatable way.
115 115
116 # Make the path relative to DESTDIR, not to prefix 116 # Make the path relative to DESTDIR, not to prefix
117 ifndef DESTDIR 117 ifndef DESTDIR
118 prefix = $(HOME) 118 prefix = $(HOME)
119 endif 119 endif
120 bindir_relative = bin 120 bindir_relative = bin
121 bindir = $(prefix)/$(bindir_relative) 121 bindir = $(prefix)/$(bindir_relative)
122 mandir = share/man 122 mandir = share/man
123 infodir = share/info 123 infodir = share/info
124 perfexecdir = libexec/perf-core 124 perfexecdir = libexec/perf-core
125 sharedir = $(prefix)/share 125 sharedir = $(prefix)/share
126 template_dir = share/perf-core/templates 126 template_dir = share/perf-core/templates
127 htmldir = share/doc/perf-doc 127 htmldir = share/doc/perf-doc
128 ifeq ($(prefix),/usr) 128 ifeq ($(prefix),/usr)
129 sysconfdir = /etc 129 sysconfdir = /etc
130 ETC_PERFCONFIG = $(sysconfdir)/perfconfig 130 ETC_PERFCONFIG = $(sysconfdir)/perfconfig
131 else 131 else
132 sysconfdir = $(prefix)/etc 132 sysconfdir = $(prefix)/etc
133 ETC_PERFCONFIG = etc/perfconfig 133 ETC_PERFCONFIG = etc/perfconfig
134 endif 134 endif
135 lib = lib 135 lib = lib
136 136
137 export prefix bindir sharedir sysconfdir 137 export prefix bindir sharedir sysconfdir
138 138
139 RM = rm -f 139 RM = rm -f
140 MKDIR = mkdir 140 MKDIR = mkdir
141 FIND = find 141 FIND = find
142 INSTALL = install 142 INSTALL = install
143 143
144 # sparse is architecture-neutral, which means that we need to tell it 144 # sparse is architecture-neutral, which means that we need to tell it
145 # explicitly what architecture to check for. Fix this up for yours.. 145 # explicitly what architecture to check for. Fix this up for yours..
146 SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__ 146 SPARSE_FLAGS = -D__BIG_ENDIAN__ -D__powerpc__
147 147
148 -include config/feature-tests.mak 148 -include config/feature-tests.mak
149 149
150 ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -fstack-protector-all),y) 150 ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -fstack-protector-all),y)
151 CFLAGS := $(CFLAGS) -fstack-protector-all 151 CFLAGS := $(CFLAGS) -fstack-protector-all
152 endif 152 endif
153 153
154 ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -Wstack-protector),y) 154 ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -Wstack-protector),y)
155 CFLAGS := $(CFLAGS) -Wstack-protector 155 CFLAGS := $(CFLAGS) -Wstack-protector
156 endif 156 endif
157 157
158 ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -Wvolatile-register-var),y) 158 ifeq ($(call try-cc,$(SOURCE_HELLO),-Werror -Wvolatile-register-var),y)
159 CFLAGS := $(CFLAGS) -Wvolatile-register-var 159 CFLAGS := $(CFLAGS) -Wvolatile-register-var
160 endif 160 endif
161 161
162 ### --- END CONFIGURATION SECTION --- 162 ### --- END CONFIGURATION SECTION ---
163 163
164 # Those must not be GNU-specific; they are shared with perl/ which may 164 # Those must not be GNU-specific; they are shared with perl/ which may
165 # be built by a different compiler. (Note that this is an artifact now 165 # be built by a different compiler. (Note that this is an artifact now
166 # but it still might be nice to keep that distinction.) 166 # but it still might be nice to keep that distinction.)
167 BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include 167 BASIC_CFLAGS = -Iutil/include -Iarch/$(ARCH)/include
168 BASIC_LDFLAGS = 168 BASIC_LDFLAGS =
169 169
170 # Guard against environment variables 170 # Guard against environment variables
171 BUILTIN_OBJS = 171 BUILTIN_OBJS =
172 LIB_H = 172 LIB_H =
173 LIB_OBJS = 173 LIB_OBJS =
174 PYRF_OBJS = 174 PYRF_OBJS =
175 SCRIPT_SH = 175 SCRIPT_SH =
176 176
177 SCRIPT_SH += perf-archive.sh 177 SCRIPT_SH += perf-archive.sh
178 178
179 grep-libs = $(filter -l%,$(1)) 179 grep-libs = $(filter -l%,$(1))
180 strip-libs = $(filter-out -l%,$(1)) 180 strip-libs = $(filter-out -l%,$(1))
181 181
182 $(OUTPUT)python/perf.so: $(PYRF_OBJS) 182 $(OUTPUT)python/perf.so: $(PYRF_OBJS)
183 $(QUIET_GEN)CFLAGS='$(BASIC_CFLAGS)' $(PYTHON_WORD) util/setup.py \ 183 $(QUIET_GEN)CFLAGS='$(BASIC_CFLAGS)' $(PYTHON_WORD) util/setup.py \
184 --quiet build_ext \ 184 --quiet build_ext; \
185 --build-lib='$(OUTPUT)python' \ 185 mkdir -p $(OUTPUT)python && \
186 --build-temp='$(OUTPUT)python/temp' 186 cp $(PYTHON_EXTBUILD_LIB)perf.so $(OUTPUT)python/
187 # 187 #
188 # No Perl scripts right now: 188 # No Perl scripts right now:
189 # 189 #
190 190
191 SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH)) 191 SCRIPTS = $(patsubst %.sh,%,$(SCRIPT_SH))
192 192
193 # 193 #
194 # Single 'perf' binary right now: 194 # Single 'perf' binary right now:
195 # 195 #
196 PROGRAMS += $(OUTPUT)perf 196 PROGRAMS += $(OUTPUT)perf
197 197
198 LANG_BINDINGS = 198 LANG_BINDINGS =
199 199
200 # what 'all' will build and 'install' will install, in perfexecdir 200 # what 'all' will build and 'install' will install, in perfexecdir
201 ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS) 201 ALL_PROGRAMS = $(PROGRAMS) $(SCRIPTS)
202 202
203 # what 'all' will build but not install in perfexecdir 203 # what 'all' will build but not install in perfexecdir
204 OTHER_PROGRAMS = $(OUTPUT)perf 204 OTHER_PROGRAMS = $(OUTPUT)perf
205 205
206 # Set paths to tools early so that they can be used for version tests. 206 # Set paths to tools early so that they can be used for version tests.
207 ifndef SHELL_PATH 207 ifndef SHELL_PATH
208 SHELL_PATH = /bin/sh 208 SHELL_PATH = /bin/sh
209 endif 209 endif
210 ifndef PERL_PATH 210 ifndef PERL_PATH
211 PERL_PATH = /usr/bin/perl 211 PERL_PATH = /usr/bin/perl
212 endif 212 endif
213 213
214 export PERL_PATH 214 export PERL_PATH
215 215
216 LIB_FILE=$(OUTPUT)libperf.a 216 LIB_FILE=$(OUTPUT)libperf.a
217 217
218 LIB_H += ../../include/linux/perf_event.h 218 LIB_H += ../../include/linux/perf_event.h
219 LIB_H += ../../include/linux/rbtree.h 219 LIB_H += ../../include/linux/rbtree.h
220 LIB_H += ../../include/linux/list.h 220 LIB_H += ../../include/linux/list.h
221 LIB_H += ../../include/linux/const.h 221 LIB_H += ../../include/linux/const.h
222 LIB_H += ../../include/linux/hash.h 222 LIB_H += ../../include/linux/hash.h
223 LIB_H += ../../include/linux/stringify.h 223 LIB_H += ../../include/linux/stringify.h
224 LIB_H += util/include/linux/bitmap.h 224 LIB_H += util/include/linux/bitmap.h
225 LIB_H += util/include/linux/bitops.h 225 LIB_H += util/include/linux/bitops.h
226 LIB_H += util/include/linux/compiler.h 226 LIB_H += util/include/linux/compiler.h
227 LIB_H += util/include/linux/const.h 227 LIB_H += util/include/linux/const.h
228 LIB_H += util/include/linux/ctype.h 228 LIB_H += util/include/linux/ctype.h
229 LIB_H += util/include/linux/kernel.h 229 LIB_H += util/include/linux/kernel.h
230 LIB_H += util/include/linux/list.h 230 LIB_H += util/include/linux/list.h
231 LIB_H += util/include/linux/module.h 231 LIB_H += util/include/linux/module.h
232 LIB_H += util/include/linux/poison.h 232 LIB_H += util/include/linux/poison.h
233 LIB_H += util/include/linux/prefetch.h 233 LIB_H += util/include/linux/prefetch.h
234 LIB_H += util/include/linux/rbtree.h 234 LIB_H += util/include/linux/rbtree.h
235 LIB_H += util/include/linux/string.h 235 LIB_H += util/include/linux/string.h
236 LIB_H += util/include/linux/types.h 236 LIB_H += util/include/linux/types.h
237 LIB_H += util/include/linux/linkage.h 237 LIB_H += util/include/linux/linkage.h
238 LIB_H += util/include/asm/asm-offsets.h 238 LIB_H += util/include/asm/asm-offsets.h
239 LIB_H += util/include/asm/bug.h 239 LIB_H += util/include/asm/bug.h
240 LIB_H += util/include/asm/byteorder.h 240 LIB_H += util/include/asm/byteorder.h
241 LIB_H += util/include/asm/hweight.h 241 LIB_H += util/include/asm/hweight.h
242 LIB_H += util/include/asm/swab.h 242 LIB_H += util/include/asm/swab.h
243 LIB_H += util/include/asm/system.h 243 LIB_H += util/include/asm/system.h
244 LIB_H += util/include/asm/uaccess.h 244 LIB_H += util/include/asm/uaccess.h
245 LIB_H += util/include/dwarf-regs.h 245 LIB_H += util/include/dwarf-regs.h
246 LIB_H += util/include/asm/dwarf2.h 246 LIB_H += util/include/asm/dwarf2.h
247 LIB_H += util/include/asm/cpufeature.h 247 LIB_H += util/include/asm/cpufeature.h
248 LIB_H += perf.h 248 LIB_H += perf.h
249 LIB_H += util/annotate.h 249 LIB_H += util/annotate.h
250 LIB_H += util/cache.h 250 LIB_H += util/cache.h
251 LIB_H += util/callchain.h 251 LIB_H += util/callchain.h
252 LIB_H += util/build-id.h 252 LIB_H += util/build-id.h
253 LIB_H += util/debug.h 253 LIB_H += util/debug.h
254 LIB_H += util/debugfs.h 254 LIB_H += util/debugfs.h
255 LIB_H += util/event.h 255 LIB_H += util/event.h
256 LIB_H += util/evsel.h 256 LIB_H += util/evsel.h
257 LIB_H += util/evlist.h 257 LIB_H += util/evlist.h
258 LIB_H += util/exec_cmd.h 258 LIB_H += util/exec_cmd.h
259 LIB_H += util/types.h 259 LIB_H += util/types.h
260 LIB_H += util/levenshtein.h 260 LIB_H += util/levenshtein.h
261 LIB_H += util/map.h 261 LIB_H += util/map.h
262 LIB_H += util/parse-options.h 262 LIB_H += util/parse-options.h
263 LIB_H += util/parse-events.h 263 LIB_H += util/parse-events.h
264 LIB_H += util/quote.h 264 LIB_H += util/quote.h
265 LIB_H += util/util.h 265 LIB_H += util/util.h
266 LIB_H += util/xyarray.h 266 LIB_H += util/xyarray.h
267 LIB_H += util/header.h 267 LIB_H += util/header.h
268 LIB_H += util/help.h 268 LIB_H += util/help.h
269 LIB_H += util/session.h 269 LIB_H += util/session.h
270 LIB_H += util/strbuf.h 270 LIB_H += util/strbuf.h
271 LIB_H += util/strlist.h 271 LIB_H += util/strlist.h
272 LIB_H += util/strfilter.h 272 LIB_H += util/strfilter.h
273 LIB_H += util/svghelper.h 273 LIB_H += util/svghelper.h
274 LIB_H += util/run-command.h 274 LIB_H += util/run-command.h
275 LIB_H += util/sigchain.h 275 LIB_H += util/sigchain.h
276 LIB_H += util/symbol.h 276 LIB_H += util/symbol.h
277 LIB_H += util/color.h 277 LIB_H += util/color.h
278 LIB_H += util/values.h 278 LIB_H += util/values.h
279 LIB_H += util/sort.h 279 LIB_H += util/sort.h
280 LIB_H += util/hist.h 280 LIB_H += util/hist.h
281 LIB_H += util/thread.h 281 LIB_H += util/thread.h
282 LIB_H += util/thread_map.h 282 LIB_H += util/thread_map.h
283 LIB_H += util/trace-event.h 283 LIB_H += util/trace-event.h
284 LIB_H += util/probe-finder.h 284 LIB_H += util/probe-finder.h
285 LIB_H += util/dwarf-aux.h 285 LIB_H += util/dwarf-aux.h
286 LIB_H += util/probe-event.h 286 LIB_H += util/probe-event.h
287 LIB_H += util/pstack.h 287 LIB_H += util/pstack.h
288 LIB_H += util/cpumap.h 288 LIB_H += util/cpumap.h
289 LIB_H += util/top.h 289 LIB_H += util/top.h
290 LIB_H += $(ARCH_INCLUDE) 290 LIB_H += $(ARCH_INCLUDE)
291 LIB_H += util/cgroup.h 291 LIB_H += util/cgroup.h
292 292
293 LIB_OBJS += $(OUTPUT)util/abspath.o 293 LIB_OBJS += $(OUTPUT)util/abspath.o
294 LIB_OBJS += $(OUTPUT)util/alias.o 294 LIB_OBJS += $(OUTPUT)util/alias.o
295 LIB_OBJS += $(OUTPUT)util/annotate.o 295 LIB_OBJS += $(OUTPUT)util/annotate.o
296 LIB_OBJS += $(OUTPUT)util/build-id.o 296 LIB_OBJS += $(OUTPUT)util/build-id.o
297 LIB_OBJS += $(OUTPUT)util/config.o 297 LIB_OBJS += $(OUTPUT)util/config.o
298 LIB_OBJS += $(OUTPUT)util/ctype.o 298 LIB_OBJS += $(OUTPUT)util/ctype.o
299 LIB_OBJS += $(OUTPUT)util/debugfs.o 299 LIB_OBJS += $(OUTPUT)util/debugfs.o
300 LIB_OBJS += $(OUTPUT)util/environment.o 300 LIB_OBJS += $(OUTPUT)util/environment.o
301 LIB_OBJS += $(OUTPUT)util/event.o 301 LIB_OBJS += $(OUTPUT)util/event.o
302 LIB_OBJS += $(OUTPUT)util/evlist.o 302 LIB_OBJS += $(OUTPUT)util/evlist.o
303 LIB_OBJS += $(OUTPUT)util/evsel.o 303 LIB_OBJS += $(OUTPUT)util/evsel.o
304 LIB_OBJS += $(OUTPUT)util/exec_cmd.o 304 LIB_OBJS += $(OUTPUT)util/exec_cmd.o
305 LIB_OBJS += $(OUTPUT)util/help.o 305 LIB_OBJS += $(OUTPUT)util/help.o
306 LIB_OBJS += $(OUTPUT)util/levenshtein.o 306 LIB_OBJS += $(OUTPUT)util/levenshtein.o
307 LIB_OBJS += $(OUTPUT)util/parse-options.o 307 LIB_OBJS += $(OUTPUT)util/parse-options.o
308 LIB_OBJS += $(OUTPUT)util/parse-events.o 308 LIB_OBJS += $(OUTPUT)util/parse-events.o
309 LIB_OBJS += $(OUTPUT)util/path.o 309 LIB_OBJS += $(OUTPUT)util/path.o
310 LIB_OBJS += $(OUTPUT)util/rbtree.o 310 LIB_OBJS += $(OUTPUT)util/rbtree.o
311 LIB_OBJS += $(OUTPUT)util/bitmap.o 311 LIB_OBJS += $(OUTPUT)util/bitmap.o
312 LIB_OBJS += $(OUTPUT)util/hweight.o 312 LIB_OBJS += $(OUTPUT)util/hweight.o
313 LIB_OBJS += $(OUTPUT)util/run-command.o 313 LIB_OBJS += $(OUTPUT)util/run-command.o
314 LIB_OBJS += $(OUTPUT)util/quote.o 314 LIB_OBJS += $(OUTPUT)util/quote.o
315 LIB_OBJS += $(OUTPUT)util/strbuf.o 315 LIB_OBJS += $(OUTPUT)util/strbuf.o
316 LIB_OBJS += $(OUTPUT)util/string.o 316 LIB_OBJS += $(OUTPUT)util/string.o
317 LIB_OBJS += $(OUTPUT)util/strlist.o 317 LIB_OBJS += $(OUTPUT)util/strlist.o
318 LIB_OBJS += $(OUTPUT)util/strfilter.o 318 LIB_OBJS += $(OUTPUT)util/strfilter.o
319 LIB_OBJS += $(OUTPUT)util/top.o 319 LIB_OBJS += $(OUTPUT)util/top.o
320 LIB_OBJS += $(OUTPUT)util/usage.o 320 LIB_OBJS += $(OUTPUT)util/usage.o
321 LIB_OBJS += $(OUTPUT)util/wrapper.o 321 LIB_OBJS += $(OUTPUT)util/wrapper.o
322 LIB_OBJS += $(OUTPUT)util/sigchain.o 322 LIB_OBJS += $(OUTPUT)util/sigchain.o
323 LIB_OBJS += $(OUTPUT)util/symbol.o 323 LIB_OBJS += $(OUTPUT)util/symbol.o
324 LIB_OBJS += $(OUTPUT)util/color.o 324 LIB_OBJS += $(OUTPUT)util/color.o
325 LIB_OBJS += $(OUTPUT)util/pager.o 325 LIB_OBJS += $(OUTPUT)util/pager.o
326 LIB_OBJS += $(OUTPUT)util/header.o 326 LIB_OBJS += $(OUTPUT)util/header.o
327 LIB_OBJS += $(OUTPUT)util/callchain.o 327 LIB_OBJS += $(OUTPUT)util/callchain.o
328 LIB_OBJS += $(OUTPUT)util/values.o 328 LIB_OBJS += $(OUTPUT)util/values.o
329 LIB_OBJS += $(OUTPUT)util/debug.o 329 LIB_OBJS += $(OUTPUT)util/debug.o
330 LIB_OBJS += $(OUTPUT)util/map.o 330 LIB_OBJS += $(OUTPUT)util/map.o
331 LIB_OBJS += $(OUTPUT)util/pstack.o 331 LIB_OBJS += $(OUTPUT)util/pstack.o
332 LIB_OBJS += $(OUTPUT)util/session.o 332 LIB_OBJS += $(OUTPUT)util/session.o
333 LIB_OBJS += $(OUTPUT)util/thread.o 333 LIB_OBJS += $(OUTPUT)util/thread.o
334 LIB_OBJS += $(OUTPUT)util/thread_map.o 334 LIB_OBJS += $(OUTPUT)util/thread_map.o
335 LIB_OBJS += $(OUTPUT)util/trace-event-parse.o 335 LIB_OBJS += $(OUTPUT)util/trace-event-parse.o
336 LIB_OBJS += $(OUTPUT)util/trace-event-read.o 336 LIB_OBJS += $(OUTPUT)util/trace-event-read.o
337 LIB_OBJS += $(OUTPUT)util/trace-event-info.o 337 LIB_OBJS += $(OUTPUT)util/trace-event-info.o
338 LIB_OBJS += $(OUTPUT)util/trace-event-scripting.o 338 LIB_OBJS += $(OUTPUT)util/trace-event-scripting.o
339 LIB_OBJS += $(OUTPUT)util/svghelper.o 339 LIB_OBJS += $(OUTPUT)util/svghelper.o
340 LIB_OBJS += $(OUTPUT)util/sort.o 340 LIB_OBJS += $(OUTPUT)util/sort.o
341 LIB_OBJS += $(OUTPUT)util/hist.o 341 LIB_OBJS += $(OUTPUT)util/hist.o
342 LIB_OBJS += $(OUTPUT)util/probe-event.o 342 LIB_OBJS += $(OUTPUT)util/probe-event.o
343 LIB_OBJS += $(OUTPUT)util/util.o 343 LIB_OBJS += $(OUTPUT)util/util.o
344 LIB_OBJS += $(OUTPUT)util/xyarray.o 344 LIB_OBJS += $(OUTPUT)util/xyarray.o
345 LIB_OBJS += $(OUTPUT)util/cpumap.o 345 LIB_OBJS += $(OUTPUT)util/cpumap.o
346 LIB_OBJS += $(OUTPUT)util/cgroup.o 346 LIB_OBJS += $(OUTPUT)util/cgroup.o
347 347
348 BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o 348 BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o
349 349
350 BUILTIN_OBJS += $(OUTPUT)builtin-bench.o 350 BUILTIN_OBJS += $(OUTPUT)builtin-bench.o
351 351
352 # Benchmark modules 352 # Benchmark modules
353 BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o 353 BUILTIN_OBJS += $(OUTPUT)bench/sched-messaging.o
354 BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o 354 BUILTIN_OBJS += $(OUTPUT)bench/sched-pipe.o
355 ifeq ($(RAW_ARCH),x86_64) 355 ifeq ($(RAW_ARCH),x86_64)
356 BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy-x86-64-asm.o 356 BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy-x86-64-asm.o
357 endif 357 endif
358 BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o 358 BUILTIN_OBJS += $(OUTPUT)bench/mem-memcpy.o
359 359
360 BUILTIN_OBJS += $(OUTPUT)builtin-diff.o 360 BUILTIN_OBJS += $(OUTPUT)builtin-diff.o
361 BUILTIN_OBJS += $(OUTPUT)builtin-evlist.o 361 BUILTIN_OBJS += $(OUTPUT)builtin-evlist.o
362 BUILTIN_OBJS += $(OUTPUT)builtin-help.o 362 BUILTIN_OBJS += $(OUTPUT)builtin-help.o
363 BUILTIN_OBJS += $(OUTPUT)builtin-sched.o 363 BUILTIN_OBJS += $(OUTPUT)builtin-sched.o
364 BUILTIN_OBJS += $(OUTPUT)builtin-buildid-list.o 364 BUILTIN_OBJS += $(OUTPUT)builtin-buildid-list.o
365 BUILTIN_OBJS += $(OUTPUT)builtin-buildid-cache.o 365 BUILTIN_OBJS += $(OUTPUT)builtin-buildid-cache.o
366 BUILTIN_OBJS += $(OUTPUT)builtin-list.o 366 BUILTIN_OBJS += $(OUTPUT)builtin-list.o
367 BUILTIN_OBJS += $(OUTPUT)builtin-record.o 367 BUILTIN_OBJS += $(OUTPUT)builtin-record.o
368 BUILTIN_OBJS += $(OUTPUT)builtin-report.o 368 BUILTIN_OBJS += $(OUTPUT)builtin-report.o
369 BUILTIN_OBJS += $(OUTPUT)builtin-stat.o 369 BUILTIN_OBJS += $(OUTPUT)builtin-stat.o
370 BUILTIN_OBJS += $(OUTPUT)builtin-timechart.o 370 BUILTIN_OBJS += $(OUTPUT)builtin-timechart.o
371 BUILTIN_OBJS += $(OUTPUT)builtin-top.o 371 BUILTIN_OBJS += $(OUTPUT)builtin-top.o
372 BUILTIN_OBJS += $(OUTPUT)builtin-script.o 372 BUILTIN_OBJS += $(OUTPUT)builtin-script.o
373 BUILTIN_OBJS += $(OUTPUT)builtin-probe.o 373 BUILTIN_OBJS += $(OUTPUT)builtin-probe.o
374 BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o 374 BUILTIN_OBJS += $(OUTPUT)builtin-kmem.o
375 BUILTIN_OBJS += $(OUTPUT)builtin-lock.o 375 BUILTIN_OBJS += $(OUTPUT)builtin-lock.o
376 BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o 376 BUILTIN_OBJS += $(OUTPUT)builtin-kvm.o
377 BUILTIN_OBJS += $(OUTPUT)builtin-test.o 377 BUILTIN_OBJS += $(OUTPUT)builtin-test.o
378 BUILTIN_OBJS += $(OUTPUT)builtin-inject.o 378 BUILTIN_OBJS += $(OUTPUT)builtin-inject.o
379 379
380 PERFLIBS = $(LIB_FILE) 380 PERFLIBS = $(LIB_FILE)
381 381
382 # Files needed for the python binding, perf.so 382 # Files needed for the python binding, perf.so
383 # pyrf is just an internal name needed for all those wrappers. 383 # pyrf is just an internal name needed for all those wrappers.
384 # This has to be in sync with what is in the 'sources' variable in 384 # This has to be in sync with what is in the 'sources' variable in
385 # tools/perf/util/setup.py 385 # tools/perf/util/setup.py
386 386
387 PYRF_OBJS += $(OUTPUT)util/cpumap.o 387 PYRF_OBJS += $(OUTPUT)util/cpumap.o
388 PYRF_OBJS += $(OUTPUT)util/ctype.o 388 PYRF_OBJS += $(OUTPUT)util/ctype.o
389 PYRF_OBJS += $(OUTPUT)util/evlist.o 389 PYRF_OBJS += $(OUTPUT)util/evlist.o
390 PYRF_OBJS += $(OUTPUT)util/evsel.o 390 PYRF_OBJS += $(OUTPUT)util/evsel.o
391 PYRF_OBJS += $(OUTPUT)util/python.o 391 PYRF_OBJS += $(OUTPUT)util/python.o
392 PYRF_OBJS += $(OUTPUT)util/thread_map.o 392 PYRF_OBJS += $(OUTPUT)util/thread_map.o
393 PYRF_OBJS += $(OUTPUT)util/util.o 393 PYRF_OBJS += $(OUTPUT)util/util.o
394 PYRF_OBJS += $(OUTPUT)util/xyarray.o 394 PYRF_OBJS += $(OUTPUT)util/xyarray.o
395 395
396 # 396 #
397 # Platform specific tweaks 397 # Platform specific tweaks
398 # 398 #
399 399
400 # We choose to avoid "if .. else if .. else .. endif endif" 400 # We choose to avoid "if .. else if .. else .. endif endif"
401 # because maintaining the nesting to match is a pain. If 401 # because maintaining the nesting to match is a pain. If
402 # we had "elif" things would have been much nicer... 402 # we had "elif" things would have been much nicer...
403 403
404 -include config.mak.autogen 404 -include config.mak.autogen
405 -include config.mak 405 -include config.mak
406 406
407 ifndef NO_DWARF 407 ifndef NO_DWARF
408 FLAGS_DWARF=$(ALL_CFLAGS) -ldw -lelf $(ALL_LDFLAGS) $(EXTLIBS) 408 FLAGS_DWARF=$(ALL_CFLAGS) -ldw -lelf $(ALL_LDFLAGS) $(EXTLIBS)
409 ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF)),y) 409 ifneq ($(call try-cc,$(SOURCE_DWARF),$(FLAGS_DWARF)),y)
410 msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev); 410 msg := $(warning No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev);
411 NO_DWARF := 1 411 NO_DWARF := 1
412 endif # Dwarf support 412 endif # Dwarf support
413 endif # NO_DWARF 413 endif # NO_DWARF
414 414
415 -include arch/$(ARCH)/Makefile 415 -include arch/$(ARCH)/Makefile
416 416
417 ifneq ($(OUTPUT),) 417 ifneq ($(OUTPUT),)
418 BASIC_CFLAGS += -I$(OUTPUT) 418 BASIC_CFLAGS += -I$(OUTPUT)
419 endif 419 endif
420 420
421 FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) 421 FLAGS_LIBELF=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS)
422 ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF)),y) 422 ifneq ($(call try-cc,$(SOURCE_LIBELF),$(FLAGS_LIBELF)),y)
423 FLAGS_GLIBC=$(ALL_CFLAGS) $(ALL_LDFLAGS) 423 FLAGS_GLIBC=$(ALL_CFLAGS) $(ALL_LDFLAGS)
424 ifneq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC)),y) 424 ifneq ($(call try-cc,$(SOURCE_GLIBC),$(FLAGS_GLIBC)),y)
425 msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static); 425 msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
426 else 426 else
427 msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel); 427 msg := $(error No libelf.h/libelf found, please install libelf-dev/elfutils-libelf-devel);
428 endif 428 endif
429 endif 429 endif
430 430
431 ifneq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_COMMON)),y) 431 ifneq ($(call try-cc,$(SOURCE_ELF_MMAP),$(FLAGS_COMMON)),y)
432 BASIC_CFLAGS += -DLIBELF_NO_MMAP 432 BASIC_CFLAGS += -DLIBELF_NO_MMAP
433 endif 433 endif
434 434
435 ifndef NO_DWARF 435 ifndef NO_DWARF
436 ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined) 436 ifeq ($(origin PERF_HAVE_DWARF_REGS), undefined)
437 msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled); 437 msg := $(warning DWARF register mappings have not been defined for architecture $(ARCH), DWARF support disabled);
438 else 438 else
439 BASIC_CFLAGS += -DDWARF_SUPPORT 439 BASIC_CFLAGS += -DDWARF_SUPPORT
440 EXTLIBS += -lelf -ldw 440 EXTLIBS += -lelf -ldw
441 LIB_OBJS += $(OUTPUT)util/probe-finder.o 441 LIB_OBJS += $(OUTPUT)util/probe-finder.o
442 LIB_OBJS += $(OUTPUT)util/dwarf-aux.o 442 LIB_OBJS += $(OUTPUT)util/dwarf-aux.o
443 endif # PERF_HAVE_DWARF_REGS 443 endif # PERF_HAVE_DWARF_REGS
444 endif # NO_DWARF 444 endif # NO_DWARF
445 445
446 ifdef NO_NEWT 446 ifdef NO_NEWT
447 BASIC_CFLAGS += -DNO_NEWT_SUPPORT 447 BASIC_CFLAGS += -DNO_NEWT_SUPPORT
448 else 448 else
449 FLAGS_NEWT=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -lnewt 449 FLAGS_NEWT=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -lnewt
450 ifneq ($(call try-cc,$(SOURCE_NEWT),$(FLAGS_NEWT)),y) 450 ifneq ($(call try-cc,$(SOURCE_NEWT),$(FLAGS_NEWT)),y)
451 msg := $(warning newt not found, disables TUI support. Please install newt-devel or libnewt-dev); 451 msg := $(warning newt not found, disables TUI support. Please install newt-devel or libnewt-dev);
452 BASIC_CFLAGS += -DNO_NEWT_SUPPORT 452 BASIC_CFLAGS += -DNO_NEWT_SUPPORT
453 else 453 else
454 # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h 454 # Fedora has /usr/include/slang/slang.h, but ubuntu /usr/include/slang.h
455 BASIC_CFLAGS += -I/usr/include/slang 455 BASIC_CFLAGS += -I/usr/include/slang
456 EXTLIBS += -lnewt -lslang 456 EXTLIBS += -lnewt -lslang
457 LIB_OBJS += $(OUTPUT)util/ui/setup.o 457 LIB_OBJS += $(OUTPUT)util/ui/setup.o
458 LIB_OBJS += $(OUTPUT)util/ui/browser.o 458 LIB_OBJS += $(OUTPUT)util/ui/browser.o
459 LIB_OBJS += $(OUTPUT)util/ui/browsers/annotate.o 459 LIB_OBJS += $(OUTPUT)util/ui/browsers/annotate.o
460 LIB_OBJS += $(OUTPUT)util/ui/browsers/hists.o 460 LIB_OBJS += $(OUTPUT)util/ui/browsers/hists.o
461 LIB_OBJS += $(OUTPUT)util/ui/browsers/map.o 461 LIB_OBJS += $(OUTPUT)util/ui/browsers/map.o
462 LIB_OBJS += $(OUTPUT)util/ui/browsers/top.o 462 LIB_OBJS += $(OUTPUT)util/ui/browsers/top.o
463 LIB_OBJS += $(OUTPUT)util/ui/helpline.o 463 LIB_OBJS += $(OUTPUT)util/ui/helpline.o
464 LIB_OBJS += $(OUTPUT)util/ui/progress.o 464 LIB_OBJS += $(OUTPUT)util/ui/progress.o
465 LIB_OBJS += $(OUTPUT)util/ui/util.o 465 LIB_OBJS += $(OUTPUT)util/ui/util.o
466 LIB_H += util/ui/browser.h 466 LIB_H += util/ui/browser.h
467 LIB_H += util/ui/browsers/map.h 467 LIB_H += util/ui/browsers/map.h
468 LIB_H += util/ui/helpline.h 468 LIB_H += util/ui/helpline.h
469 LIB_H += util/ui/libslang.h 469 LIB_H += util/ui/libslang.h
470 LIB_H += util/ui/progress.h 470 LIB_H += util/ui/progress.h
471 LIB_H += util/ui/util.h 471 LIB_H += util/ui/util.h
472 LIB_H += util/ui/ui.h 472 LIB_H += util/ui/ui.h
473 endif 473 endif
474 endif 474 endif
475 475
476 ifdef NO_LIBPERL 476 ifdef NO_LIBPERL
477 BASIC_CFLAGS += -DNO_LIBPERL 477 BASIC_CFLAGS += -DNO_LIBPERL
478 else 478 else
479 PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null) 479 PERL_EMBED_LDOPTS = $(shell perl -MExtUtils::Embed -e ldopts 2>/dev/null)
480 PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS)) 480 PERL_EMBED_LDFLAGS = $(call strip-libs,$(PERL_EMBED_LDOPTS))
481 PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS)) 481 PERL_EMBED_LIBADD = $(call grep-libs,$(PERL_EMBED_LDOPTS))
482 PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null` 482 PERL_EMBED_CCOPTS = `perl -MExtUtils::Embed -e ccopts 2>/dev/null`
483 FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS) 483 FLAGS_PERL_EMBED=$(PERL_EMBED_CCOPTS) $(PERL_EMBED_LDOPTS)
484 484
485 ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED)),y) 485 ifneq ($(call try-cc,$(SOURCE_PERL_EMBED),$(FLAGS_PERL_EMBED)),y)
486 BASIC_CFLAGS += -DNO_LIBPERL 486 BASIC_CFLAGS += -DNO_LIBPERL
487 else 487 else
488 ALL_LDFLAGS += $(PERL_EMBED_LDFLAGS) 488 ALL_LDFLAGS += $(PERL_EMBED_LDFLAGS)
489 EXTLIBS += $(PERL_EMBED_LIBADD) 489 EXTLIBS += $(PERL_EMBED_LIBADD)
490 LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o 490 LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-perl.o
491 LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o 491 LIB_OBJS += $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o
492 endif 492 endif
493 endif 493 endif
494 494
495 disable-python = $(eval $(disable-python_code)) 495 disable-python = $(eval $(disable-python_code))
496 define disable-python_code 496 define disable-python_code
497 BASIC_CFLAGS += -DNO_LIBPYTHON 497 BASIC_CFLAGS += -DNO_LIBPYTHON
498 $(if $(1),$(warning No $(1) was found)) 498 $(if $(1),$(warning No $(1) was found))
499 $(warning Python support won't be built) 499 $(warning Python support won't be built)
500 endef 500 endef
501 501
502 override PYTHON := \ 502 override PYTHON := \
503 $(call get-executable-or-default,PYTHON,python) 503 $(call get-executable-or-default,PYTHON,python)
504 504
505 ifndef PYTHON 505 ifndef PYTHON
506 $(call disable-python,python interpreter) 506 $(call disable-python,python interpreter)
507 python-clean := 507 python-clean :=
508 else 508 else
509 509
510 PYTHON_WORD := $(call shell-wordify,$(PYTHON)) 510 PYTHON_WORD := $(call shell-wordify,$(PYTHON))
511 511
512 python-clean := $(PYTHON_WORD) util/setup.py clean \ 512 # python extension build directories
513 --build-lib='$(OUTPUT)python' \ 513 PYTHON_EXTBUILD := $(OUTPUT)python_ext_build/
514 --build-temp='$(OUTPUT)python/temp' 514 PYTHON_EXTBUILD_LIB := $(PYTHON_EXTBUILD)lib/
515 PYTHON_EXTBUILD_TMP := $(PYTHON_EXTBUILD)tmp/
516 export PYTHON_EXTBUILD_LIB PYTHON_EXTBUILD_TMP
515 517
518 python-clean := rm -rf $(PYTHON_EXTBUILD) $(OUTPUT)python/perf.so
519
516 ifdef NO_LIBPYTHON 520 ifdef NO_LIBPYTHON
517 $(call disable-python) 521 $(call disable-python)
518 else 522 else
519 523
520 override PYTHON_CONFIG := \ 524 override PYTHON_CONFIG := \
521 $(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON)-config) 525 $(call get-executable-or-default,PYTHON_CONFIG,$(PYTHON)-config)
522 526
523 ifndef PYTHON_CONFIG 527 ifndef PYTHON_CONFIG
524 $(call disable-python,python-config tool) 528 $(call disable-python,python-config tool)
525 else 529 else
526 530
527 PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG)) 531 PYTHON_CONFIG_SQ := $(call shell-sq,$(PYTHON_CONFIG))
528 532
529 PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null) 533 PYTHON_EMBED_LDOPTS := $(shell $(PYTHON_CONFIG_SQ) --ldflags 2>/dev/null)
530 PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS)) 534 PYTHON_EMBED_LDFLAGS := $(call strip-libs,$(PYTHON_EMBED_LDOPTS))
531 PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS)) 535 PYTHON_EMBED_LIBADD := $(call grep-libs,$(PYTHON_EMBED_LDOPTS))
532 PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null) 536 PYTHON_EMBED_CCOPTS := $(shell $(PYTHON_CONFIG_SQ) --cflags 2>/dev/null)
533 FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS) 537 FLAGS_PYTHON_EMBED := $(PYTHON_EMBED_CCOPTS) $(PYTHON_EMBED_LDOPTS)
534 538
535 ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED)),y) 539 ifneq ($(call try-cc,$(SOURCE_PYTHON_EMBED),$(FLAGS_PYTHON_EMBED)),y)
536 $(call disable-python,Python.h (for Python 2.x)) 540 $(call disable-python,Python.h (for Python 2.x))
537 else 541 else
538 542
539 ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED)),y) 543 ifneq ($(call try-cc,$(SOURCE_PYTHON_VERSION),$(FLAGS_PYTHON_EMBED)),y)
540 $(warning Python 3 is not yet supported; please set) 544 $(warning Python 3 is not yet supported; please set)
541 $(warning PYTHON and/or PYTHON_CONFIG appropriately.) 545 $(warning PYTHON and/or PYTHON_CONFIG appropriately.)
542 $(warning If you also have Python 2 installed, then) 546 $(warning If you also have Python 2 installed, then)
543 $(warning try something like:) 547 $(warning try something like:)
544 $(warning $(and ,)) 548 $(warning $(and ,))
545 $(warning $(and ,) make PYTHON=python2) 549 $(warning $(and ,) make PYTHON=python2)
546 $(warning $(and ,)) 550 $(warning $(and ,))
547 $(warning Otherwise, disable Python support entirely:) 551 $(warning Otherwise, disable Python support entirely:)
548 $(warning $(and ,)) 552 $(warning $(and ,))
549 $(warning $(and ,) make NO_LIBPYTHON=1) 553 $(warning $(and ,) make NO_LIBPYTHON=1)
550 $(warning $(and ,)) 554 $(warning $(and ,))
551 $(error $(and ,)) 555 $(error $(and ,))
552 else 556 else
553 ALL_LDFLAGS += $(PYTHON_EMBED_LDFLAGS) 557 ALL_LDFLAGS += $(PYTHON_EMBED_LDFLAGS)
554 EXTLIBS += $(PYTHON_EMBED_LIBADD) 558 EXTLIBS += $(PYTHON_EMBED_LIBADD)
555 LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o 559 LIB_OBJS += $(OUTPUT)util/scripting-engines/trace-event-python.o
556 LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o 560 LIB_OBJS += $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o
557 LANG_BINDINGS += $(OUTPUT)python/perf.so 561 LANG_BINDINGS += $(OUTPUT)python/perf.so
558 endif 562 endif
559 563
560 endif 564 endif
561 endif 565 endif
562 endif 566 endif
563 endif 567 endif
564 568
565 ifdef NO_DEMANGLE 569 ifdef NO_DEMANGLE
566 BASIC_CFLAGS += -DNO_DEMANGLE 570 BASIC_CFLAGS += -DNO_DEMANGLE
567 else 571 else
568 ifdef HAVE_CPLUS_DEMANGLE 572 ifdef HAVE_CPLUS_DEMANGLE
569 EXTLIBS += -liberty 573 EXTLIBS += -liberty
570 BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE 574 BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
571 else 575 else
572 FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd 576 FLAGS_BFD=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -lbfd
573 has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD)) 577 has_bfd := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD))
574 ifeq ($(has_bfd),y) 578 ifeq ($(has_bfd),y)
575 EXTLIBS += -lbfd 579 EXTLIBS += -lbfd
576 else 580 else
577 FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty 581 FLAGS_BFD_IBERTY=$(FLAGS_BFD) -liberty
578 has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY)) 582 has_bfd_iberty := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY))
579 ifeq ($(has_bfd_iberty),y) 583 ifeq ($(has_bfd_iberty),y)
580 EXTLIBS += -lbfd -liberty 584 EXTLIBS += -lbfd -liberty
581 else 585 else
582 FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz 586 FLAGS_BFD_IBERTY_Z=$(FLAGS_BFD_IBERTY) -lz
583 has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z)) 587 has_bfd_iberty_z := $(call try-cc,$(SOURCE_BFD),$(FLAGS_BFD_IBERTY_Z))
584 ifeq ($(has_bfd_iberty_z),y) 588 ifeq ($(has_bfd_iberty_z),y)
585 EXTLIBS += -lbfd -liberty -lz 589 EXTLIBS += -lbfd -liberty -lz
586 else 590 else
587 FLAGS_CPLUS_DEMANGLE=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -liberty 591 FLAGS_CPLUS_DEMANGLE=$(ALL_CFLAGS) $(ALL_LDFLAGS) $(EXTLIBS) -liberty
588 has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE)) 592 has_cplus_demangle := $(call try-cc,$(SOURCE_CPLUS_DEMANGLE),$(FLAGS_CPLUS_DEMANGLE))
589 ifeq ($(has_cplus_demangle),y) 593 ifeq ($(has_cplus_demangle),y)
590 EXTLIBS += -liberty 594 EXTLIBS += -liberty
591 BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE 595 BASIC_CFLAGS += -DHAVE_CPLUS_DEMANGLE
592 else 596 else
593 msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling) 597 msg := $(warning No bfd.h/libbfd found, install binutils-dev[el]/zlib-static to gain symbol demangling)
594 BASIC_CFLAGS += -DNO_DEMANGLE 598 BASIC_CFLAGS += -DNO_DEMANGLE
595 endif 599 endif
596 endif 600 endif
597 endif 601 endif
598 endif 602 endif
599 endif 603 endif
600 endif 604 endif
601 605
602 606
603 ifdef NO_STRLCPY 607 ifdef NO_STRLCPY
604 BASIC_CFLAGS += -DNO_STRLCPY 608 BASIC_CFLAGS += -DNO_STRLCPY
605 else 609 else
606 ifneq ($(call try-cc,$(SOURCE_STRLCPY),),y) 610 ifneq ($(call try-cc,$(SOURCE_STRLCPY),),y)
607 BASIC_CFLAGS += -DNO_STRLCPY 611 BASIC_CFLAGS += -DNO_STRLCPY
608 endif 612 endif
609 endif 613 endif
610 614
611 ifneq ($(findstring $(MAKEFLAGS),s),s) 615 ifneq ($(findstring $(MAKEFLAGS),s),s)
612 ifndef V 616 ifndef V
613 QUIET_CC = @echo ' ' CC $@; 617 QUIET_CC = @echo ' ' CC $@;
614 QUIET_AR = @echo ' ' AR $@; 618 QUIET_AR = @echo ' ' AR $@;
615 QUIET_LINK = @echo ' ' LINK $@; 619 QUIET_LINK = @echo ' ' LINK $@;
616 QUIET_MKDIR = @echo ' ' MKDIR $@; 620 QUIET_MKDIR = @echo ' ' MKDIR $@;
617 QUIET_GEN = @echo ' ' GEN $@; 621 QUIET_GEN = @echo ' ' GEN $@;
618 endif 622 endif
619 endif 623 endif
620 624
621 ifdef ASCIIDOC8 625 ifdef ASCIIDOC8
622 export ASCIIDOC8 626 export ASCIIDOC8
623 endif 627 endif
624 628
625 # Shell quote (do not use $(call) to accommodate ancient setups); 629 # Shell quote (do not use $(call) to accommodate ancient setups);
626 630
627 ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG)) 631 ETC_PERFCONFIG_SQ = $(subst ','\'',$(ETC_PERFCONFIG))
628 632
629 DESTDIR_SQ = $(subst ','\'',$(DESTDIR)) 633 DESTDIR_SQ = $(subst ','\'',$(DESTDIR))
630 bindir_SQ = $(subst ','\'',$(bindir)) 634 bindir_SQ = $(subst ','\'',$(bindir))
631 bindir_relative_SQ = $(subst ','\'',$(bindir_relative)) 635 bindir_relative_SQ = $(subst ','\'',$(bindir_relative))
632 mandir_SQ = $(subst ','\'',$(mandir)) 636 mandir_SQ = $(subst ','\'',$(mandir))
633 infodir_SQ = $(subst ','\'',$(infodir)) 637 infodir_SQ = $(subst ','\'',$(infodir))
634 perfexecdir_SQ = $(subst ','\'',$(perfexecdir)) 638 perfexecdir_SQ = $(subst ','\'',$(perfexecdir))
635 template_dir_SQ = $(subst ','\'',$(template_dir)) 639 template_dir_SQ = $(subst ','\'',$(template_dir))
636 htmldir_SQ = $(subst ','\'',$(htmldir)) 640 htmldir_SQ = $(subst ','\'',$(htmldir))
637 prefix_SQ = $(subst ','\'',$(prefix)) 641 prefix_SQ = $(subst ','\'',$(prefix))
638 642
639 SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) 643 SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH))
640 644
641 LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group 645 LIBS = -Wl,--whole-archive $(PERFLIBS) -Wl,--no-whole-archive -Wl,--start-group $(EXTLIBS) -Wl,--end-group
642 646
643 ALL_CFLAGS += $(BASIC_CFLAGS) 647 ALL_CFLAGS += $(BASIC_CFLAGS)
644 ALL_CFLAGS += $(ARCH_CFLAGS) 648 ALL_CFLAGS += $(ARCH_CFLAGS)
645 ALL_LDFLAGS += $(BASIC_LDFLAGS) 649 ALL_LDFLAGS += $(BASIC_LDFLAGS)
646 650
647 export INSTALL SHELL_PATH 651 export INSTALL SHELL_PATH
648 652
649 653
650 ### Build rules 654 ### Build rules
651 655
652 SHELL = $(SHELL_PATH) 656 SHELL = $(SHELL_PATH)
653 657
654 all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS) 658 all: shell_compatibility_test $(ALL_PROGRAMS) $(LANG_BINDINGS) $(OTHER_PROGRAMS)
655 659
656 please_set_SHELL_PATH_to_a_more_modern_shell: 660 please_set_SHELL_PATH_to_a_more_modern_shell:
657 @$$(:) 661 @$$(:)
658 662
659 shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell 663 shell_compatibility_test: please_set_SHELL_PATH_to_a_more_modern_shell
660 664
661 strip: $(PROGRAMS) $(OUTPUT)perf 665 strip: $(PROGRAMS) $(OUTPUT)perf
662 $(STRIP) $(STRIP_OPTS) $(PROGRAMS) $(OUTPUT)perf 666 $(STRIP) $(STRIP_OPTS) $(PROGRAMS) $(OUTPUT)perf
663 667
664 $(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS 668 $(OUTPUT)perf.o: perf.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
665 $(QUIET_CC)$(CC) -DPERF_VERSION='"$(PERF_VERSION)"' \ 669 $(QUIET_CC)$(CC) -DPERF_VERSION='"$(PERF_VERSION)"' \
666 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \ 670 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
667 $(ALL_CFLAGS) -c $(filter %.c,$^) -o $@ 671 $(ALL_CFLAGS) -c $(filter %.c,$^) -o $@
668 672
669 $(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS) 673 $(OUTPUT)perf: $(OUTPUT)perf.o $(BUILTIN_OBJS) $(PERFLIBS)
670 $(QUIET_LINK)$(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) $(OUTPUT)perf.o \ 674 $(QUIET_LINK)$(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) $(OUTPUT)perf.o \
671 $(BUILTIN_OBJS) $(LIBS) -o $@ 675 $(BUILTIN_OBJS) $(LIBS) -o $@
672 676
673 $(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS 677 $(OUTPUT)builtin-help.o: builtin-help.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
674 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \ 678 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
675 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \ 679 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
676 '-DPERF_MAN_PATH="$(mandir_SQ)"' \ 680 '-DPERF_MAN_PATH="$(mandir_SQ)"' \
677 '-DPERF_INFO_PATH="$(infodir_SQ)"' $< 681 '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
678 682
679 $(OUTPUT)builtin-timechart.o: builtin-timechart.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS 683 $(OUTPUT)builtin-timechart.o: builtin-timechart.c $(OUTPUT)common-cmds.h $(OUTPUT)PERF-CFLAGS
680 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \ 684 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
681 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \ 685 '-DPERF_HTML_PATH="$(htmldir_SQ)"' \
682 '-DPERF_MAN_PATH="$(mandir_SQ)"' \ 686 '-DPERF_MAN_PATH="$(mandir_SQ)"' \
683 '-DPERF_INFO_PATH="$(infodir_SQ)"' $< 687 '-DPERF_INFO_PATH="$(infodir_SQ)"' $<
684 688
685 $(OUTPUT)common-cmds.h: util/generate-cmdlist.sh command-list.txt 689 $(OUTPUT)common-cmds.h: util/generate-cmdlist.sh command-list.txt
686 690
687 $(OUTPUT)common-cmds.h: $(wildcard Documentation/perf-*.txt) 691 $(OUTPUT)common-cmds.h: $(wildcard Documentation/perf-*.txt)
688 $(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@ 692 $(QUIET_GEN). util/generate-cmdlist.sh > $@+ && mv $@+ $@
689 693
690 $(SCRIPTS) : % : %.sh 694 $(SCRIPTS) : % : %.sh
691 $(QUIET_GEN)$(INSTALL) '$@.sh' '$(OUTPUT)$@' 695 $(QUIET_GEN)$(INSTALL) '$@.sh' '$(OUTPUT)$@'
692 696
693 # These can record PERF_VERSION 697 # These can record PERF_VERSION
694 $(OUTPUT)perf.o perf.spec \ 698 $(OUTPUT)perf.o perf.spec \
695 $(SCRIPTS) \ 699 $(SCRIPTS) \
696 : $(OUTPUT)PERF-VERSION-FILE 700 : $(OUTPUT)PERF-VERSION-FILE
697 701
698 $(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS 702 $(OUTPUT)%.o: %.c $(OUTPUT)PERF-CFLAGS
699 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $< 703 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
700 $(OUTPUT)%.s: %.c $(OUTPUT)PERF-CFLAGS 704 $(OUTPUT)%.s: %.c $(OUTPUT)PERF-CFLAGS
701 $(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $< 705 $(QUIET_CC)$(CC) -S $(ALL_CFLAGS) $<
702 $(OUTPUT)%.o: %.S 706 $(OUTPUT)%.o: %.S
703 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $< 707 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $<
704 708
705 $(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS 709 $(OUTPUT)util/exec_cmd.o: util/exec_cmd.c $(OUTPUT)PERF-CFLAGS
706 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \ 710 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) \
707 '-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \ 711 '-DPERF_EXEC_PATH="$(perfexecdir_SQ)"' \
708 '-DBINDIR="$(bindir_relative_SQ)"' \ 712 '-DBINDIR="$(bindir_relative_SQ)"' \
709 '-DPREFIX="$(prefix_SQ)"' \ 713 '-DPREFIX="$(prefix_SQ)"' \
710 $< 714 $<
711 715
712 $(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS 716 $(OUTPUT)util/config.o: util/config.c $(OUTPUT)PERF-CFLAGS
713 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< 717 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
714 718
715 $(OUTPUT)util/ui/browser.o: util/ui/browser.c $(OUTPUT)PERF-CFLAGS 719 $(OUTPUT)util/ui/browser.o: util/ui/browser.c $(OUTPUT)PERF-CFLAGS
716 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< 720 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
717 721
718 $(OUTPUT)util/ui/browsers/annotate.o: util/ui/browsers/annotate.c $(OUTPUT)PERF-CFLAGS 722 $(OUTPUT)util/ui/browsers/annotate.o: util/ui/browsers/annotate.c $(OUTPUT)PERF-CFLAGS
719 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< 723 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
720 724
721 $(OUTPUT)util/ui/browsers/top.o: util/ui/browsers/top.c $(OUTPUT)PERF-CFLAGS 725 $(OUTPUT)util/ui/browsers/top.o: util/ui/browsers/top.c $(OUTPUT)PERF-CFLAGS
722 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< 726 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
723 727
724 $(OUTPUT)util/ui/browsers/hists.o: util/ui/browsers/hists.c $(OUTPUT)PERF-CFLAGS 728 $(OUTPUT)util/ui/browsers/hists.o: util/ui/browsers/hists.c $(OUTPUT)PERF-CFLAGS
725 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< 729 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
726 730
727 $(OUTPUT)util/ui/browsers/map.o: util/ui/browsers/map.c $(OUTPUT)PERF-CFLAGS 731 $(OUTPUT)util/ui/browsers/map.o: util/ui/browsers/map.c $(OUTPUT)PERF-CFLAGS
728 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $< 732 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DENABLE_SLFUTURE_CONST $<
729 733
730 $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS 734 $(OUTPUT)util/rbtree.o: ../../lib/rbtree.c $(OUTPUT)PERF-CFLAGS
731 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $< 735 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) -DETC_PERFCONFIG='"$(ETC_PERFCONFIG_SQ)"' $<
732 736
733 $(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS 737 $(OUTPUT)util/scripting-engines/trace-event-perl.o: util/scripting-engines/trace-event-perl.c $(OUTPUT)PERF-CFLAGS
734 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $< 738 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
735 739
736 $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS 740 $(OUTPUT)scripts/perl/Perf-Trace-Util/Context.o: scripts/perl/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
737 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $< 741 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PERL_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
738 742
739 $(OUTPUT)util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c $(OUTPUT)PERF-CFLAGS 743 $(OUTPUT)util/scripting-engines/trace-event-python.o: util/scripting-engines/trace-event-python.c $(OUTPUT)PERF-CFLAGS
740 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $< 744 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-shadow $<
741 745
742 $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS 746 $(OUTPUT)scripts/python/Perf-Trace-Util/Context.o: scripts/python/Perf-Trace-Util/Context.c $(OUTPUT)PERF-CFLAGS
743 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $< 747 $(QUIET_CC)$(CC) -o $@ -c $(ALL_CFLAGS) $(PYTHON_EMBED_CCOPTS) -Wno-redundant-decls -Wno-strict-prototypes -Wno-unused-parameter -Wno-nested-externs $<
744 748
745 $(OUTPUT)perf-%: %.o $(PERFLIBS) 749 $(OUTPUT)perf-%: %.o $(PERFLIBS)
746 $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) 750 $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS)
747 751
748 $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H) 752 $(LIB_OBJS) $(BUILTIN_OBJS): $(LIB_H)
749 $(patsubst perf-%,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h) 753 $(patsubst perf-%,%.o,$(PROGRAMS)): $(LIB_H) $(wildcard */*.h)
750 754
751 # we compile into subdirectories. if the target directory is not the source directory, they might not exists. So 755 # we compile into subdirectories. if the target directory is not the source directory, they might not exists. So
752 # we depend the various files onto their directories. 756 # we depend the various files onto their directories.
753 DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h 757 DIRECTORY_DEPS = $(LIB_OBJS) $(BUILTIN_OBJS) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)common-cmds.h
754 $(DIRECTORY_DEPS): | $(sort $(dir $(DIRECTORY_DEPS))) 758 $(DIRECTORY_DEPS): | $(sort $(dir $(DIRECTORY_DEPS)))
755 # In the second step, we make a rule to actually create these directories 759 # In the second step, we make a rule to actually create these directories
756 $(sort $(dir $(DIRECTORY_DEPS))): 760 $(sort $(dir $(DIRECTORY_DEPS))):
757 $(QUIET_MKDIR)$(MKDIR) -p $@ 2>/dev/null 761 $(QUIET_MKDIR)$(MKDIR) -p $@ 2>/dev/null
758 762
759 $(LIB_FILE): $(LIB_OBJS) 763 $(LIB_FILE): $(LIB_OBJS)
760 $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS) 764 $(QUIET_AR)$(RM) $@ && $(AR) rcs $@ $(LIB_OBJS)
761 765
762 help: 766 help:
763 @echo 'Perf make targets:' 767 @echo 'Perf make targets:'
764 @echo ' doc - make *all* documentation (see below)' 768 @echo ' doc - make *all* documentation (see below)'
765 @echo ' man - make manpage documentation (access with man <foo>)' 769 @echo ' man - make manpage documentation (access with man <foo>)'
766 @echo ' html - make html documentation' 770 @echo ' html - make html documentation'
767 @echo ' info - make GNU info documentation (access with info <foo>)' 771 @echo ' info - make GNU info documentation (access with info <foo>)'
768 @echo ' pdf - make pdf documentation' 772 @echo ' pdf - make pdf documentation'
769 @echo ' TAGS - use etags to make tag information for source browsing' 773 @echo ' TAGS - use etags to make tag information for source browsing'
770 @echo ' tags - use ctags to make tag information for source browsing' 774 @echo ' tags - use ctags to make tag information for source browsing'
771 @echo ' cscope - use cscope to make interactive browsing database' 775 @echo ' cscope - use cscope to make interactive browsing database'
772 @echo '' 776 @echo ''
773 @echo 'Perf install targets:' 777 @echo 'Perf install targets:'
774 @echo ' NOTE: documentation build requires asciidoc, xmlto packages to be installed' 778 @echo ' NOTE: documentation build requires asciidoc, xmlto packages to be installed'
775 @echo ' HINT: use "make prefix=<path> <install target>" to install to a particular' 779 @echo ' HINT: use "make prefix=<path> <install target>" to install to a particular'
776 @echo ' path like make prefix=/usr/local install install-doc' 780 @echo ' path like make prefix=/usr/local install install-doc'
777 @echo ' install - install compiled binaries' 781 @echo ' install - install compiled binaries'
778 @echo ' install-doc - install *all* documentation' 782 @echo ' install-doc - install *all* documentation'
779 @echo ' install-man - install manpage documentation' 783 @echo ' install-man - install manpage documentation'
780 @echo ' install-html - install html documentation' 784 @echo ' install-html - install html documentation'
781 @echo ' install-info - install GNU info documentation' 785 @echo ' install-info - install GNU info documentation'
782 @echo ' install-pdf - install pdf documentation' 786 @echo ' install-pdf - install pdf documentation'
783 @echo '' 787 @echo ''
784 @echo ' quick-install-doc - alias for quick-install-man' 788 @echo ' quick-install-doc - alias for quick-install-man'
785 @echo ' quick-install-man - install the documentation quickly' 789 @echo ' quick-install-man - install the documentation quickly'
786 @echo ' quick-install-html - install the html documentation quickly' 790 @echo ' quick-install-html - install the html documentation quickly'
787 @echo '' 791 @echo ''
788 @echo 'Perf maintainer targets:' 792 @echo 'Perf maintainer targets:'
789 @echo ' distclean - alias to clean' 793 @echo ' distclean - alias to clean'
790 @echo ' clean - clean all binary objects and build output' 794 @echo ' clean - clean all binary objects and build output'
791 795
792 doc: 796 doc:
793 $(MAKE) -C Documentation all 797 $(MAKE) -C Documentation all
794 798
795 man: 799 man:
796 $(MAKE) -C Documentation man 800 $(MAKE) -C Documentation man
797 801
798 html: 802 html:
799 $(MAKE) -C Documentation html 803 $(MAKE) -C Documentation html
800 804
801 info: 805 info:
802 $(MAKE) -C Documentation info 806 $(MAKE) -C Documentation info
803 807
804 pdf: 808 pdf:
805 $(MAKE) -C Documentation pdf 809 $(MAKE) -C Documentation pdf
806 810
807 TAGS: 811 TAGS:
808 $(RM) TAGS 812 $(RM) TAGS
809 $(FIND) . -name '*.[hcS]' -print | xargs etags -a 813 $(FIND) . -name '*.[hcS]' -print | xargs etags -a
810 814
811 tags: 815 tags:
812 $(RM) tags 816 $(RM) tags
813 $(FIND) . -name '*.[hcS]' -print | xargs ctags -a 817 $(FIND) . -name '*.[hcS]' -print | xargs ctags -a
814 818
815 cscope: 819 cscope:
816 $(RM) cscope* 820 $(RM) cscope*
817 $(FIND) . -name '*.[hcS]' -print | xargs cscope -b 821 $(FIND) . -name '*.[hcS]' -print | xargs cscope -b
818 822
819 ### Detect prefix changes 823 ### Detect prefix changes
820 TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\ 824 TRACK_CFLAGS = $(subst ','\'',$(ALL_CFLAGS)):\
821 $(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ) 825 $(bindir_SQ):$(perfexecdir_SQ):$(template_dir_SQ):$(prefix_SQ)
822 826
823 $(OUTPUT)PERF-CFLAGS: .FORCE-PERF-CFLAGS 827 $(OUTPUT)PERF-CFLAGS: .FORCE-PERF-CFLAGS
824 @FLAGS='$(TRACK_CFLAGS)'; \ 828 @FLAGS='$(TRACK_CFLAGS)'; \
825 if test x"$$FLAGS" != x"`cat $(OUTPUT)PERF-CFLAGS 2>/dev/null`" ; then \ 829 if test x"$$FLAGS" != x"`cat $(OUTPUT)PERF-CFLAGS 2>/dev/null`" ; then \
826 echo 1>&2 " * new build flags or prefix"; \ 830 echo 1>&2 " * new build flags or prefix"; \
827 echo "$$FLAGS" >$(OUTPUT)PERF-CFLAGS; \ 831 echo "$$FLAGS" >$(OUTPUT)PERF-CFLAGS; \
828 fi 832 fi
829 833
830 ### Testing rules 834 ### Testing rules
831 835
832 # GNU make supports exporting all variables by "export" without parameters. 836 # GNU make supports exporting all variables by "export" without parameters.
833 # However, the environment gets quite big, and some programs have problems 837 # However, the environment gets quite big, and some programs have problems
834 # with that. 838 # with that.
835 839
836 check: $(OUTPUT)common-cmds.h 840 check: $(OUTPUT)common-cmds.h
837 if sparse; \ 841 if sparse; \
838 then \ 842 then \
839 for i in *.c */*.c; \ 843 for i in *.c */*.c; \
840 do \ 844 do \
841 sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; \ 845 sparse $(ALL_CFLAGS) $(SPARSE_FLAGS) $$i || exit; \
842 done; \ 846 done; \
843 else \ 847 else \
844 exit 1; \ 848 exit 1; \
845 fi 849 fi
846 850
847 ### Installation rules 851 ### Installation rules
848 852
849 ifneq ($(filter /%,$(firstword $(perfexecdir))),) 853 ifneq ($(filter /%,$(firstword $(perfexecdir))),)
850 perfexec_instdir = $(perfexecdir) 854 perfexec_instdir = $(perfexecdir)
851 else 855 else
852 perfexec_instdir = $(prefix)/$(perfexecdir) 856 perfexec_instdir = $(prefix)/$(perfexecdir)
853 endif 857 endif
854 perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir)) 858 perfexec_instdir_SQ = $(subst ','\'',$(perfexec_instdir))
855 859
856 install: all 860 install: all
857 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)' 861 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'
858 $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)' 862 $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'
859 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace' 863 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
860 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin' 864 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
861 $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' 865 $(INSTALL) $(OUTPUT)perf-archive -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'
862 $(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace' 866 $(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'
863 $(INSTALL) scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl' 867 $(INSTALL) scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'
864 $(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin' 868 $(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'
865 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace' 869 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace'
866 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin' 870 $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin'
867 $(INSTALL) scripts/python/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace' 871 $(INSTALL) scripts/python/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace'
868 $(INSTALL) scripts/python/*.py -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python' 872 $(INSTALL) scripts/python/*.py -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python'
869 $(INSTALL) scripts/python/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin' 873 $(INSTALL) scripts/python/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin'
870 874
875 install-python_ext:
876 $(PYTHON_WORD) util/setup.py --quiet install --root='/$(DESTDIR_SQ)'
877
871 install-doc: 878 install-doc:
872 $(MAKE) -C Documentation install 879 $(MAKE) -C Documentation install
873 880
874 install-man: 881 install-man:
875 $(MAKE) -C Documentation install-man 882 $(MAKE) -C Documentation install-man
876 883
877 install-html: 884 install-html:
878 $(MAKE) -C Documentation install-html 885 $(MAKE) -C Documentation install-html
879 886
880 install-info: 887 install-info:
881 $(MAKE) -C Documentation install-info 888 $(MAKE) -C Documentation install-info
882 889
883 install-pdf: 890 install-pdf:
884 $(MAKE) -C Documentation install-pdf 891 $(MAKE) -C Documentation install-pdf
885 892
886 quick-install-doc: 893 quick-install-doc:
887 $(MAKE) -C Documentation quick-install 894 $(MAKE) -C Documentation quick-install
888 895
889 quick-install-man: 896 quick-install-man:
890 $(MAKE) -C Documentation quick-install-man 897 $(MAKE) -C Documentation quick-install-man
891 898
892 quick-install-html: 899 quick-install-html:
893 $(MAKE) -C Documentation quick-install-html 900 $(MAKE) -C Documentation quick-install-html
894 901
895 ### Cleaning rules 902 ### Cleaning rules
896 903
897 clean: 904 clean:
898 $(RM) $(OUTPUT){*.o,*/*.o,*/*/*.o,*/*/*/*.o,$(LIB_FILE),perf-archive} 905 $(RM) $(LIB_OBJS) $(BUILTIN_OBJS) $(LIB_FILE) $(OUTPUT)perf-archive $(OUTPUT)perf.o $(LANG_BINDINGS)
899 $(RM) $(ALL_PROGRAMS) perf 906 $(RM) $(ALL_PROGRAMS) perf
900 $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* 907 $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope*
901 $(MAKE) -C Documentation/ clean 908 $(MAKE) -C Documentation/ clean
902 $(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS 909 $(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS
903 $(python-clean) 910 $(python-clean)
904 911
905 .PHONY: all install clean strip 912 .PHONY: all install clean strip
906 .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell 913 .PHONY: shell_compatibility_test please_set_SHELL_PATH_to_a_more_modern_shell
907 .PHONY: .FORCE-PERF-VERSION-FILE TAGS tags cscope .FORCE-PERF-CFLAGS 914 .PHONY: .FORCE-PERF-VERSION-FILE TAGS tags cscope .FORCE-PERF-CFLAGS
908 915
tools/perf/builtin-lock.c
1 #include "builtin.h" 1 #include "builtin.h"
2 #include "perf.h" 2 #include "perf.h"
3 3
4 #include "util/util.h" 4 #include "util/util.h"
5 #include "util/cache.h" 5 #include "util/cache.h"
6 #include "util/symbol.h" 6 #include "util/symbol.h"
7 #include "util/thread.h" 7 #include "util/thread.h"
8 #include "util/header.h" 8 #include "util/header.h"
9 9
10 #include "util/parse-options.h" 10 #include "util/parse-options.h"
11 #include "util/trace-event.h" 11 #include "util/trace-event.h"
12 12
13 #include "util/debug.h" 13 #include "util/debug.h"
14 #include "util/session.h" 14 #include "util/session.h"
15 15
16 #include <sys/types.h> 16 #include <sys/types.h>
17 #include <sys/prctl.h> 17 #include <sys/prctl.h>
18 #include <semaphore.h> 18 #include <semaphore.h>
19 #include <pthread.h> 19 #include <pthread.h>
20 #include <math.h> 20 #include <math.h>
21 #include <limits.h> 21 #include <limits.h>
22 22
23 #include <linux/list.h> 23 #include <linux/list.h>
24 #include <linux/hash.h> 24 #include <linux/hash.h>
25 25
26 static struct perf_session *session; 26 static struct perf_session *session;
27 27
28 /* based on kernel/lockdep.c */ 28 /* based on kernel/lockdep.c */
29 #define LOCKHASH_BITS 12 29 #define LOCKHASH_BITS 12
30 #define LOCKHASH_SIZE (1UL << LOCKHASH_BITS) 30 #define LOCKHASH_SIZE (1UL << LOCKHASH_BITS)
31 31
32 static struct list_head lockhash_table[LOCKHASH_SIZE]; 32 static struct list_head lockhash_table[LOCKHASH_SIZE];
33 33
34 #define __lockhashfn(key) hash_long((unsigned long)key, LOCKHASH_BITS) 34 #define __lockhashfn(key) hash_long((unsigned long)key, LOCKHASH_BITS)
35 #define lockhashentry(key) (lockhash_table + __lockhashfn((key))) 35 #define lockhashentry(key) (lockhash_table + __lockhashfn((key)))
36 36
37 struct lock_stat { 37 struct lock_stat {
38 struct list_head hash_entry; 38 struct list_head hash_entry;
39 struct rb_node rb; /* used for sorting */ 39 struct rb_node rb; /* used for sorting */
40 40
41 /* 41 /*
42 * FIXME: raw_field_value() returns unsigned long long, 42 * FIXME: raw_field_value() returns unsigned long long,
43 * so address of lockdep_map should be dealed as 64bit. 43 * so address of lockdep_map should be dealed as 64bit.
44 * Is there more better solution? 44 * Is there more better solution?
45 */ 45 */
46 void *addr; /* address of lockdep_map, used as ID */ 46 void *addr; /* address of lockdep_map, used as ID */
47 char *name; /* for strcpy(), we cannot use const */ 47 char *name; /* for strcpy(), we cannot use const */
48 48
49 unsigned int nr_acquire; 49 unsigned int nr_acquire;
50 unsigned int nr_acquired; 50 unsigned int nr_acquired;
51 unsigned int nr_contended; 51 unsigned int nr_contended;
52 unsigned int nr_release; 52 unsigned int nr_release;
53 53
54 unsigned int nr_readlock; 54 unsigned int nr_readlock;
55 unsigned int nr_trylock; 55 unsigned int nr_trylock;
56 /* these times are in nano sec. */ 56 /* these times are in nano sec. */
57 u64 wait_time_total; 57 u64 wait_time_total;
58 u64 wait_time_min; 58 u64 wait_time_min;
59 u64 wait_time_max; 59 u64 wait_time_max;
60 60
61 int discard; /* flag of blacklist */ 61 int discard; /* flag of blacklist */
62 }; 62 };
63 63
64 /* 64 /*
65 * States of lock_seq_stat 65 * States of lock_seq_stat
66 * 66 *
67 * UNINITIALIZED is required for detecting first event of acquire. 67 * UNINITIALIZED is required for detecting first event of acquire.
68 * As the nature of lock events, there is no guarantee 68 * As the nature of lock events, there is no guarantee
69 * that the first event for the locks are acquire, 69 * that the first event for the locks are acquire,
70 * it can be acquired, contended or release. 70 * it can be acquired, contended or release.
71 */ 71 */
72 #define SEQ_STATE_UNINITIALIZED 0 /* initial state */ 72 #define SEQ_STATE_UNINITIALIZED 0 /* initial state */
73 #define SEQ_STATE_RELEASED 1 73 #define SEQ_STATE_RELEASED 1
74 #define SEQ_STATE_ACQUIRING 2 74 #define SEQ_STATE_ACQUIRING 2
75 #define SEQ_STATE_ACQUIRED 3 75 #define SEQ_STATE_ACQUIRED 3
76 #define SEQ_STATE_READ_ACQUIRED 4 76 #define SEQ_STATE_READ_ACQUIRED 4
77 #define SEQ_STATE_CONTENDED 5 77 #define SEQ_STATE_CONTENDED 5
78 78
79 /* 79 /*
80 * MAX_LOCK_DEPTH 80 * MAX_LOCK_DEPTH
81 * Imported from include/linux/sched.h. 81 * Imported from include/linux/sched.h.
82 * Should this be synchronized? 82 * Should this be synchronized?
83 */ 83 */
84 #define MAX_LOCK_DEPTH 48 84 #define MAX_LOCK_DEPTH 48
85 85
86 /* 86 /*
87 * struct lock_seq_stat: 87 * struct lock_seq_stat:
88 * Place to put on state of one lock sequence 88 * Place to put on state of one lock sequence
89 * 1) acquire -> acquired -> release 89 * 1) acquire -> acquired -> release
90 * 2) acquire -> contended -> acquired -> release 90 * 2) acquire -> contended -> acquired -> release
91 * 3) acquire (with read or try) -> release 91 * 3) acquire (with read or try) -> release
92 * 4) Are there other patterns? 92 * 4) Are there other patterns?
93 */ 93 */
94 struct lock_seq_stat { 94 struct lock_seq_stat {
95 struct list_head list; 95 struct list_head list;
96 int state; 96 int state;
97 u64 prev_event_time; 97 u64 prev_event_time;
98 void *addr; 98 void *addr;
99 99
100 int read_count; 100 int read_count;
101 }; 101 };
102 102
103 struct thread_stat { 103 struct thread_stat {
104 struct rb_node rb; 104 struct rb_node rb;
105 105
106 u32 tid; 106 u32 tid;
107 struct list_head seq_list; 107 struct list_head seq_list;
108 }; 108 };
109 109
110 static struct rb_root thread_stats; 110 static struct rb_root thread_stats;
111 111
112 static struct thread_stat *thread_stat_find(u32 tid) 112 static struct thread_stat *thread_stat_find(u32 tid)
113 { 113 {
114 struct rb_node *node; 114 struct rb_node *node;
115 struct thread_stat *st; 115 struct thread_stat *st;
116 116
117 node = thread_stats.rb_node; 117 node = thread_stats.rb_node;
118 while (node) { 118 while (node) {
119 st = container_of(node, struct thread_stat, rb); 119 st = container_of(node, struct thread_stat, rb);
120 if (st->tid == tid) 120 if (st->tid == tid)
121 return st; 121 return st;
122 else if (tid < st->tid) 122 else if (tid < st->tid)
123 node = node->rb_left; 123 node = node->rb_left;
124 else 124 else
125 node = node->rb_right; 125 node = node->rb_right;
126 } 126 }
127 127
128 return NULL; 128 return NULL;
129 } 129 }
130 130
131 static void thread_stat_insert(struct thread_stat *new) 131 static void thread_stat_insert(struct thread_stat *new)
132 { 132 {
133 struct rb_node **rb = &thread_stats.rb_node; 133 struct rb_node **rb = &thread_stats.rb_node;
134 struct rb_node *parent = NULL; 134 struct rb_node *parent = NULL;
135 struct thread_stat *p; 135 struct thread_stat *p;
136 136
137 while (*rb) { 137 while (*rb) {
138 p = container_of(*rb, struct thread_stat, rb); 138 p = container_of(*rb, struct thread_stat, rb);
139 parent = *rb; 139 parent = *rb;
140 140
141 if (new->tid < p->tid) 141 if (new->tid < p->tid)
142 rb = &(*rb)->rb_left; 142 rb = &(*rb)->rb_left;
143 else if (new->tid > p->tid) 143 else if (new->tid > p->tid)
144 rb = &(*rb)->rb_right; 144 rb = &(*rb)->rb_right;
145 else 145 else
146 BUG_ON("inserting invalid thread_stat\n"); 146 BUG_ON("inserting invalid thread_stat\n");
147 } 147 }
148 148
149 rb_link_node(&new->rb, parent, rb); 149 rb_link_node(&new->rb, parent, rb);
150 rb_insert_color(&new->rb, &thread_stats); 150 rb_insert_color(&new->rb, &thread_stats);
151 } 151 }
152 152
153 static struct thread_stat *thread_stat_findnew_after_first(u32 tid) 153 static struct thread_stat *thread_stat_findnew_after_first(u32 tid)
154 { 154 {
155 struct thread_stat *st; 155 struct thread_stat *st;
156 156
157 st = thread_stat_find(tid); 157 st = thread_stat_find(tid);
158 if (st) 158 if (st)
159 return st; 159 return st;
160 160
161 st = zalloc(sizeof(struct thread_stat)); 161 st = zalloc(sizeof(struct thread_stat));
162 if (!st) 162 if (!st)
163 die("memory allocation failed\n"); 163 die("memory allocation failed\n");
164 164
165 st->tid = tid; 165 st->tid = tid;
166 INIT_LIST_HEAD(&st->seq_list); 166 INIT_LIST_HEAD(&st->seq_list);
167 167
168 thread_stat_insert(st); 168 thread_stat_insert(st);
169 169
170 return st; 170 return st;
171 } 171 }
172 172
173 static struct thread_stat *thread_stat_findnew_first(u32 tid); 173 static struct thread_stat *thread_stat_findnew_first(u32 tid);
174 static struct thread_stat *(*thread_stat_findnew)(u32 tid) = 174 static struct thread_stat *(*thread_stat_findnew)(u32 tid) =
175 thread_stat_findnew_first; 175 thread_stat_findnew_first;
176 176
177 static struct thread_stat *thread_stat_findnew_first(u32 tid) 177 static struct thread_stat *thread_stat_findnew_first(u32 tid)
178 { 178 {
179 struct thread_stat *st; 179 struct thread_stat *st;
180 180
181 st = zalloc(sizeof(struct thread_stat)); 181 st = zalloc(sizeof(struct thread_stat));
182 if (!st) 182 if (!st)
183 die("memory allocation failed\n"); 183 die("memory allocation failed\n");
184 st->tid = tid; 184 st->tid = tid;
185 INIT_LIST_HEAD(&st->seq_list); 185 INIT_LIST_HEAD(&st->seq_list);
186 186
187 rb_link_node(&st->rb, NULL, &thread_stats.rb_node); 187 rb_link_node(&st->rb, NULL, &thread_stats.rb_node);
188 rb_insert_color(&st->rb, &thread_stats); 188 rb_insert_color(&st->rb, &thread_stats);
189 189
190 thread_stat_findnew = thread_stat_findnew_after_first; 190 thread_stat_findnew = thread_stat_findnew_after_first;
191 return st; 191 return st;
192 } 192 }
193 193
194 /* build simple key function one is bigger than two */ 194 /* build simple key function one is bigger than two */
195 #define SINGLE_KEY(member) \ 195 #define SINGLE_KEY(member) \
196 static int lock_stat_key_ ## member(struct lock_stat *one, \ 196 static int lock_stat_key_ ## member(struct lock_stat *one, \
197 struct lock_stat *two) \ 197 struct lock_stat *two) \
198 { \ 198 { \
199 return one->member > two->member; \ 199 return one->member > two->member; \
200 } 200 }
201 201
202 SINGLE_KEY(nr_acquired) 202 SINGLE_KEY(nr_acquired)
203 SINGLE_KEY(nr_contended) 203 SINGLE_KEY(nr_contended)
204 SINGLE_KEY(wait_time_total) 204 SINGLE_KEY(wait_time_total)
205 SINGLE_KEY(wait_time_max) 205 SINGLE_KEY(wait_time_max)
206 206
207 static int lock_stat_key_wait_time_min(struct lock_stat *one, 207 static int lock_stat_key_wait_time_min(struct lock_stat *one,
208 struct lock_stat *two) 208 struct lock_stat *two)
209 { 209 {
210 u64 s1 = one->wait_time_min; 210 u64 s1 = one->wait_time_min;
211 u64 s2 = two->wait_time_min; 211 u64 s2 = two->wait_time_min;
212 if (s1 == ULLONG_MAX) 212 if (s1 == ULLONG_MAX)
213 s1 = 0; 213 s1 = 0;
214 if (s2 == ULLONG_MAX) 214 if (s2 == ULLONG_MAX)
215 s2 = 0; 215 s2 = 0;
216 return s1 > s2; 216 return s1 > s2;
217 } 217 }
218 218
219 struct lock_key { 219 struct lock_key {
220 /* 220 /*
221 * name: the value for specify by user 221 * name: the value for specify by user
222 * this should be simpler than raw name of member 222 * this should be simpler than raw name of member
223 * e.g. nr_acquired -> acquired, wait_time_total -> wait_total 223 * e.g. nr_acquired -> acquired, wait_time_total -> wait_total
224 */ 224 */
225 const char *name; 225 const char *name;
226 int (*key)(struct lock_stat*, struct lock_stat*); 226 int (*key)(struct lock_stat*, struct lock_stat*);
227 }; 227 };
228 228
229 static const char *sort_key = "acquired"; 229 static const char *sort_key = "acquired";
230 230
231 static int (*compare)(struct lock_stat *, struct lock_stat *); 231 static int (*compare)(struct lock_stat *, struct lock_stat *);
232 232
233 static struct rb_root result; /* place to store sorted data */ 233 static struct rb_root result; /* place to store sorted data */
234 234
235 #define DEF_KEY_LOCK(name, fn_suffix) \ 235 #define DEF_KEY_LOCK(name, fn_suffix) \
236 { #name, lock_stat_key_ ## fn_suffix } 236 { #name, lock_stat_key_ ## fn_suffix }
237 struct lock_key keys[] = { 237 struct lock_key keys[] = {
238 DEF_KEY_LOCK(acquired, nr_acquired), 238 DEF_KEY_LOCK(acquired, nr_acquired),
239 DEF_KEY_LOCK(contended, nr_contended), 239 DEF_KEY_LOCK(contended, nr_contended),
240 DEF_KEY_LOCK(wait_total, wait_time_total), 240 DEF_KEY_LOCK(wait_total, wait_time_total),
241 DEF_KEY_LOCK(wait_min, wait_time_min), 241 DEF_KEY_LOCK(wait_min, wait_time_min),
242 DEF_KEY_LOCK(wait_max, wait_time_max), 242 DEF_KEY_LOCK(wait_max, wait_time_max),
243 243
244 /* extra comparisons much complicated should be here */ 244 /* extra comparisons much complicated should be here */
245 245
246 { NULL, NULL } 246 { NULL, NULL }
247 }; 247 };
248 248
249 static void select_key(void) 249 static void select_key(void)
250 { 250 {
251 int i; 251 int i;
252 252
253 for (i = 0; keys[i].name; i++) { 253 for (i = 0; keys[i].name; i++) {
254 if (!strcmp(keys[i].name, sort_key)) { 254 if (!strcmp(keys[i].name, sort_key)) {
255 compare = keys[i].key; 255 compare = keys[i].key;
256 return; 256 return;
257 } 257 }
258 } 258 }
259 259
260 die("Unknown compare key:%s\n", sort_key); 260 die("Unknown compare key:%s\n", sort_key);
261 } 261 }
262 262
263 static void insert_to_result(struct lock_stat *st, 263 static void insert_to_result(struct lock_stat *st,
264 int (*bigger)(struct lock_stat *, struct lock_stat *)) 264 int (*bigger)(struct lock_stat *, struct lock_stat *))
265 { 265 {
266 struct rb_node **rb = &result.rb_node; 266 struct rb_node **rb = &result.rb_node;
267 struct rb_node *parent = NULL; 267 struct rb_node *parent = NULL;
268 struct lock_stat *p; 268 struct lock_stat *p;
269 269
270 while (*rb) { 270 while (*rb) {
271 p = container_of(*rb, struct lock_stat, rb); 271 p = container_of(*rb, struct lock_stat, rb);
272 parent = *rb; 272 parent = *rb;
273 273
274 if (bigger(st, p)) 274 if (bigger(st, p))
275 rb = &(*rb)->rb_left; 275 rb = &(*rb)->rb_left;
276 else 276 else
277 rb = &(*rb)->rb_right; 277 rb = &(*rb)->rb_right;
278 } 278 }
279 279
280 rb_link_node(&st->rb, parent, rb); 280 rb_link_node(&st->rb, parent, rb);
281 rb_insert_color(&st->rb, &result); 281 rb_insert_color(&st->rb, &result);
282 } 282 }
283 283
284 /* returns left most element of result, and erase it */ 284 /* returns left most element of result, and erase it */
285 static struct lock_stat *pop_from_result(void) 285 static struct lock_stat *pop_from_result(void)
286 { 286 {
287 struct rb_node *node = result.rb_node; 287 struct rb_node *node = result.rb_node;
288 288
289 if (!node) 289 if (!node)
290 return NULL; 290 return NULL;
291 291
292 while (node->rb_left) 292 while (node->rb_left)
293 node = node->rb_left; 293 node = node->rb_left;
294 294
295 rb_erase(node, &result); 295 rb_erase(node, &result);
296 return container_of(node, struct lock_stat, rb); 296 return container_of(node, struct lock_stat, rb);
297 } 297 }
298 298
299 static struct lock_stat *lock_stat_findnew(void *addr, const char *name) 299 static struct lock_stat *lock_stat_findnew(void *addr, const char *name)
300 { 300 {
301 struct list_head *entry = lockhashentry(addr); 301 struct list_head *entry = lockhashentry(addr);
302 struct lock_stat *ret, *new; 302 struct lock_stat *ret, *new;
303 303
304 list_for_each_entry(ret, entry, hash_entry) { 304 list_for_each_entry(ret, entry, hash_entry) {
305 if (ret->addr == addr) 305 if (ret->addr == addr)
306 return ret; 306 return ret;
307 } 307 }
308 308
309 new = zalloc(sizeof(struct lock_stat)); 309 new = zalloc(sizeof(struct lock_stat));
310 if (!new) 310 if (!new)
311 goto alloc_failed; 311 goto alloc_failed;
312 312
313 new->addr = addr; 313 new->addr = addr;
314 new->name = zalloc(sizeof(char) * strlen(name) + 1); 314 new->name = zalloc(sizeof(char) * strlen(name) + 1);
315 if (!new->name) 315 if (!new->name)
316 goto alloc_failed; 316 goto alloc_failed;
317 strcpy(new->name, name); 317 strcpy(new->name, name);
318 318
319 new->wait_time_min = ULLONG_MAX; 319 new->wait_time_min = ULLONG_MAX;
320 320
321 list_add(&new->hash_entry, entry); 321 list_add(&new->hash_entry, entry);
322 return new; 322 return new;
323 323
324 alloc_failed: 324 alloc_failed:
325 die("memory allocation failed\n"); 325 die("memory allocation failed\n");
326 } 326 }
327 327
328 static char const *input_name = "perf.data"; 328 static char const *input_name = "perf.data";
329 329
330 struct raw_event_sample { 330 struct raw_event_sample {
331 u32 size; 331 u32 size;
332 char data[0]; 332 char data[0];
333 }; 333 };
334 334
335 struct trace_acquire_event { 335 struct trace_acquire_event {
336 void *addr; 336 void *addr;
337 const char *name; 337 const char *name;
338 int flag; 338 int flag;
339 }; 339 };
340 340
341 struct trace_acquired_event { 341 struct trace_acquired_event {
342 void *addr; 342 void *addr;
343 const char *name; 343 const char *name;
344 }; 344 };
345 345
346 struct trace_contended_event { 346 struct trace_contended_event {
347 void *addr; 347 void *addr;
348 const char *name; 348 const char *name;
349 }; 349 };
350 350
351 struct trace_release_event { 351 struct trace_release_event {
352 void *addr; 352 void *addr;
353 const char *name; 353 const char *name;
354 }; 354 };
355 355
356 struct trace_lock_handler { 356 struct trace_lock_handler {
357 void (*acquire_event)(struct trace_acquire_event *, 357 void (*acquire_event)(struct trace_acquire_event *,
358 struct event *, 358 struct event *,
359 int cpu, 359 int cpu,
360 u64 timestamp, 360 u64 timestamp,
361 struct thread *thread); 361 struct thread *thread);
362 362
363 void (*acquired_event)(struct trace_acquired_event *, 363 void (*acquired_event)(struct trace_acquired_event *,
364 struct event *, 364 struct event *,
365 int cpu, 365 int cpu,
366 u64 timestamp, 366 u64 timestamp,
367 struct thread *thread); 367 struct thread *thread);
368 368
369 void (*contended_event)(struct trace_contended_event *, 369 void (*contended_event)(struct trace_contended_event *,
370 struct event *, 370 struct event *,
371 int cpu, 371 int cpu,
372 u64 timestamp, 372 u64 timestamp,
373 struct thread *thread); 373 struct thread *thread);
374 374
375 void (*release_event)(struct trace_release_event *, 375 void (*release_event)(struct trace_release_event *,
376 struct event *, 376 struct event *,
377 int cpu, 377 int cpu,
378 u64 timestamp, 378 u64 timestamp,
379 struct thread *thread); 379 struct thread *thread);
380 }; 380 };
381 381
382 static struct lock_seq_stat *get_seq(struct thread_stat *ts, void *addr) 382 static struct lock_seq_stat *get_seq(struct thread_stat *ts, void *addr)
383 { 383 {
384 struct lock_seq_stat *seq; 384 struct lock_seq_stat *seq;
385 385
386 list_for_each_entry(seq, &ts->seq_list, list) { 386 list_for_each_entry(seq, &ts->seq_list, list) {
387 if (seq->addr == addr) 387 if (seq->addr == addr)
388 return seq; 388 return seq;
389 } 389 }
390 390
391 seq = zalloc(sizeof(struct lock_seq_stat)); 391 seq = zalloc(sizeof(struct lock_seq_stat));
392 if (!seq) 392 if (!seq)
393 die("Not enough memory\n"); 393 die("Not enough memory\n");
394 seq->state = SEQ_STATE_UNINITIALIZED; 394 seq->state = SEQ_STATE_UNINITIALIZED;
395 seq->addr = addr; 395 seq->addr = addr;
396 396
397 list_add(&seq->list, &ts->seq_list); 397 list_add(&seq->list, &ts->seq_list);
398 return seq; 398 return seq;
399 } 399 }
400 400
401 enum broken_state { 401 enum broken_state {
402 BROKEN_ACQUIRE, 402 BROKEN_ACQUIRE,
403 BROKEN_ACQUIRED, 403 BROKEN_ACQUIRED,
404 BROKEN_CONTENDED, 404 BROKEN_CONTENDED,
405 BROKEN_RELEASE, 405 BROKEN_RELEASE,
406 BROKEN_MAX, 406 BROKEN_MAX,
407 }; 407 };
408 408
409 static int bad_hist[BROKEN_MAX]; 409 static int bad_hist[BROKEN_MAX];
410 410
411 enum acquire_flags { 411 enum acquire_flags {
412 TRY_LOCK = 1, 412 TRY_LOCK = 1,
413 READ_LOCK = 2, 413 READ_LOCK = 2,
414 }; 414 };
415 415
416 static void 416 static void
417 report_lock_acquire_event(struct trace_acquire_event *acquire_event, 417 report_lock_acquire_event(struct trace_acquire_event *acquire_event,
418 struct event *__event __used, 418 struct event *__event __used,
419 int cpu __used, 419 int cpu __used,
420 u64 timestamp __used, 420 u64 timestamp __used,
421 struct thread *thread __used) 421 struct thread *thread __used)
422 { 422 {
423 struct lock_stat *ls; 423 struct lock_stat *ls;
424 struct thread_stat *ts; 424 struct thread_stat *ts;
425 struct lock_seq_stat *seq; 425 struct lock_seq_stat *seq;
426 426
427 ls = lock_stat_findnew(acquire_event->addr, acquire_event->name); 427 ls = lock_stat_findnew(acquire_event->addr, acquire_event->name);
428 if (ls->discard) 428 if (ls->discard)
429 return; 429 return;
430 430
431 ts = thread_stat_findnew(thread->pid); 431 ts = thread_stat_findnew(thread->pid);
432 seq = get_seq(ts, acquire_event->addr); 432 seq = get_seq(ts, acquire_event->addr);
433 433
434 switch (seq->state) { 434 switch (seq->state) {
435 case SEQ_STATE_UNINITIALIZED: 435 case SEQ_STATE_UNINITIALIZED:
436 case SEQ_STATE_RELEASED: 436 case SEQ_STATE_RELEASED:
437 if (!acquire_event->flag) { 437 if (!acquire_event->flag) {
438 seq->state = SEQ_STATE_ACQUIRING; 438 seq->state = SEQ_STATE_ACQUIRING;
439 } else { 439 } else {
440 if (acquire_event->flag & TRY_LOCK) 440 if (acquire_event->flag & TRY_LOCK)
441 ls->nr_trylock++; 441 ls->nr_trylock++;
442 if (acquire_event->flag & READ_LOCK) 442 if (acquire_event->flag & READ_LOCK)
443 ls->nr_readlock++; 443 ls->nr_readlock++;
444 seq->state = SEQ_STATE_READ_ACQUIRED; 444 seq->state = SEQ_STATE_READ_ACQUIRED;
445 seq->read_count = 1; 445 seq->read_count = 1;
446 ls->nr_acquired++; 446 ls->nr_acquired++;
447 } 447 }
448 break; 448 break;
449 case SEQ_STATE_READ_ACQUIRED: 449 case SEQ_STATE_READ_ACQUIRED:
450 if (acquire_event->flag & READ_LOCK) { 450 if (acquire_event->flag & READ_LOCK) {
451 seq->read_count++; 451 seq->read_count++;
452 ls->nr_acquired++; 452 ls->nr_acquired++;
453 goto end; 453 goto end;
454 } else { 454 } else {
455 goto broken; 455 goto broken;
456 } 456 }
457 break; 457 break;
458 case SEQ_STATE_ACQUIRED: 458 case SEQ_STATE_ACQUIRED:
459 case SEQ_STATE_ACQUIRING: 459 case SEQ_STATE_ACQUIRING:
460 case SEQ_STATE_CONTENDED: 460 case SEQ_STATE_CONTENDED:
461 broken: 461 broken:
462 /* broken lock sequence, discard it */ 462 /* broken lock sequence, discard it */
463 ls->discard = 1; 463 ls->discard = 1;
464 bad_hist[BROKEN_ACQUIRE]++; 464 bad_hist[BROKEN_ACQUIRE]++;
465 list_del(&seq->list); 465 list_del(&seq->list);
466 free(seq); 466 free(seq);
467 goto end; 467 goto end;
468 break; 468 break;
469 default: 469 default:
470 BUG_ON("Unknown state of lock sequence found!\n"); 470 BUG_ON("Unknown state of lock sequence found!\n");
471 break; 471 break;
472 } 472 }
473 473
474 ls->nr_acquire++; 474 ls->nr_acquire++;
475 seq->prev_event_time = timestamp; 475 seq->prev_event_time = timestamp;
476 end: 476 end:
477 return; 477 return;
478 } 478 }
479 479
480 static void 480 static void
481 report_lock_acquired_event(struct trace_acquired_event *acquired_event, 481 report_lock_acquired_event(struct trace_acquired_event *acquired_event,
482 struct event *__event __used, 482 struct event *__event __used,
483 int cpu __used, 483 int cpu __used,
484 u64 timestamp __used, 484 u64 timestamp __used,
485 struct thread *thread __used) 485 struct thread *thread __used)
486 { 486 {
487 struct lock_stat *ls; 487 struct lock_stat *ls;
488 struct thread_stat *ts; 488 struct thread_stat *ts;
489 struct lock_seq_stat *seq; 489 struct lock_seq_stat *seq;
490 u64 contended_term; 490 u64 contended_term;
491 491
492 ls = lock_stat_findnew(acquired_event->addr, acquired_event->name); 492 ls = lock_stat_findnew(acquired_event->addr, acquired_event->name);
493 if (ls->discard) 493 if (ls->discard)
494 return; 494 return;
495 495
496 ts = thread_stat_findnew(thread->pid); 496 ts = thread_stat_findnew(thread->pid);
497 seq = get_seq(ts, acquired_event->addr); 497 seq = get_seq(ts, acquired_event->addr);
498 498
499 switch (seq->state) { 499 switch (seq->state) {
500 case SEQ_STATE_UNINITIALIZED: 500 case SEQ_STATE_UNINITIALIZED:
501 /* orphan event, do nothing */ 501 /* orphan event, do nothing */
502 return; 502 return;
503 case SEQ_STATE_ACQUIRING: 503 case SEQ_STATE_ACQUIRING:
504 break; 504 break;
505 case SEQ_STATE_CONTENDED: 505 case SEQ_STATE_CONTENDED:
506 contended_term = timestamp - seq->prev_event_time; 506 contended_term = timestamp - seq->prev_event_time;
507 ls->wait_time_total += contended_term; 507 ls->wait_time_total += contended_term;
508 if (contended_term < ls->wait_time_min) 508 if (contended_term < ls->wait_time_min)
509 ls->wait_time_min = contended_term; 509 ls->wait_time_min = contended_term;
510 if (ls->wait_time_max < contended_term) 510 if (ls->wait_time_max < contended_term)
511 ls->wait_time_max = contended_term; 511 ls->wait_time_max = contended_term;
512 break; 512 break;
513 case SEQ_STATE_RELEASED: 513 case SEQ_STATE_RELEASED:
514 case SEQ_STATE_ACQUIRED: 514 case SEQ_STATE_ACQUIRED:
515 case SEQ_STATE_READ_ACQUIRED: 515 case SEQ_STATE_READ_ACQUIRED:
516 /* broken lock sequence, discard it */ 516 /* broken lock sequence, discard it */
517 ls->discard = 1; 517 ls->discard = 1;
518 bad_hist[BROKEN_ACQUIRED]++; 518 bad_hist[BROKEN_ACQUIRED]++;
519 list_del(&seq->list); 519 list_del(&seq->list);
520 free(seq); 520 free(seq);
521 goto end; 521 goto end;
522 break; 522 break;
523 523
524 default: 524 default:
525 BUG_ON("Unknown state of lock sequence found!\n"); 525 BUG_ON("Unknown state of lock sequence found!\n");
526 break; 526 break;
527 } 527 }
528 528
529 seq->state = SEQ_STATE_ACQUIRED; 529 seq->state = SEQ_STATE_ACQUIRED;
530 ls->nr_acquired++; 530 ls->nr_acquired++;
531 seq->prev_event_time = timestamp; 531 seq->prev_event_time = timestamp;
532 end: 532 end:
533 return; 533 return;
534 } 534 }
535 535
536 static void 536 static void
537 report_lock_contended_event(struct trace_contended_event *contended_event, 537 report_lock_contended_event(struct trace_contended_event *contended_event,
538 struct event *__event __used, 538 struct event *__event __used,
539 int cpu __used, 539 int cpu __used,
540 u64 timestamp __used, 540 u64 timestamp __used,
541 struct thread *thread __used) 541 struct thread *thread __used)
542 { 542 {
543 struct lock_stat *ls; 543 struct lock_stat *ls;
544 struct thread_stat *ts; 544 struct thread_stat *ts;
545 struct lock_seq_stat *seq; 545 struct lock_seq_stat *seq;
546 546
547 ls = lock_stat_findnew(contended_event->addr, contended_event->name); 547 ls = lock_stat_findnew(contended_event->addr, contended_event->name);
548 if (ls->discard) 548 if (ls->discard)
549 return; 549 return;
550 550
551 ts = thread_stat_findnew(thread->pid); 551 ts = thread_stat_findnew(thread->pid);
552 seq = get_seq(ts, contended_event->addr); 552 seq = get_seq(ts, contended_event->addr);
553 553
554 switch (seq->state) { 554 switch (seq->state) {
555 case SEQ_STATE_UNINITIALIZED: 555 case SEQ_STATE_UNINITIALIZED:
556 /* orphan event, do nothing */ 556 /* orphan event, do nothing */
557 return; 557 return;
558 case SEQ_STATE_ACQUIRING: 558 case SEQ_STATE_ACQUIRING:
559 break; 559 break;
560 case SEQ_STATE_RELEASED: 560 case SEQ_STATE_RELEASED:
561 case SEQ_STATE_ACQUIRED: 561 case SEQ_STATE_ACQUIRED:
562 case SEQ_STATE_READ_ACQUIRED: 562 case SEQ_STATE_READ_ACQUIRED:
563 case SEQ_STATE_CONTENDED: 563 case SEQ_STATE_CONTENDED:
564 /* broken lock sequence, discard it */ 564 /* broken lock sequence, discard it */
565 ls->discard = 1; 565 ls->discard = 1;
566 bad_hist[BROKEN_CONTENDED]++; 566 bad_hist[BROKEN_CONTENDED]++;
567 list_del(&seq->list); 567 list_del(&seq->list);
568 free(seq); 568 free(seq);
569 goto end; 569 goto end;
570 break; 570 break;
571 default: 571 default:
572 BUG_ON("Unknown state of lock sequence found!\n"); 572 BUG_ON("Unknown state of lock sequence found!\n");
573 break; 573 break;
574 } 574 }
575 575
576 seq->state = SEQ_STATE_CONTENDED; 576 seq->state = SEQ_STATE_CONTENDED;
577 ls->nr_contended++; 577 ls->nr_contended++;
578 seq->prev_event_time = timestamp; 578 seq->prev_event_time = timestamp;
579 end: 579 end:
580 return; 580 return;
581 } 581 }
582 582
583 static void 583 static void
584 report_lock_release_event(struct trace_release_event *release_event, 584 report_lock_release_event(struct trace_release_event *release_event,
585 struct event *__event __used, 585 struct event *__event __used,
586 int cpu __used, 586 int cpu __used,
587 u64 timestamp __used, 587 u64 timestamp __used,
588 struct thread *thread __used) 588 struct thread *thread __used)
589 { 589 {
590 struct lock_stat *ls; 590 struct lock_stat *ls;
591 struct thread_stat *ts; 591 struct thread_stat *ts;
592 struct lock_seq_stat *seq; 592 struct lock_seq_stat *seq;
593 593
594 ls = lock_stat_findnew(release_event->addr, release_event->name); 594 ls = lock_stat_findnew(release_event->addr, release_event->name);
595 if (ls->discard) 595 if (ls->discard)
596 return; 596 return;
597 597
598 ts = thread_stat_findnew(thread->pid); 598 ts = thread_stat_findnew(thread->pid);
599 seq = get_seq(ts, release_event->addr); 599 seq = get_seq(ts, release_event->addr);
600 600
601 switch (seq->state) { 601 switch (seq->state) {
602 case SEQ_STATE_UNINITIALIZED: 602 case SEQ_STATE_UNINITIALIZED:
603 goto end; 603 goto end;
604 break; 604 break;
605 case SEQ_STATE_ACQUIRED: 605 case SEQ_STATE_ACQUIRED:
606 break; 606 break;
607 case SEQ_STATE_READ_ACQUIRED: 607 case SEQ_STATE_READ_ACQUIRED:
608 seq->read_count--; 608 seq->read_count--;
609 BUG_ON(seq->read_count < 0); 609 BUG_ON(seq->read_count < 0);
610 if (!seq->read_count) { 610 if (!seq->read_count) {
611 ls->nr_release++; 611 ls->nr_release++;
612 goto end; 612 goto end;
613 } 613 }
614 break; 614 break;
615 case SEQ_STATE_ACQUIRING: 615 case SEQ_STATE_ACQUIRING:
616 case SEQ_STATE_CONTENDED: 616 case SEQ_STATE_CONTENDED:
617 case SEQ_STATE_RELEASED: 617 case SEQ_STATE_RELEASED:
618 /* broken lock sequence, discard it */ 618 /* broken lock sequence, discard it */
619 ls->discard = 1; 619 ls->discard = 1;
620 bad_hist[BROKEN_RELEASE]++; 620 bad_hist[BROKEN_RELEASE]++;
621 goto free_seq; 621 goto free_seq;
622 break; 622 break;
623 default: 623 default:
624 BUG_ON("Unknown state of lock sequence found!\n"); 624 BUG_ON("Unknown state of lock sequence found!\n");
625 break; 625 break;
626 } 626 }
627 627
628 ls->nr_release++; 628 ls->nr_release++;
629 free_seq: 629 free_seq:
630 list_del(&seq->list); 630 list_del(&seq->list);
631 free(seq); 631 free(seq);
632 end: 632 end:
633 return; 633 return;
634 } 634 }
635 635
636 /* lock oriented handlers */ 636 /* lock oriented handlers */
637 /* TODO: handlers for CPU oriented, thread oriented */ 637 /* TODO: handlers for CPU oriented, thread oriented */
638 static struct trace_lock_handler report_lock_ops = { 638 static struct trace_lock_handler report_lock_ops = {
639 .acquire_event = report_lock_acquire_event, 639 .acquire_event = report_lock_acquire_event,
640 .acquired_event = report_lock_acquired_event, 640 .acquired_event = report_lock_acquired_event,
641 .contended_event = report_lock_contended_event, 641 .contended_event = report_lock_contended_event,
642 .release_event = report_lock_release_event, 642 .release_event = report_lock_release_event,
643 }; 643 };
644 644
645 static struct trace_lock_handler *trace_handler; 645 static struct trace_lock_handler *trace_handler;
646 646
647 static void 647 static void
648 process_lock_acquire_event(void *data, 648 process_lock_acquire_event(void *data,
649 struct event *event __used, 649 struct event *event __used,
650 int cpu __used, 650 int cpu __used,
651 u64 timestamp __used, 651 u64 timestamp __used,
652 struct thread *thread __used) 652 struct thread *thread __used)
653 { 653 {
654 struct trace_acquire_event acquire_event; 654 struct trace_acquire_event acquire_event;
655 u64 tmp; /* this is required for casting... */ 655 u64 tmp; /* this is required for casting... */
656 656
657 tmp = raw_field_value(event, "lockdep_addr", data); 657 tmp = raw_field_value(event, "lockdep_addr", data);
658 memcpy(&acquire_event.addr, &tmp, sizeof(void *)); 658 memcpy(&acquire_event.addr, &tmp, sizeof(void *));
659 acquire_event.name = (char *)raw_field_ptr(event, "name", data); 659 acquire_event.name = (char *)raw_field_ptr(event, "name", data);
660 acquire_event.flag = (int)raw_field_value(event, "flag", data); 660 acquire_event.flag = (int)raw_field_value(event, "flag", data);
661 661
662 if (trace_handler->acquire_event) 662 if (trace_handler->acquire_event)
663 trace_handler->acquire_event(&acquire_event, event, cpu, timestamp, thread); 663 trace_handler->acquire_event(&acquire_event, event, cpu, timestamp, thread);
664 } 664 }
665 665
666 static void 666 static void
667 process_lock_acquired_event(void *data, 667 process_lock_acquired_event(void *data,
668 struct event *event __used, 668 struct event *event __used,
669 int cpu __used, 669 int cpu __used,
670 u64 timestamp __used, 670 u64 timestamp __used,
671 struct thread *thread __used) 671 struct thread *thread __used)
672 { 672 {
673 struct trace_acquired_event acquired_event; 673 struct trace_acquired_event acquired_event;
674 u64 tmp; /* this is required for casting... */ 674 u64 tmp; /* this is required for casting... */
675 675
676 tmp = raw_field_value(event, "lockdep_addr", data); 676 tmp = raw_field_value(event, "lockdep_addr", data);
677 memcpy(&acquired_event.addr, &tmp, sizeof(void *)); 677 memcpy(&acquired_event.addr, &tmp, sizeof(void *));
678 acquired_event.name = (char *)raw_field_ptr(event, "name", data); 678 acquired_event.name = (char *)raw_field_ptr(event, "name", data);
679 679
680 if (trace_handler->acquire_event) 680 if (trace_handler->acquire_event)
681 trace_handler->acquired_event(&acquired_event, event, cpu, timestamp, thread); 681 trace_handler->acquired_event(&acquired_event, event, cpu, timestamp, thread);
682 } 682 }
683 683
684 static void 684 static void
685 process_lock_contended_event(void *data, 685 process_lock_contended_event(void *data,
686 struct event *event __used, 686 struct event *event __used,
687 int cpu __used, 687 int cpu __used,
688 u64 timestamp __used, 688 u64 timestamp __used,
689 struct thread *thread __used) 689 struct thread *thread __used)
690 { 690 {
691 struct trace_contended_event contended_event; 691 struct trace_contended_event contended_event;
692 u64 tmp; /* this is required for casting... */ 692 u64 tmp; /* this is required for casting... */
693 693
694 tmp = raw_field_value(event, "lockdep_addr", data); 694 tmp = raw_field_value(event, "lockdep_addr", data);
695 memcpy(&contended_event.addr, &tmp, sizeof(void *)); 695 memcpy(&contended_event.addr, &tmp, sizeof(void *));
696 contended_event.name = (char *)raw_field_ptr(event, "name", data); 696 contended_event.name = (char *)raw_field_ptr(event, "name", data);
697 697
698 if (trace_handler->acquire_event) 698 if (trace_handler->acquire_event)
699 trace_handler->contended_event(&contended_event, event, cpu, timestamp, thread); 699 trace_handler->contended_event(&contended_event, event, cpu, timestamp, thread);
700 } 700 }
701 701
702 static void 702 static void
703 process_lock_release_event(void *data, 703 process_lock_release_event(void *data,
704 struct event *event __used, 704 struct event *event __used,
705 int cpu __used, 705 int cpu __used,
706 u64 timestamp __used, 706 u64 timestamp __used,
707 struct thread *thread __used) 707 struct thread *thread __used)
708 { 708 {
709 struct trace_release_event release_event; 709 struct trace_release_event release_event;
710 u64 tmp; /* this is required for casting... */ 710 u64 tmp; /* this is required for casting... */
711 711
712 tmp = raw_field_value(event, "lockdep_addr", data); 712 tmp = raw_field_value(event, "lockdep_addr", data);
713 memcpy(&release_event.addr, &tmp, sizeof(void *)); 713 memcpy(&release_event.addr, &tmp, sizeof(void *));
714 release_event.name = (char *)raw_field_ptr(event, "name", data); 714 release_event.name = (char *)raw_field_ptr(event, "name", data);
715 715
716 if (trace_handler->acquire_event) 716 if (trace_handler->acquire_event)
717 trace_handler->release_event(&release_event, event, cpu, timestamp, thread); 717 trace_handler->release_event(&release_event, event, cpu, timestamp, thread);
718 } 718 }
719 719
720 static void 720 static void
721 process_raw_event(void *data, int cpu, u64 timestamp, struct thread *thread) 721 process_raw_event(void *data, int cpu, u64 timestamp, struct thread *thread)
722 { 722 {
723 struct event *event; 723 struct event *event;
724 int type; 724 int type;
725 725
726 type = trace_parse_common_type(data); 726 type = trace_parse_common_type(data);
727 event = trace_find_event(type); 727 event = trace_find_event(type);
728 728
729 if (!strcmp(event->name, "lock_acquire")) 729 if (!strcmp(event->name, "lock_acquire"))
730 process_lock_acquire_event(data, event, cpu, timestamp, thread); 730 process_lock_acquire_event(data, event, cpu, timestamp, thread);
731 if (!strcmp(event->name, "lock_acquired")) 731 if (!strcmp(event->name, "lock_acquired"))
732 process_lock_acquired_event(data, event, cpu, timestamp, thread); 732 process_lock_acquired_event(data, event, cpu, timestamp, thread);
733 if (!strcmp(event->name, "lock_contended")) 733 if (!strcmp(event->name, "lock_contended"))
734 process_lock_contended_event(data, event, cpu, timestamp, thread); 734 process_lock_contended_event(data, event, cpu, timestamp, thread);
735 if (!strcmp(event->name, "lock_release")) 735 if (!strcmp(event->name, "lock_release"))
736 process_lock_release_event(data, event, cpu, timestamp, thread); 736 process_lock_release_event(data, event, cpu, timestamp, thread);
737 } 737 }
738 738
739 static void print_bad_events(int bad, int total) 739 static void print_bad_events(int bad, int total)
740 { 740 {
741 /* Output for debug, this have to be removed */ 741 /* Output for debug, this have to be removed */
742 int i; 742 int i;
743 const char *name[4] = 743 const char *name[4] =
744 { "acquire", "acquired", "contended", "release" }; 744 { "acquire", "acquired", "contended", "release" };
745 745
746 pr_info("\n=== output for debug===\n\n"); 746 pr_info("\n=== output for debug===\n\n");
747 pr_info("bad: %d, total: %d\n", bad, total); 747 pr_info("bad: %d, total: %d\n", bad, total);
748 pr_info("bad rate: %f %%\n", (double)bad / (double)total * 100); 748 pr_info("bad rate: %f %%\n", (double)bad / (double)total * 100);
749 pr_info("histogram of events caused bad sequence\n"); 749 pr_info("histogram of events caused bad sequence\n");
750 for (i = 0; i < BROKEN_MAX; i++) 750 for (i = 0; i < BROKEN_MAX; i++)
751 pr_info(" %10s: %d\n", name[i], bad_hist[i]); 751 pr_info(" %10s: %d\n", name[i], bad_hist[i]);
752 } 752 }
753 753
754 /* TODO: various way to print, coloring, nano or milli sec */ 754 /* TODO: various way to print, coloring, nano or milli sec */
755 static void print_result(void) 755 static void print_result(void)
756 { 756 {
757 struct lock_stat *st; 757 struct lock_stat *st;
758 char cut_name[20]; 758 char cut_name[20];
759 int bad, total; 759 int bad, total;
760 760
761 pr_info("%20s ", "Name"); 761 pr_info("%20s ", "Name");
762 pr_info("%10s ", "acquired"); 762 pr_info("%10s ", "acquired");
763 pr_info("%10s ", "contended"); 763 pr_info("%10s ", "contended");
764 764
765 pr_info("%15s ", "total wait (ns)"); 765 pr_info("%15s ", "total wait (ns)");
766 pr_info("%15s ", "max wait (ns)"); 766 pr_info("%15s ", "max wait (ns)");
767 pr_info("%15s ", "min wait (ns)"); 767 pr_info("%15s ", "min wait (ns)");
768 768
769 pr_info("\n\n"); 769 pr_info("\n\n");
770 770
771 bad = total = 0; 771 bad = total = 0;
772 while ((st = pop_from_result())) { 772 while ((st = pop_from_result())) {
773 total++; 773 total++;
774 if (st->discard) { 774 if (st->discard) {
775 bad++; 775 bad++;
776 continue; 776 continue;
777 } 777 }
778 bzero(cut_name, 20); 778 bzero(cut_name, 20);
779 779
780 if (strlen(st->name) < 16) { 780 if (strlen(st->name) < 16) {
781 /* output raw name */ 781 /* output raw name */
782 pr_info("%20s ", st->name); 782 pr_info("%20s ", st->name);
783 } else { 783 } else {
784 strncpy(cut_name, st->name, 16); 784 strncpy(cut_name, st->name, 16);
785 cut_name[16] = '.'; 785 cut_name[16] = '.';
786 cut_name[17] = '.'; 786 cut_name[17] = '.';
787 cut_name[18] = '.'; 787 cut_name[18] = '.';
788 cut_name[19] = '\0'; 788 cut_name[19] = '\0';
789 /* cut off name for saving output style */ 789 /* cut off name for saving output style */
790 pr_info("%20s ", cut_name); 790 pr_info("%20s ", cut_name);
791 } 791 }
792 792
793 pr_info("%10u ", st->nr_acquired); 793 pr_info("%10u ", st->nr_acquired);
794 pr_info("%10u ", st->nr_contended); 794 pr_info("%10u ", st->nr_contended);
795 795
796 pr_info("%15" PRIu64 " ", st->wait_time_total); 796 pr_info("%15" PRIu64 " ", st->wait_time_total);
797 pr_info("%15" PRIu64 " ", st->wait_time_max); 797 pr_info("%15" PRIu64 " ", st->wait_time_max);
798 pr_info("%15" PRIu64 " ", st->wait_time_min == ULLONG_MAX ? 798 pr_info("%15" PRIu64 " ", st->wait_time_min == ULLONG_MAX ?
799 0 : st->wait_time_min); 799 0 : st->wait_time_min);
800 pr_info("\n"); 800 pr_info("\n");
801 } 801 }
802 802
803 print_bad_events(bad, total); 803 print_bad_events(bad, total);
804 } 804 }
805 805
806 static bool info_threads, info_map; 806 static bool info_threads, info_map;
807 807
808 static void dump_threads(void) 808 static void dump_threads(void)
809 { 809 {
810 struct thread_stat *st; 810 struct thread_stat *st;
811 struct rb_node *node; 811 struct rb_node *node;
812 struct thread *t; 812 struct thread *t;
813 813
814 pr_info("%10s: comm\n", "Thread ID"); 814 pr_info("%10s: comm\n", "Thread ID");
815 815
816 node = rb_first(&thread_stats); 816 node = rb_first(&thread_stats);
817 while (node) { 817 while (node) {
818 st = container_of(node, struct thread_stat, rb); 818 st = container_of(node, struct thread_stat, rb);
819 t = perf_session__findnew(session, st->tid); 819 t = perf_session__findnew(session, st->tid);
820 pr_info("%10d: %s\n", st->tid, t->comm); 820 pr_info("%10d: %s\n", st->tid, t->comm);
821 node = rb_next(node); 821 node = rb_next(node);
822 }; 822 };
823 } 823 }
824 824
825 static void dump_map(void) 825 static void dump_map(void)
826 { 826 {
827 unsigned int i; 827 unsigned int i;
828 struct lock_stat *st; 828 struct lock_stat *st;
829 829
830 pr_info("Address of instance: name of class\n"); 830 pr_info("Address of instance: name of class\n");
831 for (i = 0; i < LOCKHASH_SIZE; i++) { 831 for (i = 0; i < LOCKHASH_SIZE; i++) {
832 list_for_each_entry(st, &lockhash_table[i], hash_entry) { 832 list_for_each_entry(st, &lockhash_table[i], hash_entry) {
833 pr_info(" %p: %s\n", st->addr, st->name); 833 pr_info(" %p: %s\n", st->addr, st->name);
834 } 834 }
835 } 835 }
836 } 836 }
837 837
838 static void dump_info(void) 838 static void dump_info(void)
839 { 839 {
840 if (info_threads) 840 if (info_threads)
841 dump_threads(); 841 dump_threads();
842 else if (info_map) 842 else if (info_map)
843 dump_map(); 843 dump_map();
844 else 844 else
845 die("Unknown type of information\n"); 845 die("Unknown type of information\n");
846 } 846 }
847 847
848 static int process_sample_event(union perf_event *event, 848 static int process_sample_event(union perf_event *event,
849 struct perf_sample *sample, 849 struct perf_sample *sample,
850 struct perf_evsel *evsel __used, 850 struct perf_evsel *evsel __used,
851 struct perf_session *s) 851 struct perf_session *s)
852 { 852 {
853 struct thread *thread = perf_session__findnew(s, sample->tid); 853 struct thread *thread = perf_session__findnew(s, sample->tid);
854 854
855 if (thread == NULL) { 855 if (thread == NULL) {
856 pr_debug("problem processing %d event, skipping it.\n", 856 pr_debug("problem processing %d event, skipping it.\n",
857 event->header.type); 857 event->header.type);
858 return -1; 858 return -1;
859 } 859 }
860 860
861 process_raw_event(sample->raw_data, sample->cpu, sample->time, thread); 861 process_raw_event(sample->raw_data, sample->cpu, sample->time, thread);
862 862
863 return 0; 863 return 0;
864 } 864 }
865 865
866 static struct perf_event_ops eops = { 866 static struct perf_event_ops eops = {
867 .sample = process_sample_event, 867 .sample = process_sample_event,
868 .comm = perf_event__process_comm, 868 .comm = perf_event__process_comm,
869 .ordered_samples = true, 869 .ordered_samples = true,
870 }; 870 };
871 871
872 static int read_events(void) 872 static int read_events(void)
873 { 873 {
874 session = perf_session__new(input_name, O_RDONLY, 0, false, &eops); 874 session = perf_session__new(input_name, O_RDONLY, 0, false, &eops);
875 if (!session) 875 if (!session)
876 die("Initializing perf session failed\n"); 876 die("Initializing perf session failed\n");
877 877
878 return perf_session__process_events(session, &eops); 878 return perf_session__process_events(session, &eops);
879 } 879 }
880 880
881 static void sort_result(void) 881 static void sort_result(void)
882 { 882 {
883 unsigned int i; 883 unsigned int i;
884 struct lock_stat *st; 884 struct lock_stat *st;
885 885
886 for (i = 0; i < LOCKHASH_SIZE; i++) { 886 for (i = 0; i < LOCKHASH_SIZE; i++) {
887 list_for_each_entry(st, &lockhash_table[i], hash_entry) { 887 list_for_each_entry(st, &lockhash_table[i], hash_entry) {
888 insert_to_result(st, compare); 888 insert_to_result(st, compare);
889 } 889 }
890 } 890 }
891 } 891 }
892 892
893 static void __cmd_report(void) 893 static void __cmd_report(void)
894 { 894 {
895 setup_pager(); 895 setup_pager();
896 select_key(); 896 select_key();
897 read_events(); 897 read_events();
898 sort_result(); 898 sort_result();
899 print_result(); 899 print_result();
900 } 900 }
901 901
902 static const char * const report_usage[] = { 902 static const char * const report_usage[] = {
903 "perf lock report [<options>]", 903 "perf lock report [<options>]",
904 NULL 904 NULL
905 }; 905 };
906 906
907 static const struct option report_options[] = { 907 static const struct option report_options[] = {
908 OPT_STRING('k', "key", &sort_key, "acquired", 908 OPT_STRING('k', "key", &sort_key, "acquired",
909 "key for sorting (acquired / contended / wait_total / wait_max / wait_min)"), 909 "key for sorting (acquired / contended / wait_total / wait_max / wait_min)"),
910 /* TODO: type */ 910 /* TODO: type */
911 OPT_END() 911 OPT_END()
912 }; 912 };
913 913
914 static const char * const info_usage[] = { 914 static const char * const info_usage[] = {
915 "perf lock info [<options>]", 915 "perf lock info [<options>]",
916 NULL 916 NULL
917 }; 917 };
918 918
919 static const struct option info_options[] = { 919 static const struct option info_options[] = {
920 OPT_BOOLEAN('t', "threads", &info_threads, 920 OPT_BOOLEAN('t', "threads", &info_threads,
921 "dump thread list in perf.data"), 921 "dump thread list in perf.data"),
922 OPT_BOOLEAN('m', "map", &info_map, 922 OPT_BOOLEAN('m', "map", &info_map,
923 "map of lock instances (name:address table)"), 923 "map of lock instances (name:address table)"),
924 OPT_END() 924 OPT_END()
925 }; 925 };
926 926
927 static const char * const lock_usage[] = { 927 static const char * const lock_usage[] = {
928 "perf lock [<options>] {record|trace|report}", 928 "perf lock [<options>] {record|trace|report}",
929 NULL 929 NULL
930 }; 930 };
931 931
932 static const struct option lock_options[] = { 932 static const struct option lock_options[] = {
933 OPT_STRING('i', "input", &input_name, "file", "input file name"), 933 OPT_STRING('i', "input", &input_name, "file", "input file name"),
934 OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"), 934 OPT_INCR('v', "verbose", &verbose, "be more verbose (show symbol address, etc)"),
935 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"), 935 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, "dump raw trace in ASCII"),
936 OPT_END() 936 OPT_END()
937 }; 937 };
938 938
939 static const char *record_args[] = { 939 static const char *record_args[] = {
940 "record", 940 "record",
941 "-R", 941 "-R",
942 "-f", 942 "-f",
943 "-m", "1024", 943 "-m", "1024",
944 "-c", "1", 944 "-c", "1",
945 "-e", "lock:lock_acquire:r", 945 "-e", "lock:lock_acquire",
946 "-e", "lock:lock_acquired:r", 946 "-e", "lock:lock_acquired",
947 "-e", "lock:lock_contended:r", 947 "-e", "lock:lock_contended",
948 "-e", "lock:lock_release:r", 948 "-e", "lock:lock_release",
949 }; 949 };
950 950
951 static int __cmd_record(int argc, const char **argv) 951 static int __cmd_record(int argc, const char **argv)
952 { 952 {
953 unsigned int rec_argc, i, j; 953 unsigned int rec_argc, i, j;
954 const char **rec_argv; 954 const char **rec_argv;
955 955
956 rec_argc = ARRAY_SIZE(record_args) + argc - 1; 956 rec_argc = ARRAY_SIZE(record_args) + argc - 1;
957 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 957 rec_argv = calloc(rec_argc + 1, sizeof(char *));
958 958
959 if (rec_argv == NULL) 959 if (rec_argv == NULL)
960 return -ENOMEM; 960 return -ENOMEM;
961 961
962 for (i = 0; i < ARRAY_SIZE(record_args); i++) 962 for (i = 0; i < ARRAY_SIZE(record_args); i++)
963 rec_argv[i] = strdup(record_args[i]); 963 rec_argv[i] = strdup(record_args[i]);
964 964
965 for (j = 1; j < (unsigned int)argc; j++, i++) 965 for (j = 1; j < (unsigned int)argc; j++, i++)
966 rec_argv[i] = argv[j]; 966 rec_argv[i] = argv[j];
967 967
968 BUG_ON(i != rec_argc); 968 BUG_ON(i != rec_argc);
969 969
970 return cmd_record(i, rec_argv, NULL); 970 return cmd_record(i, rec_argv, NULL);
971 } 971 }
972 972
973 int cmd_lock(int argc, const char **argv, const char *prefix __used) 973 int cmd_lock(int argc, const char **argv, const char *prefix __used)
974 { 974 {
975 unsigned int i; 975 unsigned int i;
976 976
977 symbol__init(); 977 symbol__init();
978 for (i = 0; i < LOCKHASH_SIZE; i++) 978 for (i = 0; i < LOCKHASH_SIZE; i++)
979 INIT_LIST_HEAD(lockhash_table + i); 979 INIT_LIST_HEAD(lockhash_table + i);
980 980
981 argc = parse_options(argc, argv, lock_options, lock_usage, 981 argc = parse_options(argc, argv, lock_options, lock_usage,
982 PARSE_OPT_STOP_AT_NON_OPTION); 982 PARSE_OPT_STOP_AT_NON_OPTION);
983 if (!argc) 983 if (!argc)
984 usage_with_options(lock_usage, lock_options); 984 usage_with_options(lock_usage, lock_options);
985 985
986 if (!strncmp(argv[0], "rec", 3)) { 986 if (!strncmp(argv[0], "rec", 3)) {
987 return __cmd_record(argc, argv); 987 return __cmd_record(argc, argv);
988 } else if (!strncmp(argv[0], "report", 6)) { 988 } else if (!strncmp(argv[0], "report", 6)) {
989 trace_handler = &report_lock_ops; 989 trace_handler = &report_lock_ops;
990 if (argc) { 990 if (argc) {
991 argc = parse_options(argc, argv, 991 argc = parse_options(argc, argv,
992 report_options, report_usage, 0); 992 report_options, report_usage, 0);
993 if (argc) 993 if (argc)
994 usage_with_options(report_usage, report_options); 994 usage_with_options(report_usage, report_options);
995 } 995 }
996 __cmd_report(); 996 __cmd_report();
997 } else if (!strcmp(argv[0], "script")) { 997 } else if (!strcmp(argv[0], "script")) {
998 /* Aliased to 'perf script' */ 998 /* Aliased to 'perf script' */
999 return cmd_script(argc, argv, prefix); 999 return cmd_script(argc, argv, prefix);
1000 } else if (!strcmp(argv[0], "info")) { 1000 } else if (!strcmp(argv[0], "info")) {
1001 if (argc) { 1001 if (argc) {
1002 argc = parse_options(argc, argv, 1002 argc = parse_options(argc, argv,
1003 info_options, info_usage, 0); 1003 info_options, info_usage, 0);
1004 if (argc) 1004 if (argc)
1005 usage_with_options(info_usage, info_options); 1005 usage_with_options(info_usage, info_options);
1006 } 1006 }
1007 /* recycling report_lock_ops */ 1007 /* recycling report_lock_ops */
1008 trace_handler = &report_lock_ops; 1008 trace_handler = &report_lock_ops;
1009 setup_pager(); 1009 setup_pager();
1010 read_events(); 1010 read_events();
1011 dump_info(); 1011 dump_info();
1012 } else { 1012 } else {
1013 usage_with_options(lock_usage, lock_options); 1013 usage_with_options(lock_usage, lock_options);
1014 } 1014 }
1015 1015
1016 return 0; 1016 return 0;
1017 } 1017 }
1018 1018
tools/perf/builtin-record.c
1 /* 1 /*
2 * builtin-record.c 2 * builtin-record.c
3 * 3 *
4 * Builtin record command: Record the profile of a workload 4 * Builtin record command: Record the profile of a workload
5 * (or a CPU, or a PID) into the perf.data output file - for 5 * (or a CPU, or a PID) into the perf.data output file - for
6 * later analysis via perf report. 6 * later analysis via perf report.
7 */ 7 */
8 #define _FILE_OFFSET_BITS 64 8 #define _FILE_OFFSET_BITS 64
9 9
10 #include "builtin.h" 10 #include "builtin.h"
11 11
12 #include "perf.h" 12 #include "perf.h"
13 13
14 #include "util/build-id.h" 14 #include "util/build-id.h"
15 #include "util/util.h" 15 #include "util/util.h"
16 #include "util/parse-options.h" 16 #include "util/parse-options.h"
17 #include "util/parse-events.h" 17 #include "util/parse-events.h"
18 18
19 #include "util/header.h" 19 #include "util/header.h"
20 #include "util/event.h" 20 #include "util/event.h"
21 #include "util/evlist.h" 21 #include "util/evlist.h"
22 #include "util/evsel.h" 22 #include "util/evsel.h"
23 #include "util/debug.h" 23 #include "util/debug.h"
24 #include "util/session.h" 24 #include "util/session.h"
25 #include "util/symbol.h" 25 #include "util/symbol.h"
26 #include "util/cpumap.h" 26 #include "util/cpumap.h"
27 #include "util/thread_map.h" 27 #include "util/thread_map.h"
28 28
29 #include <unistd.h> 29 #include <unistd.h>
30 #include <sched.h> 30 #include <sched.h>
31 #include <sys/mman.h> 31 #include <sys/mman.h>
32 32
33 #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
34
35 enum write_mode_t { 33 enum write_mode_t {
36 WRITE_FORCE, 34 WRITE_FORCE,
37 WRITE_APPEND 35 WRITE_APPEND
38 }; 36 };
39 37
40 static u64 user_interval = ULLONG_MAX; 38 static u64 user_interval = ULLONG_MAX;
41 static u64 default_interval = 0; 39 static u64 default_interval = 0;
42 40
43 static unsigned int page_size; 41 static unsigned int page_size;
44 static unsigned int mmap_pages = UINT_MAX; 42 static unsigned int mmap_pages = UINT_MAX;
45 static unsigned int user_freq = UINT_MAX; 43 static unsigned int user_freq = UINT_MAX;
46 static int freq = 1000; 44 static int freq = 1000;
47 static int output; 45 static int output;
48 static int pipe_output = 0; 46 static int pipe_output = 0;
49 static const char *output_name = NULL; 47 static const char *output_name = NULL;
50 static int group = 0; 48 static int group = 0;
51 static int realtime_prio = 0; 49 static int realtime_prio = 0;
52 static bool nodelay = false; 50 static bool nodelay = false;
53 static bool raw_samples = false; 51 static bool raw_samples = false;
54 static bool sample_id_all_avail = true; 52 static bool sample_id_all_avail = true;
55 static bool system_wide = false; 53 static bool system_wide = false;
56 static pid_t target_pid = -1; 54 static pid_t target_pid = -1;
57 static pid_t target_tid = -1; 55 static pid_t target_tid = -1;
58 static pid_t child_pid = -1; 56 static pid_t child_pid = -1;
59 static bool no_inherit = false; 57 static bool no_inherit = false;
60 static enum write_mode_t write_mode = WRITE_FORCE; 58 static enum write_mode_t write_mode = WRITE_FORCE;
61 static bool call_graph = false; 59 static bool call_graph = false;
62 static bool inherit_stat = false; 60 static bool inherit_stat = false;
63 static bool no_samples = false; 61 static bool no_samples = false;
64 static bool sample_address = false; 62 static bool sample_address = false;
65 static bool sample_time = false; 63 static bool sample_time = false;
66 static bool no_buildid = false; 64 static bool no_buildid = false;
67 static bool no_buildid_cache = false; 65 static bool no_buildid_cache = false;
68 static struct perf_evlist *evsel_list; 66 static struct perf_evlist *evsel_list;
69 67
70 static long samples = 0; 68 static long samples = 0;
71 static u64 bytes_written = 0; 69 static u64 bytes_written = 0;
72 70
73 static int file_new = 1; 71 static int file_new = 1;
74 static off_t post_processing_offset; 72 static off_t post_processing_offset;
75 73
76 static struct perf_session *session; 74 static struct perf_session *session;
77 static const char *cpu_list; 75 static const char *cpu_list;
78 76
79 static void advance_output(size_t size) 77 static void advance_output(size_t size)
80 { 78 {
81 bytes_written += size; 79 bytes_written += size;
82 } 80 }
83 81
84 static void write_output(void *buf, size_t size) 82 static void write_output(void *buf, size_t size)
85 { 83 {
86 while (size) { 84 while (size) {
87 int ret = write(output, buf, size); 85 int ret = write(output, buf, size);
88 86
89 if (ret < 0) 87 if (ret < 0)
90 die("failed to write"); 88 die("failed to write");
91 89
92 size -= ret; 90 size -= ret;
93 buf += ret; 91 buf += ret;
94 92
95 bytes_written += ret; 93 bytes_written += ret;
96 } 94 }
97 } 95 }
98 96
99 static int process_synthesized_event(union perf_event *event, 97 static int process_synthesized_event(union perf_event *event,
100 struct perf_sample *sample __used, 98 struct perf_sample *sample __used,
101 struct perf_session *self __used) 99 struct perf_session *self __used)
102 { 100 {
103 write_output(event, event->header.size); 101 write_output(event, event->header.size);
104 return 0; 102 return 0;
105 } 103 }
106 104
107 static void mmap_read(struct perf_mmap *md) 105 static void mmap_read(struct perf_mmap *md)
108 { 106 {
109 unsigned int head = perf_mmap__read_head(md); 107 unsigned int head = perf_mmap__read_head(md);
110 unsigned int old = md->prev; 108 unsigned int old = md->prev;
111 unsigned char *data = md->base + page_size; 109 unsigned char *data = md->base + page_size;
112 unsigned long size; 110 unsigned long size;
113 void *buf; 111 void *buf;
114 112
115 if (old == head) 113 if (old == head)
116 return; 114 return;
117 115
118 samples++; 116 samples++;
119 117
120 size = head - old; 118 size = head - old;
121 119
122 if ((old & md->mask) + size != (head & md->mask)) { 120 if ((old & md->mask) + size != (head & md->mask)) {
123 buf = &data[old & md->mask]; 121 buf = &data[old & md->mask];
124 size = md->mask + 1 - (old & md->mask); 122 size = md->mask + 1 - (old & md->mask);
125 old += size; 123 old += size;
126 124
127 write_output(buf, size); 125 write_output(buf, size);
128 } 126 }
129 127
130 buf = &data[old & md->mask]; 128 buf = &data[old & md->mask];
131 size = head - old; 129 size = head - old;
132 old += size; 130 old += size;
133 131
134 write_output(buf, size); 132 write_output(buf, size);
135 133
136 md->prev = old; 134 md->prev = old;
137 perf_mmap__write_tail(md, old); 135 perf_mmap__write_tail(md, old);
138 } 136 }
139 137
140 static volatile int done = 0; 138 static volatile int done = 0;
141 static volatile int signr = -1; 139 static volatile int signr = -1;
142 140
143 static void sig_handler(int sig) 141 static void sig_handler(int sig)
144 { 142 {
145 done = 1; 143 done = 1;
146 signr = sig; 144 signr = sig;
147 } 145 }
148 146
149 static void sig_atexit(void) 147 static void sig_atexit(void)
150 { 148 {
151 if (child_pid > 0) 149 if (child_pid > 0)
152 kill(child_pid, SIGTERM); 150 kill(child_pid, SIGTERM);
153 151
154 if (signr == -1 || signr == SIGUSR1) 152 if (signr == -1 || signr == SIGUSR1)
155 return; 153 return;
156 154
157 signal(signr, SIG_DFL); 155 signal(signr, SIG_DFL);
158 kill(getpid(), signr); 156 kill(getpid(), signr);
159 } 157 }
160 158
161 static void config_attr(struct perf_evsel *evsel, struct perf_evlist *evlist) 159 static void config_attr(struct perf_evsel *evsel, struct perf_evlist *evlist)
162 { 160 {
163 struct perf_event_attr *attr = &evsel->attr; 161 struct perf_event_attr *attr = &evsel->attr;
164 int track = !evsel->idx; /* only the first counter needs these */ 162 int track = !evsel->idx; /* only the first counter needs these */
165 163
166 attr->inherit = !no_inherit; 164 attr->inherit = !no_inherit;
167 attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | 165 attr->read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
168 PERF_FORMAT_TOTAL_TIME_RUNNING | 166 PERF_FORMAT_TOTAL_TIME_RUNNING |
169 PERF_FORMAT_ID; 167 PERF_FORMAT_ID;
170 168
171 attr->sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID; 169 attr->sample_type |= PERF_SAMPLE_IP | PERF_SAMPLE_TID;
172 170
173 if (evlist->nr_entries > 1) 171 if (evlist->nr_entries > 1)
174 attr->sample_type |= PERF_SAMPLE_ID; 172 attr->sample_type |= PERF_SAMPLE_ID;
175 173
176 /* 174 /*
177 * We default some events to a 1 default interval. But keep 175 * We default some events to a 1 default interval. But keep
178 * it a weak assumption overridable by the user. 176 * it a weak assumption overridable by the user.
179 */ 177 */
180 if (!attr->sample_period || (user_freq != UINT_MAX && 178 if (!attr->sample_period || (user_freq != UINT_MAX &&
181 user_interval != ULLONG_MAX)) { 179 user_interval != ULLONG_MAX)) {
182 if (freq) { 180 if (freq) {
183 attr->sample_type |= PERF_SAMPLE_PERIOD; 181 attr->sample_type |= PERF_SAMPLE_PERIOD;
184 attr->freq = 1; 182 attr->freq = 1;
185 attr->sample_freq = freq; 183 attr->sample_freq = freq;
186 } else { 184 } else {
187 attr->sample_period = default_interval; 185 attr->sample_period = default_interval;
188 } 186 }
189 } 187 }
190 188
191 if (no_samples) 189 if (no_samples)
192 attr->sample_freq = 0; 190 attr->sample_freq = 0;
193 191
194 if (inherit_stat) 192 if (inherit_stat)
195 attr->inherit_stat = 1; 193 attr->inherit_stat = 1;
196 194
197 if (sample_address) { 195 if (sample_address) {
198 attr->sample_type |= PERF_SAMPLE_ADDR; 196 attr->sample_type |= PERF_SAMPLE_ADDR;
199 attr->mmap_data = track; 197 attr->mmap_data = track;
200 } 198 }
201 199
202 if (call_graph) 200 if (call_graph)
203 attr->sample_type |= PERF_SAMPLE_CALLCHAIN; 201 attr->sample_type |= PERF_SAMPLE_CALLCHAIN;
204 202
205 if (system_wide) 203 if (system_wide)
206 attr->sample_type |= PERF_SAMPLE_CPU; 204 attr->sample_type |= PERF_SAMPLE_CPU;
207 205
208 if (sample_id_all_avail && 206 if (sample_id_all_avail &&
209 (sample_time || system_wide || !no_inherit || cpu_list)) 207 (sample_time || system_wide || !no_inherit || cpu_list))
210 attr->sample_type |= PERF_SAMPLE_TIME; 208 attr->sample_type |= PERF_SAMPLE_TIME;
211 209
212 if (raw_samples) { 210 if (raw_samples) {
213 attr->sample_type |= PERF_SAMPLE_TIME; 211 attr->sample_type |= PERF_SAMPLE_TIME;
214 attr->sample_type |= PERF_SAMPLE_RAW; 212 attr->sample_type |= PERF_SAMPLE_RAW;
215 attr->sample_type |= PERF_SAMPLE_CPU; 213 attr->sample_type |= PERF_SAMPLE_CPU;
216 } 214 }
217 215
218 if (nodelay) { 216 if (nodelay) {
219 attr->watermark = 0; 217 attr->watermark = 0;
220 attr->wakeup_events = 1; 218 attr->wakeup_events = 1;
221 } 219 }
222 220
223 attr->mmap = track; 221 attr->mmap = track;
224 attr->comm = track; 222 attr->comm = track;
225 223
226 if (target_pid == -1 && target_tid == -1 && !system_wide) { 224 if (target_pid == -1 && target_tid == -1 && !system_wide) {
227 attr->disabled = 1; 225 attr->disabled = 1;
228 attr->enable_on_exec = 1; 226 attr->enable_on_exec = 1;
229 } 227 }
230 } 228 }
231 229
232 static bool perf_evlist__equal(struct perf_evlist *evlist, 230 static bool perf_evlist__equal(struct perf_evlist *evlist,
233 struct perf_evlist *other) 231 struct perf_evlist *other)
234 { 232 {
235 struct perf_evsel *pos, *pair; 233 struct perf_evsel *pos, *pair;
236 234
237 if (evlist->nr_entries != other->nr_entries) 235 if (evlist->nr_entries != other->nr_entries)
238 return false; 236 return false;
239 237
240 pair = list_entry(other->entries.next, struct perf_evsel, node); 238 pair = list_entry(other->entries.next, struct perf_evsel, node);
241 239
242 list_for_each_entry(pos, &evlist->entries, node) { 240 list_for_each_entry(pos, &evlist->entries, node) {
243 if (memcmp(&pos->attr, &pair->attr, sizeof(pos->attr) != 0)) 241 if (memcmp(&pos->attr, &pair->attr, sizeof(pos->attr) != 0))
244 return false; 242 return false;
245 pair = list_entry(pair->node.next, struct perf_evsel, node); 243 pair = list_entry(pair->node.next, struct perf_evsel, node);
246 } 244 }
247 245
248 return true; 246 return true;
249 } 247 }
250 248
251 static void open_counters(struct perf_evlist *evlist) 249 static void open_counters(struct perf_evlist *evlist)
252 { 250 {
253 struct perf_evsel *pos; 251 struct perf_evsel *pos;
254 252
255 if (evlist->cpus->map[0] < 0) 253 if (evlist->cpus->map[0] < 0)
256 no_inherit = true; 254 no_inherit = true;
257 255
258 list_for_each_entry(pos, &evlist->entries, node) { 256 list_for_each_entry(pos, &evlist->entries, node) {
259 struct perf_event_attr *attr = &pos->attr; 257 struct perf_event_attr *attr = &pos->attr;
260 /* 258 /*
261 * Check if parse_single_tracepoint_event has already asked for 259 * Check if parse_single_tracepoint_event has already asked for
262 * PERF_SAMPLE_TIME. 260 * PERF_SAMPLE_TIME.
263 * 261 *
264 * XXX this is kludgy but short term fix for problems introduced by 262 * XXX this is kludgy but short term fix for problems introduced by
265 * eac23d1c that broke 'perf script' by having different sample_types 263 * eac23d1c that broke 'perf script' by having different sample_types
266 * when using multiple tracepoint events when we use a perf binary 264 * when using multiple tracepoint events when we use a perf binary
267 * that tries to use sample_id_all on an older kernel. 265 * that tries to use sample_id_all on an older kernel.
268 * 266 *
269 * We need to move counter creation to perf_session, support 267 * We need to move counter creation to perf_session, support
270 * different sample_types, etc. 268 * different sample_types, etc.
271 */ 269 */
272 bool time_needed = attr->sample_type & PERF_SAMPLE_TIME; 270 bool time_needed = attr->sample_type & PERF_SAMPLE_TIME;
273 271
274 config_attr(pos, evlist); 272 config_attr(pos, evlist);
275 retry_sample_id: 273 retry_sample_id:
276 attr->sample_id_all = sample_id_all_avail ? 1 : 0; 274 attr->sample_id_all = sample_id_all_avail ? 1 : 0;
277 try_again: 275 try_again:
278 if (perf_evsel__open(pos, evlist->cpus, evlist->threads, group) < 0) { 276 if (perf_evsel__open(pos, evlist->cpus, evlist->threads, group) < 0) {
279 int err = errno; 277 int err = errno;
280 278
281 if (err == EPERM || err == EACCES) { 279 if (err == EPERM || err == EACCES) {
282 ui__warning_paranoid(); 280 ui__warning_paranoid();
283 exit(EXIT_FAILURE); 281 exit(EXIT_FAILURE);
284 } else if (err == ENODEV && cpu_list) { 282 } else if (err == ENODEV && cpu_list) {
285 die("No such device - did you specify" 283 die("No such device - did you specify"
286 " an out-of-range profile CPU?\n"); 284 " an out-of-range profile CPU?\n");
287 } else if (err == EINVAL && sample_id_all_avail) { 285 } else if (err == EINVAL && sample_id_all_avail) {
288 /* 286 /*
289 * Old kernel, no attr->sample_id_type_all field 287 * Old kernel, no attr->sample_id_type_all field
290 */ 288 */
291 sample_id_all_avail = false; 289 sample_id_all_avail = false;
292 if (!sample_time && !raw_samples && !time_needed) 290 if (!sample_time && !raw_samples && !time_needed)
293 attr->sample_type &= ~PERF_SAMPLE_TIME; 291 attr->sample_type &= ~PERF_SAMPLE_TIME;
294 292
295 goto retry_sample_id; 293 goto retry_sample_id;
296 } 294 }
297 295
298 /* 296 /*
299 * If it's cycles then fall back to hrtimer 297 * If it's cycles then fall back to hrtimer
300 * based cpu-clock-tick sw counter, which 298 * based cpu-clock-tick sw counter, which
301 * is always available even if no PMU support: 299 * is always available even if no PMU support:
302 */ 300 */
303 if (attr->type == PERF_TYPE_HARDWARE 301 if (attr->type == PERF_TYPE_HARDWARE
304 && attr->config == PERF_COUNT_HW_CPU_CYCLES) { 302 && attr->config == PERF_COUNT_HW_CPU_CYCLES) {
305 303
306 if (verbose) 304 if (verbose)
307 ui__warning("The cycles event is not supported, " 305 ui__warning("The cycles event is not supported, "
308 "trying to fall back to cpu-clock-ticks\n"); 306 "trying to fall back to cpu-clock-ticks\n");
309 attr->type = PERF_TYPE_SOFTWARE; 307 attr->type = PERF_TYPE_SOFTWARE;
310 attr->config = PERF_COUNT_SW_CPU_CLOCK; 308 attr->config = PERF_COUNT_SW_CPU_CLOCK;
311 goto try_again; 309 goto try_again;
312 } 310 }
313 311
314 if (err == ENOENT) { 312 if (err == ENOENT) {
315 ui__warning("The %s event is not supported.\n", 313 ui__warning("The %s event is not supported.\n",
316 event_name(pos)); 314 event_name(pos));
317 exit(EXIT_FAILURE); 315 exit(EXIT_FAILURE);
318 } 316 }
319 317
320 printf("\n"); 318 printf("\n");
321 error("sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information.\n", 319 error("sys_perf_event_open() syscall returned with %d (%s). /bin/dmesg may provide additional information.\n",
322 err, strerror(err)); 320 err, strerror(err));
323 321
324 #if defined(__i386__) || defined(__x86_64__) 322 #if defined(__i386__) || defined(__x86_64__)
325 if (attr->type == PERF_TYPE_HARDWARE && err == EOPNOTSUPP) 323 if (attr->type == PERF_TYPE_HARDWARE && err == EOPNOTSUPP)
326 die("No hardware sampling interrupt available." 324 die("No hardware sampling interrupt available."
327 " No APIC? If so then you can boot the kernel" 325 " No APIC? If so then you can boot the kernel"
328 " with the \"lapic\" boot parameter to" 326 " with the \"lapic\" boot parameter to"
329 " force-enable it.\n"); 327 " force-enable it.\n");
330 #endif 328 #endif
331 329
332 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n"); 330 die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
333 } 331 }
334 } 332 }
335 333
336 if (perf_evlist__set_filters(evlist)) { 334 if (perf_evlist__set_filters(evlist)) {
337 error("failed to set filter with %d (%s)\n", errno, 335 error("failed to set filter with %d (%s)\n", errno,
338 strerror(errno)); 336 strerror(errno));
339 exit(-1); 337 exit(-1);
340 } 338 }
341 339
342 if (perf_evlist__mmap(evlist, mmap_pages, false) < 0) 340 if (perf_evlist__mmap(evlist, mmap_pages, false) < 0)
343 die("failed to mmap with %d (%s)\n", errno, strerror(errno)); 341 die("failed to mmap with %d (%s)\n", errno, strerror(errno));
344 342
345 if (file_new) 343 if (file_new)
346 session->evlist = evlist; 344 session->evlist = evlist;
347 else { 345 else {
348 if (!perf_evlist__equal(session->evlist, evlist)) { 346 if (!perf_evlist__equal(session->evlist, evlist)) {
349 fprintf(stderr, "incompatible append\n"); 347 fprintf(stderr, "incompatible append\n");
350 exit(-1); 348 exit(-1);
351 } 349 }
352 } 350 }
353 351
354 perf_session__update_sample_type(session); 352 perf_session__update_sample_type(session);
355 } 353 }
356 354
357 static int process_buildids(void) 355 static int process_buildids(void)
358 { 356 {
359 u64 size = lseek(output, 0, SEEK_CUR); 357 u64 size = lseek(output, 0, SEEK_CUR);
360 358
361 if (size == 0) 359 if (size == 0)
362 return 0; 360 return 0;
363 361
364 session->fd = output; 362 session->fd = output;
365 return __perf_session__process_events(session, post_processing_offset, 363 return __perf_session__process_events(session, post_processing_offset,
366 size - post_processing_offset, 364 size - post_processing_offset,
367 size, &build_id__mark_dso_hit_ops); 365 size, &build_id__mark_dso_hit_ops);
368 } 366 }
369 367
370 static void atexit_header(void) 368 static void atexit_header(void)
371 { 369 {
372 if (!pipe_output) { 370 if (!pipe_output) {
373 session->header.data_size += bytes_written; 371 session->header.data_size += bytes_written;
374 372
375 if (!no_buildid) 373 if (!no_buildid)
376 process_buildids(); 374 process_buildids();
377 perf_session__write_header(session, evsel_list, output, true); 375 perf_session__write_header(session, evsel_list, output, true);
378 perf_session__delete(session); 376 perf_session__delete(session);
379 perf_evlist__delete(evsel_list); 377 perf_evlist__delete(evsel_list);
380 symbol__exit(); 378 symbol__exit();
381 } 379 }
382 } 380 }
383 381
384 static void perf_event__synthesize_guest_os(struct machine *machine, void *data) 382 static void perf_event__synthesize_guest_os(struct machine *machine, void *data)
385 { 383 {
386 int err; 384 int err;
387 struct perf_session *psession = data; 385 struct perf_session *psession = data;
388 386
389 if (machine__is_host(machine)) 387 if (machine__is_host(machine))
390 return; 388 return;
391 389
392 /* 390 /*
393 *As for guest kernel when processing subcommand record&report, 391 *As for guest kernel when processing subcommand record&report,
394 *we arrange module mmap prior to guest kernel mmap and trigger 392 *we arrange module mmap prior to guest kernel mmap and trigger
395 *a preload dso because default guest module symbols are loaded 393 *a preload dso because default guest module symbols are loaded
396 *from guest kallsyms instead of /lib/modules/XXX/XXX. This 394 *from guest kallsyms instead of /lib/modules/XXX/XXX. This
397 *method is used to avoid symbol missing when the first addr is 395 *method is used to avoid symbol missing when the first addr is
398 *in module instead of in guest kernel. 396 *in module instead of in guest kernel.
399 */ 397 */
400 err = perf_event__synthesize_modules(process_synthesized_event, 398 err = perf_event__synthesize_modules(process_synthesized_event,
401 psession, machine); 399 psession, machine);
402 if (err < 0) 400 if (err < 0)
403 pr_err("Couldn't record guest kernel [%d]'s reference" 401 pr_err("Couldn't record guest kernel [%d]'s reference"
404 " relocation symbol.\n", machine->pid); 402 " relocation symbol.\n", machine->pid);
405 403
406 /* 404 /*
407 * We use _stext for guest kernel because guest kernel's /proc/kallsyms 405 * We use _stext for guest kernel because guest kernel's /proc/kallsyms
408 * have no _text sometimes. 406 * have no _text sometimes.
409 */ 407 */
410 err = perf_event__synthesize_kernel_mmap(process_synthesized_event, 408 err = perf_event__synthesize_kernel_mmap(process_synthesized_event,
411 psession, machine, "_text"); 409 psession, machine, "_text");
412 if (err < 0) 410 if (err < 0)
413 err = perf_event__synthesize_kernel_mmap(process_synthesized_event, 411 err = perf_event__synthesize_kernel_mmap(process_synthesized_event,
414 psession, machine, 412 psession, machine,
415 "_stext"); 413 "_stext");
416 if (err < 0) 414 if (err < 0)
417 pr_err("Couldn't record guest kernel [%d]'s reference" 415 pr_err("Couldn't record guest kernel [%d]'s reference"
418 " relocation symbol.\n", machine->pid); 416 " relocation symbol.\n", machine->pid);
419 } 417 }
420 418
421 static struct perf_event_header finished_round_event = { 419 static struct perf_event_header finished_round_event = {
422 .size = sizeof(struct perf_event_header), 420 .size = sizeof(struct perf_event_header),
423 .type = PERF_RECORD_FINISHED_ROUND, 421 .type = PERF_RECORD_FINISHED_ROUND,
424 }; 422 };
425 423
426 static void mmap_read_all(void) 424 static void mmap_read_all(void)
427 { 425 {
428 int i; 426 int i;
429 427
430 for (i = 0; i < evsel_list->nr_mmaps; i++) { 428 for (i = 0; i < evsel_list->nr_mmaps; i++) {
431 if (evsel_list->mmap[i].base) 429 if (evsel_list->mmap[i].base)
432 mmap_read(&evsel_list->mmap[i]); 430 mmap_read(&evsel_list->mmap[i]);
433 } 431 }
434 432
435 if (perf_header__has_feat(&session->header, HEADER_TRACE_INFO)) 433 if (perf_header__has_feat(&session->header, HEADER_TRACE_INFO))
436 write_output(&finished_round_event, sizeof(finished_round_event)); 434 write_output(&finished_round_event, sizeof(finished_round_event));
437 } 435 }
438 436
439 static int __cmd_record(int argc, const char **argv) 437 static int __cmd_record(int argc, const char **argv)
440 { 438 {
441 int i;
442 struct stat st; 439 struct stat st;
443 int flags; 440 int flags;
444 int err; 441 int err;
445 unsigned long waking = 0; 442 unsigned long waking = 0;
446 int child_ready_pipe[2], go_pipe[2]; 443 int child_ready_pipe[2], go_pipe[2];
447 const bool forks = argc > 0; 444 const bool forks = argc > 0;
448 char buf; 445 char buf;
449 struct machine *machine; 446 struct machine *machine;
450 447
451 page_size = sysconf(_SC_PAGE_SIZE); 448 page_size = sysconf(_SC_PAGE_SIZE);
452 449
453 atexit(sig_atexit); 450 atexit(sig_atexit);
454 signal(SIGCHLD, sig_handler); 451 signal(SIGCHLD, sig_handler);
455 signal(SIGINT, sig_handler); 452 signal(SIGINT, sig_handler);
456 signal(SIGUSR1, sig_handler); 453 signal(SIGUSR1, sig_handler);
457 454
458 if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) { 455 if (forks && (pipe(child_ready_pipe) < 0 || pipe(go_pipe) < 0)) {
459 perror("failed to create pipes"); 456 perror("failed to create pipes");
460 exit(-1); 457 exit(-1);
461 } 458 }
462 459
463 if (!output_name) { 460 if (!output_name) {
464 if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode)) 461 if (!fstat(STDOUT_FILENO, &st) && S_ISFIFO(st.st_mode))
465 pipe_output = 1; 462 pipe_output = 1;
466 else 463 else
467 output_name = "perf.data"; 464 output_name = "perf.data";
468 } 465 }
469 if (output_name) { 466 if (output_name) {
470 if (!strcmp(output_name, "-")) 467 if (!strcmp(output_name, "-"))
471 pipe_output = 1; 468 pipe_output = 1;
472 else if (!stat(output_name, &st) && st.st_size) { 469 else if (!stat(output_name, &st) && st.st_size) {
473 if (write_mode == WRITE_FORCE) { 470 if (write_mode == WRITE_FORCE) {
474 char oldname[PATH_MAX]; 471 char oldname[PATH_MAX];
475 snprintf(oldname, sizeof(oldname), "%s.old", 472 snprintf(oldname, sizeof(oldname), "%s.old",
476 output_name); 473 output_name);
477 unlink(oldname); 474 unlink(oldname);
478 rename(output_name, oldname); 475 rename(output_name, oldname);
479 } 476 }
480 } else if (write_mode == WRITE_APPEND) { 477 } else if (write_mode == WRITE_APPEND) {
481 write_mode = WRITE_FORCE; 478 write_mode = WRITE_FORCE;
482 } 479 }
483 } 480 }
484 481
485 flags = O_CREAT|O_RDWR; 482 flags = O_CREAT|O_RDWR;
486 if (write_mode == WRITE_APPEND) 483 if (write_mode == WRITE_APPEND)
487 file_new = 0; 484 file_new = 0;
488 else 485 else
489 flags |= O_TRUNC; 486 flags |= O_TRUNC;
490 487
491 if (pipe_output) 488 if (pipe_output)
492 output = STDOUT_FILENO; 489 output = STDOUT_FILENO;
493 else 490 else
494 output = open(output_name, flags, S_IRUSR | S_IWUSR); 491 output = open(output_name, flags, S_IRUSR | S_IWUSR);
495 if (output < 0) { 492 if (output < 0) {
496 perror("failed to create output file"); 493 perror("failed to create output file");
497 exit(-1); 494 exit(-1);
498 } 495 }
499 496
500 session = perf_session__new(output_name, O_WRONLY, 497 session = perf_session__new(output_name, O_WRONLY,
501 write_mode == WRITE_FORCE, false, NULL); 498 write_mode == WRITE_FORCE, false, NULL);
502 if (session == NULL) { 499 if (session == NULL) {
503 pr_err("Not enough memory for reading perf file header\n"); 500 pr_err("Not enough memory for reading perf file header\n");
504 return -1; 501 return -1;
505 } 502 }
506 503
507 if (!no_buildid) 504 if (!no_buildid)
508 perf_header__set_feat(&session->header, HEADER_BUILD_ID); 505 perf_header__set_feat(&session->header, HEADER_BUILD_ID);
509 506
510 if (!file_new) { 507 if (!file_new) {
511 err = perf_session__read_header(session, output); 508 err = perf_session__read_header(session, output);
512 if (err < 0) 509 if (err < 0)
513 goto out_delete_session; 510 goto out_delete_session;
514 } 511 }
515 512
516 if (have_tracepoints(&evsel_list->entries)) 513 if (have_tracepoints(&evsel_list->entries))
517 perf_header__set_feat(&session->header, HEADER_TRACE_INFO); 514 perf_header__set_feat(&session->header, HEADER_TRACE_INFO);
518 515
519 /* 512 kiB: default amount of unprivileged mlocked memory */ 516 /* 512 kiB: default amount of unprivileged mlocked memory */
520 if (mmap_pages == UINT_MAX) 517 if (mmap_pages == UINT_MAX)
521 mmap_pages = (512 * 1024) / page_size; 518 mmap_pages = (512 * 1024) / page_size;
522 519
523 if (forks) { 520 if (forks) {
524 child_pid = fork(); 521 child_pid = fork();
525 if (child_pid < 0) { 522 if (child_pid < 0) {
526 perror("failed to fork"); 523 perror("failed to fork");
527 exit(-1); 524 exit(-1);
528 } 525 }
529 526
530 if (!child_pid) { 527 if (!child_pid) {
531 if (pipe_output) 528 if (pipe_output)
532 dup2(2, 1); 529 dup2(2, 1);
533 close(child_ready_pipe[0]); 530 close(child_ready_pipe[0]);
534 close(go_pipe[1]); 531 close(go_pipe[1]);
535 fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC); 532 fcntl(go_pipe[0], F_SETFD, FD_CLOEXEC);
536 533
537 /* 534 /*
538 * Do a dummy execvp to get the PLT entry resolved, 535 * Do a dummy execvp to get the PLT entry resolved,
539 * so we avoid the resolver overhead on the real 536 * so we avoid the resolver overhead on the real
540 * execvp call. 537 * execvp call.
541 */ 538 */
542 execvp("", (char **)argv); 539 execvp("", (char **)argv);
543 540
544 /* 541 /*
545 * Tell the parent we're ready to go 542 * Tell the parent we're ready to go
546 */ 543 */
547 close(child_ready_pipe[1]); 544 close(child_ready_pipe[1]);
548 545
549 /* 546 /*
550 * Wait until the parent tells us to go. 547 * Wait until the parent tells us to go.
551 */ 548 */
552 if (read(go_pipe[0], &buf, 1) == -1) 549 if (read(go_pipe[0], &buf, 1) == -1)
553 perror("unable to read pipe"); 550 perror("unable to read pipe");
554 551
555 execvp(argv[0], (char **)argv); 552 execvp(argv[0], (char **)argv);
556 553
557 perror(argv[0]); 554 perror(argv[0]);
558 kill(getppid(), SIGUSR1); 555 kill(getppid(), SIGUSR1);
559 exit(-1); 556 exit(-1);
560 } 557 }
561 558
562 if (!system_wide && target_tid == -1 && target_pid == -1) 559 if (!system_wide && target_tid == -1 && target_pid == -1)
563 evsel_list->threads->map[0] = child_pid; 560 evsel_list->threads->map[0] = child_pid;
564 561
565 close(child_ready_pipe[1]); 562 close(child_ready_pipe[1]);
566 close(go_pipe[0]); 563 close(go_pipe[0]);
567 /* 564 /*
568 * wait for child to settle 565 * wait for child to settle
569 */ 566 */
570 if (read(child_ready_pipe[0], &buf, 1) == -1) { 567 if (read(child_ready_pipe[0], &buf, 1) == -1) {
571 perror("unable to read pipe"); 568 perror("unable to read pipe");
572 exit(-1); 569 exit(-1);
573 } 570 }
574 close(child_ready_pipe[0]); 571 close(child_ready_pipe[0]);
575 } 572 }
576 573
577 open_counters(evsel_list); 574 open_counters(evsel_list);
578 575
579 /* 576 /*
580 * perf_session__delete(session) will be called at atexit_header() 577 * perf_session__delete(session) will be called at atexit_header()
581 */ 578 */
582 atexit(atexit_header); 579 atexit(atexit_header);
583 580
584 if (pipe_output) { 581 if (pipe_output) {
585 err = perf_header__write_pipe(output); 582 err = perf_header__write_pipe(output);
586 if (err < 0) 583 if (err < 0)
587 return err; 584 return err;
588 } else if (file_new) { 585 } else if (file_new) {
589 err = perf_session__write_header(session, evsel_list, 586 err = perf_session__write_header(session, evsel_list,
590 output, false); 587 output, false);
591 if (err < 0) 588 if (err < 0)
592 return err; 589 return err;
593 } 590 }
594 591
595 post_processing_offset = lseek(output, 0, SEEK_CUR); 592 post_processing_offset = lseek(output, 0, SEEK_CUR);
596 593
597 if (pipe_output) { 594 if (pipe_output) {
598 err = perf_session__synthesize_attrs(session, 595 err = perf_session__synthesize_attrs(session,
599 process_synthesized_event); 596 process_synthesized_event);
600 if (err < 0) { 597 if (err < 0) {
601 pr_err("Couldn't synthesize attrs.\n"); 598 pr_err("Couldn't synthesize attrs.\n");
602 return err; 599 return err;
603 } 600 }
604 601
605 err = perf_event__synthesize_event_types(process_synthesized_event, 602 err = perf_event__synthesize_event_types(process_synthesized_event,
606 session); 603 session);
607 if (err < 0) { 604 if (err < 0) {
608 pr_err("Couldn't synthesize event_types.\n"); 605 pr_err("Couldn't synthesize event_types.\n");
609 return err; 606 return err;
610 } 607 }
611 608
612 if (have_tracepoints(&evsel_list->entries)) { 609 if (have_tracepoints(&evsel_list->entries)) {
613 /* 610 /*
614 * FIXME err <= 0 here actually means that 611 * FIXME err <= 0 here actually means that
615 * there were no tracepoints so its not really 612 * there were no tracepoints so its not really
616 * an error, just that we don't need to 613 * an error, just that we don't need to
617 * synthesize anything. We really have to 614 * synthesize anything. We really have to
618 * return this more properly and also 615 * return this more properly and also
619 * propagate errors that now are calling die() 616 * propagate errors that now are calling die()
620 */ 617 */
621 err = perf_event__synthesize_tracing_data(output, evsel_list, 618 err = perf_event__synthesize_tracing_data(output, evsel_list,
622 process_synthesized_event, 619 process_synthesized_event,
623 session); 620 session);
624 if (err <= 0) { 621 if (err <= 0) {
625 pr_err("Couldn't record tracing data.\n"); 622 pr_err("Couldn't record tracing data.\n");
626 return err; 623 return err;
627 } 624 }
628 advance_output(err); 625 advance_output(err);
629 } 626 }
630 } 627 }
631 628
632 machine = perf_session__find_host_machine(session); 629 machine = perf_session__find_host_machine(session);
633 if (!machine) { 630 if (!machine) {
634 pr_err("Couldn't find native kernel information.\n"); 631 pr_err("Couldn't find native kernel information.\n");
635 return -1; 632 return -1;
636 } 633 }
637 634
638 err = perf_event__synthesize_kernel_mmap(process_synthesized_event, 635 err = perf_event__synthesize_kernel_mmap(process_synthesized_event,
639 session, machine, "_text"); 636 session, machine, "_text");
640 if (err < 0) 637 if (err < 0)
641 err = perf_event__synthesize_kernel_mmap(process_synthesized_event, 638 err = perf_event__synthesize_kernel_mmap(process_synthesized_event,
642 session, machine, "_stext"); 639 session, machine, "_stext");
643 if (err < 0) 640 if (err < 0)
644 pr_err("Couldn't record kernel reference relocation symbol\n" 641 pr_err("Couldn't record kernel reference relocation symbol\n"
645 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n" 642 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
646 "Check /proc/kallsyms permission or run as root.\n"); 643 "Check /proc/kallsyms permission or run as root.\n");
647 644
648 err = perf_event__synthesize_modules(process_synthesized_event, 645 err = perf_event__synthesize_modules(process_synthesized_event,
649 session, machine); 646 session, machine);
650 if (err < 0) 647 if (err < 0)
651 pr_err("Couldn't record kernel module information.\n" 648 pr_err("Couldn't record kernel module information.\n"
652 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n" 649 "Symbol resolution may be skewed if relocation was used (e.g. kexec).\n"
653 "Check /proc/modules permission or run as root.\n"); 650 "Check /proc/modules permission or run as root.\n");
654 651
655 if (perf_guest) 652 if (perf_guest)
656 perf_session__process_machines(session, 653 perf_session__process_machines(session,
657 perf_event__synthesize_guest_os); 654 perf_event__synthesize_guest_os);
658 655
659 if (!system_wide) 656 if (!system_wide)
660 perf_event__synthesize_thread_map(evsel_list->threads, 657 perf_event__synthesize_thread_map(evsel_list->threads,
661 process_synthesized_event, 658 process_synthesized_event,
662 session); 659 session);
663 else 660 else
664 perf_event__synthesize_threads(process_synthesized_event, 661 perf_event__synthesize_threads(process_synthesized_event,
665 session); 662 session);
666 663
667 if (realtime_prio) { 664 if (realtime_prio) {
668 struct sched_param param; 665 struct sched_param param;
669 666
670 param.sched_priority = realtime_prio; 667 param.sched_priority = realtime_prio;
671 if (sched_setscheduler(0, SCHED_FIFO, &param)) { 668 if (sched_setscheduler(0, SCHED_FIFO, &param)) {
672 pr_err("Could not set realtime priority.\n"); 669 pr_err("Could not set realtime priority.\n");
673 exit(-1); 670 exit(-1);
674 } 671 }
675 } 672 }
676 673
677 /* 674 /*
678 * Let the child rip 675 * Let the child rip
679 */ 676 */
680 if (forks) 677 if (forks)
681 close(go_pipe[1]); 678 close(go_pipe[1]);
682 679
683 for (;;) { 680 for (;;) {
684 int hits = samples; 681 int hits = samples;
685 int thread;
686 682
687 mmap_read_all(); 683 mmap_read_all();
688 684
689 if (hits == samples) { 685 if (hits == samples) {
690 if (done) 686 if (done)
691 break; 687 break;
692 err = poll(evsel_list->pollfd, evsel_list->nr_fds, -1); 688 err = poll(evsel_list->pollfd, evsel_list->nr_fds, -1);
693 waking++; 689 waking++;
694 } 690 }
695 691
696 if (done) { 692 if (done)
697 for (i = 0; i < evsel_list->cpus->nr; i++) { 693 perf_evlist__disable(evsel_list);
698 struct perf_evsel *pos;
699
700 list_for_each_entry(pos, &evsel_list->entries, node) {
701 for (thread = 0;
702 thread < evsel_list->threads->nr;
703 thread++)
704 ioctl(FD(pos, i, thread),
705 PERF_EVENT_IOC_DISABLE);
706 }
707 }
708 }
709 } 694 }
710 695
711 if (quiet || signr == SIGUSR1) 696 if (quiet || signr == SIGUSR1)
712 return 0; 697 return 0;
713 698
714 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking); 699 fprintf(stderr, "[ perf record: Woken up %ld times to write data ]\n", waking);
715 700
716 /* 701 /*
717 * Approximate RIP event size: 24 bytes. 702 * Approximate RIP event size: 24 bytes.
718 */ 703 */
719 fprintf(stderr, 704 fprintf(stderr,
720 "[ perf record: Captured and wrote %.3f MB %s (~%" PRIu64 " samples) ]\n", 705 "[ perf record: Captured and wrote %.3f MB %s (~%" PRIu64 " samples) ]\n",
721 (double)bytes_written / 1024.0 / 1024.0, 706 (double)bytes_written / 1024.0 / 1024.0,
722 output_name, 707 output_name,
723 bytes_written / 24); 708 bytes_written / 24);
724 709
725 return 0; 710 return 0;
726 711
727 out_delete_session: 712 out_delete_session:
728 perf_session__delete(session); 713 perf_session__delete(session);
729 return err; 714 return err;
730 } 715 }
731 716
732 static const char * const record_usage[] = { 717 static const char * const record_usage[] = {
733 "perf record [<options>] [<command>]", 718 "perf record [<options>] [<command>]",
734 "perf record [<options>] -- <command> [<options>]", 719 "perf record [<options>] -- <command> [<options>]",
735 NULL 720 NULL
736 }; 721 };
737 722
738 static bool force, append_file; 723 static bool force, append_file;
739 724
740 const struct option record_options[] = { 725 const struct option record_options[] = {
741 OPT_CALLBACK('e', "event", &evsel_list, "event", 726 OPT_CALLBACK('e', "event", &evsel_list, "event",
742 "event selector. use 'perf list' to list available events", 727 "event selector. use 'perf list' to list available events",
743 parse_events_option), 728 parse_events_option),
744 OPT_CALLBACK(0, "filter", &evsel_list, "filter", 729 OPT_CALLBACK(0, "filter", &evsel_list, "filter",
745 "event filter", parse_filter), 730 "event filter", parse_filter),
746 OPT_INTEGER('p', "pid", &target_pid, 731 OPT_INTEGER('p', "pid", &target_pid,
747 "record events on existing process id"), 732 "record events on existing process id"),
748 OPT_INTEGER('t', "tid", &target_tid, 733 OPT_INTEGER('t', "tid", &target_tid,
749 "record events on existing thread id"), 734 "record events on existing thread id"),
750 OPT_INTEGER('r', "realtime", &realtime_prio, 735 OPT_INTEGER('r', "realtime", &realtime_prio,
751 "collect data with this RT SCHED_FIFO priority"), 736 "collect data with this RT SCHED_FIFO priority"),
752 OPT_BOOLEAN('D', "no-delay", &nodelay, 737 OPT_BOOLEAN('D', "no-delay", &nodelay,
753 "collect data without buffering"), 738 "collect data without buffering"),
754 OPT_BOOLEAN('R', "raw-samples", &raw_samples, 739 OPT_BOOLEAN('R', "raw-samples", &raw_samples,
755 "collect raw sample records from all opened counters"), 740 "collect raw sample records from all opened counters"),
756 OPT_BOOLEAN('a', "all-cpus", &system_wide, 741 OPT_BOOLEAN('a', "all-cpus", &system_wide,
757 "system-wide collection from all CPUs"), 742 "system-wide collection from all CPUs"),
758 OPT_BOOLEAN('A', "append", &append_file, 743 OPT_BOOLEAN('A', "append", &append_file,
759 "append to the output file to do incremental profiling"), 744 "append to the output file to do incremental profiling"),
760 OPT_STRING('C', "cpu", &cpu_list, "cpu", 745 OPT_STRING('C', "cpu", &cpu_list, "cpu",
761 "list of cpus to monitor"), 746 "list of cpus to monitor"),
762 OPT_BOOLEAN('f', "force", &force, 747 OPT_BOOLEAN('f', "force", &force,
763 "overwrite existing data file (deprecated)"), 748 "overwrite existing data file (deprecated)"),
764 OPT_U64('c', "count", &user_interval, "event period to sample"), 749 OPT_U64('c', "count", &user_interval, "event period to sample"),
765 OPT_STRING('o', "output", &output_name, "file", 750 OPT_STRING('o', "output", &output_name, "file",
766 "output file name"), 751 "output file name"),
767 OPT_BOOLEAN('i', "no-inherit", &no_inherit, 752 OPT_BOOLEAN('i', "no-inherit", &no_inherit,
768 "child tasks do not inherit counters"), 753 "child tasks do not inherit counters"),
769 OPT_UINTEGER('F', "freq", &user_freq, "profile at this frequency"), 754 OPT_UINTEGER('F', "freq", &user_freq, "profile at this frequency"),
770 OPT_UINTEGER('m', "mmap-pages", &mmap_pages, "number of mmap data pages"), 755 OPT_UINTEGER('m', "mmap-pages", &mmap_pages, "number of mmap data pages"),
771 OPT_BOOLEAN('g', "call-graph", &call_graph, 756 OPT_BOOLEAN('g', "call-graph", &call_graph,
772 "do call-graph (stack chain/backtrace) recording"), 757 "do call-graph (stack chain/backtrace) recording"),
773 OPT_INCR('v', "verbose", &verbose, 758 OPT_INCR('v', "verbose", &verbose,
774 "be more verbose (show counter open errors, etc)"), 759 "be more verbose (show counter open errors, etc)"),
775 OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"), 760 OPT_BOOLEAN('q', "quiet", &quiet, "don't print any message"),
776 OPT_BOOLEAN('s', "stat", &inherit_stat, 761 OPT_BOOLEAN('s', "stat", &inherit_stat,
777 "per thread counts"), 762 "per thread counts"),
778 OPT_BOOLEAN('d', "data", &sample_address, 763 OPT_BOOLEAN('d', "data", &sample_address,
779 "Sample addresses"), 764 "Sample addresses"),
780 OPT_BOOLEAN('T', "timestamp", &sample_time, "Sample timestamps"), 765 OPT_BOOLEAN('T', "timestamp", &sample_time, "Sample timestamps"),
781 OPT_BOOLEAN('n', "no-samples", &no_samples, 766 OPT_BOOLEAN('n', "no-samples", &no_samples,
782 "don't sample"), 767 "don't sample"),
783 OPT_BOOLEAN('N', "no-buildid-cache", &no_buildid_cache, 768 OPT_BOOLEAN('N', "no-buildid-cache", &no_buildid_cache,
784 "do not update the buildid cache"), 769 "do not update the buildid cache"),
785 OPT_BOOLEAN('B', "no-buildid", &no_buildid, 770 OPT_BOOLEAN('B', "no-buildid", &no_buildid,
786 "do not collect buildids in perf.data"), 771 "do not collect buildids in perf.data"),
787 OPT_CALLBACK('G', "cgroup", &evsel_list, "name", 772 OPT_CALLBACK('G', "cgroup", &evsel_list, "name",
788 "monitor event in cgroup name only", 773 "monitor event in cgroup name only",
789 parse_cgroups), 774 parse_cgroups),
790 OPT_END() 775 OPT_END()
791 }; 776 };
792 777
793 int cmd_record(int argc, const char **argv, const char *prefix __used) 778 int cmd_record(int argc, const char **argv, const char *prefix __used)
794 { 779 {
795 int err = -ENOMEM; 780 int err = -ENOMEM;
796 struct perf_evsel *pos; 781 struct perf_evsel *pos;
797 782
798 evsel_list = perf_evlist__new(NULL, NULL); 783 evsel_list = perf_evlist__new(NULL, NULL);
799 if (evsel_list == NULL) 784 if (evsel_list == NULL)
800 return -ENOMEM; 785 return -ENOMEM;
801 786
802 argc = parse_options(argc, argv, record_options, record_usage, 787 argc = parse_options(argc, argv, record_options, record_usage,
803 PARSE_OPT_STOP_AT_NON_OPTION); 788 PARSE_OPT_STOP_AT_NON_OPTION);
804 if (!argc && target_pid == -1 && target_tid == -1 && 789 if (!argc && target_pid == -1 && target_tid == -1 &&
805 !system_wide && !cpu_list) 790 !system_wide && !cpu_list)
806 usage_with_options(record_usage, record_options); 791 usage_with_options(record_usage, record_options);
807 792
808 if (force && append_file) { 793 if (force && append_file) {
809 fprintf(stderr, "Can't overwrite and append at the same time." 794 fprintf(stderr, "Can't overwrite and append at the same time."
810 " You need to choose between -f and -A"); 795 " You need to choose between -f and -A");
811 usage_with_options(record_usage, record_options); 796 usage_with_options(record_usage, record_options);
812 } else if (append_file) { 797 } else if (append_file) {
813 write_mode = WRITE_APPEND; 798 write_mode = WRITE_APPEND;
814 } else { 799 } else {
815 write_mode = WRITE_FORCE; 800 write_mode = WRITE_FORCE;
816 } 801 }
817 802
818 if (nr_cgroups && !system_wide) { 803 if (nr_cgroups && !system_wide) {
819 fprintf(stderr, "cgroup monitoring only available in" 804 fprintf(stderr, "cgroup monitoring only available in"
820 " system-wide mode\n"); 805 " system-wide mode\n");
821 usage_with_options(record_usage, record_options); 806 usage_with_options(record_usage, record_options);
822 } 807 }
823 808
824 symbol__init(); 809 symbol__init();
825 810
826 if (symbol_conf.kptr_restrict) 811 if (symbol_conf.kptr_restrict)
827 pr_warning( 812 pr_warning(
828 "WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n" 813 "WARNING: Kernel address maps (/proc/{kallsyms,modules}) are restricted,\n"
829 "check /proc/sys/kernel/kptr_restrict.\n\n" 814 "check /proc/sys/kernel/kptr_restrict.\n\n"
830 "Samples in kernel functions may not be resolved if a suitable vmlinux\n" 815 "Samples in kernel functions may not be resolved if a suitable vmlinux\n"
831 "file is not found in the buildid cache or in the vmlinux path.\n\n" 816 "file is not found in the buildid cache or in the vmlinux path.\n\n"
832 "Samples in kernel modules won't be resolved at all.\n\n" 817 "Samples in kernel modules won't be resolved at all.\n\n"
833 "If some relocation was applied (e.g. kexec) symbols may be misresolved\n" 818 "If some relocation was applied (e.g. kexec) symbols may be misresolved\n"
834 "even with a suitable vmlinux or kallsyms file.\n\n"); 819 "even with a suitable vmlinux or kallsyms file.\n\n");
835 820
836 if (no_buildid_cache || no_buildid) 821 if (no_buildid_cache || no_buildid)
837 disable_buildid_cache(); 822 disable_buildid_cache();
838 823
839 if (evsel_list->nr_entries == 0 && 824 if (evsel_list->nr_entries == 0 &&
840 perf_evlist__add_default(evsel_list) < 0) { 825 perf_evlist__add_default(evsel_list) < 0) {
841 pr_err("Not enough memory for event selector list\n"); 826 pr_err("Not enough memory for event selector list\n");
842 goto out_symbol_exit; 827 goto out_symbol_exit;
843 } 828 }
844 829
845 if (target_pid != -1) 830 if (target_pid != -1)
846 target_tid = target_pid; 831 target_tid = target_pid;
847 832
848 if (perf_evlist__create_maps(evsel_list, target_pid, 833 if (perf_evlist__create_maps(evsel_list, target_pid,
849 target_tid, cpu_list) < 0) 834 target_tid, cpu_list) < 0)
850 usage_with_options(record_usage, record_options); 835 usage_with_options(record_usage, record_options);
851 836
852 list_for_each_entry(pos, &evsel_list->entries, node) { 837 list_for_each_entry(pos, &evsel_list->entries, node) {
853 if (perf_evsel__alloc_fd(pos, evsel_list->cpus->nr, 838 if (perf_evsel__alloc_fd(pos, evsel_list->cpus->nr,
854 evsel_list->threads->nr) < 0) 839 evsel_list->threads->nr) < 0)
855 goto out_free_fd; 840 goto out_free_fd;
856 if (perf_header__push_event(pos->attr.config, event_name(pos))) 841 if (perf_header__push_event(pos->attr.config, event_name(pos)))
857 goto out_free_fd; 842 goto out_free_fd;
858 } 843 }
859 844
860 if (perf_evlist__alloc_pollfd(evsel_list) < 0) 845 if (perf_evlist__alloc_pollfd(evsel_list) < 0)
861 goto out_free_fd; 846 goto out_free_fd;
862 847
863 if (user_interval != ULLONG_MAX) 848 if (user_interval != ULLONG_MAX)
864 default_interval = user_interval; 849 default_interval = user_interval;
865 if (user_freq != UINT_MAX) 850 if (user_freq != UINT_MAX)
866 freq = user_freq; 851 freq = user_freq;
867 852
868 /* 853 /*
869 * User specified count overrides default frequency. 854 * User specified count overrides default frequency.
870 */ 855 */
871 if (default_interval) 856 if (default_interval)
872 freq = 0; 857 freq = 0;
873 else if (freq) { 858 else if (freq) {
874 default_interval = freq; 859 default_interval = freq;
875 } else { 860 } else {
876 fprintf(stderr, "frequency and count are zero, aborting\n"); 861 fprintf(stderr, "frequency and count are zero, aborting\n");
877 err = -EINVAL; 862 err = -EINVAL;
878 goto out_free_fd; 863 goto out_free_fd;
879 } 864 }
880 865
881 err = __cmd_record(argc, argv); 866 err = __cmd_record(argc, argv);
882 out_free_fd: 867 out_free_fd:
883 perf_evlist__delete_maps(evsel_list); 868 perf_evlist__delete_maps(evsel_list);
884 out_symbol_exit: 869 out_symbol_exit:
885 symbol__exit(); 870 symbol__exit();
886 return err; 871 return err;
887 } 872 }
888 873
tools/perf/builtin-report.c
1 /* 1 /*
2 * builtin-report.c 2 * builtin-report.c
3 * 3 *
4 * Builtin report command: Analyze the perf.data input file, 4 * Builtin report command: Analyze the perf.data input file,
5 * look up and read DSOs and symbol information and display 5 * look up and read DSOs and symbol information and display
6 * a histogram of results, along various sorting keys. 6 * a histogram of results, along various sorting keys.
7 */ 7 */
8 #include "builtin.h" 8 #include "builtin.h"
9 9
10 #include "util/util.h" 10 #include "util/util.h"
11 11
12 #include "util/annotate.h" 12 #include "util/annotate.h"
13 #include "util/color.h" 13 #include "util/color.h"
14 #include <linux/list.h> 14 #include <linux/list.h>
15 #include "util/cache.h" 15 #include "util/cache.h"
16 #include <linux/rbtree.h> 16 #include <linux/rbtree.h>
17 #include "util/symbol.h" 17 #include "util/symbol.h"
18 #include "util/callchain.h" 18 #include "util/callchain.h"
19 #include "util/strlist.h" 19 #include "util/strlist.h"
20 #include "util/values.h" 20 #include "util/values.h"
21 21
22 #include "perf.h" 22 #include "perf.h"
23 #include "util/debug.h" 23 #include "util/debug.h"
24 #include "util/evlist.h" 24 #include "util/evlist.h"
25 #include "util/evsel.h" 25 #include "util/evsel.h"
26 #include "util/header.h" 26 #include "util/header.h"
27 #include "util/session.h" 27 #include "util/session.h"
28 28
29 #include "util/parse-options.h" 29 #include "util/parse-options.h"
30 #include "util/parse-events.h" 30 #include "util/parse-events.h"
31 31
32 #include "util/thread.h" 32 #include "util/thread.h"
33 #include "util/sort.h" 33 #include "util/sort.h"
34 #include "util/hist.h" 34 #include "util/hist.h"
35 35
36 #include <linux/bitmap.h> 36 #include <linux/bitmap.h>
37 37
38 static char const *input_name = "perf.data"; 38 static char const *input_name = "perf.data";
39 39
40 static bool force, use_tui, use_stdio; 40 static bool force, use_tui, use_stdio;
41 static bool hide_unresolved; 41 static bool hide_unresolved;
42 static bool dont_use_callchains; 42 static bool dont_use_callchains;
43 43
44 static bool show_threads; 44 static bool show_threads;
45 static struct perf_read_values show_threads_values; 45 static struct perf_read_values show_threads_values;
46 46
47 static const char default_pretty_printing_style[] = "normal"; 47 static const char default_pretty_printing_style[] = "normal";
48 static const char *pretty_printing_style = default_pretty_printing_style; 48 static const char *pretty_printing_style = default_pretty_printing_style;
49 49
50 static char callchain_default_opt[] = "fractal,0.5,callee"; 50 static char callchain_default_opt[] = "fractal,0.5,callee";
51 static bool inverted_callchain; 51 static bool inverted_callchain;
52 static symbol_filter_t annotate_init; 52 static symbol_filter_t annotate_init;
53 53
54 static const char *cpu_list; 54 static const char *cpu_list;
55 static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS); 55 static DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
56 56
57 static int perf_session__add_hist_entry(struct perf_session *session, 57 static int perf_session__add_hist_entry(struct perf_session *session,
58 struct addr_location *al, 58 struct addr_location *al,
59 struct perf_sample *sample, 59 struct perf_sample *sample,
60 struct perf_evsel *evsel) 60 struct perf_evsel *evsel)
61 { 61 {
62 struct symbol *parent = NULL; 62 struct symbol *parent = NULL;
63 int err = 0; 63 int err = 0;
64 struct hist_entry *he; 64 struct hist_entry *he;
65 65
66 if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) { 66 if ((sort__has_parent || symbol_conf.use_callchain) && sample->callchain) {
67 err = perf_session__resolve_callchain(session, al->thread, 67 err = perf_session__resolve_callchain(session, al->thread,
68 sample->callchain, &parent); 68 sample->callchain, &parent);
69 if (err) 69 if (err)
70 return err; 70 return err;
71 } 71 }
72 72
73 he = __hists__add_entry(&evsel->hists, al, parent, sample->period); 73 he = __hists__add_entry(&evsel->hists, al, parent, sample->period);
74 if (he == NULL) 74 if (he == NULL)
75 return -ENOMEM; 75 return -ENOMEM;
76 76
77 if (symbol_conf.use_callchain) { 77 if (symbol_conf.use_callchain) {
78 err = callchain_append(he->callchain, &session->callchain_cursor, 78 err = callchain_append(he->callchain, &session->callchain_cursor,
79 sample->period); 79 sample->period);
80 if (err) 80 if (err)
81 return err; 81 return err;
82 } 82 }
83 /* 83 /*
84 * Only in the newt browser we are doing integrated annotation, 84 * Only in the newt browser we are doing integrated annotation,
85 * so we don't allocated the extra space needed because the stdio 85 * so we don't allocated the extra space needed because the stdio
86 * code will not use it. 86 * code will not use it.
87 */ 87 */
88 if (al->sym != NULL && use_browser > 0) { 88 if (al->sym != NULL && use_browser > 0) {
89 struct annotation *notes = symbol__annotation(he->ms.sym); 89 struct annotation *notes = symbol__annotation(he->ms.sym);
90 90
91 assert(evsel != NULL); 91 assert(evsel != NULL);
92 92
93 err = -ENOMEM; 93 err = -ENOMEM;
94 if (notes->src == NULL && 94 if (notes->src == NULL &&
95 symbol__alloc_hist(he->ms.sym, session->evlist->nr_entries) < 0) 95 symbol__alloc_hist(he->ms.sym, session->evlist->nr_entries) < 0)
96 goto out; 96 goto out;
97 97
98 err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr); 98 err = hist_entry__inc_addr_samples(he, evsel->idx, al->addr);
99 } 99 }
100 100
101 evsel->hists.stats.total_period += sample->period; 101 evsel->hists.stats.total_period += sample->period;
102 hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE); 102 hists__inc_nr_events(&evsel->hists, PERF_RECORD_SAMPLE);
103 out: 103 out:
104 return err; 104 return err;
105 } 105 }
106 106
107 107
108 static int process_sample_event(union perf_event *event, 108 static int process_sample_event(union perf_event *event,
109 struct perf_sample *sample, 109 struct perf_sample *sample,
110 struct perf_evsel *evsel, 110 struct perf_evsel *evsel,
111 struct perf_session *session) 111 struct perf_session *session)
112 { 112 {
113 struct addr_location al; 113 struct addr_location al;
114 114
115 if (perf_event__preprocess_sample(event, session, &al, sample, 115 if (perf_event__preprocess_sample(event, session, &al, sample,
116 annotate_init) < 0) { 116 annotate_init) < 0) {
117 fprintf(stderr, "problem processing %d event, skipping it.\n", 117 fprintf(stderr, "problem processing %d event, skipping it.\n",
118 event->header.type); 118 event->header.type);
119 return -1; 119 return -1;
120 } 120 }
121 121
122 if (al.filtered || (hide_unresolved && al.sym == NULL)) 122 if (al.filtered || (hide_unresolved && al.sym == NULL))
123 return 0; 123 return 0;
124 124
125 if (cpu_list && !test_bit(sample->cpu, cpu_bitmap)) 125 if (cpu_list && !test_bit(sample->cpu, cpu_bitmap))
126 return 0; 126 return 0;
127 127
128 if (al.map != NULL) 128 if (al.map != NULL)
129 al.map->dso->hit = 1; 129 al.map->dso->hit = 1;
130 130
131 if (perf_session__add_hist_entry(session, &al, sample, evsel)) { 131 if (perf_session__add_hist_entry(session, &al, sample, evsel)) {
132 pr_debug("problem incrementing symbol period, skipping event\n"); 132 pr_debug("problem incrementing symbol period, skipping event\n");
133 return -1; 133 return -1;
134 } 134 }
135 135
136 return 0; 136 return 0;
137 } 137 }
138 138
139 static int process_read_event(union perf_event *event, 139 static int process_read_event(union perf_event *event,
140 struct perf_sample *sample __used, 140 struct perf_sample *sample __used,
141 struct perf_session *session) 141 struct perf_session *session)
142 { 142 {
143 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist, 143 struct perf_evsel *evsel = perf_evlist__id2evsel(session->evlist,
144 event->read.id); 144 event->read.id);
145 if (show_threads) { 145 if (show_threads) {
146 const char *name = evsel ? event_name(evsel) : "unknown"; 146 const char *name = evsel ? event_name(evsel) : "unknown";
147 perf_read_values_add_value(&show_threads_values, 147 perf_read_values_add_value(&show_threads_values,
148 event->read.pid, event->read.tid, 148 event->read.pid, event->read.tid,
149 event->read.id, 149 event->read.id,
150 name, 150 name,
151 event->read.value); 151 event->read.value);
152 } 152 }
153 153
154 dump_printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid, 154 dump_printf(": %d %d %s %" PRIu64 "\n", event->read.pid, event->read.tid,
155 evsel ? event_name(evsel) : "FAIL", 155 evsel ? event_name(evsel) : "FAIL",
156 event->read.value); 156 event->read.value);
157 157
158 return 0; 158 return 0;
159 } 159 }
160 160
161 static int perf_session__setup_sample_type(struct perf_session *self) 161 static int perf_session__setup_sample_type(struct perf_session *self)
162 { 162 {
163 if (!(self->sample_type & PERF_SAMPLE_CALLCHAIN)) { 163 if (!(self->sample_type & PERF_SAMPLE_CALLCHAIN)) {
164 if (sort__has_parent) { 164 if (sort__has_parent) {
165 fprintf(stderr, "selected --sort parent, but no" 165 ui__warning("Selected --sort parent, but no "
166 " callchain data. Did you call" 166 "callchain data. Did you call "
167 " perf record without -g?\n"); 167 "'perf record' without -g?\n");
168 return -EINVAL; 168 return -EINVAL;
169 } 169 }
170 if (symbol_conf.use_callchain) { 170 if (symbol_conf.use_callchain) {
171 fprintf(stderr, "selected -g but no callchain data." 171 ui__warning("Selected -g but no callchain data. Did "
172 " Did you call perf record without" 172 "you call 'perf record' without -g?\n");
173 " -g?\n");
174 return -1; 173 return -1;
175 } 174 }
176 } else if (!dont_use_callchains && callchain_param.mode != CHAIN_NONE && 175 } else if (!dont_use_callchains && callchain_param.mode != CHAIN_NONE &&
177 !symbol_conf.use_callchain) { 176 !symbol_conf.use_callchain) {
178 symbol_conf.use_callchain = true; 177 symbol_conf.use_callchain = true;
179 if (callchain_register_param(&callchain_param) < 0) { 178 if (callchain_register_param(&callchain_param) < 0) {
180 fprintf(stderr, "Can't register callchain" 179 ui__warning("Can't register callchain "
181 " params\n"); 180 "params.\n");
182 return -EINVAL; 181 return -EINVAL;
183 } 182 }
184 } 183 }
185 184
186 return 0; 185 return 0;
187 } 186 }
188 187
189 static struct perf_event_ops event_ops = { 188 static struct perf_event_ops event_ops = {
190 .sample = process_sample_event, 189 .sample = process_sample_event,
191 .mmap = perf_event__process_mmap, 190 .mmap = perf_event__process_mmap,
192 .comm = perf_event__process_comm, 191 .comm = perf_event__process_comm,
193 .exit = perf_event__process_task, 192 .exit = perf_event__process_task,
194 .fork = perf_event__process_task, 193 .fork = perf_event__process_task,
195 .lost = perf_event__process_lost, 194 .lost = perf_event__process_lost,
196 .read = process_read_event, 195 .read = process_read_event,
197 .attr = perf_event__process_attr, 196 .attr = perf_event__process_attr,
198 .event_type = perf_event__process_event_type, 197 .event_type = perf_event__process_event_type,
199 .tracing_data = perf_event__process_tracing_data, 198 .tracing_data = perf_event__process_tracing_data,
200 .build_id = perf_event__process_build_id, 199 .build_id = perf_event__process_build_id,
201 .ordered_samples = true, 200 .ordered_samples = true,
202 .ordering_requires_timestamps = true, 201 .ordering_requires_timestamps = true,
203 }; 202 };
204 203
205 extern volatile int session_done; 204 extern volatile int session_done;
206 205
207 static void sig_handler(int sig __used) 206 static void sig_handler(int sig __used)
208 { 207 {
209 session_done = 1; 208 session_done = 1;
210 } 209 }
211 210
212 static size_t hists__fprintf_nr_sample_events(struct hists *self, 211 static size_t hists__fprintf_nr_sample_events(struct hists *self,
213 const char *evname, FILE *fp) 212 const char *evname, FILE *fp)
214 { 213 {
215 size_t ret; 214 size_t ret;
216 char unit; 215 char unit;
217 unsigned long nr_events = self->stats.nr_events[PERF_RECORD_SAMPLE]; 216 unsigned long nr_events = self->stats.nr_events[PERF_RECORD_SAMPLE];
218 217
219 nr_events = convert_unit(nr_events, &unit); 218 nr_events = convert_unit(nr_events, &unit);
220 ret = fprintf(fp, "# Events: %lu%c", nr_events, unit); 219 ret = fprintf(fp, "# Events: %lu%c", nr_events, unit);
221 if (evname != NULL) 220 if (evname != NULL)
222 ret += fprintf(fp, " %s", evname); 221 ret += fprintf(fp, " %s", evname);
223 return ret + fprintf(fp, "\n#\n"); 222 return ret + fprintf(fp, "\n#\n");
224 } 223 }
225 224
226 static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist, 225 static int perf_evlist__tty_browse_hists(struct perf_evlist *evlist,
227 const char *help) 226 const char *help)
228 { 227 {
229 struct perf_evsel *pos; 228 struct perf_evsel *pos;
230 229
231 list_for_each_entry(pos, &evlist->entries, node) { 230 list_for_each_entry(pos, &evlist->entries, node) {
232 struct hists *hists = &pos->hists; 231 struct hists *hists = &pos->hists;
233 const char *evname = NULL; 232 const char *evname = NULL;
234 233
235 if (rb_first(&hists->entries) != rb_last(&hists->entries)) 234 if (rb_first(&hists->entries) != rb_last(&hists->entries))
236 evname = event_name(pos); 235 evname = event_name(pos);
237 236
238 hists__fprintf_nr_sample_events(hists, evname, stdout); 237 hists__fprintf_nr_sample_events(hists, evname, stdout);
239 hists__fprintf(hists, NULL, false, stdout); 238 hists__fprintf(hists, NULL, false, stdout);
240 fprintf(stdout, "\n\n"); 239 fprintf(stdout, "\n\n");
241 } 240 }
242 241
243 if (sort_order == default_sort_order && 242 if (sort_order == default_sort_order &&
244 parent_pattern == default_parent_pattern) { 243 parent_pattern == default_parent_pattern) {
245 fprintf(stdout, "#\n# (%s)\n#\n", help); 244 fprintf(stdout, "#\n# (%s)\n#\n", help);
246 245
247 if (show_threads) { 246 if (show_threads) {
248 bool style = !strcmp(pretty_printing_style, "raw"); 247 bool style = !strcmp(pretty_printing_style, "raw");
249 perf_read_values_display(stdout, &show_threads_values, 248 perf_read_values_display(stdout, &show_threads_values,
250 style); 249 style);
251 perf_read_values_destroy(&show_threads_values); 250 perf_read_values_destroy(&show_threads_values);
252 } 251 }
253 } 252 }
254 253
255 return 0; 254 return 0;
256 } 255 }
257 256
258 static int __cmd_report(void) 257 static int __cmd_report(void)
259 { 258 {
260 int ret = -EINVAL; 259 int ret = -EINVAL;
261 u64 nr_samples; 260 u64 nr_samples;
262 struct perf_session *session; 261 struct perf_session *session;
263 struct perf_evsel *pos; 262 struct perf_evsel *pos;
264 struct map *kernel_map; 263 struct map *kernel_map;
265 struct kmap *kernel_kmap; 264 struct kmap *kernel_kmap;
266 const char *help = "For a higher level overview, try: perf report --sort comm,dso"; 265 const char *help = "For a higher level overview, try: perf report --sort comm,dso";
267 266
268 signal(SIGINT, sig_handler); 267 signal(SIGINT, sig_handler);
269 268
270 session = perf_session__new(input_name, O_RDONLY, force, false, &event_ops); 269 session = perf_session__new(input_name, O_RDONLY, force, false, &event_ops);
271 if (session == NULL) 270 if (session == NULL)
272 return -ENOMEM; 271 return -ENOMEM;
273 272
274 if (cpu_list) { 273 if (cpu_list) {
275 ret = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap); 274 ret = perf_session__cpu_bitmap(session, cpu_list, cpu_bitmap);
276 if (ret) 275 if (ret)
277 goto out_delete; 276 goto out_delete;
278 } 277 }
279 278
280 if (show_threads) 279 if (show_threads)
281 perf_read_values_init(&show_threads_values); 280 perf_read_values_init(&show_threads_values);
282 281
283 ret = perf_session__setup_sample_type(session); 282 ret = perf_session__setup_sample_type(session);
284 if (ret) 283 if (ret)
285 goto out_delete; 284 goto out_delete;
286 285
287 ret = perf_session__process_events(session, &event_ops); 286 ret = perf_session__process_events(session, &event_ops);
288 if (ret) 287 if (ret)
289 goto out_delete; 288 goto out_delete;
290 289
291 kernel_map = session->host_machine.vmlinux_maps[MAP__FUNCTION]; 290 kernel_map = session->host_machine.vmlinux_maps[MAP__FUNCTION];
292 kernel_kmap = map__kmap(kernel_map); 291 kernel_kmap = map__kmap(kernel_map);
293 if (kernel_map == NULL || 292 if (kernel_map == NULL ||
294 (kernel_map->dso->hit && 293 (kernel_map->dso->hit &&
295 (kernel_kmap->ref_reloc_sym == NULL || 294 (kernel_kmap->ref_reloc_sym == NULL ||
296 kernel_kmap->ref_reloc_sym->addr == 0))) { 295 kernel_kmap->ref_reloc_sym->addr == 0))) {
297 const struct dso *kdso = kernel_map->dso; 296 const struct dso *kdso = kernel_map->dso;
298 297
299 ui__warning( 298 ui__warning(
300 "Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n" 299 "Kernel address maps (/proc/{kallsyms,modules}) were restricted.\n\n"
301 "Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n" 300 "Check /proc/sys/kernel/kptr_restrict before running 'perf record'.\n\n%s\n\n"
302 "Samples in kernel modules can't be resolved as well.\n\n", 301 "Samples in kernel modules can't be resolved as well.\n\n",
303 RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION]) ? 302 RB_EMPTY_ROOT(&kdso->symbols[MAP__FUNCTION]) ?
304 "As no suitable kallsyms nor vmlinux was found, kernel samples\n" 303 "As no suitable kallsyms nor vmlinux was found, kernel samples\n"
305 "can't be resolved." : 304 "can't be resolved." :
306 "If some relocation was applied (e.g. kexec) symbols may be misresolved."); 305 "If some relocation was applied (e.g. kexec) symbols may be misresolved.");
307 } 306 }
308 307
309 if (dump_trace) { 308 if (dump_trace) {
310 perf_session__fprintf_nr_events(session, stdout); 309 perf_session__fprintf_nr_events(session, stdout);
311 goto out_delete; 310 goto out_delete;
312 } 311 }
313 312
314 if (verbose > 3) 313 if (verbose > 3)
315 perf_session__fprintf(session, stdout); 314 perf_session__fprintf(session, stdout);
316 315
317 if (verbose > 2) 316 if (verbose > 2)
318 perf_session__fprintf_dsos(session, stdout); 317 perf_session__fprintf_dsos(session, stdout);
319 318
320 nr_samples = 0; 319 nr_samples = 0;
321 list_for_each_entry(pos, &session->evlist->entries, node) { 320 list_for_each_entry(pos, &session->evlist->entries, node) {
322 struct hists *hists = &pos->hists; 321 struct hists *hists = &pos->hists;
323 322
324 hists__collapse_resort(hists); 323 hists__collapse_resort(hists);
325 hists__output_resort(hists); 324 hists__output_resort(hists);
326 nr_samples += hists->stats.nr_events[PERF_RECORD_SAMPLE]; 325 nr_samples += hists->stats.nr_events[PERF_RECORD_SAMPLE];
327 } 326 }
328 327
329 if (nr_samples == 0) { 328 if (nr_samples == 0) {
330 ui__warning("The %s file has no samples!\n", input_name); 329 ui__warning("The %s file has no samples!\n", input_name);
331 goto out_delete; 330 goto out_delete;
332 } 331 }
333 332
334 if (use_browser > 0) 333 if (use_browser > 0)
335 perf_evlist__tui_browse_hists(session->evlist, help); 334 perf_evlist__tui_browse_hists(session->evlist, help);
336 else 335 else
337 perf_evlist__tty_browse_hists(session->evlist, help); 336 perf_evlist__tty_browse_hists(session->evlist, help);
338 337
339 out_delete: 338 out_delete:
340 /* 339 /*
341 * Speed up the exit process, for large files this can 340 * Speed up the exit process, for large files this can
342 * take quite a while. 341 * take quite a while.
343 * 342 *
344 * XXX Enable this when using valgrind or if we ever 343 * XXX Enable this when using valgrind or if we ever
345 * librarize this command. 344 * librarize this command.
346 * 345 *
347 * Also experiment with obstacks to see how much speed 346 * Also experiment with obstacks to see how much speed
348 * up we'll get here. 347 * up we'll get here.
349 * 348 *
350 * perf_session__delete(session); 349 * perf_session__delete(session);
351 */ 350 */
352 return ret; 351 return ret;
353 } 352 }
354 353
355 static int 354 static int
356 parse_callchain_opt(const struct option *opt __used, const char *arg, 355 parse_callchain_opt(const struct option *opt __used, const char *arg,
357 int unset) 356 int unset)
358 { 357 {
359 char *tok, *tok2; 358 char *tok, *tok2;
360 char *endptr; 359 char *endptr;
361 360
362 /* 361 /*
363 * --no-call-graph 362 * --no-call-graph
364 */ 363 */
365 if (unset) { 364 if (unset) {
366 dont_use_callchains = true; 365 dont_use_callchains = true;
367 return 0; 366 return 0;
368 } 367 }
369 368
370 symbol_conf.use_callchain = true; 369 symbol_conf.use_callchain = true;
371 370
372 if (!arg) 371 if (!arg)
373 return 0; 372 return 0;
374 373
375 tok = strtok((char *)arg, ","); 374 tok = strtok((char *)arg, ",");
376 if (!tok) 375 if (!tok)
377 return -1; 376 return -1;
378 377
379 /* get the output mode */ 378 /* get the output mode */
380 if (!strncmp(tok, "graph", strlen(arg))) 379 if (!strncmp(tok, "graph", strlen(arg)))
381 callchain_param.mode = CHAIN_GRAPH_ABS; 380 callchain_param.mode = CHAIN_GRAPH_ABS;
382 381
383 else if (!strncmp(tok, "flat", strlen(arg))) 382 else if (!strncmp(tok, "flat", strlen(arg)))
384 callchain_param.mode = CHAIN_FLAT; 383 callchain_param.mode = CHAIN_FLAT;
385 384
386 else if (!strncmp(tok, "fractal", strlen(arg))) 385 else if (!strncmp(tok, "fractal", strlen(arg)))
387 callchain_param.mode = CHAIN_GRAPH_REL; 386 callchain_param.mode = CHAIN_GRAPH_REL;
388 387
389 else if (!strncmp(tok, "none", strlen(arg))) { 388 else if (!strncmp(tok, "none", strlen(arg))) {
390 callchain_param.mode = CHAIN_NONE; 389 callchain_param.mode = CHAIN_NONE;
391 symbol_conf.use_callchain = false; 390 symbol_conf.use_callchain = false;
392 391
393 return 0; 392 return 0;
394 } 393 }
395 394
396 else 395 else
397 return -1; 396 return -1;
398 397
399 /* get the min percentage */ 398 /* get the min percentage */
400 tok = strtok(NULL, ","); 399 tok = strtok(NULL, ",");
401 if (!tok) 400 if (!tok)
402 goto setup; 401 goto setup;
403 402
404 callchain_param.min_percent = strtod(tok, &endptr); 403 callchain_param.min_percent = strtod(tok, &endptr);
405 if (tok == endptr) 404 if (tok == endptr)
406 return -1; 405 return -1;
407 406
408 /* get the print limit */ 407 /* get the print limit */
409 tok2 = strtok(NULL, ","); 408 tok2 = strtok(NULL, ",");
410 if (!tok2) 409 if (!tok2)
411 goto setup; 410 goto setup;
412 411
413 if (tok2[0] != 'c') { 412 if (tok2[0] != 'c') {
414 callchain_param.print_limit = strtod(tok2, &endptr); 413 callchain_param.print_limit = strtod(tok2, &endptr);
415 tok2 = strtok(NULL, ","); 414 tok2 = strtok(NULL, ",");
416 if (!tok2) 415 if (!tok2)
417 goto setup; 416 goto setup;
418 } 417 }
419 418
420 /* get the call chain order */ 419 /* get the call chain order */
421 if (!strcmp(tok2, "caller")) 420 if (!strcmp(tok2, "caller"))
422 callchain_param.order = ORDER_CALLER; 421 callchain_param.order = ORDER_CALLER;
423 else if (!strcmp(tok2, "callee")) 422 else if (!strcmp(tok2, "callee"))
424 callchain_param.order = ORDER_CALLEE; 423 callchain_param.order = ORDER_CALLEE;
425 else 424 else
426 return -1; 425 return -1;
427 setup: 426 setup:
428 if (callchain_register_param(&callchain_param) < 0) { 427 if (callchain_register_param(&callchain_param) < 0) {
429 fprintf(stderr, "Can't register callchain params\n"); 428 fprintf(stderr, "Can't register callchain params\n");
430 return -1; 429 return -1;
431 } 430 }
432 return 0; 431 return 0;
433 } 432 }
434 433
435 static const char * const report_usage[] = { 434 static const char * const report_usage[] = {
436 "perf report [<options>] <command>", 435 "perf report [<options>] <command>",
437 NULL 436 NULL
438 }; 437 };
439 438
440 static const struct option options[] = { 439 static const struct option options[] = {
441 OPT_STRING('i', "input", &input_name, "file", 440 OPT_STRING('i', "input", &input_name, "file",
442 "input file name"), 441 "input file name"),
443 OPT_INCR('v', "verbose", &verbose, 442 OPT_INCR('v', "verbose", &verbose,
444 "be more verbose (show symbol address, etc)"), 443 "be more verbose (show symbol address, etc)"),
445 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 444 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
446 "dump raw trace in ASCII"), 445 "dump raw trace in ASCII"),
447 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name, 446 OPT_STRING('k', "vmlinux", &symbol_conf.vmlinux_name,
448 "file", "vmlinux pathname"), 447 "file", "vmlinux pathname"),
449 OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name, 448 OPT_STRING(0, "kallsyms", &symbol_conf.kallsyms_name,
450 "file", "kallsyms pathname"), 449 "file", "kallsyms pathname"),
451 OPT_BOOLEAN('f', "force", &force, "don't complain, do it"), 450 OPT_BOOLEAN('f', "force", &force, "don't complain, do it"),
452 OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules, 451 OPT_BOOLEAN('m', "modules", &symbol_conf.use_modules,
453 "load module symbols - WARNING: use only with -k and LIVE kernel"), 452 "load module symbols - WARNING: use only with -k and LIVE kernel"),
454 OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples, 453 OPT_BOOLEAN('n', "show-nr-samples", &symbol_conf.show_nr_samples,
455 "Show a column with the number of samples"), 454 "Show a column with the number of samples"),
456 OPT_BOOLEAN('T', "threads", &show_threads, 455 OPT_BOOLEAN('T', "threads", &show_threads,
457 "Show per-thread event counters"), 456 "Show per-thread event counters"),
458 OPT_STRING(0, "pretty", &pretty_printing_style, "key", 457 OPT_STRING(0, "pretty", &pretty_printing_style, "key",
459 "pretty printing style key: normal raw"), 458 "pretty printing style key: normal raw"),
460 OPT_BOOLEAN(0, "tui", &use_tui, "Use the TUI interface"), 459 OPT_BOOLEAN(0, "tui", &use_tui, "Use the TUI interface"),
461 OPT_BOOLEAN(0, "stdio", &use_stdio, "Use the stdio interface"), 460 OPT_BOOLEAN(0, "stdio", &use_stdio, "Use the stdio interface"),
462 OPT_STRING('s', "sort", &sort_order, "key[,key2...]", 461 OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
463 "sort by key(s): pid, comm, dso, symbol, parent"), 462 "sort by key(s): pid, comm, dso, symbol, parent"),
464 OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization, 463 OPT_BOOLEAN(0, "showcpuutilization", &symbol_conf.show_cpu_utilization,
465 "Show sample percentage for different cpu modes"), 464 "Show sample percentage for different cpu modes"),
466 OPT_STRING('p', "parent", &parent_pattern, "regex", 465 OPT_STRING('p', "parent", &parent_pattern, "regex",
467 "regex filter to identify parent, see: '--sort parent'"), 466 "regex filter to identify parent, see: '--sort parent'"),
468 OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other, 467 OPT_BOOLEAN('x', "exclude-other", &symbol_conf.exclude_other,
469 "Only display entries with parent-match"), 468 "Only display entries with parent-match"),
470 OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent, call_order", 469 OPT_CALLBACK_DEFAULT('g', "call-graph", NULL, "output_type,min_percent, call_order",
471 "Display callchains using output_type (graph, flat, fractal, or none) , min percent threshold and callchain order. " 470 "Display callchains using output_type (graph, flat, fractal, or none) , min percent threshold and callchain order. "
472 "Default: fractal,0.5,callee", &parse_callchain_opt, callchain_default_opt), 471 "Default: fractal,0.5,callee", &parse_callchain_opt, callchain_default_opt),
473 OPT_BOOLEAN('G', "inverted", &inverted_callchain, "alias for inverted call graph"), 472 OPT_BOOLEAN('G', "inverted", &inverted_callchain, "alias for inverted call graph"),
474 OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]", 473 OPT_STRING('d', "dsos", &symbol_conf.dso_list_str, "dso[,dso...]",
475 "only consider symbols in these dsos"), 474 "only consider symbols in these dsos"),
476 OPT_STRING('C', "comms", &symbol_conf.comm_list_str, "comm[,comm...]", 475 OPT_STRING('C', "comms", &symbol_conf.comm_list_str, "comm[,comm...]",
477 "only consider symbols in these comms"), 476 "only consider symbols in these comms"),
478 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]", 477 OPT_STRING('S', "symbols", &symbol_conf.sym_list_str, "symbol[,symbol...]",
479 "only consider these symbols"), 478 "only consider these symbols"),
480 OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str, 479 OPT_STRING('w', "column-widths", &symbol_conf.col_width_list_str,
481 "width[,width...]", 480 "width[,width...]",
482 "don't try to adjust column width, use these fixed values"), 481 "don't try to adjust column width, use these fixed values"),
483 OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator", 482 OPT_STRING('t', "field-separator", &symbol_conf.field_sep, "separator",
484 "separator for columns, no spaces will be added between " 483 "separator for columns, no spaces will be added between "
485 "columns '.' is reserved."), 484 "columns '.' is reserved."),
486 OPT_BOOLEAN('U', "hide-unresolved", &hide_unresolved, 485 OPT_BOOLEAN('U', "hide-unresolved", &hide_unresolved,
487 "Only display entries resolved to a symbol"), 486 "Only display entries resolved to a symbol"),
488 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory", 487 OPT_STRING(0, "symfs", &symbol_conf.symfs, "directory",
489 "Look for files with symbols relative to this directory"), 488 "Look for files with symbols relative to this directory"),
490 OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"), 489 OPT_STRING('c', "cpu", &cpu_list, "cpu", "list of cpus to profile"),
491 OPT_END() 490 OPT_END()
492 }; 491 };
493 492
494 int cmd_report(int argc, const char **argv, const char *prefix __used) 493 int cmd_report(int argc, const char **argv, const char *prefix __used)
495 { 494 {
496 argc = parse_options(argc, argv, options, report_usage, 0); 495 argc = parse_options(argc, argv, options, report_usage, 0);
497 496
498 if (use_stdio) 497 if (use_stdio)
499 use_browser = 0; 498 use_browser = 0;
500 else if (use_tui) 499 else if (use_tui)
501 use_browser = 1; 500 use_browser = 1;
502 501
503 if (inverted_callchain) 502 if (inverted_callchain)
504 callchain_param.order = ORDER_CALLER; 503 callchain_param.order = ORDER_CALLER;
505 504
506 if (strcmp(input_name, "-") != 0) 505 if (strcmp(input_name, "-") != 0)
507 setup_browser(true); 506 setup_browser(true);
508 else 507 else
509 use_browser = 0; 508 use_browser = 0;
510 /* 509 /*
511 * Only in the newt browser we are doing integrated annotation, 510 * Only in the newt browser we are doing integrated annotation,
512 * so don't allocate extra space that won't be used in the stdio 511 * so don't allocate extra space that won't be used in the stdio
513 * implementation. 512 * implementation.
514 */ 513 */
515 if (use_browser > 0) { 514 if (use_browser > 0) {
516 symbol_conf.priv_size = sizeof(struct annotation); 515 symbol_conf.priv_size = sizeof(struct annotation);
517 annotate_init = symbol__annotate_init; 516 annotate_init = symbol__annotate_init;
518 /* 517 /*
519 * For searching by name on the "Browse map details". 518 * For searching by name on the "Browse map details".
520 * providing it only in verbose mode not to bloat too 519 * providing it only in verbose mode not to bloat too
521 * much struct symbol. 520 * much struct symbol.
522 */ 521 */
523 if (verbose) { 522 if (verbose) {
524 /* 523 /*
525 * XXX: Need to provide a less kludgy way to ask for 524 * XXX: Need to provide a less kludgy way to ask for
526 * more space per symbol, the u32 is for the index on 525 * more space per symbol, the u32 is for the index on
527 * the ui browser. 526 * the ui browser.
528 * See symbol__browser_index. 527 * See symbol__browser_index.
529 */ 528 */
530 symbol_conf.priv_size += sizeof(u32); 529 symbol_conf.priv_size += sizeof(u32);
531 symbol_conf.sort_by_name = true; 530 symbol_conf.sort_by_name = true;
532 } 531 }
533 } 532 }
534 533
535 if (symbol__init() < 0) 534 if (symbol__init() < 0)
536 return -1; 535 return -1;
537 536
538 setup_sorting(report_usage, options); 537 setup_sorting(report_usage, options);
539 538
540 if (parent_pattern != default_parent_pattern) { 539 if (parent_pattern != default_parent_pattern) {
541 if (sort_dimension__add("parent") < 0) 540 if (sort_dimension__add("parent") < 0)
542 return -1; 541 return -1;
543 542
544 /* 543 /*
545 * Only show the parent fields if we explicitly 544 * Only show the parent fields if we explicitly
546 * sort that way. If we only use parent machinery 545 * sort that way. If we only use parent machinery
547 * for filtering, we don't want it. 546 * for filtering, we don't want it.
548 */ 547 */
549 if (!strstr(sort_order, "parent")) 548 if (!strstr(sort_order, "parent"))
550 sort_parent.elide = 1; 549 sort_parent.elide = 1;
551 } else 550 } else
552 symbol_conf.exclude_other = false; 551 symbol_conf.exclude_other = false;
553 552
554 /* 553 /*
555 * Any (unrecognized) arguments left? 554 * Any (unrecognized) arguments left?
556 */ 555 */
557 if (argc) 556 if (argc)
558 usage_with_options(report_usage, options); 557 usage_with_options(report_usage, options);
559 558
560 sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", stdout); 559 sort_entry__setup_elide(&sort_dso, symbol_conf.dso_list, "dso", stdout);
561 sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout); 560 sort_entry__setup_elide(&sort_comm, symbol_conf.comm_list, "comm", stdout);
562 sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout); 561 sort_entry__setup_elide(&sort_sym, symbol_conf.sym_list, "symbol", stdout);
563 562
564 return __cmd_report(); 563 return __cmd_report();
565 } 564 }
566 565
tools/perf/builtin-sched.c
1 #include "builtin.h" 1 #include "builtin.h"
2 #include "perf.h" 2 #include "perf.h"
3 3
4 #include "util/util.h" 4 #include "util/util.h"
5 #include "util/cache.h" 5 #include "util/cache.h"
6 #include "util/symbol.h" 6 #include "util/symbol.h"
7 #include "util/thread.h" 7 #include "util/thread.h"
8 #include "util/header.h" 8 #include "util/header.h"
9 #include "util/session.h" 9 #include "util/session.h"
10 10
11 #include "util/parse-options.h" 11 #include "util/parse-options.h"
12 #include "util/trace-event.h" 12 #include "util/trace-event.h"
13 13
14 #include "util/debug.h" 14 #include "util/debug.h"
15 15
16 #include <sys/prctl.h> 16 #include <sys/prctl.h>
17 17
18 #include <semaphore.h> 18 #include <semaphore.h>
19 #include <pthread.h> 19 #include <pthread.h>
20 #include <math.h> 20 #include <math.h>
21 21
22 static char const *input_name = "perf.data"; 22 static char const *input_name = "perf.data";
23 23
24 static char default_sort_order[] = "avg, max, switch, runtime"; 24 static char default_sort_order[] = "avg, max, switch, runtime";
25 static const char *sort_order = default_sort_order; 25 static const char *sort_order = default_sort_order;
26 26
27 static int profile_cpu = -1; 27 static int profile_cpu = -1;
28 28
29 #define PR_SET_NAME 15 /* Set process name */ 29 #define PR_SET_NAME 15 /* Set process name */
30 #define MAX_CPUS 4096 30 #define MAX_CPUS 4096
31 31
32 static u64 run_measurement_overhead; 32 static u64 run_measurement_overhead;
33 static u64 sleep_measurement_overhead; 33 static u64 sleep_measurement_overhead;
34 34
35 #define COMM_LEN 20 35 #define COMM_LEN 20
36 #define SYM_LEN 129 36 #define SYM_LEN 129
37 37
38 #define MAX_PID 65536 38 #define MAX_PID 65536
39 39
40 static unsigned long nr_tasks; 40 static unsigned long nr_tasks;
41 41
42 struct sched_atom; 42 struct sched_atom;
43 43
44 struct task_desc { 44 struct task_desc {
45 unsigned long nr; 45 unsigned long nr;
46 unsigned long pid; 46 unsigned long pid;
47 char comm[COMM_LEN]; 47 char comm[COMM_LEN];
48 48
49 unsigned long nr_events; 49 unsigned long nr_events;
50 unsigned long curr_event; 50 unsigned long curr_event;
51 struct sched_atom **atoms; 51 struct sched_atom **atoms;
52 52
53 pthread_t thread; 53 pthread_t thread;
54 sem_t sleep_sem; 54 sem_t sleep_sem;
55 55
56 sem_t ready_for_work; 56 sem_t ready_for_work;
57 sem_t work_done_sem; 57 sem_t work_done_sem;
58 58
59 u64 cpu_usage; 59 u64 cpu_usage;
60 }; 60 };
61 61
62 enum sched_event_type { 62 enum sched_event_type {
63 SCHED_EVENT_RUN, 63 SCHED_EVENT_RUN,
64 SCHED_EVENT_SLEEP, 64 SCHED_EVENT_SLEEP,
65 SCHED_EVENT_WAKEUP, 65 SCHED_EVENT_WAKEUP,
66 SCHED_EVENT_MIGRATION, 66 SCHED_EVENT_MIGRATION,
67 }; 67 };
68 68
69 struct sched_atom { 69 struct sched_atom {
70 enum sched_event_type type; 70 enum sched_event_type type;
71 int specific_wait; 71 int specific_wait;
72 u64 timestamp; 72 u64 timestamp;
73 u64 duration; 73 u64 duration;
74 unsigned long nr; 74 unsigned long nr;
75 sem_t *wait_sem; 75 sem_t *wait_sem;
76 struct task_desc *wakee; 76 struct task_desc *wakee;
77 }; 77 };
78 78
79 static struct task_desc *pid_to_task[MAX_PID]; 79 static struct task_desc *pid_to_task[MAX_PID];
80 80
81 static struct task_desc **tasks; 81 static struct task_desc **tasks;
82 82
83 static pthread_mutex_t start_work_mutex = PTHREAD_MUTEX_INITIALIZER; 83 static pthread_mutex_t start_work_mutex = PTHREAD_MUTEX_INITIALIZER;
84 static u64 start_time; 84 static u64 start_time;
85 85
86 static pthread_mutex_t work_done_wait_mutex = PTHREAD_MUTEX_INITIALIZER; 86 static pthread_mutex_t work_done_wait_mutex = PTHREAD_MUTEX_INITIALIZER;
87 87
88 static unsigned long nr_run_events; 88 static unsigned long nr_run_events;
89 static unsigned long nr_sleep_events; 89 static unsigned long nr_sleep_events;
90 static unsigned long nr_wakeup_events; 90 static unsigned long nr_wakeup_events;
91 91
92 static unsigned long nr_sleep_corrections; 92 static unsigned long nr_sleep_corrections;
93 static unsigned long nr_run_events_optimized; 93 static unsigned long nr_run_events_optimized;
94 94
95 static unsigned long targetless_wakeups; 95 static unsigned long targetless_wakeups;
96 static unsigned long multitarget_wakeups; 96 static unsigned long multitarget_wakeups;
97 97
98 static u64 cpu_usage; 98 static u64 cpu_usage;
99 static u64 runavg_cpu_usage; 99 static u64 runavg_cpu_usage;
100 static u64 parent_cpu_usage; 100 static u64 parent_cpu_usage;
101 static u64 runavg_parent_cpu_usage; 101 static u64 runavg_parent_cpu_usage;
102 102
103 static unsigned long nr_runs; 103 static unsigned long nr_runs;
104 static u64 sum_runtime; 104 static u64 sum_runtime;
105 static u64 sum_fluct; 105 static u64 sum_fluct;
106 static u64 run_avg; 106 static u64 run_avg;
107 107
108 static unsigned int replay_repeat = 10; 108 static unsigned int replay_repeat = 10;
109 static unsigned long nr_timestamps; 109 static unsigned long nr_timestamps;
110 static unsigned long nr_unordered_timestamps; 110 static unsigned long nr_unordered_timestamps;
111 static unsigned long nr_state_machine_bugs; 111 static unsigned long nr_state_machine_bugs;
112 static unsigned long nr_context_switch_bugs; 112 static unsigned long nr_context_switch_bugs;
113 static unsigned long nr_events; 113 static unsigned long nr_events;
114 static unsigned long nr_lost_chunks; 114 static unsigned long nr_lost_chunks;
115 static unsigned long nr_lost_events; 115 static unsigned long nr_lost_events;
116 116
117 #define TASK_STATE_TO_CHAR_STR "RSDTtZX" 117 #define TASK_STATE_TO_CHAR_STR "RSDTtZX"
118 118
119 enum thread_state { 119 enum thread_state {
120 THREAD_SLEEPING = 0, 120 THREAD_SLEEPING = 0,
121 THREAD_WAIT_CPU, 121 THREAD_WAIT_CPU,
122 THREAD_SCHED_IN, 122 THREAD_SCHED_IN,
123 THREAD_IGNORE 123 THREAD_IGNORE
124 }; 124 };
125 125
126 struct work_atom { 126 struct work_atom {
127 struct list_head list; 127 struct list_head list;
128 enum thread_state state; 128 enum thread_state state;
129 u64 sched_out_time; 129 u64 sched_out_time;
130 u64 wake_up_time; 130 u64 wake_up_time;
131 u64 sched_in_time; 131 u64 sched_in_time;
132 u64 runtime; 132 u64 runtime;
133 }; 133 };
134 134
135 struct work_atoms { 135 struct work_atoms {
136 struct list_head work_list; 136 struct list_head work_list;
137 struct thread *thread; 137 struct thread *thread;
138 struct rb_node node; 138 struct rb_node node;
139 u64 max_lat; 139 u64 max_lat;
140 u64 max_lat_at; 140 u64 max_lat_at;
141 u64 total_lat; 141 u64 total_lat;
142 u64 nb_atoms; 142 u64 nb_atoms;
143 u64 total_runtime; 143 u64 total_runtime;
144 }; 144 };
145 145
146 typedef int (*sort_fn_t)(struct work_atoms *, struct work_atoms *); 146 typedef int (*sort_fn_t)(struct work_atoms *, struct work_atoms *);
147 147
148 static struct rb_root atom_root, sorted_atom_root; 148 static struct rb_root atom_root, sorted_atom_root;
149 149
150 static u64 all_runtime; 150 static u64 all_runtime;
151 static u64 all_count; 151 static u64 all_count;
152 152
153 153
154 static u64 get_nsecs(void) 154 static u64 get_nsecs(void)
155 { 155 {
156 struct timespec ts; 156 struct timespec ts;
157 157
158 clock_gettime(CLOCK_MONOTONIC, &ts); 158 clock_gettime(CLOCK_MONOTONIC, &ts);
159 159
160 return ts.tv_sec * 1000000000ULL + ts.tv_nsec; 160 return ts.tv_sec * 1000000000ULL + ts.tv_nsec;
161 } 161 }
162 162
163 static void burn_nsecs(u64 nsecs) 163 static void burn_nsecs(u64 nsecs)
164 { 164 {
165 u64 T0 = get_nsecs(), T1; 165 u64 T0 = get_nsecs(), T1;
166 166
167 do { 167 do {
168 T1 = get_nsecs(); 168 T1 = get_nsecs();
169 } while (T1 + run_measurement_overhead < T0 + nsecs); 169 } while (T1 + run_measurement_overhead < T0 + nsecs);
170 } 170 }
171 171
172 static void sleep_nsecs(u64 nsecs) 172 static void sleep_nsecs(u64 nsecs)
173 { 173 {
174 struct timespec ts; 174 struct timespec ts;
175 175
176 ts.tv_nsec = nsecs % 999999999; 176 ts.tv_nsec = nsecs % 999999999;
177 ts.tv_sec = nsecs / 999999999; 177 ts.tv_sec = nsecs / 999999999;
178 178
179 nanosleep(&ts, NULL); 179 nanosleep(&ts, NULL);
180 } 180 }
181 181
182 static void calibrate_run_measurement_overhead(void) 182 static void calibrate_run_measurement_overhead(void)
183 { 183 {
184 u64 T0, T1, delta, min_delta = 1000000000ULL; 184 u64 T0, T1, delta, min_delta = 1000000000ULL;
185 int i; 185 int i;
186 186
187 for (i = 0; i < 10; i++) { 187 for (i = 0; i < 10; i++) {
188 T0 = get_nsecs(); 188 T0 = get_nsecs();
189 burn_nsecs(0); 189 burn_nsecs(0);
190 T1 = get_nsecs(); 190 T1 = get_nsecs();
191 delta = T1-T0; 191 delta = T1-T0;
192 min_delta = min(min_delta, delta); 192 min_delta = min(min_delta, delta);
193 } 193 }
194 run_measurement_overhead = min_delta; 194 run_measurement_overhead = min_delta;
195 195
196 printf("run measurement overhead: %" PRIu64 " nsecs\n", min_delta); 196 printf("run measurement overhead: %" PRIu64 " nsecs\n", min_delta);
197 } 197 }
198 198
199 static void calibrate_sleep_measurement_overhead(void) 199 static void calibrate_sleep_measurement_overhead(void)
200 { 200 {
201 u64 T0, T1, delta, min_delta = 1000000000ULL; 201 u64 T0, T1, delta, min_delta = 1000000000ULL;
202 int i; 202 int i;
203 203
204 for (i = 0; i < 10; i++) { 204 for (i = 0; i < 10; i++) {
205 T0 = get_nsecs(); 205 T0 = get_nsecs();
206 sleep_nsecs(10000); 206 sleep_nsecs(10000);
207 T1 = get_nsecs(); 207 T1 = get_nsecs();
208 delta = T1-T0; 208 delta = T1-T0;
209 min_delta = min(min_delta, delta); 209 min_delta = min(min_delta, delta);
210 } 210 }
211 min_delta -= 10000; 211 min_delta -= 10000;
212 sleep_measurement_overhead = min_delta; 212 sleep_measurement_overhead = min_delta;
213 213
214 printf("sleep measurement overhead: %" PRIu64 " nsecs\n", min_delta); 214 printf("sleep measurement overhead: %" PRIu64 " nsecs\n", min_delta);
215 } 215 }
216 216
217 static struct sched_atom * 217 static struct sched_atom *
218 get_new_event(struct task_desc *task, u64 timestamp) 218 get_new_event(struct task_desc *task, u64 timestamp)
219 { 219 {
220 struct sched_atom *event = zalloc(sizeof(*event)); 220 struct sched_atom *event = zalloc(sizeof(*event));
221 unsigned long idx = task->nr_events; 221 unsigned long idx = task->nr_events;
222 size_t size; 222 size_t size;
223 223
224 event->timestamp = timestamp; 224 event->timestamp = timestamp;
225 event->nr = idx; 225 event->nr = idx;
226 226
227 task->nr_events++; 227 task->nr_events++;
228 size = sizeof(struct sched_atom *) * task->nr_events; 228 size = sizeof(struct sched_atom *) * task->nr_events;
229 task->atoms = realloc(task->atoms, size); 229 task->atoms = realloc(task->atoms, size);
230 BUG_ON(!task->atoms); 230 BUG_ON(!task->atoms);
231 231
232 task->atoms[idx] = event; 232 task->atoms[idx] = event;
233 233
234 return event; 234 return event;
235 } 235 }
236 236
237 static struct sched_atom *last_event(struct task_desc *task) 237 static struct sched_atom *last_event(struct task_desc *task)
238 { 238 {
239 if (!task->nr_events) 239 if (!task->nr_events)
240 return NULL; 240 return NULL;
241 241
242 return task->atoms[task->nr_events - 1]; 242 return task->atoms[task->nr_events - 1];
243 } 243 }
244 244
245 static void 245 static void
246 add_sched_event_run(struct task_desc *task, u64 timestamp, u64 duration) 246 add_sched_event_run(struct task_desc *task, u64 timestamp, u64 duration)
247 { 247 {
248 struct sched_atom *event, *curr_event = last_event(task); 248 struct sched_atom *event, *curr_event = last_event(task);
249 249
250 /* 250 /*
251 * optimize an existing RUN event by merging this one 251 * optimize an existing RUN event by merging this one
252 * to it: 252 * to it:
253 */ 253 */
254 if (curr_event && curr_event->type == SCHED_EVENT_RUN) { 254 if (curr_event && curr_event->type == SCHED_EVENT_RUN) {
255 nr_run_events_optimized++; 255 nr_run_events_optimized++;
256 curr_event->duration += duration; 256 curr_event->duration += duration;
257 return; 257 return;
258 } 258 }
259 259
260 event = get_new_event(task, timestamp); 260 event = get_new_event(task, timestamp);
261 261
262 event->type = SCHED_EVENT_RUN; 262 event->type = SCHED_EVENT_RUN;
263 event->duration = duration; 263 event->duration = duration;
264 264
265 nr_run_events++; 265 nr_run_events++;
266 } 266 }
267 267
268 static void 268 static void
269 add_sched_event_wakeup(struct task_desc *task, u64 timestamp, 269 add_sched_event_wakeup(struct task_desc *task, u64 timestamp,
270 struct task_desc *wakee) 270 struct task_desc *wakee)
271 { 271 {
272 struct sched_atom *event, *wakee_event; 272 struct sched_atom *event, *wakee_event;
273 273
274 event = get_new_event(task, timestamp); 274 event = get_new_event(task, timestamp);
275 event->type = SCHED_EVENT_WAKEUP; 275 event->type = SCHED_EVENT_WAKEUP;
276 event->wakee = wakee; 276 event->wakee = wakee;
277 277
278 wakee_event = last_event(wakee); 278 wakee_event = last_event(wakee);
279 if (!wakee_event || wakee_event->type != SCHED_EVENT_SLEEP) { 279 if (!wakee_event || wakee_event->type != SCHED_EVENT_SLEEP) {
280 targetless_wakeups++; 280 targetless_wakeups++;
281 return; 281 return;
282 } 282 }
283 if (wakee_event->wait_sem) { 283 if (wakee_event->wait_sem) {
284 multitarget_wakeups++; 284 multitarget_wakeups++;
285 return; 285 return;
286 } 286 }
287 287
288 wakee_event->wait_sem = zalloc(sizeof(*wakee_event->wait_sem)); 288 wakee_event->wait_sem = zalloc(sizeof(*wakee_event->wait_sem));
289 sem_init(wakee_event->wait_sem, 0, 0); 289 sem_init(wakee_event->wait_sem, 0, 0);
290 wakee_event->specific_wait = 1; 290 wakee_event->specific_wait = 1;
291 event->wait_sem = wakee_event->wait_sem; 291 event->wait_sem = wakee_event->wait_sem;
292 292
293 nr_wakeup_events++; 293 nr_wakeup_events++;
294 } 294 }
295 295
296 static void 296 static void
297 add_sched_event_sleep(struct task_desc *task, u64 timestamp, 297 add_sched_event_sleep(struct task_desc *task, u64 timestamp,
298 u64 task_state __used) 298 u64 task_state __used)
299 { 299 {
300 struct sched_atom *event = get_new_event(task, timestamp); 300 struct sched_atom *event = get_new_event(task, timestamp);
301 301
302 event->type = SCHED_EVENT_SLEEP; 302 event->type = SCHED_EVENT_SLEEP;
303 303
304 nr_sleep_events++; 304 nr_sleep_events++;
305 } 305 }
306 306
307 static struct task_desc *register_pid(unsigned long pid, const char *comm) 307 static struct task_desc *register_pid(unsigned long pid, const char *comm)
308 { 308 {
309 struct task_desc *task; 309 struct task_desc *task;
310 310
311 BUG_ON(pid >= MAX_PID); 311 BUG_ON(pid >= MAX_PID);
312 312
313 task = pid_to_task[pid]; 313 task = pid_to_task[pid];
314 314
315 if (task) 315 if (task)
316 return task; 316 return task;
317 317
318 task = zalloc(sizeof(*task)); 318 task = zalloc(sizeof(*task));
319 task->pid = pid; 319 task->pid = pid;
320 task->nr = nr_tasks; 320 task->nr = nr_tasks;
321 strcpy(task->comm, comm); 321 strcpy(task->comm, comm);
322 /* 322 /*
323 * every task starts in sleeping state - this gets ignored 323 * every task starts in sleeping state - this gets ignored
324 * if there's no wakeup pointing to this sleep state: 324 * if there's no wakeup pointing to this sleep state:
325 */ 325 */
326 add_sched_event_sleep(task, 0, 0); 326 add_sched_event_sleep(task, 0, 0);
327 327
328 pid_to_task[pid] = task; 328 pid_to_task[pid] = task;
329 nr_tasks++; 329 nr_tasks++;
330 tasks = realloc(tasks, nr_tasks*sizeof(struct task_task *)); 330 tasks = realloc(tasks, nr_tasks*sizeof(struct task_task *));
331 BUG_ON(!tasks); 331 BUG_ON(!tasks);
332 tasks[task->nr] = task; 332 tasks[task->nr] = task;
333 333
334 if (verbose) 334 if (verbose)
335 printf("registered task #%ld, PID %ld (%s)\n", nr_tasks, pid, comm); 335 printf("registered task #%ld, PID %ld (%s)\n", nr_tasks, pid, comm);
336 336
337 return task; 337 return task;
338 } 338 }
339 339
340 340
341 static void print_task_traces(void) 341 static void print_task_traces(void)
342 { 342 {
343 struct task_desc *task; 343 struct task_desc *task;
344 unsigned long i; 344 unsigned long i;
345 345
346 for (i = 0; i < nr_tasks; i++) { 346 for (i = 0; i < nr_tasks; i++) {
347 task = tasks[i]; 347 task = tasks[i];
348 printf("task %6ld (%20s:%10ld), nr_events: %ld\n", 348 printf("task %6ld (%20s:%10ld), nr_events: %ld\n",
349 task->nr, task->comm, task->pid, task->nr_events); 349 task->nr, task->comm, task->pid, task->nr_events);
350 } 350 }
351 } 351 }
352 352
353 static void add_cross_task_wakeups(void) 353 static void add_cross_task_wakeups(void)
354 { 354 {
355 struct task_desc *task1, *task2; 355 struct task_desc *task1, *task2;
356 unsigned long i, j; 356 unsigned long i, j;
357 357
358 for (i = 0; i < nr_tasks; i++) { 358 for (i = 0; i < nr_tasks; i++) {
359 task1 = tasks[i]; 359 task1 = tasks[i];
360 j = i + 1; 360 j = i + 1;
361 if (j == nr_tasks) 361 if (j == nr_tasks)
362 j = 0; 362 j = 0;
363 task2 = tasks[j]; 363 task2 = tasks[j];
364 add_sched_event_wakeup(task1, 0, task2); 364 add_sched_event_wakeup(task1, 0, task2);
365 } 365 }
366 } 366 }
367 367
368 static void 368 static void
369 process_sched_event(struct task_desc *this_task __used, struct sched_atom *atom) 369 process_sched_event(struct task_desc *this_task __used, struct sched_atom *atom)
370 { 370 {
371 int ret = 0; 371 int ret = 0;
372 372
373 switch (atom->type) { 373 switch (atom->type) {
374 case SCHED_EVENT_RUN: 374 case SCHED_EVENT_RUN:
375 burn_nsecs(atom->duration); 375 burn_nsecs(atom->duration);
376 break; 376 break;
377 case SCHED_EVENT_SLEEP: 377 case SCHED_EVENT_SLEEP:
378 if (atom->wait_sem) 378 if (atom->wait_sem)
379 ret = sem_wait(atom->wait_sem); 379 ret = sem_wait(atom->wait_sem);
380 BUG_ON(ret); 380 BUG_ON(ret);
381 break; 381 break;
382 case SCHED_EVENT_WAKEUP: 382 case SCHED_EVENT_WAKEUP:
383 if (atom->wait_sem) 383 if (atom->wait_sem)
384 ret = sem_post(atom->wait_sem); 384 ret = sem_post(atom->wait_sem);
385 BUG_ON(ret); 385 BUG_ON(ret);
386 break; 386 break;
387 case SCHED_EVENT_MIGRATION: 387 case SCHED_EVENT_MIGRATION:
388 break; 388 break;
389 default: 389 default:
390 BUG_ON(1); 390 BUG_ON(1);
391 } 391 }
392 } 392 }
393 393
394 static u64 get_cpu_usage_nsec_parent(void) 394 static u64 get_cpu_usage_nsec_parent(void)
395 { 395 {
396 struct rusage ru; 396 struct rusage ru;
397 u64 sum; 397 u64 sum;
398 int err; 398 int err;
399 399
400 err = getrusage(RUSAGE_SELF, &ru); 400 err = getrusage(RUSAGE_SELF, &ru);
401 BUG_ON(err); 401 BUG_ON(err);
402 402
403 sum = ru.ru_utime.tv_sec*1e9 + ru.ru_utime.tv_usec*1e3; 403 sum = ru.ru_utime.tv_sec*1e9 + ru.ru_utime.tv_usec*1e3;
404 sum += ru.ru_stime.tv_sec*1e9 + ru.ru_stime.tv_usec*1e3; 404 sum += ru.ru_stime.tv_sec*1e9 + ru.ru_stime.tv_usec*1e3;
405 405
406 return sum; 406 return sum;
407 } 407 }
408 408
409 static int self_open_counters(void) 409 static int self_open_counters(void)
410 { 410 {
411 struct perf_event_attr attr; 411 struct perf_event_attr attr;
412 int fd; 412 int fd;
413 413
414 memset(&attr, 0, sizeof(attr)); 414 memset(&attr, 0, sizeof(attr));
415 415
416 attr.type = PERF_TYPE_SOFTWARE; 416 attr.type = PERF_TYPE_SOFTWARE;
417 attr.config = PERF_COUNT_SW_TASK_CLOCK; 417 attr.config = PERF_COUNT_SW_TASK_CLOCK;
418 418
419 fd = sys_perf_event_open(&attr, 0, -1, -1, 0); 419 fd = sys_perf_event_open(&attr, 0, -1, -1, 0);
420 420
421 if (fd < 0) 421 if (fd < 0)
422 die("Error: sys_perf_event_open() syscall returned" 422 die("Error: sys_perf_event_open() syscall returned"
423 "with %d (%s)\n", fd, strerror(errno)); 423 "with %d (%s)\n", fd, strerror(errno));
424 return fd; 424 return fd;
425 } 425 }
426 426
427 static u64 get_cpu_usage_nsec_self(int fd) 427 static u64 get_cpu_usage_nsec_self(int fd)
428 { 428 {
429 u64 runtime; 429 u64 runtime;
430 int ret; 430 int ret;
431 431
432 ret = read(fd, &runtime, sizeof(runtime)); 432 ret = read(fd, &runtime, sizeof(runtime));
433 BUG_ON(ret != sizeof(runtime)); 433 BUG_ON(ret != sizeof(runtime));
434 434
435 return runtime; 435 return runtime;
436 } 436 }
437 437
438 static void *thread_func(void *ctx) 438 static void *thread_func(void *ctx)
439 { 439 {
440 struct task_desc *this_task = ctx; 440 struct task_desc *this_task = ctx;
441 u64 cpu_usage_0, cpu_usage_1; 441 u64 cpu_usage_0, cpu_usage_1;
442 unsigned long i, ret; 442 unsigned long i, ret;
443 char comm2[22]; 443 char comm2[22];
444 int fd; 444 int fd;
445 445
446 sprintf(comm2, ":%s", this_task->comm); 446 sprintf(comm2, ":%s", this_task->comm);
447 prctl(PR_SET_NAME, comm2); 447 prctl(PR_SET_NAME, comm2);
448 fd = self_open_counters(); 448 fd = self_open_counters();
449 449
450 again: 450 again:
451 ret = sem_post(&this_task->ready_for_work); 451 ret = sem_post(&this_task->ready_for_work);
452 BUG_ON(ret); 452 BUG_ON(ret);
453 ret = pthread_mutex_lock(&start_work_mutex); 453 ret = pthread_mutex_lock(&start_work_mutex);
454 BUG_ON(ret); 454 BUG_ON(ret);
455 ret = pthread_mutex_unlock(&start_work_mutex); 455 ret = pthread_mutex_unlock(&start_work_mutex);
456 BUG_ON(ret); 456 BUG_ON(ret);
457 457
458 cpu_usage_0 = get_cpu_usage_nsec_self(fd); 458 cpu_usage_0 = get_cpu_usage_nsec_self(fd);
459 459
460 for (i = 0; i < this_task->nr_events; i++) { 460 for (i = 0; i < this_task->nr_events; i++) {
461 this_task->curr_event = i; 461 this_task->curr_event = i;
462 process_sched_event(this_task, this_task->atoms[i]); 462 process_sched_event(this_task, this_task->atoms[i]);
463 } 463 }
464 464
465 cpu_usage_1 = get_cpu_usage_nsec_self(fd); 465 cpu_usage_1 = get_cpu_usage_nsec_self(fd);
466 this_task->cpu_usage = cpu_usage_1 - cpu_usage_0; 466 this_task->cpu_usage = cpu_usage_1 - cpu_usage_0;
467 ret = sem_post(&this_task->work_done_sem); 467 ret = sem_post(&this_task->work_done_sem);
468 BUG_ON(ret); 468 BUG_ON(ret);
469 469
470 ret = pthread_mutex_lock(&work_done_wait_mutex); 470 ret = pthread_mutex_lock(&work_done_wait_mutex);
471 BUG_ON(ret); 471 BUG_ON(ret);
472 ret = pthread_mutex_unlock(&work_done_wait_mutex); 472 ret = pthread_mutex_unlock(&work_done_wait_mutex);
473 BUG_ON(ret); 473 BUG_ON(ret);
474 474
475 goto again; 475 goto again;
476 } 476 }
477 477
478 static void create_tasks(void) 478 static void create_tasks(void)
479 { 479 {
480 struct task_desc *task; 480 struct task_desc *task;
481 pthread_attr_t attr; 481 pthread_attr_t attr;
482 unsigned long i; 482 unsigned long i;
483 int err; 483 int err;
484 484
485 err = pthread_attr_init(&attr); 485 err = pthread_attr_init(&attr);
486 BUG_ON(err); 486 BUG_ON(err);
487 err = pthread_attr_setstacksize(&attr, 487 err = pthread_attr_setstacksize(&attr,
488 (size_t) max(16 * 1024, PTHREAD_STACK_MIN)); 488 (size_t) max(16 * 1024, PTHREAD_STACK_MIN));
489 BUG_ON(err); 489 BUG_ON(err);
490 err = pthread_mutex_lock(&start_work_mutex); 490 err = pthread_mutex_lock(&start_work_mutex);
491 BUG_ON(err); 491 BUG_ON(err);
492 err = pthread_mutex_lock(&work_done_wait_mutex); 492 err = pthread_mutex_lock(&work_done_wait_mutex);
493 BUG_ON(err); 493 BUG_ON(err);
494 for (i = 0; i < nr_tasks; i++) { 494 for (i = 0; i < nr_tasks; i++) {
495 task = tasks[i]; 495 task = tasks[i];
496 sem_init(&task->sleep_sem, 0, 0); 496 sem_init(&task->sleep_sem, 0, 0);
497 sem_init(&task->ready_for_work, 0, 0); 497 sem_init(&task->ready_for_work, 0, 0);
498 sem_init(&task->work_done_sem, 0, 0); 498 sem_init(&task->work_done_sem, 0, 0);
499 task->curr_event = 0; 499 task->curr_event = 0;
500 err = pthread_create(&task->thread, &attr, thread_func, task); 500 err = pthread_create(&task->thread, &attr, thread_func, task);
501 BUG_ON(err); 501 BUG_ON(err);
502 } 502 }
503 } 503 }
504 504
505 static void wait_for_tasks(void) 505 static void wait_for_tasks(void)
506 { 506 {
507 u64 cpu_usage_0, cpu_usage_1; 507 u64 cpu_usage_0, cpu_usage_1;
508 struct task_desc *task; 508 struct task_desc *task;
509 unsigned long i, ret; 509 unsigned long i, ret;
510 510
511 start_time = get_nsecs(); 511 start_time = get_nsecs();
512 cpu_usage = 0; 512 cpu_usage = 0;
513 pthread_mutex_unlock(&work_done_wait_mutex); 513 pthread_mutex_unlock(&work_done_wait_mutex);
514 514
515 for (i = 0; i < nr_tasks; i++) { 515 for (i = 0; i < nr_tasks; i++) {
516 task = tasks[i]; 516 task = tasks[i];
517 ret = sem_wait(&task->ready_for_work); 517 ret = sem_wait(&task->ready_for_work);
518 BUG_ON(ret); 518 BUG_ON(ret);
519 sem_init(&task->ready_for_work, 0, 0); 519 sem_init(&task->ready_for_work, 0, 0);
520 } 520 }
521 ret = pthread_mutex_lock(&work_done_wait_mutex); 521 ret = pthread_mutex_lock(&work_done_wait_mutex);
522 BUG_ON(ret); 522 BUG_ON(ret);
523 523
524 cpu_usage_0 = get_cpu_usage_nsec_parent(); 524 cpu_usage_0 = get_cpu_usage_nsec_parent();
525 525
526 pthread_mutex_unlock(&start_work_mutex); 526 pthread_mutex_unlock(&start_work_mutex);
527 527
528 for (i = 0; i < nr_tasks; i++) { 528 for (i = 0; i < nr_tasks; i++) {
529 task = tasks[i]; 529 task = tasks[i];
530 ret = sem_wait(&task->work_done_sem); 530 ret = sem_wait(&task->work_done_sem);
531 BUG_ON(ret); 531 BUG_ON(ret);
532 sem_init(&task->work_done_sem, 0, 0); 532 sem_init(&task->work_done_sem, 0, 0);
533 cpu_usage += task->cpu_usage; 533 cpu_usage += task->cpu_usage;
534 task->cpu_usage = 0; 534 task->cpu_usage = 0;
535 } 535 }
536 536
537 cpu_usage_1 = get_cpu_usage_nsec_parent(); 537 cpu_usage_1 = get_cpu_usage_nsec_parent();
538 if (!runavg_cpu_usage) 538 if (!runavg_cpu_usage)
539 runavg_cpu_usage = cpu_usage; 539 runavg_cpu_usage = cpu_usage;
540 runavg_cpu_usage = (runavg_cpu_usage*9 + cpu_usage)/10; 540 runavg_cpu_usage = (runavg_cpu_usage*9 + cpu_usage)/10;
541 541
542 parent_cpu_usage = cpu_usage_1 - cpu_usage_0; 542 parent_cpu_usage = cpu_usage_1 - cpu_usage_0;
543 if (!runavg_parent_cpu_usage) 543 if (!runavg_parent_cpu_usage)
544 runavg_parent_cpu_usage = parent_cpu_usage; 544 runavg_parent_cpu_usage = parent_cpu_usage;
545 runavg_parent_cpu_usage = (runavg_parent_cpu_usage*9 + 545 runavg_parent_cpu_usage = (runavg_parent_cpu_usage*9 +
546 parent_cpu_usage)/10; 546 parent_cpu_usage)/10;
547 547
548 ret = pthread_mutex_lock(&start_work_mutex); 548 ret = pthread_mutex_lock(&start_work_mutex);
549 BUG_ON(ret); 549 BUG_ON(ret);
550 550
551 for (i = 0; i < nr_tasks; i++) { 551 for (i = 0; i < nr_tasks; i++) {
552 task = tasks[i]; 552 task = tasks[i];
553 sem_init(&task->sleep_sem, 0, 0); 553 sem_init(&task->sleep_sem, 0, 0);
554 task->curr_event = 0; 554 task->curr_event = 0;
555 } 555 }
556 } 556 }
557 557
558 static void run_one_test(void) 558 static void run_one_test(void)
559 { 559 {
560 u64 T0, T1, delta, avg_delta, fluct; 560 u64 T0, T1, delta, avg_delta, fluct;
561 561
562 T0 = get_nsecs(); 562 T0 = get_nsecs();
563 wait_for_tasks(); 563 wait_for_tasks();
564 T1 = get_nsecs(); 564 T1 = get_nsecs();
565 565
566 delta = T1 - T0; 566 delta = T1 - T0;
567 sum_runtime += delta; 567 sum_runtime += delta;
568 nr_runs++; 568 nr_runs++;
569 569
570 avg_delta = sum_runtime / nr_runs; 570 avg_delta = sum_runtime / nr_runs;
571 if (delta < avg_delta) 571 if (delta < avg_delta)
572 fluct = avg_delta - delta; 572 fluct = avg_delta - delta;
573 else 573 else
574 fluct = delta - avg_delta; 574 fluct = delta - avg_delta;
575 sum_fluct += fluct; 575 sum_fluct += fluct;
576 if (!run_avg) 576 if (!run_avg)
577 run_avg = delta; 577 run_avg = delta;
578 run_avg = (run_avg*9 + delta)/10; 578 run_avg = (run_avg*9 + delta)/10;
579 579
580 printf("#%-3ld: %0.3f, ", 580 printf("#%-3ld: %0.3f, ",
581 nr_runs, (double)delta/1000000.0); 581 nr_runs, (double)delta/1000000.0);
582 582
583 printf("ravg: %0.2f, ", 583 printf("ravg: %0.2f, ",
584 (double)run_avg/1e6); 584 (double)run_avg/1e6);
585 585
586 printf("cpu: %0.2f / %0.2f", 586 printf("cpu: %0.2f / %0.2f",
587 (double)cpu_usage/1e6, (double)runavg_cpu_usage/1e6); 587 (double)cpu_usage/1e6, (double)runavg_cpu_usage/1e6);
588 588
589 #if 0 589 #if 0
590 /* 590 /*
591 * rusage statistics done by the parent, these are less 591 * rusage statistics done by the parent, these are less
592 * accurate than the sum_exec_runtime based statistics: 592 * accurate than the sum_exec_runtime based statistics:
593 */ 593 */
594 printf(" [%0.2f / %0.2f]", 594 printf(" [%0.2f / %0.2f]",
595 (double)parent_cpu_usage/1e6, 595 (double)parent_cpu_usage/1e6,
596 (double)runavg_parent_cpu_usage/1e6); 596 (double)runavg_parent_cpu_usage/1e6);
597 #endif 597 #endif
598 598
599 printf("\n"); 599 printf("\n");
600 600
601 if (nr_sleep_corrections) 601 if (nr_sleep_corrections)
602 printf(" (%ld sleep corrections)\n", nr_sleep_corrections); 602 printf(" (%ld sleep corrections)\n", nr_sleep_corrections);
603 nr_sleep_corrections = 0; 603 nr_sleep_corrections = 0;
604 } 604 }
605 605
606 static void test_calibrations(void) 606 static void test_calibrations(void)
607 { 607 {
608 u64 T0, T1; 608 u64 T0, T1;
609 609
610 T0 = get_nsecs(); 610 T0 = get_nsecs();
611 burn_nsecs(1e6); 611 burn_nsecs(1e6);
612 T1 = get_nsecs(); 612 T1 = get_nsecs();
613 613
614 printf("the run test took %" PRIu64 " nsecs\n", T1 - T0); 614 printf("the run test took %" PRIu64 " nsecs\n", T1 - T0);
615 615
616 T0 = get_nsecs(); 616 T0 = get_nsecs();
617 sleep_nsecs(1e6); 617 sleep_nsecs(1e6);
618 T1 = get_nsecs(); 618 T1 = get_nsecs();
619 619
620 printf("the sleep test took %" PRIu64 " nsecs\n", T1 - T0); 620 printf("the sleep test took %" PRIu64 " nsecs\n", T1 - T0);
621 } 621 }
622 622
623 #define FILL_FIELD(ptr, field, event, data) \ 623 #define FILL_FIELD(ptr, field, event, data) \
624 ptr.field = (typeof(ptr.field)) raw_field_value(event, #field, data) 624 ptr.field = (typeof(ptr.field)) raw_field_value(event, #field, data)
625 625
626 #define FILL_ARRAY(ptr, array, event, data) \ 626 #define FILL_ARRAY(ptr, array, event, data) \
627 do { \ 627 do { \
628 void *__array = raw_field_ptr(event, #array, data); \ 628 void *__array = raw_field_ptr(event, #array, data); \
629 memcpy(ptr.array, __array, sizeof(ptr.array)); \ 629 memcpy(ptr.array, __array, sizeof(ptr.array)); \
630 } while(0) 630 } while(0)
631 631
632 #define FILL_COMMON_FIELDS(ptr, event, data) \ 632 #define FILL_COMMON_FIELDS(ptr, event, data) \
633 do { \ 633 do { \
634 FILL_FIELD(ptr, common_type, event, data); \ 634 FILL_FIELD(ptr, common_type, event, data); \
635 FILL_FIELD(ptr, common_flags, event, data); \ 635 FILL_FIELD(ptr, common_flags, event, data); \
636 FILL_FIELD(ptr, common_preempt_count, event, data); \ 636 FILL_FIELD(ptr, common_preempt_count, event, data); \
637 FILL_FIELD(ptr, common_pid, event, data); \ 637 FILL_FIELD(ptr, common_pid, event, data); \
638 FILL_FIELD(ptr, common_tgid, event, data); \ 638 FILL_FIELD(ptr, common_tgid, event, data); \
639 } while (0) 639 } while (0)
640 640
641 641
642 642
643 struct trace_switch_event { 643 struct trace_switch_event {
644 u32 size; 644 u32 size;
645 645
646 u16 common_type; 646 u16 common_type;
647 u8 common_flags; 647 u8 common_flags;
648 u8 common_preempt_count; 648 u8 common_preempt_count;
649 u32 common_pid; 649 u32 common_pid;
650 u32 common_tgid; 650 u32 common_tgid;
651 651
652 char prev_comm[16]; 652 char prev_comm[16];
653 u32 prev_pid; 653 u32 prev_pid;
654 u32 prev_prio; 654 u32 prev_prio;
655 u64 prev_state; 655 u64 prev_state;
656 char next_comm[16]; 656 char next_comm[16];
657 u32 next_pid; 657 u32 next_pid;
658 u32 next_prio; 658 u32 next_prio;
659 }; 659 };
660 660
661 struct trace_runtime_event { 661 struct trace_runtime_event {
662 u32 size; 662 u32 size;
663 663
664 u16 common_type; 664 u16 common_type;
665 u8 common_flags; 665 u8 common_flags;
666 u8 common_preempt_count; 666 u8 common_preempt_count;
667 u32 common_pid; 667 u32 common_pid;
668 u32 common_tgid; 668 u32 common_tgid;
669 669
670 char comm[16]; 670 char comm[16];
671 u32 pid; 671 u32 pid;
672 u64 runtime; 672 u64 runtime;
673 u64 vruntime; 673 u64 vruntime;
674 }; 674 };
675 675
676 struct trace_wakeup_event { 676 struct trace_wakeup_event {
677 u32 size; 677 u32 size;
678 678
679 u16 common_type; 679 u16 common_type;
680 u8 common_flags; 680 u8 common_flags;
681 u8 common_preempt_count; 681 u8 common_preempt_count;
682 u32 common_pid; 682 u32 common_pid;
683 u32 common_tgid; 683 u32 common_tgid;
684 684
685 char comm[16]; 685 char comm[16];
686 u32 pid; 686 u32 pid;
687 687
688 u32 prio; 688 u32 prio;
689 u32 success; 689 u32 success;
690 u32 cpu; 690 u32 cpu;
691 }; 691 };
692 692
693 struct trace_fork_event { 693 struct trace_fork_event {
694 u32 size; 694 u32 size;
695 695
696 u16 common_type; 696 u16 common_type;
697 u8 common_flags; 697 u8 common_flags;
698 u8 common_preempt_count; 698 u8 common_preempt_count;
699 u32 common_pid; 699 u32 common_pid;
700 u32 common_tgid; 700 u32 common_tgid;
701 701
702 char parent_comm[16]; 702 char parent_comm[16];
703 u32 parent_pid; 703 u32 parent_pid;
704 char child_comm[16]; 704 char child_comm[16];
705 u32 child_pid; 705 u32 child_pid;
706 }; 706 };
707 707
708 struct trace_migrate_task_event { 708 struct trace_migrate_task_event {
709 u32 size; 709 u32 size;
710 710
711 u16 common_type; 711 u16 common_type;
712 u8 common_flags; 712 u8 common_flags;
713 u8 common_preempt_count; 713 u8 common_preempt_count;
714 u32 common_pid; 714 u32 common_pid;
715 u32 common_tgid; 715 u32 common_tgid;
716 716
717 char comm[16]; 717 char comm[16];
718 u32 pid; 718 u32 pid;
719 719
720 u32 prio; 720 u32 prio;
721 u32 cpu; 721 u32 cpu;
722 }; 722 };
723 723
724 struct trace_sched_handler { 724 struct trace_sched_handler {
725 void (*switch_event)(struct trace_switch_event *, 725 void (*switch_event)(struct trace_switch_event *,
726 struct perf_session *, 726 struct perf_session *,
727 struct event *, 727 struct event *,
728 int cpu, 728 int cpu,
729 u64 timestamp, 729 u64 timestamp,
730 struct thread *thread); 730 struct thread *thread);
731 731
732 void (*runtime_event)(struct trace_runtime_event *, 732 void (*runtime_event)(struct trace_runtime_event *,
733 struct perf_session *, 733 struct perf_session *,
734 struct event *, 734 struct event *,
735 int cpu, 735 int cpu,
736 u64 timestamp, 736 u64 timestamp,
737 struct thread *thread); 737 struct thread *thread);
738 738
739 void (*wakeup_event)(struct trace_wakeup_event *, 739 void (*wakeup_event)(struct trace_wakeup_event *,
740 struct perf_session *, 740 struct perf_session *,
741 struct event *, 741 struct event *,
742 int cpu, 742 int cpu,
743 u64 timestamp, 743 u64 timestamp,
744 struct thread *thread); 744 struct thread *thread);
745 745
746 void (*fork_event)(struct trace_fork_event *, 746 void (*fork_event)(struct trace_fork_event *,
747 struct event *, 747 struct event *,
748 int cpu, 748 int cpu,
749 u64 timestamp, 749 u64 timestamp,
750 struct thread *thread); 750 struct thread *thread);
751 751
752 void (*migrate_task_event)(struct trace_migrate_task_event *, 752 void (*migrate_task_event)(struct trace_migrate_task_event *,
753 struct perf_session *session, 753 struct perf_session *session,
754 struct event *, 754 struct event *,
755 int cpu, 755 int cpu,
756 u64 timestamp, 756 u64 timestamp,
757 struct thread *thread); 757 struct thread *thread);
758 }; 758 };
759 759
760 760
761 static void 761 static void
762 replay_wakeup_event(struct trace_wakeup_event *wakeup_event, 762 replay_wakeup_event(struct trace_wakeup_event *wakeup_event,
763 struct perf_session *session __used, 763 struct perf_session *session __used,
764 struct event *event, 764 struct event *event,
765 int cpu __used, 765 int cpu __used,
766 u64 timestamp __used, 766 u64 timestamp __used,
767 struct thread *thread __used) 767 struct thread *thread __used)
768 { 768 {
769 struct task_desc *waker, *wakee; 769 struct task_desc *waker, *wakee;
770 770
771 if (verbose) { 771 if (verbose) {
772 printf("sched_wakeup event %p\n", event); 772 printf("sched_wakeup event %p\n", event);
773 773
774 printf(" ... pid %d woke up %s/%d\n", 774 printf(" ... pid %d woke up %s/%d\n",
775 wakeup_event->common_pid, 775 wakeup_event->common_pid,
776 wakeup_event->comm, 776 wakeup_event->comm,
777 wakeup_event->pid); 777 wakeup_event->pid);
778 } 778 }
779 779
780 waker = register_pid(wakeup_event->common_pid, "<unknown>"); 780 waker = register_pid(wakeup_event->common_pid, "<unknown>");
781 wakee = register_pid(wakeup_event->pid, wakeup_event->comm); 781 wakee = register_pid(wakeup_event->pid, wakeup_event->comm);
782 782
783 add_sched_event_wakeup(waker, timestamp, wakee); 783 add_sched_event_wakeup(waker, timestamp, wakee);
784 } 784 }
785 785
786 static u64 cpu_last_switched[MAX_CPUS]; 786 static u64 cpu_last_switched[MAX_CPUS];
787 787
788 static void 788 static void
789 replay_switch_event(struct trace_switch_event *switch_event, 789 replay_switch_event(struct trace_switch_event *switch_event,
790 struct perf_session *session __used, 790 struct perf_session *session __used,
791 struct event *event, 791 struct event *event,
792 int cpu, 792 int cpu,
793 u64 timestamp, 793 u64 timestamp,
794 struct thread *thread __used) 794 struct thread *thread __used)
795 { 795 {
796 struct task_desc *prev, __used *next; 796 struct task_desc *prev, __used *next;
797 u64 timestamp0; 797 u64 timestamp0;
798 s64 delta; 798 s64 delta;
799 799
800 if (verbose) 800 if (verbose)
801 printf("sched_switch event %p\n", event); 801 printf("sched_switch event %p\n", event);
802 802
803 if (cpu >= MAX_CPUS || cpu < 0) 803 if (cpu >= MAX_CPUS || cpu < 0)
804 return; 804 return;
805 805
806 timestamp0 = cpu_last_switched[cpu]; 806 timestamp0 = cpu_last_switched[cpu];
807 if (timestamp0) 807 if (timestamp0)
808 delta = timestamp - timestamp0; 808 delta = timestamp - timestamp0;
809 else 809 else
810 delta = 0; 810 delta = 0;
811 811
812 if (delta < 0) 812 if (delta < 0)
813 die("hm, delta: %" PRIu64 " < 0 ?\n", delta); 813 die("hm, delta: %" PRIu64 " < 0 ?\n", delta);
814 814
815 if (verbose) { 815 if (verbose) {
816 printf(" ... switch from %s/%d to %s/%d [ran %" PRIu64 " nsecs]\n", 816 printf(" ... switch from %s/%d to %s/%d [ran %" PRIu64 " nsecs]\n",
817 switch_event->prev_comm, switch_event->prev_pid, 817 switch_event->prev_comm, switch_event->prev_pid,
818 switch_event->next_comm, switch_event->next_pid, 818 switch_event->next_comm, switch_event->next_pid,
819 delta); 819 delta);
820 } 820 }
821 821
822 prev = register_pid(switch_event->prev_pid, switch_event->prev_comm); 822 prev = register_pid(switch_event->prev_pid, switch_event->prev_comm);
823 next = register_pid(switch_event->next_pid, switch_event->next_comm); 823 next = register_pid(switch_event->next_pid, switch_event->next_comm);
824 824
825 cpu_last_switched[cpu] = timestamp; 825 cpu_last_switched[cpu] = timestamp;
826 826
827 add_sched_event_run(prev, timestamp, delta); 827 add_sched_event_run(prev, timestamp, delta);
828 add_sched_event_sleep(prev, timestamp, switch_event->prev_state); 828 add_sched_event_sleep(prev, timestamp, switch_event->prev_state);
829 } 829 }
830 830
831 831
832 static void 832 static void
833 replay_fork_event(struct trace_fork_event *fork_event, 833 replay_fork_event(struct trace_fork_event *fork_event,
834 struct event *event, 834 struct event *event,
835 int cpu __used, 835 int cpu __used,
836 u64 timestamp __used, 836 u64 timestamp __used,
837 struct thread *thread __used) 837 struct thread *thread __used)
838 { 838 {
839 if (verbose) { 839 if (verbose) {
840 printf("sched_fork event %p\n", event); 840 printf("sched_fork event %p\n", event);
841 printf("... parent: %s/%d\n", fork_event->parent_comm, fork_event->parent_pid); 841 printf("... parent: %s/%d\n", fork_event->parent_comm, fork_event->parent_pid);
842 printf("... child: %s/%d\n", fork_event->child_comm, fork_event->child_pid); 842 printf("... child: %s/%d\n", fork_event->child_comm, fork_event->child_pid);
843 } 843 }
844 register_pid(fork_event->parent_pid, fork_event->parent_comm); 844 register_pid(fork_event->parent_pid, fork_event->parent_comm);
845 register_pid(fork_event->child_pid, fork_event->child_comm); 845 register_pid(fork_event->child_pid, fork_event->child_comm);
846 } 846 }
847 847
848 static struct trace_sched_handler replay_ops = { 848 static struct trace_sched_handler replay_ops = {
849 .wakeup_event = replay_wakeup_event, 849 .wakeup_event = replay_wakeup_event,
850 .switch_event = replay_switch_event, 850 .switch_event = replay_switch_event,
851 .fork_event = replay_fork_event, 851 .fork_event = replay_fork_event,
852 }; 852 };
853 853
854 struct sort_dimension { 854 struct sort_dimension {
855 const char *name; 855 const char *name;
856 sort_fn_t cmp; 856 sort_fn_t cmp;
857 struct list_head list; 857 struct list_head list;
858 }; 858 };
859 859
860 static LIST_HEAD(cmp_pid); 860 static LIST_HEAD(cmp_pid);
861 861
862 static int 862 static int
863 thread_lat_cmp(struct list_head *list, struct work_atoms *l, struct work_atoms *r) 863 thread_lat_cmp(struct list_head *list, struct work_atoms *l, struct work_atoms *r)
864 { 864 {
865 struct sort_dimension *sort; 865 struct sort_dimension *sort;
866 int ret = 0; 866 int ret = 0;
867 867
868 BUG_ON(list_empty(list)); 868 BUG_ON(list_empty(list));
869 869
870 list_for_each_entry(sort, list, list) { 870 list_for_each_entry(sort, list, list) {
871 ret = sort->cmp(l, r); 871 ret = sort->cmp(l, r);
872 if (ret) 872 if (ret)
873 return ret; 873 return ret;
874 } 874 }
875 875
876 return ret; 876 return ret;
877 } 877 }
878 878
879 static struct work_atoms * 879 static struct work_atoms *
880 thread_atoms_search(struct rb_root *root, struct thread *thread, 880 thread_atoms_search(struct rb_root *root, struct thread *thread,
881 struct list_head *sort_list) 881 struct list_head *sort_list)
882 { 882 {
883 struct rb_node *node = root->rb_node; 883 struct rb_node *node = root->rb_node;
884 struct work_atoms key = { .thread = thread }; 884 struct work_atoms key = { .thread = thread };
885 885
886 while (node) { 886 while (node) {
887 struct work_atoms *atoms; 887 struct work_atoms *atoms;
888 int cmp; 888 int cmp;
889 889
890 atoms = container_of(node, struct work_atoms, node); 890 atoms = container_of(node, struct work_atoms, node);
891 891
892 cmp = thread_lat_cmp(sort_list, &key, atoms); 892 cmp = thread_lat_cmp(sort_list, &key, atoms);
893 if (cmp > 0) 893 if (cmp > 0)
894 node = node->rb_left; 894 node = node->rb_left;
895 else if (cmp < 0) 895 else if (cmp < 0)
896 node = node->rb_right; 896 node = node->rb_right;
897 else { 897 else {
898 BUG_ON(thread != atoms->thread); 898 BUG_ON(thread != atoms->thread);
899 return atoms; 899 return atoms;
900 } 900 }
901 } 901 }
902 return NULL; 902 return NULL;
903 } 903 }
904 904
905 static void 905 static void
906 __thread_latency_insert(struct rb_root *root, struct work_atoms *data, 906 __thread_latency_insert(struct rb_root *root, struct work_atoms *data,
907 struct list_head *sort_list) 907 struct list_head *sort_list)
908 { 908 {
909 struct rb_node **new = &(root->rb_node), *parent = NULL; 909 struct rb_node **new = &(root->rb_node), *parent = NULL;
910 910
911 while (*new) { 911 while (*new) {
912 struct work_atoms *this; 912 struct work_atoms *this;
913 int cmp; 913 int cmp;
914 914
915 this = container_of(*new, struct work_atoms, node); 915 this = container_of(*new, struct work_atoms, node);
916 parent = *new; 916 parent = *new;
917 917
918 cmp = thread_lat_cmp(sort_list, data, this); 918 cmp = thread_lat_cmp(sort_list, data, this);
919 919
920 if (cmp > 0) 920 if (cmp > 0)
921 new = &((*new)->rb_left); 921 new = &((*new)->rb_left);
922 else 922 else
923 new = &((*new)->rb_right); 923 new = &((*new)->rb_right);
924 } 924 }
925 925
926 rb_link_node(&data->node, parent, new); 926 rb_link_node(&data->node, parent, new);
927 rb_insert_color(&data->node, root); 927 rb_insert_color(&data->node, root);
928 } 928 }
929 929
930 static void thread_atoms_insert(struct thread *thread) 930 static void thread_atoms_insert(struct thread *thread)
931 { 931 {
932 struct work_atoms *atoms = zalloc(sizeof(*atoms)); 932 struct work_atoms *atoms = zalloc(sizeof(*atoms));
933 if (!atoms) 933 if (!atoms)
934 die("No memory"); 934 die("No memory");
935 935
936 atoms->thread = thread; 936 atoms->thread = thread;
937 INIT_LIST_HEAD(&atoms->work_list); 937 INIT_LIST_HEAD(&atoms->work_list);
938 __thread_latency_insert(&atom_root, atoms, &cmp_pid); 938 __thread_latency_insert(&atom_root, atoms, &cmp_pid);
939 } 939 }
940 940
941 static void 941 static void
942 latency_fork_event(struct trace_fork_event *fork_event __used, 942 latency_fork_event(struct trace_fork_event *fork_event __used,
943 struct event *event __used, 943 struct event *event __used,
944 int cpu __used, 944 int cpu __used,
945 u64 timestamp __used, 945 u64 timestamp __used,
946 struct thread *thread __used) 946 struct thread *thread __used)
947 { 947 {
948 /* should insert the newcomer */ 948 /* should insert the newcomer */
949 } 949 }
950 950
951 __used 951 __used
952 static char sched_out_state(struct trace_switch_event *switch_event) 952 static char sched_out_state(struct trace_switch_event *switch_event)
953 { 953 {
954 const char *str = TASK_STATE_TO_CHAR_STR; 954 const char *str = TASK_STATE_TO_CHAR_STR;
955 955
956 return str[switch_event->prev_state]; 956 return str[switch_event->prev_state];
957 } 957 }
958 958
959 static void 959 static void
960 add_sched_out_event(struct work_atoms *atoms, 960 add_sched_out_event(struct work_atoms *atoms,
961 char run_state, 961 char run_state,
962 u64 timestamp) 962 u64 timestamp)
963 { 963 {
964 struct work_atom *atom = zalloc(sizeof(*atom)); 964 struct work_atom *atom = zalloc(sizeof(*atom));
965 if (!atom) 965 if (!atom)
966 die("Non memory"); 966 die("Non memory");
967 967
968 atom->sched_out_time = timestamp; 968 atom->sched_out_time = timestamp;
969 969
970 if (run_state == 'R') { 970 if (run_state == 'R') {
971 atom->state = THREAD_WAIT_CPU; 971 atom->state = THREAD_WAIT_CPU;
972 atom->wake_up_time = atom->sched_out_time; 972 atom->wake_up_time = atom->sched_out_time;
973 } 973 }
974 974
975 list_add_tail(&atom->list, &atoms->work_list); 975 list_add_tail(&atom->list, &atoms->work_list);
976 } 976 }
977 977
978 static void 978 static void
979 add_runtime_event(struct work_atoms *atoms, u64 delta, u64 timestamp __used) 979 add_runtime_event(struct work_atoms *atoms, u64 delta, u64 timestamp __used)
980 { 980 {
981 struct work_atom *atom; 981 struct work_atom *atom;
982 982
983 BUG_ON(list_empty(&atoms->work_list)); 983 BUG_ON(list_empty(&atoms->work_list));
984 984
985 atom = list_entry(atoms->work_list.prev, struct work_atom, list); 985 atom = list_entry(atoms->work_list.prev, struct work_atom, list);
986 986
987 atom->runtime += delta; 987 atom->runtime += delta;
988 atoms->total_runtime += delta; 988 atoms->total_runtime += delta;
989 } 989 }
990 990
991 static void 991 static void
992 add_sched_in_event(struct work_atoms *atoms, u64 timestamp) 992 add_sched_in_event(struct work_atoms *atoms, u64 timestamp)
993 { 993 {
994 struct work_atom *atom; 994 struct work_atom *atom;
995 u64 delta; 995 u64 delta;
996 996
997 if (list_empty(&atoms->work_list)) 997 if (list_empty(&atoms->work_list))
998 return; 998 return;
999 999
1000 atom = list_entry(atoms->work_list.prev, struct work_atom, list); 1000 atom = list_entry(atoms->work_list.prev, struct work_atom, list);
1001 1001
1002 if (atom->state != THREAD_WAIT_CPU) 1002 if (atom->state != THREAD_WAIT_CPU)
1003 return; 1003 return;
1004 1004
1005 if (timestamp < atom->wake_up_time) { 1005 if (timestamp < atom->wake_up_time) {
1006 atom->state = THREAD_IGNORE; 1006 atom->state = THREAD_IGNORE;
1007 return; 1007 return;
1008 } 1008 }
1009 1009
1010 atom->state = THREAD_SCHED_IN; 1010 atom->state = THREAD_SCHED_IN;
1011 atom->sched_in_time = timestamp; 1011 atom->sched_in_time = timestamp;
1012 1012
1013 delta = atom->sched_in_time - atom->wake_up_time; 1013 delta = atom->sched_in_time - atom->wake_up_time;
1014 atoms->total_lat += delta; 1014 atoms->total_lat += delta;
1015 if (delta > atoms->max_lat) { 1015 if (delta > atoms->max_lat) {
1016 atoms->max_lat = delta; 1016 atoms->max_lat = delta;
1017 atoms->max_lat_at = timestamp; 1017 atoms->max_lat_at = timestamp;
1018 } 1018 }
1019 atoms->nb_atoms++; 1019 atoms->nb_atoms++;
1020 } 1020 }
1021 1021
1022 static void 1022 static void
1023 latency_switch_event(struct trace_switch_event *switch_event, 1023 latency_switch_event(struct trace_switch_event *switch_event,
1024 struct perf_session *session, 1024 struct perf_session *session,
1025 struct event *event __used, 1025 struct event *event __used,
1026 int cpu, 1026 int cpu,
1027 u64 timestamp, 1027 u64 timestamp,
1028 struct thread *thread __used) 1028 struct thread *thread __used)
1029 { 1029 {
1030 struct work_atoms *out_events, *in_events; 1030 struct work_atoms *out_events, *in_events;
1031 struct thread *sched_out, *sched_in; 1031 struct thread *sched_out, *sched_in;
1032 u64 timestamp0; 1032 u64 timestamp0;
1033 s64 delta; 1033 s64 delta;
1034 1034
1035 BUG_ON(cpu >= MAX_CPUS || cpu < 0); 1035 BUG_ON(cpu >= MAX_CPUS || cpu < 0);
1036 1036
1037 timestamp0 = cpu_last_switched[cpu]; 1037 timestamp0 = cpu_last_switched[cpu];
1038 cpu_last_switched[cpu] = timestamp; 1038 cpu_last_switched[cpu] = timestamp;
1039 if (timestamp0) 1039 if (timestamp0)
1040 delta = timestamp - timestamp0; 1040 delta = timestamp - timestamp0;
1041 else 1041 else
1042 delta = 0; 1042 delta = 0;
1043 1043
1044 if (delta < 0) 1044 if (delta < 0)
1045 die("hm, delta: %" PRIu64 " < 0 ?\n", delta); 1045 die("hm, delta: %" PRIu64 " < 0 ?\n", delta);
1046 1046
1047 1047
1048 sched_out = perf_session__findnew(session, switch_event->prev_pid); 1048 sched_out = perf_session__findnew(session, switch_event->prev_pid);
1049 sched_in = perf_session__findnew(session, switch_event->next_pid); 1049 sched_in = perf_session__findnew(session, switch_event->next_pid);
1050 1050
1051 out_events = thread_atoms_search(&atom_root, sched_out, &cmp_pid); 1051 out_events = thread_atoms_search(&atom_root, sched_out, &cmp_pid);
1052 if (!out_events) { 1052 if (!out_events) {
1053 thread_atoms_insert(sched_out); 1053 thread_atoms_insert(sched_out);
1054 out_events = thread_atoms_search(&atom_root, sched_out, &cmp_pid); 1054 out_events = thread_atoms_search(&atom_root, sched_out, &cmp_pid);
1055 if (!out_events) 1055 if (!out_events)
1056 die("out-event: Internal tree error"); 1056 die("out-event: Internal tree error");
1057 } 1057 }
1058 add_sched_out_event(out_events, sched_out_state(switch_event), timestamp); 1058 add_sched_out_event(out_events, sched_out_state(switch_event), timestamp);
1059 1059
1060 in_events = thread_atoms_search(&atom_root, sched_in, &cmp_pid); 1060 in_events = thread_atoms_search(&atom_root, sched_in, &cmp_pid);
1061 if (!in_events) { 1061 if (!in_events) {
1062 thread_atoms_insert(sched_in); 1062 thread_atoms_insert(sched_in);
1063 in_events = thread_atoms_search(&atom_root, sched_in, &cmp_pid); 1063 in_events = thread_atoms_search(&atom_root, sched_in, &cmp_pid);
1064 if (!in_events) 1064 if (!in_events)
1065 die("in-event: Internal tree error"); 1065 die("in-event: Internal tree error");
1066 /* 1066 /*
1067 * Take came in we have not heard about yet, 1067 * Take came in we have not heard about yet,
1068 * add in an initial atom in runnable state: 1068 * add in an initial atom in runnable state:
1069 */ 1069 */
1070 add_sched_out_event(in_events, 'R', timestamp); 1070 add_sched_out_event(in_events, 'R', timestamp);
1071 } 1071 }
1072 add_sched_in_event(in_events, timestamp); 1072 add_sched_in_event(in_events, timestamp);
1073 } 1073 }
1074 1074
1075 static void 1075 static void
1076 latency_runtime_event(struct trace_runtime_event *runtime_event, 1076 latency_runtime_event(struct trace_runtime_event *runtime_event,
1077 struct perf_session *session, 1077 struct perf_session *session,
1078 struct event *event __used, 1078 struct event *event __used,
1079 int cpu, 1079 int cpu,
1080 u64 timestamp, 1080 u64 timestamp,
1081 struct thread *this_thread __used) 1081 struct thread *this_thread __used)
1082 { 1082 {
1083 struct thread *thread = perf_session__findnew(session, runtime_event->pid); 1083 struct thread *thread = perf_session__findnew(session, runtime_event->pid);
1084 struct work_atoms *atoms = thread_atoms_search(&atom_root, thread, &cmp_pid); 1084 struct work_atoms *atoms = thread_atoms_search(&atom_root, thread, &cmp_pid);
1085 1085
1086 BUG_ON(cpu >= MAX_CPUS || cpu < 0); 1086 BUG_ON(cpu >= MAX_CPUS || cpu < 0);
1087 if (!atoms) { 1087 if (!atoms) {
1088 thread_atoms_insert(thread); 1088 thread_atoms_insert(thread);
1089 atoms = thread_atoms_search(&atom_root, thread, &cmp_pid); 1089 atoms = thread_atoms_search(&atom_root, thread, &cmp_pid);
1090 if (!atoms) 1090 if (!atoms)
1091 die("in-event: Internal tree error"); 1091 die("in-event: Internal tree error");
1092 add_sched_out_event(atoms, 'R', timestamp); 1092 add_sched_out_event(atoms, 'R', timestamp);
1093 } 1093 }
1094 1094
1095 add_runtime_event(atoms, runtime_event->runtime, timestamp); 1095 add_runtime_event(atoms, runtime_event->runtime, timestamp);
1096 } 1096 }
1097 1097
1098 static void 1098 static void
1099 latency_wakeup_event(struct trace_wakeup_event *wakeup_event, 1099 latency_wakeup_event(struct trace_wakeup_event *wakeup_event,
1100 struct perf_session *session, 1100 struct perf_session *session,
1101 struct event *__event __used, 1101 struct event *__event __used,
1102 int cpu __used, 1102 int cpu __used,
1103 u64 timestamp, 1103 u64 timestamp,
1104 struct thread *thread __used) 1104 struct thread *thread __used)
1105 { 1105 {
1106 struct work_atoms *atoms; 1106 struct work_atoms *atoms;
1107 struct work_atom *atom; 1107 struct work_atom *atom;
1108 struct thread *wakee; 1108 struct thread *wakee;
1109 1109
1110 /* Note for later, it may be interesting to observe the failing cases */ 1110 /* Note for later, it may be interesting to observe the failing cases */
1111 if (!wakeup_event->success) 1111 if (!wakeup_event->success)
1112 return; 1112 return;
1113 1113
1114 wakee = perf_session__findnew(session, wakeup_event->pid); 1114 wakee = perf_session__findnew(session, wakeup_event->pid);
1115 atoms = thread_atoms_search(&atom_root, wakee, &cmp_pid); 1115 atoms = thread_atoms_search(&atom_root, wakee, &cmp_pid);
1116 if (!atoms) { 1116 if (!atoms) {
1117 thread_atoms_insert(wakee); 1117 thread_atoms_insert(wakee);
1118 atoms = thread_atoms_search(&atom_root, wakee, &cmp_pid); 1118 atoms = thread_atoms_search(&atom_root, wakee, &cmp_pid);
1119 if (!atoms) 1119 if (!atoms)
1120 die("wakeup-event: Internal tree error"); 1120 die("wakeup-event: Internal tree error");
1121 add_sched_out_event(atoms, 'S', timestamp); 1121 add_sched_out_event(atoms, 'S', timestamp);
1122 } 1122 }
1123 1123
1124 BUG_ON(list_empty(&atoms->work_list)); 1124 BUG_ON(list_empty(&atoms->work_list));
1125 1125
1126 atom = list_entry(atoms->work_list.prev, struct work_atom, list); 1126 atom = list_entry(atoms->work_list.prev, struct work_atom, list);
1127 1127
1128 /* 1128 /*
1129 * You WILL be missing events if you've recorded only 1129 * You WILL be missing events if you've recorded only
1130 * one CPU, or are only looking at only one, so don't 1130 * one CPU, or are only looking at only one, so don't
1131 * make useless noise. 1131 * make useless noise.
1132 */ 1132 */
1133 if (profile_cpu == -1 && atom->state != THREAD_SLEEPING) 1133 if (profile_cpu == -1 && atom->state != THREAD_SLEEPING)
1134 nr_state_machine_bugs++; 1134 nr_state_machine_bugs++;
1135 1135
1136 nr_timestamps++; 1136 nr_timestamps++;
1137 if (atom->sched_out_time > timestamp) { 1137 if (atom->sched_out_time > timestamp) {
1138 nr_unordered_timestamps++; 1138 nr_unordered_timestamps++;
1139 return; 1139 return;
1140 } 1140 }
1141 1141
1142 atom->state = THREAD_WAIT_CPU; 1142 atom->state = THREAD_WAIT_CPU;
1143 atom->wake_up_time = timestamp; 1143 atom->wake_up_time = timestamp;
1144 } 1144 }
1145 1145
1146 static void 1146 static void
1147 latency_migrate_task_event(struct trace_migrate_task_event *migrate_task_event, 1147 latency_migrate_task_event(struct trace_migrate_task_event *migrate_task_event,
1148 struct perf_session *session, 1148 struct perf_session *session,
1149 struct event *__event __used, 1149 struct event *__event __used,
1150 int cpu __used, 1150 int cpu __used,
1151 u64 timestamp, 1151 u64 timestamp,
1152 struct thread *thread __used) 1152 struct thread *thread __used)
1153 { 1153 {
1154 struct work_atoms *atoms; 1154 struct work_atoms *atoms;
1155 struct work_atom *atom; 1155 struct work_atom *atom;
1156 struct thread *migrant; 1156 struct thread *migrant;
1157 1157
1158 /* 1158 /*
1159 * Only need to worry about migration when profiling one CPU. 1159 * Only need to worry about migration when profiling one CPU.
1160 */ 1160 */
1161 if (profile_cpu == -1) 1161 if (profile_cpu == -1)
1162 return; 1162 return;
1163 1163
1164 migrant = perf_session__findnew(session, migrate_task_event->pid); 1164 migrant = perf_session__findnew(session, migrate_task_event->pid);
1165 atoms = thread_atoms_search(&atom_root, migrant, &cmp_pid); 1165 atoms = thread_atoms_search(&atom_root, migrant, &cmp_pid);
1166 if (!atoms) { 1166 if (!atoms) {
1167 thread_atoms_insert(migrant); 1167 thread_atoms_insert(migrant);
1168 register_pid(migrant->pid, migrant->comm); 1168 register_pid(migrant->pid, migrant->comm);
1169 atoms = thread_atoms_search(&atom_root, migrant, &cmp_pid); 1169 atoms = thread_atoms_search(&atom_root, migrant, &cmp_pid);
1170 if (!atoms) 1170 if (!atoms)
1171 die("migration-event: Internal tree error"); 1171 die("migration-event: Internal tree error");
1172 add_sched_out_event(atoms, 'R', timestamp); 1172 add_sched_out_event(atoms, 'R', timestamp);
1173 } 1173 }
1174 1174
1175 BUG_ON(list_empty(&atoms->work_list)); 1175 BUG_ON(list_empty(&atoms->work_list));
1176 1176
1177 atom = list_entry(atoms->work_list.prev, struct work_atom, list); 1177 atom = list_entry(atoms->work_list.prev, struct work_atom, list);
1178 atom->sched_in_time = atom->sched_out_time = atom->wake_up_time = timestamp; 1178 atom->sched_in_time = atom->sched_out_time = atom->wake_up_time = timestamp;
1179 1179
1180 nr_timestamps++; 1180 nr_timestamps++;
1181 1181
1182 if (atom->sched_out_time > timestamp) 1182 if (atom->sched_out_time > timestamp)
1183 nr_unordered_timestamps++; 1183 nr_unordered_timestamps++;
1184 } 1184 }
1185 1185
1186 static struct trace_sched_handler lat_ops = { 1186 static struct trace_sched_handler lat_ops = {
1187 .wakeup_event = latency_wakeup_event, 1187 .wakeup_event = latency_wakeup_event,
1188 .switch_event = latency_switch_event, 1188 .switch_event = latency_switch_event,
1189 .runtime_event = latency_runtime_event, 1189 .runtime_event = latency_runtime_event,
1190 .fork_event = latency_fork_event, 1190 .fork_event = latency_fork_event,
1191 .migrate_task_event = latency_migrate_task_event, 1191 .migrate_task_event = latency_migrate_task_event,
1192 }; 1192 };
1193 1193
1194 static void output_lat_thread(struct work_atoms *work_list) 1194 static void output_lat_thread(struct work_atoms *work_list)
1195 { 1195 {
1196 int i; 1196 int i;
1197 int ret; 1197 int ret;
1198 u64 avg; 1198 u64 avg;
1199 1199
1200 if (!work_list->nb_atoms) 1200 if (!work_list->nb_atoms)
1201 return; 1201 return;
1202 /* 1202 /*
1203 * Ignore idle threads: 1203 * Ignore idle threads:
1204 */ 1204 */
1205 if (!strcmp(work_list->thread->comm, "swapper")) 1205 if (!strcmp(work_list->thread->comm, "swapper"))
1206 return; 1206 return;
1207 1207
1208 all_runtime += work_list->total_runtime; 1208 all_runtime += work_list->total_runtime;
1209 all_count += work_list->nb_atoms; 1209 all_count += work_list->nb_atoms;
1210 1210
1211 ret = printf(" %s:%d ", work_list->thread->comm, work_list->thread->pid); 1211 ret = printf(" %s:%d ", work_list->thread->comm, work_list->thread->pid);
1212 1212
1213 for (i = 0; i < 24 - ret; i++) 1213 for (i = 0; i < 24 - ret; i++)
1214 printf(" "); 1214 printf(" ");
1215 1215
1216 avg = work_list->total_lat / work_list->nb_atoms; 1216 avg = work_list->total_lat / work_list->nb_atoms;
1217 1217
1218 printf("|%11.3f ms |%9" PRIu64 " | avg:%9.3f ms | max:%9.3f ms | max at: %9.6f s\n", 1218 printf("|%11.3f ms |%9" PRIu64 " | avg:%9.3f ms | max:%9.3f ms | max at: %9.6f s\n",
1219 (double)work_list->total_runtime / 1e6, 1219 (double)work_list->total_runtime / 1e6,
1220 work_list->nb_atoms, (double)avg / 1e6, 1220 work_list->nb_atoms, (double)avg / 1e6,
1221 (double)work_list->max_lat / 1e6, 1221 (double)work_list->max_lat / 1e6,
1222 (double)work_list->max_lat_at / 1e9); 1222 (double)work_list->max_lat_at / 1e9);
1223 } 1223 }
1224 1224
1225 static int pid_cmp(struct work_atoms *l, struct work_atoms *r) 1225 static int pid_cmp(struct work_atoms *l, struct work_atoms *r)
1226 { 1226 {
1227 if (l->thread->pid < r->thread->pid) 1227 if (l->thread->pid < r->thread->pid)
1228 return -1; 1228 return -1;
1229 if (l->thread->pid > r->thread->pid) 1229 if (l->thread->pid > r->thread->pid)
1230 return 1; 1230 return 1;
1231 1231
1232 return 0; 1232 return 0;
1233 } 1233 }
1234 1234
1235 static struct sort_dimension pid_sort_dimension = { 1235 static struct sort_dimension pid_sort_dimension = {
1236 .name = "pid", 1236 .name = "pid",
1237 .cmp = pid_cmp, 1237 .cmp = pid_cmp,
1238 }; 1238 };
1239 1239
1240 static int avg_cmp(struct work_atoms *l, struct work_atoms *r) 1240 static int avg_cmp(struct work_atoms *l, struct work_atoms *r)
1241 { 1241 {
1242 u64 avgl, avgr; 1242 u64 avgl, avgr;
1243 1243
1244 if (!l->nb_atoms) 1244 if (!l->nb_atoms)
1245 return -1; 1245 return -1;
1246 1246
1247 if (!r->nb_atoms) 1247 if (!r->nb_atoms)
1248 return 1; 1248 return 1;
1249 1249
1250 avgl = l->total_lat / l->nb_atoms; 1250 avgl = l->total_lat / l->nb_atoms;
1251 avgr = r->total_lat / r->nb_atoms; 1251 avgr = r->total_lat / r->nb_atoms;
1252 1252
1253 if (avgl < avgr) 1253 if (avgl < avgr)
1254 return -1; 1254 return -1;
1255 if (avgl > avgr) 1255 if (avgl > avgr)
1256 return 1; 1256 return 1;
1257 1257
1258 return 0; 1258 return 0;
1259 } 1259 }
1260 1260
1261 static struct sort_dimension avg_sort_dimension = { 1261 static struct sort_dimension avg_sort_dimension = {
1262 .name = "avg", 1262 .name = "avg",
1263 .cmp = avg_cmp, 1263 .cmp = avg_cmp,
1264 }; 1264 };
1265 1265
1266 static int max_cmp(struct work_atoms *l, struct work_atoms *r) 1266 static int max_cmp(struct work_atoms *l, struct work_atoms *r)
1267 { 1267 {
1268 if (l->max_lat < r->max_lat) 1268 if (l->max_lat < r->max_lat)
1269 return -1; 1269 return -1;
1270 if (l->max_lat > r->max_lat) 1270 if (l->max_lat > r->max_lat)
1271 return 1; 1271 return 1;
1272 1272
1273 return 0; 1273 return 0;
1274 } 1274 }
1275 1275
1276 static struct sort_dimension max_sort_dimension = { 1276 static struct sort_dimension max_sort_dimension = {
1277 .name = "max", 1277 .name = "max",
1278 .cmp = max_cmp, 1278 .cmp = max_cmp,
1279 }; 1279 };
1280 1280
1281 static int switch_cmp(struct work_atoms *l, struct work_atoms *r) 1281 static int switch_cmp(struct work_atoms *l, struct work_atoms *r)
1282 { 1282 {
1283 if (l->nb_atoms < r->nb_atoms) 1283 if (l->nb_atoms < r->nb_atoms)
1284 return -1; 1284 return -1;
1285 if (l->nb_atoms > r->nb_atoms) 1285 if (l->nb_atoms > r->nb_atoms)
1286 return 1; 1286 return 1;
1287 1287
1288 return 0; 1288 return 0;
1289 } 1289 }
1290 1290
1291 static struct sort_dimension switch_sort_dimension = { 1291 static struct sort_dimension switch_sort_dimension = {
1292 .name = "switch", 1292 .name = "switch",
1293 .cmp = switch_cmp, 1293 .cmp = switch_cmp,
1294 }; 1294 };
1295 1295
1296 static int runtime_cmp(struct work_atoms *l, struct work_atoms *r) 1296 static int runtime_cmp(struct work_atoms *l, struct work_atoms *r)
1297 { 1297 {
1298 if (l->total_runtime < r->total_runtime) 1298 if (l->total_runtime < r->total_runtime)
1299 return -1; 1299 return -1;
1300 if (l->total_runtime > r->total_runtime) 1300 if (l->total_runtime > r->total_runtime)
1301 return 1; 1301 return 1;
1302 1302
1303 return 0; 1303 return 0;
1304 } 1304 }
1305 1305
1306 static struct sort_dimension runtime_sort_dimension = { 1306 static struct sort_dimension runtime_sort_dimension = {
1307 .name = "runtime", 1307 .name = "runtime",
1308 .cmp = runtime_cmp, 1308 .cmp = runtime_cmp,
1309 }; 1309 };
1310 1310
1311 static struct sort_dimension *available_sorts[] = { 1311 static struct sort_dimension *available_sorts[] = {
1312 &pid_sort_dimension, 1312 &pid_sort_dimension,
1313 &avg_sort_dimension, 1313 &avg_sort_dimension,
1314 &max_sort_dimension, 1314 &max_sort_dimension,
1315 &switch_sort_dimension, 1315 &switch_sort_dimension,
1316 &runtime_sort_dimension, 1316 &runtime_sort_dimension,
1317 }; 1317 };
1318 1318
1319 #define NB_AVAILABLE_SORTS (int)(sizeof(available_sorts) / sizeof(struct sort_dimension *)) 1319 #define NB_AVAILABLE_SORTS (int)(sizeof(available_sorts) / sizeof(struct sort_dimension *))
1320 1320
1321 static LIST_HEAD(sort_list); 1321 static LIST_HEAD(sort_list);
1322 1322
1323 static int sort_dimension__add(const char *tok, struct list_head *list) 1323 static int sort_dimension__add(const char *tok, struct list_head *list)
1324 { 1324 {
1325 int i; 1325 int i;
1326 1326
1327 for (i = 0; i < NB_AVAILABLE_SORTS; i++) { 1327 for (i = 0; i < NB_AVAILABLE_SORTS; i++) {
1328 if (!strcmp(available_sorts[i]->name, tok)) { 1328 if (!strcmp(available_sorts[i]->name, tok)) {
1329 list_add_tail(&available_sorts[i]->list, list); 1329 list_add_tail(&available_sorts[i]->list, list);
1330 1330
1331 return 0; 1331 return 0;
1332 } 1332 }
1333 } 1333 }
1334 1334
1335 return -1; 1335 return -1;
1336 } 1336 }
1337 1337
1338 static void setup_sorting(void); 1338 static void setup_sorting(void);
1339 1339
1340 static void sort_lat(void) 1340 static void sort_lat(void)
1341 { 1341 {
1342 struct rb_node *node; 1342 struct rb_node *node;
1343 1343
1344 for (;;) { 1344 for (;;) {
1345 struct work_atoms *data; 1345 struct work_atoms *data;
1346 node = rb_first(&atom_root); 1346 node = rb_first(&atom_root);
1347 if (!node) 1347 if (!node)
1348 break; 1348 break;
1349 1349
1350 rb_erase(node, &atom_root); 1350 rb_erase(node, &atom_root);
1351 data = rb_entry(node, struct work_atoms, node); 1351 data = rb_entry(node, struct work_atoms, node);
1352 __thread_latency_insert(&sorted_atom_root, data, &sort_list); 1352 __thread_latency_insert(&sorted_atom_root, data, &sort_list);
1353 } 1353 }
1354 } 1354 }
1355 1355
1356 static struct trace_sched_handler *trace_handler; 1356 static struct trace_sched_handler *trace_handler;
1357 1357
1358 static void 1358 static void
1359 process_sched_wakeup_event(void *data, struct perf_session *session, 1359 process_sched_wakeup_event(void *data, struct perf_session *session,
1360 struct event *event, 1360 struct event *event,
1361 int cpu __used, 1361 int cpu __used,
1362 u64 timestamp __used, 1362 u64 timestamp __used,
1363 struct thread *thread __used) 1363 struct thread *thread __used)
1364 { 1364 {
1365 struct trace_wakeup_event wakeup_event; 1365 struct trace_wakeup_event wakeup_event;
1366 1366
1367 FILL_COMMON_FIELDS(wakeup_event, event, data); 1367 FILL_COMMON_FIELDS(wakeup_event, event, data);
1368 1368
1369 FILL_ARRAY(wakeup_event, comm, event, data); 1369 FILL_ARRAY(wakeup_event, comm, event, data);
1370 FILL_FIELD(wakeup_event, pid, event, data); 1370 FILL_FIELD(wakeup_event, pid, event, data);
1371 FILL_FIELD(wakeup_event, prio, event, data); 1371 FILL_FIELD(wakeup_event, prio, event, data);
1372 FILL_FIELD(wakeup_event, success, event, data); 1372 FILL_FIELD(wakeup_event, success, event, data);
1373 FILL_FIELD(wakeup_event, cpu, event, data); 1373 FILL_FIELD(wakeup_event, cpu, event, data);
1374 1374
1375 if (trace_handler->wakeup_event) 1375 if (trace_handler->wakeup_event)
1376 trace_handler->wakeup_event(&wakeup_event, session, event, 1376 trace_handler->wakeup_event(&wakeup_event, session, event,
1377 cpu, timestamp, thread); 1377 cpu, timestamp, thread);
1378 } 1378 }
1379 1379
1380 /* 1380 /*
1381 * Track the current task - that way we can know whether there's any 1381 * Track the current task - that way we can know whether there's any
1382 * weird events, such as a task being switched away that is not current. 1382 * weird events, such as a task being switched away that is not current.
1383 */ 1383 */
1384 static int max_cpu; 1384 static int max_cpu;
1385 1385
1386 static u32 curr_pid[MAX_CPUS] = { [0 ... MAX_CPUS-1] = -1 }; 1386 static u32 curr_pid[MAX_CPUS] = { [0 ... MAX_CPUS-1] = -1 };
1387 1387
1388 static struct thread *curr_thread[MAX_CPUS]; 1388 static struct thread *curr_thread[MAX_CPUS];
1389 1389
1390 static char next_shortname1 = 'A'; 1390 static char next_shortname1 = 'A';
1391 static char next_shortname2 = '0'; 1391 static char next_shortname2 = '0';
1392 1392
1393 static void 1393 static void
1394 map_switch_event(struct trace_switch_event *switch_event, 1394 map_switch_event(struct trace_switch_event *switch_event,
1395 struct perf_session *session, 1395 struct perf_session *session,
1396 struct event *event __used, 1396 struct event *event __used,
1397 int this_cpu, 1397 int this_cpu,
1398 u64 timestamp, 1398 u64 timestamp,
1399 struct thread *thread __used) 1399 struct thread *thread __used)
1400 { 1400 {
1401 struct thread *sched_out __used, *sched_in; 1401 struct thread *sched_out __used, *sched_in;
1402 int new_shortname; 1402 int new_shortname;
1403 u64 timestamp0; 1403 u64 timestamp0;
1404 s64 delta; 1404 s64 delta;
1405 int cpu; 1405 int cpu;
1406 1406
1407 BUG_ON(this_cpu >= MAX_CPUS || this_cpu < 0); 1407 BUG_ON(this_cpu >= MAX_CPUS || this_cpu < 0);
1408 1408
1409 if (this_cpu > max_cpu) 1409 if (this_cpu > max_cpu)
1410 max_cpu = this_cpu; 1410 max_cpu = this_cpu;
1411 1411
1412 timestamp0 = cpu_last_switched[this_cpu]; 1412 timestamp0 = cpu_last_switched[this_cpu];
1413 cpu_last_switched[this_cpu] = timestamp; 1413 cpu_last_switched[this_cpu] = timestamp;
1414 if (timestamp0) 1414 if (timestamp0)
1415 delta = timestamp - timestamp0; 1415 delta = timestamp - timestamp0;
1416 else 1416 else
1417 delta = 0; 1417 delta = 0;
1418 1418
1419 if (delta < 0) 1419 if (delta < 0)
1420 die("hm, delta: %" PRIu64 " < 0 ?\n", delta); 1420 die("hm, delta: %" PRIu64 " < 0 ?\n", delta);
1421 1421
1422 1422
1423 sched_out = perf_session__findnew(session, switch_event->prev_pid); 1423 sched_out = perf_session__findnew(session, switch_event->prev_pid);
1424 sched_in = perf_session__findnew(session, switch_event->next_pid); 1424 sched_in = perf_session__findnew(session, switch_event->next_pid);
1425 1425
1426 curr_thread[this_cpu] = sched_in; 1426 curr_thread[this_cpu] = sched_in;
1427 1427
1428 printf(" "); 1428 printf(" ");
1429 1429
1430 new_shortname = 0; 1430 new_shortname = 0;
1431 if (!sched_in->shortname[0]) { 1431 if (!sched_in->shortname[0]) {
1432 sched_in->shortname[0] = next_shortname1; 1432 sched_in->shortname[0] = next_shortname1;
1433 sched_in->shortname[1] = next_shortname2; 1433 sched_in->shortname[1] = next_shortname2;
1434 1434
1435 if (next_shortname1 < 'Z') { 1435 if (next_shortname1 < 'Z') {
1436 next_shortname1++; 1436 next_shortname1++;
1437 } else { 1437 } else {
1438 next_shortname1='A'; 1438 next_shortname1='A';
1439 if (next_shortname2 < '9') { 1439 if (next_shortname2 < '9') {
1440 next_shortname2++; 1440 next_shortname2++;
1441 } else { 1441 } else {
1442 next_shortname2='0'; 1442 next_shortname2='0';
1443 } 1443 }
1444 } 1444 }
1445 new_shortname = 1; 1445 new_shortname = 1;
1446 } 1446 }
1447 1447
1448 for (cpu = 0; cpu <= max_cpu; cpu++) { 1448 for (cpu = 0; cpu <= max_cpu; cpu++) {
1449 if (cpu != this_cpu) 1449 if (cpu != this_cpu)
1450 printf(" "); 1450 printf(" ");
1451 else 1451 else
1452 printf("*"); 1452 printf("*");
1453 1453
1454 if (curr_thread[cpu]) { 1454 if (curr_thread[cpu]) {
1455 if (curr_thread[cpu]->pid) 1455 if (curr_thread[cpu]->pid)
1456 printf("%2s ", curr_thread[cpu]->shortname); 1456 printf("%2s ", curr_thread[cpu]->shortname);
1457 else 1457 else
1458 printf(". "); 1458 printf(". ");
1459 } else 1459 } else
1460 printf(" "); 1460 printf(" ");
1461 } 1461 }
1462 1462
1463 printf(" %12.6f secs ", (double)timestamp/1e9); 1463 printf(" %12.6f secs ", (double)timestamp/1e9);
1464 if (new_shortname) { 1464 if (new_shortname) {
1465 printf("%s => %s:%d\n", 1465 printf("%s => %s:%d\n",
1466 sched_in->shortname, sched_in->comm, sched_in->pid); 1466 sched_in->shortname, sched_in->comm, sched_in->pid);
1467 } else { 1467 } else {
1468 printf("\n"); 1468 printf("\n");
1469 } 1469 }
1470 } 1470 }
1471 1471
1472 1472
1473 static void 1473 static void
1474 process_sched_switch_event(void *data, struct perf_session *session, 1474 process_sched_switch_event(void *data, struct perf_session *session,
1475 struct event *event, 1475 struct event *event,
1476 int this_cpu, 1476 int this_cpu,
1477 u64 timestamp __used, 1477 u64 timestamp __used,
1478 struct thread *thread __used) 1478 struct thread *thread __used)
1479 { 1479 {
1480 struct trace_switch_event switch_event; 1480 struct trace_switch_event switch_event;
1481 1481
1482 FILL_COMMON_FIELDS(switch_event, event, data); 1482 FILL_COMMON_FIELDS(switch_event, event, data);
1483 1483
1484 FILL_ARRAY(switch_event, prev_comm, event, data); 1484 FILL_ARRAY(switch_event, prev_comm, event, data);
1485 FILL_FIELD(switch_event, prev_pid, event, data); 1485 FILL_FIELD(switch_event, prev_pid, event, data);
1486 FILL_FIELD(switch_event, prev_prio, event, data); 1486 FILL_FIELD(switch_event, prev_prio, event, data);
1487 FILL_FIELD(switch_event, prev_state, event, data); 1487 FILL_FIELD(switch_event, prev_state, event, data);
1488 FILL_ARRAY(switch_event, next_comm, event, data); 1488 FILL_ARRAY(switch_event, next_comm, event, data);
1489 FILL_FIELD(switch_event, next_pid, event, data); 1489 FILL_FIELD(switch_event, next_pid, event, data);
1490 FILL_FIELD(switch_event, next_prio, event, data); 1490 FILL_FIELD(switch_event, next_prio, event, data);
1491 1491
1492 if (curr_pid[this_cpu] != (u32)-1) { 1492 if (curr_pid[this_cpu] != (u32)-1) {
1493 /* 1493 /*
1494 * Are we trying to switch away a PID that is 1494 * Are we trying to switch away a PID that is
1495 * not current? 1495 * not current?
1496 */ 1496 */
1497 if (curr_pid[this_cpu] != switch_event.prev_pid) 1497 if (curr_pid[this_cpu] != switch_event.prev_pid)
1498 nr_context_switch_bugs++; 1498 nr_context_switch_bugs++;
1499 } 1499 }
1500 if (trace_handler->switch_event) 1500 if (trace_handler->switch_event)
1501 trace_handler->switch_event(&switch_event, session, event, 1501 trace_handler->switch_event(&switch_event, session, event,
1502 this_cpu, timestamp, thread); 1502 this_cpu, timestamp, thread);
1503 1503
1504 curr_pid[this_cpu] = switch_event.next_pid; 1504 curr_pid[this_cpu] = switch_event.next_pid;
1505 } 1505 }
1506 1506
1507 static void 1507 static void
1508 process_sched_runtime_event(void *data, struct perf_session *session, 1508 process_sched_runtime_event(void *data, struct perf_session *session,
1509 struct event *event, 1509 struct event *event,
1510 int cpu __used, 1510 int cpu __used,
1511 u64 timestamp __used, 1511 u64 timestamp __used,
1512 struct thread *thread __used) 1512 struct thread *thread __used)
1513 { 1513 {
1514 struct trace_runtime_event runtime_event; 1514 struct trace_runtime_event runtime_event;
1515 1515
1516 FILL_ARRAY(runtime_event, comm, event, data); 1516 FILL_ARRAY(runtime_event, comm, event, data);
1517 FILL_FIELD(runtime_event, pid, event, data); 1517 FILL_FIELD(runtime_event, pid, event, data);
1518 FILL_FIELD(runtime_event, runtime, event, data); 1518 FILL_FIELD(runtime_event, runtime, event, data);
1519 FILL_FIELD(runtime_event, vruntime, event, data); 1519 FILL_FIELD(runtime_event, vruntime, event, data);
1520 1520
1521 if (trace_handler->runtime_event) 1521 if (trace_handler->runtime_event)
1522 trace_handler->runtime_event(&runtime_event, session, event, cpu, timestamp, thread); 1522 trace_handler->runtime_event(&runtime_event, session, event, cpu, timestamp, thread);
1523 } 1523 }
1524 1524
1525 static void 1525 static void
1526 process_sched_fork_event(void *data, 1526 process_sched_fork_event(void *data,
1527 struct event *event, 1527 struct event *event,
1528 int cpu __used, 1528 int cpu __used,
1529 u64 timestamp __used, 1529 u64 timestamp __used,
1530 struct thread *thread __used) 1530 struct thread *thread __used)
1531 { 1531 {
1532 struct trace_fork_event fork_event; 1532 struct trace_fork_event fork_event;
1533 1533
1534 FILL_COMMON_FIELDS(fork_event, event, data); 1534 FILL_COMMON_FIELDS(fork_event, event, data);
1535 1535
1536 FILL_ARRAY(fork_event, parent_comm, event, data); 1536 FILL_ARRAY(fork_event, parent_comm, event, data);
1537 FILL_FIELD(fork_event, parent_pid, event, data); 1537 FILL_FIELD(fork_event, parent_pid, event, data);
1538 FILL_ARRAY(fork_event, child_comm, event, data); 1538 FILL_ARRAY(fork_event, child_comm, event, data);
1539 FILL_FIELD(fork_event, child_pid, event, data); 1539 FILL_FIELD(fork_event, child_pid, event, data);
1540 1540
1541 if (trace_handler->fork_event) 1541 if (trace_handler->fork_event)
1542 trace_handler->fork_event(&fork_event, event, 1542 trace_handler->fork_event(&fork_event, event,
1543 cpu, timestamp, thread); 1543 cpu, timestamp, thread);
1544 } 1544 }
1545 1545
1546 static void 1546 static void
1547 process_sched_exit_event(struct event *event, 1547 process_sched_exit_event(struct event *event,
1548 int cpu __used, 1548 int cpu __used,
1549 u64 timestamp __used, 1549 u64 timestamp __used,
1550 struct thread *thread __used) 1550 struct thread *thread __used)
1551 { 1551 {
1552 if (verbose) 1552 if (verbose)
1553 printf("sched_exit event %p\n", event); 1553 printf("sched_exit event %p\n", event);
1554 } 1554 }
1555 1555
1556 static void 1556 static void
1557 process_sched_migrate_task_event(void *data, struct perf_session *session, 1557 process_sched_migrate_task_event(void *data, struct perf_session *session,
1558 struct event *event, 1558 struct event *event,
1559 int cpu __used, 1559 int cpu __used,
1560 u64 timestamp __used, 1560 u64 timestamp __used,
1561 struct thread *thread __used) 1561 struct thread *thread __used)
1562 { 1562 {
1563 struct trace_migrate_task_event migrate_task_event; 1563 struct trace_migrate_task_event migrate_task_event;
1564 1564
1565 FILL_COMMON_FIELDS(migrate_task_event, event, data); 1565 FILL_COMMON_FIELDS(migrate_task_event, event, data);
1566 1566
1567 FILL_ARRAY(migrate_task_event, comm, event, data); 1567 FILL_ARRAY(migrate_task_event, comm, event, data);
1568 FILL_FIELD(migrate_task_event, pid, event, data); 1568 FILL_FIELD(migrate_task_event, pid, event, data);
1569 FILL_FIELD(migrate_task_event, prio, event, data); 1569 FILL_FIELD(migrate_task_event, prio, event, data);
1570 FILL_FIELD(migrate_task_event, cpu, event, data); 1570 FILL_FIELD(migrate_task_event, cpu, event, data);
1571 1571
1572 if (trace_handler->migrate_task_event) 1572 if (trace_handler->migrate_task_event)
1573 trace_handler->migrate_task_event(&migrate_task_event, session, 1573 trace_handler->migrate_task_event(&migrate_task_event, session,
1574 event, cpu, timestamp, thread); 1574 event, cpu, timestamp, thread);
1575 } 1575 }
1576 1576
1577 static void process_raw_event(union perf_event *raw_event __used, 1577 static void process_raw_event(union perf_event *raw_event __used,
1578 struct perf_session *session, void *data, int cpu, 1578 struct perf_session *session, void *data, int cpu,
1579 u64 timestamp, struct thread *thread) 1579 u64 timestamp, struct thread *thread)
1580 { 1580 {
1581 struct event *event; 1581 struct event *event;
1582 int type; 1582 int type;
1583 1583
1584 1584
1585 type = trace_parse_common_type(data); 1585 type = trace_parse_common_type(data);
1586 event = trace_find_event(type); 1586 event = trace_find_event(type);
1587 1587
1588 if (!strcmp(event->name, "sched_switch")) 1588 if (!strcmp(event->name, "sched_switch"))
1589 process_sched_switch_event(data, session, event, cpu, timestamp, thread); 1589 process_sched_switch_event(data, session, event, cpu, timestamp, thread);
1590 if (!strcmp(event->name, "sched_stat_runtime")) 1590 if (!strcmp(event->name, "sched_stat_runtime"))
1591 process_sched_runtime_event(data, session, event, cpu, timestamp, thread); 1591 process_sched_runtime_event(data, session, event, cpu, timestamp, thread);
1592 if (!strcmp(event->name, "sched_wakeup")) 1592 if (!strcmp(event->name, "sched_wakeup"))
1593 process_sched_wakeup_event(data, session, event, cpu, timestamp, thread); 1593 process_sched_wakeup_event(data, session, event, cpu, timestamp, thread);
1594 if (!strcmp(event->name, "sched_wakeup_new")) 1594 if (!strcmp(event->name, "sched_wakeup_new"))
1595 process_sched_wakeup_event(data, session, event, cpu, timestamp, thread); 1595 process_sched_wakeup_event(data, session, event, cpu, timestamp, thread);
1596 if (!strcmp(event->name, "sched_process_fork")) 1596 if (!strcmp(event->name, "sched_process_fork"))
1597 process_sched_fork_event(data, event, cpu, timestamp, thread); 1597 process_sched_fork_event(data, event, cpu, timestamp, thread);
1598 if (!strcmp(event->name, "sched_process_exit")) 1598 if (!strcmp(event->name, "sched_process_exit"))
1599 process_sched_exit_event(event, cpu, timestamp, thread); 1599 process_sched_exit_event(event, cpu, timestamp, thread);
1600 if (!strcmp(event->name, "sched_migrate_task")) 1600 if (!strcmp(event->name, "sched_migrate_task"))
1601 process_sched_migrate_task_event(data, session, event, cpu, timestamp, thread); 1601 process_sched_migrate_task_event(data, session, event, cpu, timestamp, thread);
1602 } 1602 }
1603 1603
1604 static int process_sample_event(union perf_event *event, 1604 static int process_sample_event(union perf_event *event,
1605 struct perf_sample *sample, 1605 struct perf_sample *sample,
1606 struct perf_evsel *evsel __used, 1606 struct perf_evsel *evsel __used,
1607 struct perf_session *session) 1607 struct perf_session *session)
1608 { 1608 {
1609 struct thread *thread; 1609 struct thread *thread;
1610 1610
1611 if (!(session->sample_type & PERF_SAMPLE_RAW)) 1611 if (!(session->sample_type & PERF_SAMPLE_RAW))
1612 return 0; 1612 return 0;
1613 1613
1614 thread = perf_session__findnew(session, sample->pid); 1614 thread = perf_session__findnew(session, sample->pid);
1615 if (thread == NULL) { 1615 if (thread == NULL) {
1616 pr_debug("problem processing %d event, skipping it.\n", 1616 pr_debug("problem processing %d event, skipping it.\n",
1617 event->header.type); 1617 event->header.type);
1618 return -1; 1618 return -1;
1619 } 1619 }
1620 1620
1621 dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid); 1621 dump_printf(" ... thread: %s:%d\n", thread->comm, thread->pid);
1622 1622
1623 if (profile_cpu != -1 && profile_cpu != (int)sample->cpu) 1623 if (profile_cpu != -1 && profile_cpu != (int)sample->cpu)
1624 return 0; 1624 return 0;
1625 1625
1626 process_raw_event(event, session, sample->raw_data, sample->cpu, 1626 process_raw_event(event, session, sample->raw_data, sample->cpu,
1627 sample->time, thread); 1627 sample->time, thread);
1628 1628
1629 return 0; 1629 return 0;
1630 } 1630 }
1631 1631
1632 static struct perf_event_ops event_ops = { 1632 static struct perf_event_ops event_ops = {
1633 .sample = process_sample_event, 1633 .sample = process_sample_event,
1634 .comm = perf_event__process_comm, 1634 .comm = perf_event__process_comm,
1635 .lost = perf_event__process_lost, 1635 .lost = perf_event__process_lost,
1636 .fork = perf_event__process_task, 1636 .fork = perf_event__process_task,
1637 .ordered_samples = true, 1637 .ordered_samples = true,
1638 }; 1638 };
1639 1639
1640 static int read_events(void) 1640 static void read_events(bool destroy, struct perf_session **psession)
1641 { 1641 {
1642 int err = -EINVAL; 1642 int err = -EINVAL;
1643 struct perf_session *session = perf_session__new(input_name, O_RDONLY, 1643 struct perf_session *session = perf_session__new(input_name, O_RDONLY,
1644 0, false, &event_ops); 1644 0, false, &event_ops);
1645 if (session == NULL) 1645 if (session == NULL)
1646 return -ENOMEM; 1646 die("No Memory");
1647 1647
1648 if (perf_session__has_traces(session, "record -R")) { 1648 if (perf_session__has_traces(session, "record -R")) {
1649 err = perf_session__process_events(session, &event_ops); 1649 err = perf_session__process_events(session, &event_ops);
1650 if (err)
1651 die("Failed to process events, error %d", err);
1652
1650 nr_events = session->hists.stats.nr_events[0]; 1653 nr_events = session->hists.stats.nr_events[0];
1651 nr_lost_events = session->hists.stats.total_lost; 1654 nr_lost_events = session->hists.stats.total_lost;
1652 nr_lost_chunks = session->hists.stats.nr_events[PERF_RECORD_LOST]; 1655 nr_lost_chunks = session->hists.stats.nr_events[PERF_RECORD_LOST];
1653 } 1656 }
1654 1657
1655 perf_session__delete(session); 1658 if (destroy)
1656 return err; 1659 perf_session__delete(session);
1660
1661 if (psession)
1662 *psession = session;
1657 } 1663 }
1658 1664
1659 static void print_bad_events(void) 1665 static void print_bad_events(void)
1660 { 1666 {
1661 if (nr_unordered_timestamps && nr_timestamps) { 1667 if (nr_unordered_timestamps && nr_timestamps) {
1662 printf(" INFO: %.3f%% unordered timestamps (%ld out of %ld)\n", 1668 printf(" INFO: %.3f%% unordered timestamps (%ld out of %ld)\n",
1663 (double)nr_unordered_timestamps/(double)nr_timestamps*100.0, 1669 (double)nr_unordered_timestamps/(double)nr_timestamps*100.0,
1664 nr_unordered_timestamps, nr_timestamps); 1670 nr_unordered_timestamps, nr_timestamps);
1665 } 1671 }
1666 if (nr_lost_events && nr_events) { 1672 if (nr_lost_events && nr_events) {
1667 printf(" INFO: %.3f%% lost events (%ld out of %ld, in %ld chunks)\n", 1673 printf(" INFO: %.3f%% lost events (%ld out of %ld, in %ld chunks)\n",
1668 (double)nr_lost_events/(double)nr_events*100.0, 1674 (double)nr_lost_events/(double)nr_events*100.0,
1669 nr_lost_events, nr_events, nr_lost_chunks); 1675 nr_lost_events, nr_events, nr_lost_chunks);
1670 } 1676 }
1671 if (nr_state_machine_bugs && nr_timestamps) { 1677 if (nr_state_machine_bugs && nr_timestamps) {
1672 printf(" INFO: %.3f%% state machine bugs (%ld out of %ld)", 1678 printf(" INFO: %.3f%% state machine bugs (%ld out of %ld)",
1673 (double)nr_state_machine_bugs/(double)nr_timestamps*100.0, 1679 (double)nr_state_machine_bugs/(double)nr_timestamps*100.0,
1674 nr_state_machine_bugs, nr_timestamps); 1680 nr_state_machine_bugs, nr_timestamps);
1675 if (nr_lost_events) 1681 if (nr_lost_events)
1676 printf(" (due to lost events?)"); 1682 printf(" (due to lost events?)");
1677 printf("\n"); 1683 printf("\n");
1678 } 1684 }
1679 if (nr_context_switch_bugs && nr_timestamps) { 1685 if (nr_context_switch_bugs && nr_timestamps) {
1680 printf(" INFO: %.3f%% context switch bugs (%ld out of %ld)", 1686 printf(" INFO: %.3f%% context switch bugs (%ld out of %ld)",
1681 (double)nr_context_switch_bugs/(double)nr_timestamps*100.0, 1687 (double)nr_context_switch_bugs/(double)nr_timestamps*100.0,
1682 nr_context_switch_bugs, nr_timestamps); 1688 nr_context_switch_bugs, nr_timestamps);
1683 if (nr_lost_events) 1689 if (nr_lost_events)
1684 printf(" (due to lost events?)"); 1690 printf(" (due to lost events?)");
1685 printf("\n"); 1691 printf("\n");
1686 } 1692 }
1687 } 1693 }
1688 1694
1689 static void __cmd_lat(void) 1695 static void __cmd_lat(void)
1690 { 1696 {
1691 struct rb_node *next; 1697 struct rb_node *next;
1698 struct perf_session *session;
1692 1699
1693 setup_pager(); 1700 setup_pager();
1694 read_events(); 1701 read_events(false, &session);
1695 sort_lat(); 1702 sort_lat();
1696 1703
1697 printf("\n ---------------------------------------------------------------------------------------------------------------\n"); 1704 printf("\n ---------------------------------------------------------------------------------------------------------------\n");
1698 printf(" Task | Runtime ms | Switches | Average delay ms | Maximum delay ms | Maximum delay at |\n"); 1705 printf(" Task | Runtime ms | Switches | Average delay ms | Maximum delay ms | Maximum delay at |\n");
1699 printf(" ---------------------------------------------------------------------------------------------------------------\n"); 1706 printf(" ---------------------------------------------------------------------------------------------------------------\n");
1700 1707
1701 next = rb_first(&sorted_atom_root); 1708 next = rb_first(&sorted_atom_root);
1702 1709
1703 while (next) { 1710 while (next) {
1704 struct work_atoms *work_list; 1711 struct work_atoms *work_list;
1705 1712
1706 work_list = rb_entry(next, struct work_atoms, node); 1713 work_list = rb_entry(next, struct work_atoms, node);
1707 output_lat_thread(work_list); 1714 output_lat_thread(work_list);
1708 next = rb_next(next); 1715 next = rb_next(next);
1709 } 1716 }
1710 1717
1711 printf(" -----------------------------------------------------------------------------------------\n"); 1718 printf(" -----------------------------------------------------------------------------------------\n");
1712 printf(" TOTAL: |%11.3f ms |%9" PRIu64 " |\n", 1719 printf(" TOTAL: |%11.3f ms |%9" PRIu64 " |\n",
1713 (double)all_runtime/1e6, all_count); 1720 (double)all_runtime/1e6, all_count);
1714 1721
1715 printf(" ---------------------------------------------------\n"); 1722 printf(" ---------------------------------------------------\n");
1716 1723
1717 print_bad_events(); 1724 print_bad_events();
1718 printf("\n"); 1725 printf("\n");
1719 1726
1727 perf_session__delete(session);
1720 } 1728 }
1721 1729
1722 static struct trace_sched_handler map_ops = { 1730 static struct trace_sched_handler map_ops = {
1723 .wakeup_event = NULL, 1731 .wakeup_event = NULL,
1724 .switch_event = map_switch_event, 1732 .switch_event = map_switch_event,
1725 .runtime_event = NULL, 1733 .runtime_event = NULL,
1726 .fork_event = NULL, 1734 .fork_event = NULL,
1727 }; 1735 };
1728 1736
1729 static void __cmd_map(void) 1737 static void __cmd_map(void)
1730 { 1738 {
1731 max_cpu = sysconf(_SC_NPROCESSORS_CONF); 1739 max_cpu = sysconf(_SC_NPROCESSORS_CONF);
1732 1740
1733 setup_pager(); 1741 setup_pager();
1734 read_events(); 1742 read_events(true, NULL);
1735 print_bad_events(); 1743 print_bad_events();
1736 } 1744 }
1737 1745
1738 static void __cmd_replay(void) 1746 static void __cmd_replay(void)
1739 { 1747 {
1740 unsigned long i; 1748 unsigned long i;
1741 1749
1742 calibrate_run_measurement_overhead(); 1750 calibrate_run_measurement_overhead();
1743 calibrate_sleep_measurement_overhead(); 1751 calibrate_sleep_measurement_overhead();
1744 1752
1745 test_calibrations(); 1753 test_calibrations();
1746 1754
1747 read_events(); 1755 read_events(true, NULL);
1748 1756
1749 printf("nr_run_events: %ld\n", nr_run_events); 1757 printf("nr_run_events: %ld\n", nr_run_events);
1750 printf("nr_sleep_events: %ld\n", nr_sleep_events); 1758 printf("nr_sleep_events: %ld\n", nr_sleep_events);
1751 printf("nr_wakeup_events: %ld\n", nr_wakeup_events); 1759 printf("nr_wakeup_events: %ld\n", nr_wakeup_events);
1752 1760
1753 if (targetless_wakeups) 1761 if (targetless_wakeups)
1754 printf("target-less wakeups: %ld\n", targetless_wakeups); 1762 printf("target-less wakeups: %ld\n", targetless_wakeups);
1755 if (multitarget_wakeups) 1763 if (multitarget_wakeups)
1756 printf("multi-target wakeups: %ld\n", multitarget_wakeups); 1764 printf("multi-target wakeups: %ld\n", multitarget_wakeups);
1757 if (nr_run_events_optimized) 1765 if (nr_run_events_optimized)
1758 printf("run atoms optimized: %ld\n", 1766 printf("run atoms optimized: %ld\n",
1759 nr_run_events_optimized); 1767 nr_run_events_optimized);
1760 1768
1761 print_task_traces(); 1769 print_task_traces();
1762 add_cross_task_wakeups(); 1770 add_cross_task_wakeups();
1763 1771
1764 create_tasks(); 1772 create_tasks();
1765 printf("------------------------------------------------------------\n"); 1773 printf("------------------------------------------------------------\n");
1766 for (i = 0; i < replay_repeat; i++) 1774 for (i = 0; i < replay_repeat; i++)
1767 run_one_test(); 1775 run_one_test();
1768 } 1776 }
1769 1777
1770 1778
1771 static const char * const sched_usage[] = { 1779 static const char * const sched_usage[] = {
1772 "perf sched [<options>] {record|latency|map|replay|trace}", 1780 "perf sched [<options>] {record|latency|map|replay|script}",
1773 NULL 1781 NULL
1774 }; 1782 };
1775 1783
1776 static const struct option sched_options[] = { 1784 static const struct option sched_options[] = {
1777 OPT_STRING('i', "input", &input_name, "file", 1785 OPT_STRING('i', "input", &input_name, "file",
1778 "input file name"), 1786 "input file name"),
1779 OPT_INCR('v', "verbose", &verbose, 1787 OPT_INCR('v', "verbose", &verbose,
1780 "be more verbose (show symbol address, etc)"), 1788 "be more verbose (show symbol address, etc)"),
1781 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 1789 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1782 "dump raw trace in ASCII"), 1790 "dump raw trace in ASCII"),
1783 OPT_END() 1791 OPT_END()
1784 }; 1792 };
1785 1793
1786 static const char * const latency_usage[] = { 1794 static const char * const latency_usage[] = {
1787 "perf sched latency [<options>]", 1795 "perf sched latency [<options>]",
1788 NULL 1796 NULL
1789 }; 1797 };
1790 1798
1791 static const struct option latency_options[] = { 1799 static const struct option latency_options[] = {
1792 OPT_STRING('s', "sort", &sort_order, "key[,key2...]", 1800 OPT_STRING('s', "sort", &sort_order, "key[,key2...]",
1793 "sort by key(s): runtime, switch, avg, max"), 1801 "sort by key(s): runtime, switch, avg, max"),
1794 OPT_INCR('v', "verbose", &verbose, 1802 OPT_INCR('v', "verbose", &verbose,
1795 "be more verbose (show symbol address, etc)"), 1803 "be more verbose (show symbol address, etc)"),
1796 OPT_INTEGER('C', "CPU", &profile_cpu, 1804 OPT_INTEGER('C', "CPU", &profile_cpu,
1797 "CPU to profile on"), 1805 "CPU to profile on"),
1798 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 1806 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1799 "dump raw trace in ASCII"), 1807 "dump raw trace in ASCII"),
1800 OPT_END() 1808 OPT_END()
1801 }; 1809 };
1802 1810
1803 static const char * const replay_usage[] = { 1811 static const char * const replay_usage[] = {
1804 "perf sched replay [<options>]", 1812 "perf sched replay [<options>]",
1805 NULL 1813 NULL
1806 }; 1814 };
1807 1815
1808 static const struct option replay_options[] = { 1816 static const struct option replay_options[] = {
1809 OPT_UINTEGER('r', "repeat", &replay_repeat, 1817 OPT_UINTEGER('r', "repeat", &replay_repeat,
1810 "repeat the workload replay N times (-1: infinite)"), 1818 "repeat the workload replay N times (-1: infinite)"),
1811 OPT_INCR('v', "verbose", &verbose, 1819 OPT_INCR('v', "verbose", &verbose,
1812 "be more verbose (show symbol address, etc)"), 1820 "be more verbose (show symbol address, etc)"),
1813 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace, 1821 OPT_BOOLEAN('D', "dump-raw-trace", &dump_trace,
1814 "dump raw trace in ASCII"), 1822 "dump raw trace in ASCII"),
1815 OPT_END() 1823 OPT_END()
1816 }; 1824 };
1817 1825
1818 static void setup_sorting(void) 1826 static void setup_sorting(void)
1819 { 1827 {
1820 char *tmp, *tok, *str = strdup(sort_order); 1828 char *tmp, *tok, *str = strdup(sort_order);
1821 1829
1822 for (tok = strtok_r(str, ", ", &tmp); 1830 for (tok = strtok_r(str, ", ", &tmp);
1823 tok; tok = strtok_r(NULL, ", ", &tmp)) { 1831 tok; tok = strtok_r(NULL, ", ", &tmp)) {
1824 if (sort_dimension__add(tok, &sort_list) < 0) { 1832 if (sort_dimension__add(tok, &sort_list) < 0) {
1825 error("Unknown --sort key: `%s'", tok); 1833 error("Unknown --sort key: `%s'", tok);
1826 usage_with_options(latency_usage, latency_options); 1834 usage_with_options(latency_usage, latency_options);
1827 } 1835 }
1828 } 1836 }
1829 1837
1830 free(str); 1838 free(str);
1831 1839
1832 sort_dimension__add("pid", &cmp_pid); 1840 sort_dimension__add("pid", &cmp_pid);
1833 } 1841 }
1834 1842
1835 static const char *record_args[] = { 1843 static const char *record_args[] = {
1836 "record", 1844 "record",
1837 "-a", 1845 "-a",
1838 "-R", 1846 "-R",
1839 "-f", 1847 "-f",
1840 "-m", "1024", 1848 "-m", "1024",
1841 "-c", "1", 1849 "-c", "1",
1842 "-e", "sched:sched_switch", 1850 "-e", "sched:sched_switch",
1843 "-e", "sched:sched_stat_wait", 1851 "-e", "sched:sched_stat_wait",
1844 "-e", "sched:sched_stat_sleep", 1852 "-e", "sched:sched_stat_sleep",
1845 "-e", "sched:sched_stat_iowait", 1853 "-e", "sched:sched_stat_iowait",
1846 "-e", "sched:sched_stat_runtime", 1854 "-e", "sched:sched_stat_runtime",
1847 "-e", "sched:sched_process_exit", 1855 "-e", "sched:sched_process_exit",
1848 "-e", "sched:sched_process_fork", 1856 "-e", "sched:sched_process_fork",
1849 "-e", "sched:sched_wakeup", 1857 "-e", "sched:sched_wakeup",
1850 "-e", "sched:sched_migrate_task", 1858 "-e", "sched:sched_migrate_task",
1851 }; 1859 };
1852 1860
1853 static int __cmd_record(int argc, const char **argv) 1861 static int __cmd_record(int argc, const char **argv)
1854 { 1862 {
1855 unsigned int rec_argc, i, j; 1863 unsigned int rec_argc, i, j;
1856 const char **rec_argv; 1864 const char **rec_argv;
1857 1865
1858 rec_argc = ARRAY_SIZE(record_args) + argc - 1; 1866 rec_argc = ARRAY_SIZE(record_args) + argc - 1;
1859 rec_argv = calloc(rec_argc + 1, sizeof(char *)); 1867 rec_argv = calloc(rec_argc + 1, sizeof(char *));
1860 1868
1861 if (rec_argv == NULL) 1869 if (rec_argv == NULL)
1862 return -ENOMEM; 1870 return -ENOMEM;
1863 1871
1864 for (i = 0; i < ARRAY_SIZE(record_args); i++) 1872 for (i = 0; i < ARRAY_SIZE(record_args); i++)
1865 rec_argv[i] = strdup(record_args[i]); 1873 rec_argv[i] = strdup(record_args[i]);
1866 1874
1867 for (j = 1; j < (unsigned int)argc; j++, i++) 1875 for (j = 1; j < (unsigned int)argc; j++, i++)
1868 rec_argv[i] = argv[j]; 1876 rec_argv[i] = argv[j];
1869 1877
1870 BUG_ON(i != rec_argc); 1878 BUG_ON(i != rec_argc);
1871 1879
1872 return cmd_record(i, rec_argv, NULL); 1880 return cmd_record(i, rec_argv, NULL);
1873 } 1881 }
1874 1882
1875 int cmd_sched(int argc, const char **argv, const char *prefix __used) 1883 int cmd_sched(int argc, const char **argv, const char *prefix __used)
1876 { 1884 {
1877 argc = parse_options(argc, argv, sched_options, sched_usage, 1885 argc = parse_options(argc, argv, sched_options, sched_usage,
1878 PARSE_OPT_STOP_AT_NON_OPTION); 1886 PARSE_OPT_STOP_AT_NON_OPTION);
1879 if (!argc) 1887 if (!argc)
1880 usage_with_options(sched_usage, sched_options); 1888 usage_with_options(sched_usage, sched_options);
1881 1889
1882 /* 1890 /*
1883 * Aliased to 'perf script' for now: 1891 * Aliased to 'perf script' for now:
1884 */ 1892 */
1885 if (!strcmp(argv[0], "script")) 1893 if (!strcmp(argv[0], "script"))
1886 return cmd_script(argc, argv, prefix); 1894 return cmd_script(argc, argv, prefix);
1887 1895
1888 symbol__init(); 1896 symbol__init();
1889 if (!strncmp(argv[0], "rec", 3)) { 1897 if (!strncmp(argv[0], "rec", 3)) {
1890 return __cmd_record(argc, argv); 1898 return __cmd_record(argc, argv);
1891 } else if (!strncmp(argv[0], "lat", 3)) { 1899 } else if (!strncmp(argv[0], "lat", 3)) {
1892 trace_handler = &lat_ops; 1900 trace_handler = &lat_ops;
1893 if (argc > 1) { 1901 if (argc > 1) {
1894 argc = parse_options(argc, argv, latency_options, latency_usage, 0); 1902 argc = parse_options(argc, argv, latency_options, latency_usage, 0);
1895 if (argc) 1903 if (argc)
1896 usage_with_options(latency_usage, latency_options); 1904 usage_with_options(latency_usage, latency_options);
1897 } 1905 }
1898 setup_sorting(); 1906 setup_sorting();
1899 __cmd_lat(); 1907 __cmd_lat();
1900 } else if (!strcmp(argv[0], "map")) { 1908 } else if (!strcmp(argv[0], "map")) {
1901 trace_handler = &map_ops; 1909 trace_handler = &map_ops;
1902 setup_sorting(); 1910 setup_sorting();
1903 __cmd_map(); 1911 __cmd_map();
1904 } else if (!strncmp(argv[0], "rep", 3)) { 1912 } else if (!strncmp(argv[0], "rep", 3)) {
1905 trace_handler = &replay_ops; 1913 trace_handler = &replay_ops;
1906 if (argc) { 1914 if (argc) {
1907 argc = parse_options(argc, argv, replay_options, replay_usage, 0); 1915 argc = parse_options(argc, argv, replay_options, replay_usage, 0);
1908 if (argc) 1916 if (argc)
1909 usage_with_options(replay_usage, replay_options); 1917 usage_with_options(replay_usage, replay_options);
1910 } 1918 }
1911 __cmd_replay(); 1919 __cmd_replay();
1912 } else { 1920 } else {
1913 usage_with_options(sched_usage, sched_options); 1921 usage_with_options(sched_usage, sched_options);
1914 } 1922 }
1915 1923
1916 return 0; 1924 return 0;
1917 } 1925 }
1918 1926
tools/perf/util/config.c
1 /* 1 /*
2 * GIT - The information manager from hell 2 * GIT - The information manager from hell
3 * 3 *
4 * Copyright (C) Linus Torvalds, 2005 4 * Copyright (C) Linus Torvalds, 2005
5 * Copyright (C) Johannes Schindelin, 2005 5 * Copyright (C) Johannes Schindelin, 2005
6 * 6 *
7 */ 7 */
8 #include "util.h" 8 #include "util.h"
9 #include "cache.h" 9 #include "cache.h"
10 #include "exec_cmd.h" 10 #include "exec_cmd.h"
11 11
12 #define MAXNAME (256) 12 #define MAXNAME (256)
13 13
14 #define DEBUG_CACHE_DIR ".debug" 14 #define DEBUG_CACHE_DIR ".debug"
15 15
16 16
17 char buildid_dir[MAXPATHLEN]; /* root dir for buildid, binary cache */ 17 char buildid_dir[MAXPATHLEN]; /* root dir for buildid, binary cache */
18 18
19 static FILE *config_file; 19 static FILE *config_file;
20 static const char *config_file_name; 20 static const char *config_file_name;
21 static int config_linenr; 21 static int config_linenr;
22 static int config_file_eof; 22 static int config_file_eof;
23 23
24 static const char *config_exclusive_filename; 24 static const char *config_exclusive_filename;
25 25
26 static int get_next_char(void) 26 static int get_next_char(void)
27 { 27 {
28 int c; 28 int c;
29 FILE *f; 29 FILE *f;
30 30
31 c = '\n'; 31 c = '\n';
32 if ((f = config_file) != NULL) { 32 if ((f = config_file) != NULL) {
33 c = fgetc(f); 33 c = fgetc(f);
34 if (c == '\r') { 34 if (c == '\r') {
35 /* DOS like systems */ 35 /* DOS like systems */
36 c = fgetc(f); 36 c = fgetc(f);
37 if (c != '\n') { 37 if (c != '\n') {
38 ungetc(c, f); 38 ungetc(c, f);
39 c = '\r'; 39 c = '\r';
40 } 40 }
41 } 41 }
42 if (c == '\n') 42 if (c == '\n')
43 config_linenr++; 43 config_linenr++;
44 if (c == EOF) { 44 if (c == EOF) {
45 config_file_eof = 1; 45 config_file_eof = 1;
46 c = '\n'; 46 c = '\n';
47 } 47 }
48 } 48 }
49 return c; 49 return c;
50 } 50 }
51 51
52 static char *parse_value(void) 52 static char *parse_value(void)
53 { 53 {
54 static char value[1024]; 54 static char value[1024];
55 int quote = 0, comment = 0, space = 0; 55 int quote = 0, comment = 0, space = 0;
56 size_t len = 0; 56 size_t len = 0;
57 57
58 for (;;) { 58 for (;;) {
59 int c = get_next_char(); 59 int c = get_next_char();
60 60
61 if (len >= sizeof(value) - 1) 61 if (len >= sizeof(value) - 1)
62 return NULL; 62 return NULL;
63 if (c == '\n') { 63 if (c == '\n') {
64 if (quote) 64 if (quote)
65 return NULL; 65 return NULL;
66 value[len] = 0; 66 value[len] = 0;
67 return value; 67 return value;
68 } 68 }
69 if (comment) 69 if (comment)
70 continue; 70 continue;
71 if (isspace(c) && !quote) { 71 if (isspace(c) && !quote) {
72 space = 1; 72 space = 1;
73 continue; 73 continue;
74 } 74 }
75 if (!quote) { 75 if (!quote) {
76 if (c == ';' || c == '#') { 76 if (c == ';' || c == '#') {
77 comment = 1; 77 comment = 1;
78 continue; 78 continue;
79 } 79 }
80 } 80 }
81 if (space) { 81 if (space) {
82 if (len) 82 if (len)
83 value[len++] = ' '; 83 value[len++] = ' ';
84 space = 0; 84 space = 0;
85 } 85 }
86 if (c == '\\') { 86 if (c == '\\') {
87 c = get_next_char(); 87 c = get_next_char();
88 switch (c) { 88 switch (c) {
89 case '\n': 89 case '\n':
90 continue; 90 continue;
91 case 't': 91 case 't':
92 c = '\t'; 92 c = '\t';
93 break; 93 break;
94 case 'b': 94 case 'b':
95 c = '\b'; 95 c = '\b';
96 break; 96 break;
97 case 'n': 97 case 'n':
98 c = '\n'; 98 c = '\n';
99 break; 99 break;
100 /* Some characters escape as themselves */ 100 /* Some characters escape as themselves */
101 case '\\': case '"': 101 case '\\': case '"':
102 break; 102 break;
103 /* Reject unknown escape sequences */ 103 /* Reject unknown escape sequences */
104 default: 104 default:
105 return NULL; 105 return NULL;
106 } 106 }
107 value[len++] = c; 107 value[len++] = c;
108 continue; 108 continue;
109 } 109 }
110 if (c == '"') { 110 if (c == '"') {
111 quote = 1-quote; 111 quote = 1-quote;
112 continue; 112 continue;
113 } 113 }
114 value[len++] = c; 114 value[len++] = c;
115 } 115 }
116 } 116 }
117 117
118 static inline int iskeychar(int c) 118 static inline int iskeychar(int c)
119 { 119 {
120 return isalnum(c) || c == '-'; 120 return isalnum(c) || c == '-';
121 } 121 }
122 122
123 static int get_value(config_fn_t fn, void *data, char *name, unsigned int len) 123 static int get_value(config_fn_t fn, void *data, char *name, unsigned int len)
124 { 124 {
125 int c; 125 int c;
126 char *value; 126 char *value;
127 127
128 /* Get the full name */ 128 /* Get the full name */
129 for (;;) { 129 for (;;) {
130 c = get_next_char(); 130 c = get_next_char();
131 if (config_file_eof) 131 if (config_file_eof)
132 break; 132 break;
133 if (!iskeychar(c)) 133 if (!iskeychar(c))
134 break; 134 break;
135 name[len++] = c; 135 name[len++] = c;
136 if (len >= MAXNAME) 136 if (len >= MAXNAME)
137 return -1; 137 return -1;
138 } 138 }
139 name[len] = 0; 139 name[len] = 0;
140 while (c == ' ' || c == '\t') 140 while (c == ' ' || c == '\t')
141 c = get_next_char(); 141 c = get_next_char();
142 142
143 value = NULL; 143 value = NULL;
144 if (c != '\n') { 144 if (c != '\n') {
145 if (c != '=') 145 if (c != '=')
146 return -1; 146 return -1;
147 value = parse_value(); 147 value = parse_value();
148 if (!value) 148 if (!value)
149 return -1; 149 return -1;
150 } 150 }
151 return fn(name, value, data); 151 return fn(name, value, data);
152 } 152 }
153 153
154 static int get_extended_base_var(char *name, int baselen, int c) 154 static int get_extended_base_var(char *name, int baselen, int c)
155 { 155 {
156 do { 156 do {
157 if (c == '\n') 157 if (c == '\n')
158 return -1; 158 return -1;
159 c = get_next_char(); 159 c = get_next_char();
160 } while (isspace(c)); 160 } while (isspace(c));
161 161
162 /* We require the format to be '[base "extension"]' */ 162 /* We require the format to be '[base "extension"]' */
163 if (c != '"') 163 if (c != '"')
164 return -1; 164 return -1;
165 name[baselen++] = '.'; 165 name[baselen++] = '.';
166 166
167 for (;;) { 167 for (;;) {
168 int ch = get_next_char(); 168 int ch = get_next_char();
169 169
170 if (ch == '\n') 170 if (ch == '\n')
171 return -1; 171 return -1;
172 if (ch == '"') 172 if (ch == '"')
173 break; 173 break;
174 if (ch == '\\') { 174 if (ch == '\\') {
175 ch = get_next_char(); 175 ch = get_next_char();
176 if (ch == '\n') 176 if (ch == '\n')
177 return -1; 177 return -1;
178 } 178 }
179 name[baselen++] = ch; 179 name[baselen++] = ch;
180 if (baselen > MAXNAME / 2) 180 if (baselen > MAXNAME / 2)
181 return -1; 181 return -1;
182 } 182 }
183 183
184 /* Final ']' */ 184 /* Final ']' */
185 if (get_next_char() != ']') 185 if (get_next_char() != ']')
186 return -1; 186 return -1;
187 return baselen; 187 return baselen;
188 } 188 }
189 189
190 static int get_base_var(char *name) 190 static int get_base_var(char *name)
191 { 191 {
192 int baselen = 0; 192 int baselen = 0;
193 193
194 for (;;) { 194 for (;;) {
195 int c = get_next_char(); 195 int c = get_next_char();
196 if (config_file_eof) 196 if (config_file_eof)
197 return -1; 197 return -1;
198 if (c == ']') 198 if (c == ']')
199 return baselen; 199 return baselen;
200 if (isspace(c)) 200 if (isspace(c))
201 return get_extended_base_var(name, baselen, c); 201 return get_extended_base_var(name, baselen, c);
202 if (!iskeychar(c) && c != '.') 202 if (!iskeychar(c) && c != '.')
203 return -1; 203 return -1;
204 if (baselen > MAXNAME / 2) 204 if (baselen > MAXNAME / 2)
205 return -1; 205 return -1;
206 name[baselen++] = tolower(c); 206 name[baselen++] = tolower(c);
207 } 207 }
208 } 208 }
209 209
210 static int perf_parse_file(config_fn_t fn, void *data) 210 static int perf_parse_file(config_fn_t fn, void *data)
211 { 211 {
212 int comment = 0; 212 int comment = 0;
213 int baselen = 0; 213 int baselen = 0;
214 static char var[MAXNAME]; 214 static char var[MAXNAME];
215 215
216 /* U+FEFF Byte Order Mark in UTF8 */ 216 /* U+FEFF Byte Order Mark in UTF8 */
217 static const unsigned char *utf8_bom = (unsigned char *) "\xef\xbb\xbf"; 217 static const unsigned char *utf8_bom = (unsigned char *) "\xef\xbb\xbf";
218 const unsigned char *bomptr = utf8_bom; 218 const unsigned char *bomptr = utf8_bom;
219 219
220 for (;;) { 220 for (;;) {
221 int c = get_next_char(); 221 int c = get_next_char();
222 if (bomptr && *bomptr) { 222 if (bomptr && *bomptr) {
223 /* We are at the file beginning; skip UTF8-encoded BOM 223 /* We are at the file beginning; skip UTF8-encoded BOM
224 * if present. Sane editors won't put this in on their 224 * if present. Sane editors won't put this in on their
225 * own, but e.g. Windows Notepad will do it happily. */ 225 * own, but e.g. Windows Notepad will do it happily. */
226 if ((unsigned char) c == *bomptr) { 226 if ((unsigned char) c == *bomptr) {
227 bomptr++; 227 bomptr++;
228 continue; 228 continue;
229 } else { 229 } else {
230 /* Do not tolerate partial BOM. */ 230 /* Do not tolerate partial BOM. */
231 if (bomptr != utf8_bom) 231 if (bomptr != utf8_bom)
232 break; 232 break;
233 /* No BOM at file beginning. Cool. */ 233 /* No BOM at file beginning. Cool. */
234 bomptr = NULL; 234 bomptr = NULL;
235 } 235 }
236 } 236 }
237 if (c == '\n') { 237 if (c == '\n') {
238 if (config_file_eof) 238 if (config_file_eof)
239 return 0; 239 return 0;
240 comment = 0; 240 comment = 0;
241 continue; 241 continue;
242 } 242 }
243 if (comment || isspace(c)) 243 if (comment || isspace(c))
244 continue; 244 continue;
245 if (c == '#' || c == ';') { 245 if (c == '#' || c == ';') {
246 comment = 1; 246 comment = 1;
247 continue; 247 continue;
248 } 248 }
249 if (c == '[') { 249 if (c == '[') {
250 baselen = get_base_var(var); 250 baselen = get_base_var(var);
251 if (baselen <= 0) 251 if (baselen <= 0)
252 break; 252 break;
253 var[baselen++] = '.'; 253 var[baselen++] = '.';
254 var[baselen] = 0; 254 var[baselen] = 0;
255 continue; 255 continue;
256 } 256 }
257 if (!isalpha(c)) 257 if (!isalpha(c))
258 break; 258 break;
259 var[baselen] = tolower(c); 259 var[baselen] = tolower(c);
260 if (get_value(fn, data, var, baselen+1) < 0) 260 if (get_value(fn, data, var, baselen+1) < 0)
261 break; 261 break;
262 } 262 }
263 die("bad config file line %d in %s", config_linenr, config_file_name); 263 die("bad config file line %d in %s", config_linenr, config_file_name);
264 } 264 }
265 265
266 static int parse_unit_factor(const char *end, unsigned long *val) 266 static int parse_unit_factor(const char *end, unsigned long *val)
267 { 267 {
268 if (!*end) 268 if (!*end)
269 return 1; 269 return 1;
270 else if (!strcasecmp(end, "k")) { 270 else if (!strcasecmp(end, "k")) {
271 *val *= 1024; 271 *val *= 1024;
272 return 1; 272 return 1;
273 } 273 }
274 else if (!strcasecmp(end, "m")) { 274 else if (!strcasecmp(end, "m")) {
275 *val *= 1024 * 1024; 275 *val *= 1024 * 1024;
276 return 1; 276 return 1;
277 } 277 }
278 else if (!strcasecmp(end, "g")) { 278 else if (!strcasecmp(end, "g")) {
279 *val *= 1024 * 1024 * 1024; 279 *val *= 1024 * 1024 * 1024;
280 return 1; 280 return 1;
281 } 281 }
282 return 0; 282 return 0;
283 } 283 }
284 284
285 static int perf_parse_long(const char *value, long *ret) 285 static int perf_parse_long(const char *value, long *ret)
286 { 286 {
287 if (value && *value) { 287 if (value && *value) {
288 char *end; 288 char *end;
289 long val = strtol(value, &end, 0); 289 long val = strtol(value, &end, 0);
290 unsigned long factor = 1; 290 unsigned long factor = 1;
291 if (!parse_unit_factor(end, &factor)) 291 if (!parse_unit_factor(end, &factor))
292 return 0; 292 return 0;
293 *ret = val * factor; 293 *ret = val * factor;
294 return 1; 294 return 1;
295 } 295 }
296 return 0; 296 return 0;
297 } 297 }
298 298
299 static void die_bad_config(const char *name) 299 static void die_bad_config(const char *name)
300 { 300 {
301 if (config_file_name) 301 if (config_file_name)
302 die("bad config value for '%s' in %s", name, config_file_name); 302 die("bad config value for '%s' in %s", name, config_file_name);
303 die("bad config value for '%s'", name); 303 die("bad config value for '%s'", name);
304 } 304 }
305 305
306 int perf_config_int(const char *name, const char *value) 306 int perf_config_int(const char *name, const char *value)
307 { 307 {
308 long ret = 0; 308 long ret = 0;
309 if (!perf_parse_long(value, &ret)) 309 if (!perf_parse_long(value, &ret))
310 die_bad_config(name); 310 die_bad_config(name);
311 return ret; 311 return ret;
312 } 312 }
313 313
314 static int perf_config_bool_or_int(const char *name, const char *value, int *is_bool) 314 static int perf_config_bool_or_int(const char *name, const char *value, int *is_bool)
315 { 315 {
316 *is_bool = 1; 316 *is_bool = 1;
317 if (!value) 317 if (!value)
318 return 1; 318 return 1;
319 if (!*value) 319 if (!*value)
320 return 0; 320 return 0;
321 if (!strcasecmp(value, "true") || !strcasecmp(value, "yes") || !strcasecmp(value, "on")) 321 if (!strcasecmp(value, "true") || !strcasecmp(value, "yes") || !strcasecmp(value, "on"))
322 return 1; 322 return 1;
323 if (!strcasecmp(value, "false") || !strcasecmp(value, "no") || !strcasecmp(value, "off")) 323 if (!strcasecmp(value, "false") || !strcasecmp(value, "no") || !strcasecmp(value, "off"))
324 return 0; 324 return 0;
325 *is_bool = 0; 325 *is_bool = 0;
326 return perf_config_int(name, value); 326 return perf_config_int(name, value);
327 } 327 }
328 328
329 int perf_config_bool(const char *name, const char *value) 329 int perf_config_bool(const char *name, const char *value)
330 { 330 {
331 int discard; 331 int discard;
332 return !!perf_config_bool_or_int(name, value, &discard); 332 return !!perf_config_bool_or_int(name, value, &discard);
333 } 333 }
334 334
335 const char *perf_config_dirname(const char *name, const char *value) 335 const char *perf_config_dirname(const char *name, const char *value)
336 { 336 {
337 if (!name) 337 if (!name)
338 return NULL; 338 return NULL;
339 return value; 339 return value;
340 } 340 }
341 341
342 static int perf_default_core_config(const char *var __used, const char *value __used) 342 static int perf_default_core_config(const char *var __used, const char *value __used)
343 { 343 {
344 /* Add other config variables here and to Documentation/config.txt. */ 344 /* Add other config variables here and to Documentation/config.txt. */
345 return 0; 345 return 0;
346 } 346 }
347 347
348 int perf_default_config(const char *var, const char *value, void *dummy __used) 348 int perf_default_config(const char *var, const char *value, void *dummy __used)
349 { 349 {
350 if (!prefixcmp(var, "core.")) 350 if (!prefixcmp(var, "core."))
351 return perf_default_core_config(var, value); 351 return perf_default_core_config(var, value);
352 352
353 /* Add other config variables here and to Documentation/config.txt. */ 353 /* Add other config variables here and to Documentation/config.txt. */
354 return 0; 354 return 0;
355 } 355 }
356 356
357 static int perf_config_from_file(config_fn_t fn, const char *filename, void *data) 357 static int perf_config_from_file(config_fn_t fn, const char *filename, void *data)
358 { 358 {
359 int ret; 359 int ret;
360 FILE *f = fopen(filename, "r"); 360 FILE *f = fopen(filename, "r");
361 361
362 ret = -1; 362 ret = -1;
363 if (f) { 363 if (f) {
364 config_file = f; 364 config_file = f;
365 config_file_name = filename; 365 config_file_name = filename;
366 config_linenr = 1; 366 config_linenr = 1;
367 config_file_eof = 0; 367 config_file_eof = 0;
368 ret = perf_parse_file(fn, data); 368 ret = perf_parse_file(fn, data);
369 fclose(f); 369 fclose(f);
370 config_file_name = NULL; 370 config_file_name = NULL;
371 } 371 }
372 return ret; 372 return ret;
373 } 373 }
374 374
375 static const char *perf_etc_perfconfig(void) 375 static const char *perf_etc_perfconfig(void)
376 { 376 {
377 static const char *system_wide; 377 static const char *system_wide;
378 if (!system_wide) 378 if (!system_wide)
379 system_wide = system_path(ETC_PERFCONFIG); 379 system_wide = system_path(ETC_PERFCONFIG);
380 return system_wide; 380 return system_wide;
381 } 381 }
382 382
383 static int perf_env_bool(const char *k, int def) 383 static int perf_env_bool(const char *k, int def)
384 { 384 {
385 const char *v = getenv(k); 385 const char *v = getenv(k);
386 return v ? perf_config_bool(k, v) : def; 386 return v ? perf_config_bool(k, v) : def;
387 } 387 }
388 388
389 static int perf_config_system(void) 389 static int perf_config_system(void)
390 { 390 {
391 return !perf_env_bool("PERF_CONFIG_NOSYSTEM", 0); 391 return !perf_env_bool("PERF_CONFIG_NOSYSTEM", 0);
392 } 392 }
393 393
394 static int perf_config_global(void) 394 static int perf_config_global(void)
395 { 395 {
396 return !perf_env_bool("PERF_CONFIG_NOGLOBAL", 0); 396 return !perf_env_bool("PERF_CONFIG_NOGLOBAL", 0);
397 } 397 }
398 398
399 int perf_config(config_fn_t fn, void *data) 399 int perf_config(config_fn_t fn, void *data)
400 { 400 {
401 int ret = 0, found = 0; 401 int ret = 0, found = 0;
402 char *repo_config = NULL;
403 const char *home = NULL; 402 const char *home = NULL;
404 403
405 /* Setting $PERF_CONFIG makes perf read _only_ the given config file. */ 404 /* Setting $PERF_CONFIG makes perf read _only_ the given config file. */
406 if (config_exclusive_filename) 405 if (config_exclusive_filename)
407 return perf_config_from_file(fn, config_exclusive_filename, data); 406 return perf_config_from_file(fn, config_exclusive_filename, data);
408 if (perf_config_system() && !access(perf_etc_perfconfig(), R_OK)) { 407 if (perf_config_system() && !access(perf_etc_perfconfig(), R_OK)) {
409 ret += perf_config_from_file(fn, perf_etc_perfconfig(), 408 ret += perf_config_from_file(fn, perf_etc_perfconfig(),
410 data); 409 data);
411 found += 1; 410 found += 1;
412 } 411 }
413 412
414 home = getenv("HOME"); 413 home = getenv("HOME");
415 if (perf_config_global() && home) { 414 if (perf_config_global() && home) {
416 char *user_config = strdup(mkpath("%s/.perfconfig", home)); 415 char *user_config = strdup(mkpath("%s/.perfconfig", home));
417 if (!access(user_config, R_OK)) { 416 struct stat st;
418 ret += perf_config_from_file(fn, user_config, data); 417
419 found += 1; 418 if (user_config == NULL) {
419 warning("Not enough memory to process %s/.perfconfig, "
420 "ignoring it.", home);
421 goto out;
420 } 422 }
421 free(user_config);
422 }
423 423
424 repo_config = perf_pathdup("config"); 424 if (stat(user_config, &st) < 0)
425 if (!access(repo_config, R_OK)) { 425 goto out_free;
426 ret += perf_config_from_file(fn, repo_config, data); 426
427 if (st.st_uid && (st.st_uid != geteuid())) {
428 warning("File %s not owned by current user or root, "
429 "ignoring it.", user_config);
430 goto out_free;
431 }
432
433 if (!st.st_size)
434 goto out_free;
435
436 ret += perf_config_from_file(fn, user_config, data);
427 found += 1; 437 found += 1;
438 out_free:
439 free(user_config);
428 } 440 }
429 free(repo_config); 441 out:
430 if (found == 0) 442 if (found == 0)
431 return -1; 443 return -1;
432 return ret; 444 return ret;
433 } 445 }
434 446
435 /* 447 /*
436 * Call this to report error for your variable that should not 448 * Call this to report error for your variable that should not
437 * get a boolean value (i.e. "[my] var" means "true"). 449 * get a boolean value (i.e. "[my] var" means "true").
438 */ 450 */
439 int config_error_nonbool(const char *var) 451 int config_error_nonbool(const char *var)
440 { 452 {
441 return error("Missing value for '%s'", var); 453 return error("Missing value for '%s'", var);
442 } 454 }
443 455
444 struct buildid_dir_config { 456 struct buildid_dir_config {
445 char *dir; 457 char *dir;
446 }; 458 };
447 459
448 static int buildid_dir_command_config(const char *var, const char *value, 460 static int buildid_dir_command_config(const char *var, const char *value,
449 void *data) 461 void *data)
450 { 462 {
451 struct buildid_dir_config *c = data; 463 struct buildid_dir_config *c = data;
452 const char *v; 464 const char *v;
453 465
454 /* same dir for all commands */ 466 /* same dir for all commands */
455 if (!prefixcmp(var, "buildid.") && !strcmp(var + 8, "dir")) { 467 if (!prefixcmp(var, "buildid.") && !strcmp(var + 8, "dir")) {
456 v = perf_config_dirname(var, value); 468 v = perf_config_dirname(var, value);
457 if (!v) 469 if (!v)
458 return -1; 470 return -1;
459 strncpy(c->dir, v, MAXPATHLEN-1); 471 strncpy(c->dir, v, MAXPATHLEN-1);
460 c->dir[MAXPATHLEN-1] = '\0'; 472 c->dir[MAXPATHLEN-1] = '\0';
461 } 473 }
462 return 0; 474 return 0;
463 } 475 }
464 476
465 static void check_buildid_dir_config(void) 477 static void check_buildid_dir_config(void)
466 { 478 {
467 struct buildid_dir_config c; 479 struct buildid_dir_config c;
468 c.dir = buildid_dir; 480 c.dir = buildid_dir;
469 perf_config(buildid_dir_command_config, &c); 481 perf_config(buildid_dir_command_config, &c);
470 } 482 }
471 483
472 void set_buildid_dir(void) 484 void set_buildid_dir(void)
473 { 485 {
474 buildid_dir[0] = '\0'; 486 buildid_dir[0] = '\0';
475 487
476 /* try config file */ 488 /* try config file */
477 check_buildid_dir_config(); 489 check_buildid_dir_config();
478 490
479 /* default to $HOME/.debug */ 491 /* default to $HOME/.debug */
480 if (buildid_dir[0] == '\0') { 492 if (buildid_dir[0] == '\0') {
481 char *v = getenv("HOME"); 493 char *v = getenv("HOME");
482 if (v) { 494 if (v) {
483 snprintf(buildid_dir, MAXPATHLEN-1, "%s/%s", 495 snprintf(buildid_dir, MAXPATHLEN-1, "%s/%s",
484 v, DEBUG_CACHE_DIR); 496 v, DEBUG_CACHE_DIR);
485 } else { 497 } else {
486 strncpy(buildid_dir, DEBUG_CACHE_DIR, MAXPATHLEN-1); 498 strncpy(buildid_dir, DEBUG_CACHE_DIR, MAXPATHLEN-1);
487 } 499 }
488 buildid_dir[MAXPATHLEN-1] = '\0'; 500 buildid_dir[MAXPATHLEN-1] = '\0';
489 } 501 }
490 /* for communicating with external commands */ 502 /* for communicating with external commands */
tools/perf/util/evlist.c
1 /* 1 /*
2 * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com> 2 * Copyright (C) 2011, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
3 * 3 *
4 * Parts came from builtin-{top,stat,record}.c, see those files for further 4 * Parts came from builtin-{top,stat,record}.c, see those files for further
5 * copyright notes. 5 * copyright notes.
6 * 6 *
7 * Released under the GPL v2. (and only v2, not any later version) 7 * Released under the GPL v2. (and only v2, not any later version)
8 */ 8 */
9 #include <poll.h> 9 #include <poll.h>
10 #include "cpumap.h" 10 #include "cpumap.h"
11 #include "thread_map.h" 11 #include "thread_map.h"
12 #include "evlist.h" 12 #include "evlist.h"
13 #include "evsel.h" 13 #include "evsel.h"
14 #include "util.h" 14 #include "util.h"
15 15
16 #include <sys/mman.h> 16 #include <sys/mman.h>
17 17
18 #include <linux/bitops.h> 18 #include <linux/bitops.h>
19 #include <linux/hash.h> 19 #include <linux/hash.h>
20 20
21 #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) 21 #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y))
22 #define SID(e, x, y) xyarray__entry(e->sample_id, x, y) 22 #define SID(e, x, y) xyarray__entry(e->sample_id, x, y)
23 23
24 void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus, 24 void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus,
25 struct thread_map *threads) 25 struct thread_map *threads)
26 { 26 {
27 int i; 27 int i;
28 28
29 for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i) 29 for (i = 0; i < PERF_EVLIST__HLIST_SIZE; ++i)
30 INIT_HLIST_HEAD(&evlist->heads[i]); 30 INIT_HLIST_HEAD(&evlist->heads[i]);
31 INIT_LIST_HEAD(&evlist->entries); 31 INIT_LIST_HEAD(&evlist->entries);
32 perf_evlist__set_maps(evlist, cpus, threads); 32 perf_evlist__set_maps(evlist, cpus, threads);
33 } 33 }
34 34
35 struct perf_evlist *perf_evlist__new(struct cpu_map *cpus, 35 struct perf_evlist *perf_evlist__new(struct cpu_map *cpus,
36 struct thread_map *threads) 36 struct thread_map *threads)
37 { 37 {
38 struct perf_evlist *evlist = zalloc(sizeof(*evlist)); 38 struct perf_evlist *evlist = zalloc(sizeof(*evlist));
39 39
40 if (evlist != NULL) 40 if (evlist != NULL)
41 perf_evlist__init(evlist, cpus, threads); 41 perf_evlist__init(evlist, cpus, threads);
42 42
43 return evlist; 43 return evlist;
44 } 44 }
45 45
46 static void perf_evlist__purge(struct perf_evlist *evlist) 46 static void perf_evlist__purge(struct perf_evlist *evlist)
47 { 47 {
48 struct perf_evsel *pos, *n; 48 struct perf_evsel *pos, *n;
49 49
50 list_for_each_entry_safe(pos, n, &evlist->entries, node) { 50 list_for_each_entry_safe(pos, n, &evlist->entries, node) {
51 list_del_init(&pos->node); 51 list_del_init(&pos->node);
52 perf_evsel__delete(pos); 52 perf_evsel__delete(pos);
53 } 53 }
54 54
55 evlist->nr_entries = 0; 55 evlist->nr_entries = 0;
56 } 56 }
57 57
58 void perf_evlist__exit(struct perf_evlist *evlist) 58 void perf_evlist__exit(struct perf_evlist *evlist)
59 { 59 {
60 free(evlist->mmap); 60 free(evlist->mmap);
61 free(evlist->pollfd); 61 free(evlist->pollfd);
62 evlist->mmap = NULL; 62 evlist->mmap = NULL;
63 evlist->pollfd = NULL; 63 evlist->pollfd = NULL;
64 } 64 }
65 65
66 void perf_evlist__delete(struct perf_evlist *evlist) 66 void perf_evlist__delete(struct perf_evlist *evlist)
67 { 67 {
68 perf_evlist__purge(evlist); 68 perf_evlist__purge(evlist);
69 perf_evlist__exit(evlist); 69 perf_evlist__exit(evlist);
70 free(evlist); 70 free(evlist);
71 } 71 }
72 72
73 void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry) 73 void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry)
74 { 74 {
75 list_add_tail(&entry->node, &evlist->entries); 75 list_add_tail(&entry->node, &evlist->entries);
76 ++evlist->nr_entries; 76 ++evlist->nr_entries;
77 } 77 }
78 78
79 int perf_evlist__add_default(struct perf_evlist *evlist) 79 int perf_evlist__add_default(struct perf_evlist *evlist)
80 { 80 {
81 struct perf_event_attr attr = { 81 struct perf_event_attr attr = {
82 .type = PERF_TYPE_HARDWARE, 82 .type = PERF_TYPE_HARDWARE,
83 .config = PERF_COUNT_HW_CPU_CYCLES, 83 .config = PERF_COUNT_HW_CPU_CYCLES,
84 }; 84 };
85 struct perf_evsel *evsel = perf_evsel__new(&attr, 0); 85 struct perf_evsel *evsel = perf_evsel__new(&attr, 0);
86 86
87 if (evsel == NULL) 87 if (evsel == NULL)
88 return -ENOMEM; 88 return -ENOMEM;
89 89
90 perf_evlist__add(evlist, evsel); 90 perf_evlist__add(evlist, evsel);
91 return 0; 91 return 0;
92 } 92 }
93 93
94 void perf_evlist__disable(struct perf_evlist *evlist)
95 {
96 int cpu, thread;
97 struct perf_evsel *pos;
98
99 for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
100 list_for_each_entry(pos, &evlist->entries, node) {
101 for (thread = 0; thread < evlist->threads->nr; thread++)
102 ioctl(FD(pos, cpu, thread), PERF_EVENT_IOC_DISABLE);
103 }
104 }
105 }
106
94 int perf_evlist__alloc_pollfd(struct perf_evlist *evlist) 107 int perf_evlist__alloc_pollfd(struct perf_evlist *evlist)
95 { 108 {
96 int nfds = evlist->cpus->nr * evlist->threads->nr * evlist->nr_entries; 109 int nfds = evlist->cpus->nr * evlist->threads->nr * evlist->nr_entries;
97 evlist->pollfd = malloc(sizeof(struct pollfd) * nfds); 110 evlist->pollfd = malloc(sizeof(struct pollfd) * nfds);
98 return evlist->pollfd != NULL ? 0 : -ENOMEM; 111 return evlist->pollfd != NULL ? 0 : -ENOMEM;
99 } 112 }
100 113
101 void perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd) 114 void perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd)
102 { 115 {
103 fcntl(fd, F_SETFL, O_NONBLOCK); 116 fcntl(fd, F_SETFL, O_NONBLOCK);
104 evlist->pollfd[evlist->nr_fds].fd = fd; 117 evlist->pollfd[evlist->nr_fds].fd = fd;
105 evlist->pollfd[evlist->nr_fds].events = POLLIN; 118 evlist->pollfd[evlist->nr_fds].events = POLLIN;
106 evlist->nr_fds++; 119 evlist->nr_fds++;
107 } 120 }
108 121
109 static void perf_evlist__id_hash(struct perf_evlist *evlist, 122 static void perf_evlist__id_hash(struct perf_evlist *evlist,
110 struct perf_evsel *evsel, 123 struct perf_evsel *evsel,
111 int cpu, int thread, u64 id) 124 int cpu, int thread, u64 id)
112 { 125 {
113 int hash; 126 int hash;
114 struct perf_sample_id *sid = SID(evsel, cpu, thread); 127 struct perf_sample_id *sid = SID(evsel, cpu, thread);
115 128
116 sid->id = id; 129 sid->id = id;
117 sid->evsel = evsel; 130 sid->evsel = evsel;
118 hash = hash_64(sid->id, PERF_EVLIST__HLIST_BITS); 131 hash = hash_64(sid->id, PERF_EVLIST__HLIST_BITS);
119 hlist_add_head(&sid->node, &evlist->heads[hash]); 132 hlist_add_head(&sid->node, &evlist->heads[hash]);
120 } 133 }
121 134
122 void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel, 135 void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel,
123 int cpu, int thread, u64 id) 136 int cpu, int thread, u64 id)
124 { 137 {
125 perf_evlist__id_hash(evlist, evsel, cpu, thread, id); 138 perf_evlist__id_hash(evlist, evsel, cpu, thread, id);
126 evsel->id[evsel->ids++] = id; 139 evsel->id[evsel->ids++] = id;
127 } 140 }
128 141
129 static int perf_evlist__id_add_fd(struct perf_evlist *evlist, 142 static int perf_evlist__id_add_fd(struct perf_evlist *evlist,
130 struct perf_evsel *evsel, 143 struct perf_evsel *evsel,
131 int cpu, int thread, int fd) 144 int cpu, int thread, int fd)
132 { 145 {
133 u64 read_data[4] = { 0, }; 146 u64 read_data[4] = { 0, };
134 int id_idx = 1; /* The first entry is the counter value */ 147 int id_idx = 1; /* The first entry is the counter value */
135 148
136 if (!(evsel->attr.read_format & PERF_FORMAT_ID) || 149 if (!(evsel->attr.read_format & PERF_FORMAT_ID) ||
137 read(fd, &read_data, sizeof(read_data)) == -1) 150 read(fd, &read_data, sizeof(read_data)) == -1)
138 return -1; 151 return -1;
139 152
140 if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED) 153 if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_ENABLED)
141 ++id_idx; 154 ++id_idx;
142 if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING) 155 if (evsel->attr.read_format & PERF_FORMAT_TOTAL_TIME_RUNNING)
143 ++id_idx; 156 ++id_idx;
144 157
145 perf_evlist__id_add(evlist, evsel, cpu, thread, read_data[id_idx]); 158 perf_evlist__id_add(evlist, evsel, cpu, thread, read_data[id_idx]);
146 return 0; 159 return 0;
147 } 160 }
148 161
149 struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id) 162 struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id)
150 { 163 {
151 struct hlist_head *head; 164 struct hlist_head *head;
152 struct hlist_node *pos; 165 struct hlist_node *pos;
153 struct perf_sample_id *sid; 166 struct perf_sample_id *sid;
154 int hash; 167 int hash;
155 168
156 if (evlist->nr_entries == 1) 169 if (evlist->nr_entries == 1)
157 return list_entry(evlist->entries.next, struct perf_evsel, node); 170 return list_entry(evlist->entries.next, struct perf_evsel, node);
158 171
159 hash = hash_64(id, PERF_EVLIST__HLIST_BITS); 172 hash = hash_64(id, PERF_EVLIST__HLIST_BITS);
160 head = &evlist->heads[hash]; 173 head = &evlist->heads[hash];
161 174
162 hlist_for_each_entry(sid, pos, head, node) 175 hlist_for_each_entry(sid, pos, head, node)
163 if (sid->id == id) 176 if (sid->id == id)
164 return sid->evsel; 177 return sid->evsel;
165 return NULL; 178 return NULL;
166 } 179 }
167 180
168 union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx) 181 union perf_event *perf_evlist__mmap_read(struct perf_evlist *evlist, int idx)
169 { 182 {
170 /* XXX Move this to perf.c, making it generally available */ 183 /* XXX Move this to perf.c, making it generally available */
171 unsigned int page_size = sysconf(_SC_PAGE_SIZE); 184 unsigned int page_size = sysconf(_SC_PAGE_SIZE);
172 struct perf_mmap *md = &evlist->mmap[idx]; 185 struct perf_mmap *md = &evlist->mmap[idx];
173 unsigned int head = perf_mmap__read_head(md); 186 unsigned int head = perf_mmap__read_head(md);
174 unsigned int old = md->prev; 187 unsigned int old = md->prev;
175 unsigned char *data = md->base + page_size; 188 unsigned char *data = md->base + page_size;
176 union perf_event *event = NULL; 189 union perf_event *event = NULL;
177 190
178 if (evlist->overwrite) { 191 if (evlist->overwrite) {
179 /* 192 /*
180 * If we're further behind than half the buffer, there's a chance 193 * If we're further behind than half the buffer, there's a chance
181 * the writer will bite our tail and mess up the samples under us. 194 * the writer will bite our tail and mess up the samples under us.
182 * 195 *
183 * If we somehow ended up ahead of the head, we got messed up. 196 * If we somehow ended up ahead of the head, we got messed up.
184 * 197 *
185 * In either case, truncate and restart at head. 198 * In either case, truncate and restart at head.
186 */ 199 */
187 int diff = head - old; 200 int diff = head - old;
188 if (diff > md->mask / 2 || diff < 0) { 201 if (diff > md->mask / 2 || diff < 0) {
189 fprintf(stderr, "WARNING: failed to keep up with mmap data.\n"); 202 fprintf(stderr, "WARNING: failed to keep up with mmap data.\n");
190 203
191 /* 204 /*
192 * head points to a known good entry, start there. 205 * head points to a known good entry, start there.
193 */ 206 */
194 old = head; 207 old = head;
195 } 208 }
196 } 209 }
197 210
198 if (old != head) { 211 if (old != head) {
199 size_t size; 212 size_t size;
200 213
201 event = (union perf_event *)&data[old & md->mask]; 214 event = (union perf_event *)&data[old & md->mask];
202 size = event->header.size; 215 size = event->header.size;
203 216
204 /* 217 /*
205 * Event straddles the mmap boundary -- header should always 218 * Event straddles the mmap boundary -- header should always
206 * be inside due to u64 alignment of output. 219 * be inside due to u64 alignment of output.
207 */ 220 */
208 if ((old & md->mask) + size != ((old + size) & md->mask)) { 221 if ((old & md->mask) + size != ((old + size) & md->mask)) {
209 unsigned int offset = old; 222 unsigned int offset = old;
210 unsigned int len = min(sizeof(*event), size), cpy; 223 unsigned int len = min(sizeof(*event), size), cpy;
211 void *dst = &evlist->event_copy; 224 void *dst = &evlist->event_copy;
212 225
213 do { 226 do {
214 cpy = min(md->mask + 1 - (offset & md->mask), len); 227 cpy = min(md->mask + 1 - (offset & md->mask), len);
215 memcpy(dst, &data[offset & md->mask], cpy); 228 memcpy(dst, &data[offset & md->mask], cpy);
216 offset += cpy; 229 offset += cpy;
217 dst += cpy; 230 dst += cpy;
218 len -= cpy; 231 len -= cpy;
219 } while (len); 232 } while (len);
220 233
221 event = &evlist->event_copy; 234 event = &evlist->event_copy;
222 } 235 }
223 236
224 old += size; 237 old += size;
225 } 238 }
226 239
227 md->prev = old; 240 md->prev = old;
228 241
229 if (!evlist->overwrite) 242 if (!evlist->overwrite)
230 perf_mmap__write_tail(md, old); 243 perf_mmap__write_tail(md, old);
231 244
232 return event; 245 return event;
233 } 246 }
234 247
235 void perf_evlist__munmap(struct perf_evlist *evlist) 248 void perf_evlist__munmap(struct perf_evlist *evlist)
236 { 249 {
237 int i; 250 int i;
238 251
239 for (i = 0; i < evlist->nr_mmaps; i++) { 252 for (i = 0; i < evlist->nr_mmaps; i++) {
240 if (evlist->mmap[i].base != NULL) { 253 if (evlist->mmap[i].base != NULL) {
241 munmap(evlist->mmap[i].base, evlist->mmap_len); 254 munmap(evlist->mmap[i].base, evlist->mmap_len);
242 evlist->mmap[i].base = NULL; 255 evlist->mmap[i].base = NULL;
243 } 256 }
244 } 257 }
245 258
246 free(evlist->mmap); 259 free(evlist->mmap);
247 evlist->mmap = NULL; 260 evlist->mmap = NULL;
248 } 261 }
249 262
250 int perf_evlist__alloc_mmap(struct perf_evlist *evlist) 263 int perf_evlist__alloc_mmap(struct perf_evlist *evlist)
251 { 264 {
252 evlist->nr_mmaps = evlist->cpus->nr; 265 evlist->nr_mmaps = evlist->cpus->nr;
253 if (evlist->cpus->map[0] == -1) 266 if (evlist->cpus->map[0] == -1)
254 evlist->nr_mmaps = evlist->threads->nr; 267 evlist->nr_mmaps = evlist->threads->nr;
255 evlist->mmap = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap)); 268 evlist->mmap = zalloc(evlist->nr_mmaps * sizeof(struct perf_mmap));
256 return evlist->mmap != NULL ? 0 : -ENOMEM; 269 return evlist->mmap != NULL ? 0 : -ENOMEM;
257 } 270 }
258 271
259 static int __perf_evlist__mmap(struct perf_evlist *evlist, 272 static int __perf_evlist__mmap(struct perf_evlist *evlist,
260 int idx, int prot, int mask, int fd) 273 int idx, int prot, int mask, int fd)
261 { 274 {
262 evlist->mmap[idx].prev = 0; 275 evlist->mmap[idx].prev = 0;
263 evlist->mmap[idx].mask = mask; 276 evlist->mmap[idx].mask = mask;
264 evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot, 277 evlist->mmap[idx].base = mmap(NULL, evlist->mmap_len, prot,
265 MAP_SHARED, fd, 0); 278 MAP_SHARED, fd, 0);
266 if (evlist->mmap[idx].base == MAP_FAILED) 279 if (evlist->mmap[idx].base == MAP_FAILED)
267 return -1; 280 return -1;
268 281
269 perf_evlist__add_pollfd(evlist, fd); 282 perf_evlist__add_pollfd(evlist, fd);
270 return 0; 283 return 0;
271 } 284 }
272 285
273 static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int mask) 286 static int perf_evlist__mmap_per_cpu(struct perf_evlist *evlist, int prot, int mask)
274 { 287 {
275 struct perf_evsel *evsel; 288 struct perf_evsel *evsel;
276 int cpu, thread; 289 int cpu, thread;
277 290
278 for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { 291 for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
279 int output = -1; 292 int output = -1;
280 293
281 for (thread = 0; thread < evlist->threads->nr; thread++) { 294 for (thread = 0; thread < evlist->threads->nr; thread++) {
282 list_for_each_entry(evsel, &evlist->entries, node) { 295 list_for_each_entry(evsel, &evlist->entries, node) {
283 int fd = FD(evsel, cpu, thread); 296 int fd = FD(evsel, cpu, thread);
284 297
285 if (output == -1) { 298 if (output == -1) {
286 output = fd; 299 output = fd;
287 if (__perf_evlist__mmap(evlist, cpu, 300 if (__perf_evlist__mmap(evlist, cpu,
288 prot, mask, output) < 0) 301 prot, mask, output) < 0)
289 goto out_unmap; 302 goto out_unmap;
290 } else { 303 } else {
291 if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0) 304 if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0)
292 goto out_unmap; 305 goto out_unmap;
293 } 306 }
294 307
295 if ((evsel->attr.read_format & PERF_FORMAT_ID) && 308 if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
296 perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0) 309 perf_evlist__id_add_fd(evlist, evsel, cpu, thread, fd) < 0)
297 goto out_unmap; 310 goto out_unmap;
298 } 311 }
299 } 312 }
300 } 313 }
301 314
302 return 0; 315 return 0;
303 316
304 out_unmap: 317 out_unmap:
305 for (cpu = 0; cpu < evlist->cpus->nr; cpu++) { 318 for (cpu = 0; cpu < evlist->cpus->nr; cpu++) {
306 if (evlist->mmap[cpu].base != NULL) { 319 if (evlist->mmap[cpu].base != NULL) {
307 munmap(evlist->mmap[cpu].base, evlist->mmap_len); 320 munmap(evlist->mmap[cpu].base, evlist->mmap_len);
308 evlist->mmap[cpu].base = NULL; 321 evlist->mmap[cpu].base = NULL;
309 } 322 }
310 } 323 }
311 return -1; 324 return -1;
312 } 325 }
313 326
314 static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, int mask) 327 static int perf_evlist__mmap_per_thread(struct perf_evlist *evlist, int prot, int mask)
315 { 328 {
316 struct perf_evsel *evsel; 329 struct perf_evsel *evsel;
317 int thread; 330 int thread;
318 331
319 for (thread = 0; thread < evlist->threads->nr; thread++) { 332 for (thread = 0; thread < evlist->threads->nr; thread++) {
320 int output = -1; 333 int output = -1;
321 334
322 list_for_each_entry(evsel, &evlist->entries, node) { 335 list_for_each_entry(evsel, &evlist->entries, node) {
323 int fd = FD(evsel, 0, thread); 336 int fd = FD(evsel, 0, thread);
324 337
325 if (output == -1) { 338 if (output == -1) {
326 output = fd; 339 output = fd;
327 if (__perf_evlist__mmap(evlist, thread, 340 if (__perf_evlist__mmap(evlist, thread,
328 prot, mask, output) < 0) 341 prot, mask, output) < 0)
329 goto out_unmap; 342 goto out_unmap;
330 } else { 343 } else {
331 if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0) 344 if (ioctl(fd, PERF_EVENT_IOC_SET_OUTPUT, output) != 0)
332 goto out_unmap; 345 goto out_unmap;
333 } 346 }
334 347
335 if ((evsel->attr.read_format & PERF_FORMAT_ID) && 348 if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
336 perf_evlist__id_add_fd(evlist, evsel, 0, thread, fd) < 0) 349 perf_evlist__id_add_fd(evlist, evsel, 0, thread, fd) < 0)
337 goto out_unmap; 350 goto out_unmap;
338 } 351 }
339 } 352 }
340 353
341 return 0; 354 return 0;
342 355
343 out_unmap: 356 out_unmap:
344 for (thread = 0; thread < evlist->threads->nr; thread++) { 357 for (thread = 0; thread < evlist->threads->nr; thread++) {
345 if (evlist->mmap[thread].base != NULL) { 358 if (evlist->mmap[thread].base != NULL) {
346 munmap(evlist->mmap[thread].base, evlist->mmap_len); 359 munmap(evlist->mmap[thread].base, evlist->mmap_len);
347 evlist->mmap[thread].base = NULL; 360 evlist->mmap[thread].base = NULL;
348 } 361 }
349 } 362 }
350 return -1; 363 return -1;
351 } 364 }
352 365
353 /** perf_evlist__mmap - Create per cpu maps to receive events 366 /** perf_evlist__mmap - Create per cpu maps to receive events
354 * 367 *
355 * @evlist - list of events 368 * @evlist - list of events
356 * @pages - map length in pages 369 * @pages - map length in pages
357 * @overwrite - overwrite older events? 370 * @overwrite - overwrite older events?
358 * 371 *
359 * If overwrite is false the user needs to signal event consuption using: 372 * If overwrite is false the user needs to signal event consuption using:
360 * 373 *
361 * struct perf_mmap *m = &evlist->mmap[cpu]; 374 * struct perf_mmap *m = &evlist->mmap[cpu];
362 * unsigned int head = perf_mmap__read_head(m); 375 * unsigned int head = perf_mmap__read_head(m);
363 * 376 *
364 * perf_mmap__write_tail(m, head) 377 * perf_mmap__write_tail(m, head)
365 * 378 *
366 * Using perf_evlist__read_on_cpu does this automatically. 379 * Using perf_evlist__read_on_cpu does this automatically.
367 */ 380 */
368 int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite) 381 int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite)
369 { 382 {
370 unsigned int page_size = sysconf(_SC_PAGE_SIZE); 383 unsigned int page_size = sysconf(_SC_PAGE_SIZE);
371 int mask = pages * page_size - 1; 384 int mask = pages * page_size - 1;
372 struct perf_evsel *evsel; 385 struct perf_evsel *evsel;
373 const struct cpu_map *cpus = evlist->cpus; 386 const struct cpu_map *cpus = evlist->cpus;
374 const struct thread_map *threads = evlist->threads; 387 const struct thread_map *threads = evlist->threads;
375 int prot = PROT_READ | (overwrite ? 0 : PROT_WRITE); 388 int prot = PROT_READ | (overwrite ? 0 : PROT_WRITE);
376 389
377 if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0) 390 if (evlist->mmap == NULL && perf_evlist__alloc_mmap(evlist) < 0)
378 return -ENOMEM; 391 return -ENOMEM;
379 392
380 if (evlist->pollfd == NULL && perf_evlist__alloc_pollfd(evlist) < 0) 393 if (evlist->pollfd == NULL && perf_evlist__alloc_pollfd(evlist) < 0)
381 return -ENOMEM; 394 return -ENOMEM;
382 395
383 evlist->overwrite = overwrite; 396 evlist->overwrite = overwrite;
384 evlist->mmap_len = (pages + 1) * page_size; 397 evlist->mmap_len = (pages + 1) * page_size;
385 398
386 list_for_each_entry(evsel, &evlist->entries, node) { 399 list_for_each_entry(evsel, &evlist->entries, node) {
387 if ((evsel->attr.read_format & PERF_FORMAT_ID) && 400 if ((evsel->attr.read_format & PERF_FORMAT_ID) &&
388 evsel->sample_id == NULL && 401 evsel->sample_id == NULL &&
389 perf_evsel__alloc_id(evsel, cpus->nr, threads->nr) < 0) 402 perf_evsel__alloc_id(evsel, cpus->nr, threads->nr) < 0)
390 return -ENOMEM; 403 return -ENOMEM;
391 } 404 }
392 405
393 if (evlist->cpus->map[0] == -1) 406 if (evlist->cpus->map[0] == -1)
394 return perf_evlist__mmap_per_thread(evlist, prot, mask); 407 return perf_evlist__mmap_per_thread(evlist, prot, mask);
395 408
396 return perf_evlist__mmap_per_cpu(evlist, prot, mask); 409 return perf_evlist__mmap_per_cpu(evlist, prot, mask);
397 } 410 }
398 411
399 int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, 412 int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid,
400 pid_t target_tid, const char *cpu_list) 413 pid_t target_tid, const char *cpu_list)
401 { 414 {
402 evlist->threads = thread_map__new(target_pid, target_tid); 415 evlist->threads = thread_map__new(target_pid, target_tid);
403 416
404 if (evlist->threads == NULL) 417 if (evlist->threads == NULL)
405 return -1; 418 return -1;
406 419
407 if (cpu_list == NULL && target_tid != -1) 420 if (cpu_list == NULL && target_tid != -1)
408 evlist->cpus = cpu_map__dummy_new(); 421 evlist->cpus = cpu_map__dummy_new();
409 else 422 else
410 evlist->cpus = cpu_map__new(cpu_list); 423 evlist->cpus = cpu_map__new(cpu_list);
411 424
412 if (evlist->cpus == NULL) 425 if (evlist->cpus == NULL)
413 goto out_delete_threads; 426 goto out_delete_threads;
414 427
415 return 0; 428 return 0;
416 429
417 out_delete_threads: 430 out_delete_threads:
418 thread_map__delete(evlist->threads); 431 thread_map__delete(evlist->threads);
419 return -1; 432 return -1;
420 } 433 }
421 434
422 void perf_evlist__delete_maps(struct perf_evlist *evlist) 435 void perf_evlist__delete_maps(struct perf_evlist *evlist)
423 { 436 {
424 cpu_map__delete(evlist->cpus); 437 cpu_map__delete(evlist->cpus);
425 thread_map__delete(evlist->threads); 438 thread_map__delete(evlist->threads);
426 evlist->cpus = NULL; 439 evlist->cpus = NULL;
427 evlist->threads = NULL; 440 evlist->threads = NULL;
428 } 441 }
429 442
430 int perf_evlist__set_filters(struct perf_evlist *evlist) 443 int perf_evlist__set_filters(struct perf_evlist *evlist)
431 { 444 {
432 const struct thread_map *threads = evlist->threads; 445 const struct thread_map *threads = evlist->threads;
433 const struct cpu_map *cpus = evlist->cpus; 446 const struct cpu_map *cpus = evlist->cpus;
434 struct perf_evsel *evsel; 447 struct perf_evsel *evsel;
435 char *filter; 448 char *filter;
436 int thread; 449 int thread;
437 int cpu; 450 int cpu;
438 int err; 451 int err;
439 int fd; 452 int fd;
440 453
441 list_for_each_entry(evsel, &evlist->entries, node) { 454 list_for_each_entry(evsel, &evlist->entries, node) {
442 filter = evsel->filter; 455 filter = evsel->filter;
443 if (!filter) 456 if (!filter)
444 continue; 457 continue;
445 for (cpu = 0; cpu < cpus->nr; cpu++) { 458 for (cpu = 0; cpu < cpus->nr; cpu++) {
446 for (thread = 0; thread < threads->nr; thread++) { 459 for (thread = 0; thread < threads->nr; thread++) {
447 fd = FD(evsel, cpu, thread); 460 fd = FD(evsel, cpu, thread);
448 err = ioctl(fd, PERF_EVENT_IOC_SET_FILTER, filter); 461 err = ioctl(fd, PERF_EVENT_IOC_SET_FILTER, filter);
449 if (err) 462 if (err)
450 return err; 463 return err;
451 } 464 }
452 } 465 }
453 } 466 }
454 467
455 return 0; 468 return 0;
456 } 469 }
457 470
458 bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist) 471 bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist)
459 { 472 {
460 struct perf_evsel *pos, *first; 473 struct perf_evsel *pos, *first;
461 474
462 pos = first = list_entry(evlist->entries.next, struct perf_evsel, node); 475 pos = first = list_entry(evlist->entries.next, struct perf_evsel, node);
463 476
464 list_for_each_entry_continue(pos, &evlist->entries, node) { 477 list_for_each_entry_continue(pos, &evlist->entries, node) {
465 if (first->attr.sample_type != pos->attr.sample_type) 478 if (first->attr.sample_type != pos->attr.sample_type)
466 return false; 479 return false;
467 } 480 }
468 481
469 return true; 482 return true;
470 } 483 }
471 484
472 u64 perf_evlist__sample_type(const struct perf_evlist *evlist) 485 u64 perf_evlist__sample_type(const struct perf_evlist *evlist)
473 { 486 {
474 struct perf_evsel *first; 487 struct perf_evsel *first;
475 488
476 first = list_entry(evlist->entries.next, struct perf_evsel, node); 489 first = list_entry(evlist->entries.next, struct perf_evsel, node);
477 return first->attr.sample_type; 490 return first->attr.sample_type;
478 } 491 }
479 492
480 bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist) 493 bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist)
481 { 494 {
482 struct perf_evsel *pos, *first; 495 struct perf_evsel *pos, *first;
483 496
484 pos = first = list_entry(evlist->entries.next, struct perf_evsel, node); 497 pos = first = list_entry(evlist->entries.next, struct perf_evsel, node);
485 498
486 list_for_each_entry_continue(pos, &evlist->entries, node) { 499 list_for_each_entry_continue(pos, &evlist->entries, node) {
487 if (first->attr.sample_id_all != pos->attr.sample_id_all) 500 if (first->attr.sample_id_all != pos->attr.sample_id_all)
488 return false; 501 return false;
489 } 502 }
490 503
491 return true; 504 return true;
492 } 505 }
493 506
494 bool perf_evlist__sample_id_all(const struct perf_evlist *evlist) 507 bool perf_evlist__sample_id_all(const struct perf_evlist *evlist)
495 { 508 {
496 struct perf_evsel *first; 509 struct perf_evsel *first;
497 510
498 first = list_entry(evlist->entries.next, struct perf_evsel, node); 511 first = list_entry(evlist->entries.next, struct perf_evsel, node);
499 return first->attr.sample_id_all; 512 return first->attr.sample_id_all;
500 } 513 }
501 514
tools/perf/util/evlist.h
1 #ifndef __PERF_EVLIST_H 1 #ifndef __PERF_EVLIST_H
2 #define __PERF_EVLIST_H 1 2 #define __PERF_EVLIST_H 1
3 3
4 #include <linux/list.h> 4 #include <linux/list.h>
5 #include "../perf.h" 5 #include "../perf.h"
6 #include "event.h" 6 #include "event.h"
7 7
8 struct pollfd; 8 struct pollfd;
9 struct thread_map; 9 struct thread_map;
10 struct cpu_map; 10 struct cpu_map;
11 11
12 #define PERF_EVLIST__HLIST_BITS 8 12 #define PERF_EVLIST__HLIST_BITS 8
13 #define PERF_EVLIST__HLIST_SIZE (1 << PERF_EVLIST__HLIST_BITS) 13 #define PERF_EVLIST__HLIST_SIZE (1 << PERF_EVLIST__HLIST_BITS)
14 14
15 struct perf_evlist { 15 struct perf_evlist {
16 struct list_head entries; 16 struct list_head entries;
17 struct hlist_head heads[PERF_EVLIST__HLIST_SIZE]; 17 struct hlist_head heads[PERF_EVLIST__HLIST_SIZE];
18 int nr_entries; 18 int nr_entries;
19 int nr_fds; 19 int nr_fds;
20 int nr_mmaps; 20 int nr_mmaps;
21 int mmap_len; 21 int mmap_len;
22 bool overwrite; 22 bool overwrite;
23 union perf_event event_copy; 23 union perf_event event_copy;
24 struct perf_mmap *mmap; 24 struct perf_mmap *mmap;
25 struct pollfd *pollfd; 25 struct pollfd *pollfd;
26 struct thread_map *threads; 26 struct thread_map *threads;
27 struct cpu_map *cpus; 27 struct cpu_map *cpus;
28 }; 28 };
29 29
30 struct perf_evsel; 30 struct perf_evsel;
31 31
32 struct perf_evlist *perf_evlist__new(struct cpu_map *cpus, 32 struct perf_evlist *perf_evlist__new(struct cpu_map *cpus,
33 struct thread_map *threads); 33 struct thread_map *threads);
34 void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus, 34 void perf_evlist__init(struct perf_evlist *evlist, struct cpu_map *cpus,
35 struct thread_map *threads); 35 struct thread_map *threads);
36 void perf_evlist__exit(struct perf_evlist *evlist); 36 void perf_evlist__exit(struct perf_evlist *evlist);
37 void perf_evlist__delete(struct perf_evlist *evlist); 37 void perf_evlist__delete(struct perf_evlist *evlist);
38 38
39 void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry); 39 void perf_evlist__add(struct perf_evlist *evlist, struct perf_evsel *entry);
40 int perf_evlist__add_default(struct perf_evlist *evlist); 40 int perf_evlist__add_default(struct perf_evlist *evlist);
41 41
42 void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel, 42 void perf_evlist__id_add(struct perf_evlist *evlist, struct perf_evsel *evsel,
43 int cpu, int thread, u64 id); 43 int cpu, int thread, u64 id);
44 44
45 int perf_evlist__alloc_pollfd(struct perf_evlist *evlist); 45 int perf_evlist__alloc_pollfd(struct perf_evlist *evlist);
46 void perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd); 46 void perf_evlist__add_pollfd(struct perf_evlist *evlist, int fd);
47 47
48 struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id); 48 struct perf_evsel *perf_evlist__id2evsel(struct perf_evlist *evlist, u64 id);
49 49
50 union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx); 50 union perf_event *perf_evlist__mmap_read(struct perf_evlist *self, int idx);
51 51
52 int perf_evlist__alloc_mmap(struct perf_evlist *evlist); 52 int perf_evlist__alloc_mmap(struct perf_evlist *evlist);
53 int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite); 53 int perf_evlist__mmap(struct perf_evlist *evlist, int pages, bool overwrite);
54 void perf_evlist__munmap(struct perf_evlist *evlist); 54 void perf_evlist__munmap(struct perf_evlist *evlist);
55 55
56 void perf_evlist__disable(struct perf_evlist *evlist);
57
56 static inline void perf_evlist__set_maps(struct perf_evlist *evlist, 58 static inline void perf_evlist__set_maps(struct perf_evlist *evlist,
57 struct cpu_map *cpus, 59 struct cpu_map *cpus,
58 struct thread_map *threads) 60 struct thread_map *threads)
59 { 61 {
60 evlist->cpus = cpus; 62 evlist->cpus = cpus;
61 evlist->threads = threads; 63 evlist->threads = threads;
62 } 64 }
63 65
64 int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid, 66 int perf_evlist__create_maps(struct perf_evlist *evlist, pid_t target_pid,
65 pid_t target_tid, const char *cpu_list); 67 pid_t target_tid, const char *cpu_list);
66 void perf_evlist__delete_maps(struct perf_evlist *evlist); 68 void perf_evlist__delete_maps(struct perf_evlist *evlist);
67 int perf_evlist__set_filters(struct perf_evlist *evlist); 69 int perf_evlist__set_filters(struct perf_evlist *evlist);
68 70
69 u64 perf_evlist__sample_type(const struct perf_evlist *evlist); 71 u64 perf_evlist__sample_type(const struct perf_evlist *evlist);
70 bool perf_evlist__sample_id_all(const const struct perf_evlist *evlist); 72 bool perf_evlist__sample_id_all(const const struct perf_evlist *evlist);
71 73
72 bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist); 74 bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist);
73 bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist); 75 bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist);
74 #endif /* __PERF_EVLIST_H */ 76 #endif /* __PERF_EVLIST_H */
75 77
tools/perf/util/header.c
1 #define _FILE_OFFSET_BITS 64 1 #define _FILE_OFFSET_BITS 64
2 2
3 #include <sys/types.h> 3 #include <sys/types.h>
4 #include <byteswap.h> 4 #include <byteswap.h>
5 #include <unistd.h> 5 #include <unistd.h>
6 #include <stdio.h> 6 #include <stdio.h>
7 #include <stdlib.h> 7 #include <stdlib.h>
8 #include <linux/list.h> 8 #include <linux/list.h>
9 #include <linux/kernel.h> 9 #include <linux/kernel.h>
10 10
11 #include "evlist.h" 11 #include "evlist.h"
12 #include "evsel.h" 12 #include "evsel.h"
13 #include "util.h" 13 #include "util.h"
14 #include "header.h" 14 #include "header.h"
15 #include "../perf.h" 15 #include "../perf.h"
16 #include "trace-event.h" 16 #include "trace-event.h"
17 #include "session.h" 17 #include "session.h"
18 #include "symbol.h" 18 #include "symbol.h"
19 #include "debug.h" 19 #include "debug.h"
20 20
21 static bool no_buildid_cache = false; 21 static bool no_buildid_cache = false;
22 22
23 static int event_count; 23 static int event_count;
24 static struct perf_trace_event_type *events; 24 static struct perf_trace_event_type *events;
25 25
26 int perf_header__push_event(u64 id, const char *name) 26 int perf_header__push_event(u64 id, const char *name)
27 { 27 {
28 if (strlen(name) > MAX_EVENT_NAME) 28 if (strlen(name) > MAX_EVENT_NAME)
29 pr_warning("Event %s will be truncated\n", name); 29 pr_warning("Event %s will be truncated\n", name);
30 30
31 if (!events) { 31 if (!events) {
32 events = malloc(sizeof(struct perf_trace_event_type)); 32 events = malloc(sizeof(struct perf_trace_event_type));
33 if (events == NULL) 33 if (events == NULL)
34 return -ENOMEM; 34 return -ENOMEM;
35 } else { 35 } else {
36 struct perf_trace_event_type *nevents; 36 struct perf_trace_event_type *nevents;
37 37
38 nevents = realloc(events, (event_count + 1) * sizeof(*events)); 38 nevents = realloc(events, (event_count + 1) * sizeof(*events));
39 if (nevents == NULL) 39 if (nevents == NULL)
40 return -ENOMEM; 40 return -ENOMEM;
41 events = nevents; 41 events = nevents;
42 } 42 }
43 memset(&events[event_count], 0, sizeof(struct perf_trace_event_type)); 43 memset(&events[event_count], 0, sizeof(struct perf_trace_event_type));
44 events[event_count].event_id = id; 44 events[event_count].event_id = id;
45 strncpy(events[event_count].name, name, MAX_EVENT_NAME - 1); 45 strncpy(events[event_count].name, name, MAX_EVENT_NAME - 1);
46 event_count++; 46 event_count++;
47 return 0; 47 return 0;
48 } 48 }
49 49
50 char *perf_header__find_event(u64 id) 50 char *perf_header__find_event(u64 id)
51 { 51 {
52 int i; 52 int i;
53 for (i = 0 ; i < event_count; i++) { 53 for (i = 0 ; i < event_count; i++) {
54 if (events[i].event_id == id) 54 if (events[i].event_id == id)
55 return events[i].name; 55 return events[i].name;
56 } 56 }
57 return NULL; 57 return NULL;
58 } 58 }
59 59
60 static const char *__perf_magic = "PERFFILE"; 60 static const char *__perf_magic = "PERFFILE";
61 61
62 #define PERF_MAGIC (*(u64 *)__perf_magic) 62 #define PERF_MAGIC (*(u64 *)__perf_magic)
63 63
64 struct perf_file_attr { 64 struct perf_file_attr {
65 struct perf_event_attr attr; 65 struct perf_event_attr attr;
66 struct perf_file_section ids; 66 struct perf_file_section ids;
67 }; 67 };
68 68
69 void perf_header__set_feat(struct perf_header *header, int feat) 69 void perf_header__set_feat(struct perf_header *header, int feat)
70 { 70 {
71 set_bit(feat, header->adds_features); 71 set_bit(feat, header->adds_features);
72 } 72 }
73 73
74 void perf_header__clear_feat(struct perf_header *header, int feat) 74 void perf_header__clear_feat(struct perf_header *header, int feat)
75 { 75 {
76 clear_bit(feat, header->adds_features); 76 clear_bit(feat, header->adds_features);
77 } 77 }
78 78
79 bool perf_header__has_feat(const struct perf_header *header, int feat) 79 bool perf_header__has_feat(const struct perf_header *header, int feat)
80 { 80 {
81 return test_bit(feat, header->adds_features); 81 return test_bit(feat, header->adds_features);
82 } 82 }
83 83
84 static int do_write(int fd, const void *buf, size_t size) 84 static int do_write(int fd, const void *buf, size_t size)
85 { 85 {
86 while (size) { 86 while (size) {
87 int ret = write(fd, buf, size); 87 int ret = write(fd, buf, size);
88 88
89 if (ret < 0) 89 if (ret < 0)
90 return -errno; 90 return -errno;
91 91
92 size -= ret; 92 size -= ret;
93 buf += ret; 93 buf += ret;
94 } 94 }
95 95
96 return 0; 96 return 0;
97 } 97 }
98 98
99 #define NAME_ALIGN 64 99 #define NAME_ALIGN 64
100 100
101 static int write_padded(int fd, const void *bf, size_t count, 101 static int write_padded(int fd, const void *bf, size_t count,
102 size_t count_aligned) 102 size_t count_aligned)
103 { 103 {
104 static const char zero_buf[NAME_ALIGN]; 104 static const char zero_buf[NAME_ALIGN];
105 int err = do_write(fd, bf, count); 105 int err = do_write(fd, bf, count);
106 106
107 if (!err) 107 if (!err)
108 err = do_write(fd, zero_buf, count_aligned - count); 108 err = do_write(fd, zero_buf, count_aligned - count);
109 109
110 return err; 110 return err;
111 } 111 }
112 112
113 #define dsos__for_each_with_build_id(pos, head) \ 113 #define dsos__for_each_with_build_id(pos, head) \
114 list_for_each_entry(pos, head, node) \ 114 list_for_each_entry(pos, head, node) \
115 if (!pos->has_build_id) \ 115 if (!pos->has_build_id) \
116 continue; \ 116 continue; \
117 else 117 else
118 118
119 static int __dsos__write_buildid_table(struct list_head *head, pid_t pid, 119 static int __dsos__write_buildid_table(struct list_head *head, pid_t pid,
120 u16 misc, int fd) 120 u16 misc, int fd)
121 { 121 {
122 struct dso *pos; 122 struct dso *pos;
123 123
124 dsos__for_each_with_build_id(pos, head) { 124 dsos__for_each_with_build_id(pos, head) {
125 int err; 125 int err;
126 struct build_id_event b; 126 struct build_id_event b;
127 size_t len; 127 size_t len;
128 128
129 if (!pos->hit) 129 if (!pos->hit)
130 continue; 130 continue;
131 len = pos->long_name_len + 1; 131 len = pos->long_name_len + 1;
132 len = ALIGN(len, NAME_ALIGN); 132 len = ALIGN(len, NAME_ALIGN);
133 memset(&b, 0, sizeof(b)); 133 memset(&b, 0, sizeof(b));
134 memcpy(&b.build_id, pos->build_id, sizeof(pos->build_id)); 134 memcpy(&b.build_id, pos->build_id, sizeof(pos->build_id));
135 b.pid = pid; 135 b.pid = pid;
136 b.header.misc = misc; 136 b.header.misc = misc;
137 b.header.size = sizeof(b) + len; 137 b.header.size = sizeof(b) + len;
138 err = do_write(fd, &b, sizeof(b)); 138 err = do_write(fd, &b, sizeof(b));
139 if (err < 0) 139 if (err < 0)
140 return err; 140 return err;
141 err = write_padded(fd, pos->long_name, 141 err = write_padded(fd, pos->long_name,
142 pos->long_name_len + 1, len); 142 pos->long_name_len + 1, len);
143 if (err < 0) 143 if (err < 0)
144 return err; 144 return err;
145 } 145 }
146 146
147 return 0; 147 return 0;
148 } 148 }
149 149
150 static int machine__write_buildid_table(struct machine *machine, int fd) 150 static int machine__write_buildid_table(struct machine *machine, int fd)
151 { 151 {
152 int err; 152 int err;
153 u16 kmisc = PERF_RECORD_MISC_KERNEL, 153 u16 kmisc = PERF_RECORD_MISC_KERNEL,
154 umisc = PERF_RECORD_MISC_USER; 154 umisc = PERF_RECORD_MISC_USER;
155 155
156 if (!machine__is_host(machine)) { 156 if (!machine__is_host(machine)) {
157 kmisc = PERF_RECORD_MISC_GUEST_KERNEL; 157 kmisc = PERF_RECORD_MISC_GUEST_KERNEL;
158 umisc = PERF_RECORD_MISC_GUEST_USER; 158 umisc = PERF_RECORD_MISC_GUEST_USER;
159 } 159 }
160 160
161 err = __dsos__write_buildid_table(&machine->kernel_dsos, machine->pid, 161 err = __dsos__write_buildid_table(&machine->kernel_dsos, machine->pid,
162 kmisc, fd); 162 kmisc, fd);
163 if (err == 0) 163 if (err == 0)
164 err = __dsos__write_buildid_table(&machine->user_dsos, 164 err = __dsos__write_buildid_table(&machine->user_dsos,
165 machine->pid, umisc, fd); 165 machine->pid, umisc, fd);
166 return err; 166 return err;
167 } 167 }
168 168
169 static int dsos__write_buildid_table(struct perf_header *header, int fd) 169 static int dsos__write_buildid_table(struct perf_header *header, int fd)
170 { 170 {
171 struct perf_session *session = container_of(header, 171 struct perf_session *session = container_of(header,
172 struct perf_session, header); 172 struct perf_session, header);
173 struct rb_node *nd; 173 struct rb_node *nd;
174 int err = machine__write_buildid_table(&session->host_machine, fd); 174 int err = machine__write_buildid_table(&session->host_machine, fd);
175 175
176 if (err) 176 if (err)
177 return err; 177 return err;
178 178
179 for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) { 179 for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
180 struct machine *pos = rb_entry(nd, struct machine, rb_node); 180 struct machine *pos = rb_entry(nd, struct machine, rb_node);
181 err = machine__write_buildid_table(pos, fd); 181 err = machine__write_buildid_table(pos, fd);
182 if (err) 182 if (err)
183 break; 183 break;
184 } 184 }
185 return err; 185 return err;
186 } 186 }
187 187
188 int build_id_cache__add_s(const char *sbuild_id, const char *debugdir, 188 int build_id_cache__add_s(const char *sbuild_id, const char *debugdir,
189 const char *name, bool is_kallsyms) 189 const char *name, bool is_kallsyms)
190 { 190 {
191 const size_t size = PATH_MAX; 191 const size_t size = PATH_MAX;
192 char *realname, *filename = malloc(size), 192 char *realname, *filename = zalloc(size),
193 *linkname = malloc(size), *targetname; 193 *linkname = zalloc(size), *targetname;
194 int len, err = -1; 194 int len, err = -1;
195 195
196 if (is_kallsyms) { 196 if (is_kallsyms) {
197 if (symbol_conf.kptr_restrict) { 197 if (symbol_conf.kptr_restrict) {
198 pr_debug("Not caching a kptr_restrict'ed /proc/kallsyms\n"); 198 pr_debug("Not caching a kptr_restrict'ed /proc/kallsyms\n");
199 return 0; 199 return 0;
200 } 200 }
201 realname = (char *)name; 201 realname = (char *)name;
202 } else 202 } else
203 realname = realpath(name, NULL); 203 realname = realpath(name, NULL);
204 204
205 if (realname == NULL || filename == NULL || linkname == NULL) 205 if (realname == NULL || filename == NULL || linkname == NULL)
206 goto out_free; 206 goto out_free;
207 207
208 len = snprintf(filename, size, "%s%s%s", 208 len = snprintf(filename, size, "%s%s%s",
209 debugdir, is_kallsyms ? "/" : "", realname); 209 debugdir, is_kallsyms ? "/" : "", realname);
210 if (mkdir_p(filename, 0755)) 210 if (mkdir_p(filename, 0755))
211 goto out_free; 211 goto out_free;
212 212
213 snprintf(filename + len, sizeof(filename) - len, "/%s", sbuild_id); 213 snprintf(filename + len, sizeof(filename) - len, "/%s", sbuild_id);
214 214
215 if (access(filename, F_OK)) { 215 if (access(filename, F_OK)) {
216 if (is_kallsyms) { 216 if (is_kallsyms) {
217 if (copyfile("/proc/kallsyms", filename)) 217 if (copyfile("/proc/kallsyms", filename))
218 goto out_free; 218 goto out_free;
219 } else if (link(realname, filename) && copyfile(name, filename)) 219 } else if (link(realname, filename) && copyfile(name, filename))
220 goto out_free; 220 goto out_free;
221 } 221 }
222 222
223 len = snprintf(linkname, size, "%s/.build-id/%.2s", 223 len = snprintf(linkname, size, "%s/.build-id/%.2s",
224 debugdir, sbuild_id); 224 debugdir, sbuild_id);
225 225
226 if (access(linkname, X_OK) && mkdir_p(linkname, 0755)) 226 if (access(linkname, X_OK) && mkdir_p(linkname, 0755))
227 goto out_free; 227 goto out_free;
228 228
229 snprintf(linkname + len, size - len, "/%s", sbuild_id + 2); 229 snprintf(linkname + len, size - len, "/%s", sbuild_id + 2);
230 targetname = filename + strlen(debugdir) - 5; 230 targetname = filename + strlen(debugdir) - 5;
231 memcpy(targetname, "../..", 5); 231 memcpy(targetname, "../..", 5);
232 232
233 if (symlink(targetname, linkname) == 0) 233 if (symlink(targetname, linkname) == 0)
234 err = 0; 234 err = 0;
235 out_free: 235 out_free:
236 if (!is_kallsyms) 236 if (!is_kallsyms)
237 free(realname); 237 free(realname);
238 free(filename); 238 free(filename);
239 free(linkname); 239 free(linkname);
240 return err; 240 return err;
241 } 241 }
242 242
243 static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size, 243 static int build_id_cache__add_b(const u8 *build_id, size_t build_id_size,
244 const char *name, const char *debugdir, 244 const char *name, const char *debugdir,
245 bool is_kallsyms) 245 bool is_kallsyms)
246 { 246 {
247 char sbuild_id[BUILD_ID_SIZE * 2 + 1]; 247 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
248 248
249 build_id__sprintf(build_id, build_id_size, sbuild_id); 249 build_id__sprintf(build_id, build_id_size, sbuild_id);
250 250
251 return build_id_cache__add_s(sbuild_id, debugdir, name, is_kallsyms); 251 return build_id_cache__add_s(sbuild_id, debugdir, name, is_kallsyms);
252 } 252 }
253 253
254 int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir) 254 int build_id_cache__remove_s(const char *sbuild_id, const char *debugdir)
255 { 255 {
256 const size_t size = PATH_MAX; 256 const size_t size = PATH_MAX;
257 char *filename = malloc(size), 257 char *filename = zalloc(size),
258 *linkname = malloc(size); 258 *linkname = zalloc(size);
259 int err = -1; 259 int err = -1;
260 260
261 if (filename == NULL || linkname == NULL) 261 if (filename == NULL || linkname == NULL)
262 goto out_free; 262 goto out_free;
263 263
264 snprintf(linkname, size, "%s/.build-id/%.2s/%s", 264 snprintf(linkname, size, "%s/.build-id/%.2s/%s",
265 debugdir, sbuild_id, sbuild_id + 2); 265 debugdir, sbuild_id, sbuild_id + 2);
266 266
267 if (access(linkname, F_OK)) 267 if (access(linkname, F_OK))
268 goto out_free; 268 goto out_free;
269 269
270 if (readlink(linkname, filename, size) < 0) 270 if (readlink(linkname, filename, size) < 0)
271 goto out_free; 271 goto out_free;
272 272
273 if (unlink(linkname)) 273 if (unlink(linkname))
274 goto out_free; 274 goto out_free;
275 275
276 /* 276 /*
277 * Since the link is relative, we must make it absolute: 277 * Since the link is relative, we must make it absolute:
278 */ 278 */
279 snprintf(linkname, size, "%s/.build-id/%.2s/%s", 279 snprintf(linkname, size, "%s/.build-id/%.2s/%s",
280 debugdir, sbuild_id, filename); 280 debugdir, sbuild_id, filename);
281 281
282 if (unlink(linkname)) 282 if (unlink(linkname))
283 goto out_free; 283 goto out_free;
284 284
285 err = 0; 285 err = 0;
286 out_free: 286 out_free:
287 free(filename); 287 free(filename);
288 free(linkname); 288 free(linkname);
289 return err; 289 return err;
290 } 290 }
291 291
292 static int dso__cache_build_id(struct dso *dso, const char *debugdir) 292 static int dso__cache_build_id(struct dso *dso, const char *debugdir)
293 { 293 {
294 bool is_kallsyms = dso->kernel && dso->long_name[0] != '/'; 294 bool is_kallsyms = dso->kernel && dso->long_name[0] != '/';
295 295
296 return build_id_cache__add_b(dso->build_id, sizeof(dso->build_id), 296 return build_id_cache__add_b(dso->build_id, sizeof(dso->build_id),
297 dso->long_name, debugdir, is_kallsyms); 297 dso->long_name, debugdir, is_kallsyms);
298 } 298 }
299 299
300 static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir) 300 static int __dsos__cache_build_ids(struct list_head *head, const char *debugdir)
301 { 301 {
302 struct dso *pos; 302 struct dso *pos;
303 int err = 0; 303 int err = 0;
304 304
305 dsos__for_each_with_build_id(pos, head) 305 dsos__for_each_with_build_id(pos, head)
306 if (dso__cache_build_id(pos, debugdir)) 306 if (dso__cache_build_id(pos, debugdir))
307 err = -1; 307 err = -1;
308 308
309 return err; 309 return err;
310 } 310 }
311 311
312 static int machine__cache_build_ids(struct machine *machine, const char *debugdir) 312 static int machine__cache_build_ids(struct machine *machine, const char *debugdir)
313 { 313 {
314 int ret = __dsos__cache_build_ids(&machine->kernel_dsos, debugdir); 314 int ret = __dsos__cache_build_ids(&machine->kernel_dsos, debugdir);
315 ret |= __dsos__cache_build_ids(&machine->user_dsos, debugdir); 315 ret |= __dsos__cache_build_ids(&machine->user_dsos, debugdir);
316 return ret; 316 return ret;
317 } 317 }
318 318
319 static int perf_session__cache_build_ids(struct perf_session *session) 319 static int perf_session__cache_build_ids(struct perf_session *session)
320 { 320 {
321 struct rb_node *nd; 321 struct rb_node *nd;
322 int ret; 322 int ret;
323 char debugdir[PATH_MAX]; 323 char debugdir[PATH_MAX];
324 324
325 snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir); 325 snprintf(debugdir, sizeof(debugdir), "%s", buildid_dir);
326 326
327 if (mkdir(debugdir, 0755) != 0 && errno != EEXIST) 327 if (mkdir(debugdir, 0755) != 0 && errno != EEXIST)
328 return -1; 328 return -1;
329 329
330 ret = machine__cache_build_ids(&session->host_machine, debugdir); 330 ret = machine__cache_build_ids(&session->host_machine, debugdir);
331 331
332 for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) { 332 for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
333 struct machine *pos = rb_entry(nd, struct machine, rb_node); 333 struct machine *pos = rb_entry(nd, struct machine, rb_node);
334 ret |= machine__cache_build_ids(pos, debugdir); 334 ret |= machine__cache_build_ids(pos, debugdir);
335 } 335 }
336 return ret ? -1 : 0; 336 return ret ? -1 : 0;
337 } 337 }
338 338
339 static bool machine__read_build_ids(struct machine *machine, bool with_hits) 339 static bool machine__read_build_ids(struct machine *machine, bool with_hits)
340 { 340 {
341 bool ret = __dsos__read_build_ids(&machine->kernel_dsos, with_hits); 341 bool ret = __dsos__read_build_ids(&machine->kernel_dsos, with_hits);
342 ret |= __dsos__read_build_ids(&machine->user_dsos, with_hits); 342 ret |= __dsos__read_build_ids(&machine->user_dsos, with_hits);
343 return ret; 343 return ret;
344 } 344 }
345 345
346 static bool perf_session__read_build_ids(struct perf_session *session, bool with_hits) 346 static bool perf_session__read_build_ids(struct perf_session *session, bool with_hits)
347 { 347 {
348 struct rb_node *nd; 348 struct rb_node *nd;
349 bool ret = machine__read_build_ids(&session->host_machine, with_hits); 349 bool ret = machine__read_build_ids(&session->host_machine, with_hits);
350 350
351 for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) { 351 for (nd = rb_first(&session->machines); nd; nd = rb_next(nd)) {
352 struct machine *pos = rb_entry(nd, struct machine, rb_node); 352 struct machine *pos = rb_entry(nd, struct machine, rb_node);
353 ret |= machine__read_build_ids(pos, with_hits); 353 ret |= machine__read_build_ids(pos, with_hits);
354 } 354 }
355 355
356 return ret; 356 return ret;
357 } 357 }
358 358
359 static int perf_header__adds_write(struct perf_header *header, 359 static int perf_header__adds_write(struct perf_header *header,
360 struct perf_evlist *evlist, int fd) 360 struct perf_evlist *evlist, int fd)
361 { 361 {
362 int nr_sections; 362 int nr_sections;
363 struct perf_session *session; 363 struct perf_session *session;
364 struct perf_file_section *feat_sec; 364 struct perf_file_section *feat_sec;
365 int sec_size; 365 int sec_size;
366 u64 sec_start; 366 u64 sec_start;
367 int idx = 0, err; 367 int idx = 0, err;
368 368
369 session = container_of(header, struct perf_session, header); 369 session = container_of(header, struct perf_session, header);
370 370
371 if (perf_header__has_feat(header, HEADER_BUILD_ID && 371 if (perf_header__has_feat(header, HEADER_BUILD_ID &&
372 !perf_session__read_build_ids(session, true))) 372 !perf_session__read_build_ids(session, true)))
373 perf_header__clear_feat(header, HEADER_BUILD_ID); 373 perf_header__clear_feat(header, HEADER_BUILD_ID);
374 374
375 nr_sections = bitmap_weight(header->adds_features, HEADER_FEAT_BITS); 375 nr_sections = bitmap_weight(header->adds_features, HEADER_FEAT_BITS);
376 if (!nr_sections) 376 if (!nr_sections)
377 return 0; 377 return 0;
378 378
379 feat_sec = calloc(sizeof(*feat_sec), nr_sections); 379 feat_sec = calloc(sizeof(*feat_sec), nr_sections);
380 if (feat_sec == NULL) 380 if (feat_sec == NULL)
381 return -ENOMEM; 381 return -ENOMEM;
382 382
383 sec_size = sizeof(*feat_sec) * nr_sections; 383 sec_size = sizeof(*feat_sec) * nr_sections;
384 384
385 sec_start = header->data_offset + header->data_size; 385 sec_start = header->data_offset + header->data_size;
386 lseek(fd, sec_start + sec_size, SEEK_SET); 386 lseek(fd, sec_start + sec_size, SEEK_SET);
387 387
388 if (perf_header__has_feat(header, HEADER_TRACE_INFO)) { 388 if (perf_header__has_feat(header, HEADER_TRACE_INFO)) {
389 struct perf_file_section *trace_sec; 389 struct perf_file_section *trace_sec;
390 390
391 trace_sec = &feat_sec[idx++]; 391 trace_sec = &feat_sec[idx++];
392 392
393 /* Write trace info */ 393 /* Write trace info */
394 trace_sec->offset = lseek(fd, 0, SEEK_CUR); 394 trace_sec->offset = lseek(fd, 0, SEEK_CUR);
395 read_tracing_data(fd, &evlist->entries); 395 read_tracing_data(fd, &evlist->entries);
396 trace_sec->size = lseek(fd, 0, SEEK_CUR) - trace_sec->offset; 396 trace_sec->size = lseek(fd, 0, SEEK_CUR) - trace_sec->offset;
397 } 397 }
398 398
399 if (perf_header__has_feat(header, HEADER_BUILD_ID)) { 399 if (perf_header__has_feat(header, HEADER_BUILD_ID)) {
400 struct perf_file_section *buildid_sec; 400 struct perf_file_section *buildid_sec;
401 401
402 buildid_sec = &feat_sec[idx++]; 402 buildid_sec = &feat_sec[idx++];
403 403
404 /* Write build-ids */ 404 /* Write build-ids */
405 buildid_sec->offset = lseek(fd, 0, SEEK_CUR); 405 buildid_sec->offset = lseek(fd, 0, SEEK_CUR);
406 err = dsos__write_buildid_table(header, fd); 406 err = dsos__write_buildid_table(header, fd);
407 if (err < 0) { 407 if (err < 0) {
408 pr_debug("failed to write buildid table\n"); 408 pr_debug("failed to write buildid table\n");
409 goto out_free; 409 goto out_free;
410 } 410 }
411 buildid_sec->size = lseek(fd, 0, SEEK_CUR) - 411 buildid_sec->size = lseek(fd, 0, SEEK_CUR) -
412 buildid_sec->offset; 412 buildid_sec->offset;
413 if (!no_buildid_cache) 413 if (!no_buildid_cache)
414 perf_session__cache_build_ids(session); 414 perf_session__cache_build_ids(session);
415 } 415 }
416 416
417 lseek(fd, sec_start, SEEK_SET); 417 lseek(fd, sec_start, SEEK_SET);
418 err = do_write(fd, feat_sec, sec_size); 418 err = do_write(fd, feat_sec, sec_size);
419 if (err < 0) 419 if (err < 0)
420 pr_debug("failed to write feature section\n"); 420 pr_debug("failed to write feature section\n");
421 out_free: 421 out_free:
422 free(feat_sec); 422 free(feat_sec);
423 return err; 423 return err;
424 } 424 }
425 425
426 int perf_header__write_pipe(int fd) 426 int perf_header__write_pipe(int fd)
427 { 427 {
428 struct perf_pipe_file_header f_header; 428 struct perf_pipe_file_header f_header;
429 int err; 429 int err;
430 430
431 f_header = (struct perf_pipe_file_header){ 431 f_header = (struct perf_pipe_file_header){
432 .magic = PERF_MAGIC, 432 .magic = PERF_MAGIC,
433 .size = sizeof(f_header), 433 .size = sizeof(f_header),
434 }; 434 };
435 435
436 err = do_write(fd, &f_header, sizeof(f_header)); 436 err = do_write(fd, &f_header, sizeof(f_header));
437 if (err < 0) { 437 if (err < 0) {
438 pr_debug("failed to write perf pipe header\n"); 438 pr_debug("failed to write perf pipe header\n");
439 return err; 439 return err;
440 } 440 }
441 441
442 return 0; 442 return 0;
443 } 443 }
444 444
445 int perf_session__write_header(struct perf_session *session, 445 int perf_session__write_header(struct perf_session *session,
446 struct perf_evlist *evlist, 446 struct perf_evlist *evlist,
447 int fd, bool at_exit) 447 int fd, bool at_exit)
448 { 448 {
449 struct perf_file_header f_header; 449 struct perf_file_header f_header;
450 struct perf_file_attr f_attr; 450 struct perf_file_attr f_attr;
451 struct perf_header *header = &session->header; 451 struct perf_header *header = &session->header;
452 struct perf_evsel *attr, *pair = NULL; 452 struct perf_evsel *attr, *pair = NULL;
453 int err; 453 int err;
454 454
455 lseek(fd, sizeof(f_header), SEEK_SET); 455 lseek(fd, sizeof(f_header), SEEK_SET);
456 456
457 if (session->evlist != evlist) 457 if (session->evlist != evlist)
458 pair = list_entry(session->evlist->entries.next, struct perf_evsel, node); 458 pair = list_entry(session->evlist->entries.next, struct perf_evsel, node);
459 459
460 list_for_each_entry(attr, &evlist->entries, node) { 460 list_for_each_entry(attr, &evlist->entries, node) {
461 attr->id_offset = lseek(fd, 0, SEEK_CUR); 461 attr->id_offset = lseek(fd, 0, SEEK_CUR);
462 err = do_write(fd, attr->id, attr->ids * sizeof(u64)); 462 err = do_write(fd, attr->id, attr->ids * sizeof(u64));
463 if (err < 0) { 463 if (err < 0) {
464 out_err_write: 464 out_err_write:
465 pr_debug("failed to write perf header\n"); 465 pr_debug("failed to write perf header\n");
466 return err; 466 return err;
467 } 467 }
468 if (session->evlist != evlist) { 468 if (session->evlist != evlist) {
469 err = do_write(fd, pair->id, pair->ids * sizeof(u64)); 469 err = do_write(fd, pair->id, pair->ids * sizeof(u64));
470 if (err < 0) 470 if (err < 0)
471 goto out_err_write; 471 goto out_err_write;
472 attr->ids += pair->ids; 472 attr->ids += pair->ids;
473 pair = list_entry(pair->node.next, struct perf_evsel, node); 473 pair = list_entry(pair->node.next, struct perf_evsel, node);
474 } 474 }
475 } 475 }
476 476
477 header->attr_offset = lseek(fd, 0, SEEK_CUR); 477 header->attr_offset = lseek(fd, 0, SEEK_CUR);
478 478
479 list_for_each_entry(attr, &evlist->entries, node) { 479 list_for_each_entry(attr, &evlist->entries, node) {
480 f_attr = (struct perf_file_attr){ 480 f_attr = (struct perf_file_attr){
481 .attr = attr->attr, 481 .attr = attr->attr,
482 .ids = { 482 .ids = {
483 .offset = attr->id_offset, 483 .offset = attr->id_offset,
484 .size = attr->ids * sizeof(u64), 484 .size = attr->ids * sizeof(u64),
485 } 485 }
486 }; 486 };
487 err = do_write(fd, &f_attr, sizeof(f_attr)); 487 err = do_write(fd, &f_attr, sizeof(f_attr));
488 if (err < 0) { 488 if (err < 0) {
489 pr_debug("failed to write perf header attribute\n"); 489 pr_debug("failed to write perf header attribute\n");
490 return err; 490 return err;
491 } 491 }
492 } 492 }
493 493
494 header->event_offset = lseek(fd, 0, SEEK_CUR); 494 header->event_offset = lseek(fd, 0, SEEK_CUR);
495 header->event_size = event_count * sizeof(struct perf_trace_event_type); 495 header->event_size = event_count * sizeof(struct perf_trace_event_type);
496 if (events) { 496 if (events) {
497 err = do_write(fd, events, header->event_size); 497 err = do_write(fd, events, header->event_size);
498 if (err < 0) { 498 if (err < 0) {
499 pr_debug("failed to write perf header events\n"); 499 pr_debug("failed to write perf header events\n");
500 return err; 500 return err;
501 } 501 }
502 } 502 }
503 503
504 header->data_offset = lseek(fd, 0, SEEK_CUR); 504 header->data_offset = lseek(fd, 0, SEEK_CUR);
505 505
506 if (at_exit) { 506 if (at_exit) {
507 err = perf_header__adds_write(header, evlist, fd); 507 err = perf_header__adds_write(header, evlist, fd);
508 if (err < 0) 508 if (err < 0)
509 return err; 509 return err;
510 } 510 }
511 511
512 f_header = (struct perf_file_header){ 512 f_header = (struct perf_file_header){
513 .magic = PERF_MAGIC, 513 .magic = PERF_MAGIC,
514 .size = sizeof(f_header), 514 .size = sizeof(f_header),
515 .attr_size = sizeof(f_attr), 515 .attr_size = sizeof(f_attr),
516 .attrs = { 516 .attrs = {
517 .offset = header->attr_offset, 517 .offset = header->attr_offset,
518 .size = evlist->nr_entries * sizeof(f_attr), 518 .size = evlist->nr_entries * sizeof(f_attr),
519 }, 519 },
520 .data = { 520 .data = {
521 .offset = header->data_offset, 521 .offset = header->data_offset,
522 .size = header->data_size, 522 .size = header->data_size,
523 }, 523 },
524 .event_types = { 524 .event_types = {
525 .offset = header->event_offset, 525 .offset = header->event_offset,
526 .size = header->event_size, 526 .size = header->event_size,
527 }, 527 },
528 }; 528 };
529 529
530 memcpy(&f_header.adds_features, &header->adds_features, sizeof(header->adds_features)); 530 memcpy(&f_header.adds_features, &header->adds_features, sizeof(header->adds_features));
531 531
532 lseek(fd, 0, SEEK_SET); 532 lseek(fd, 0, SEEK_SET);
533 err = do_write(fd, &f_header, sizeof(f_header)); 533 err = do_write(fd, &f_header, sizeof(f_header));
534 if (err < 0) { 534 if (err < 0) {
535 pr_debug("failed to write perf header\n"); 535 pr_debug("failed to write perf header\n");
536 return err; 536 return err;
537 } 537 }
538 lseek(fd, header->data_offset + header->data_size, SEEK_SET); 538 lseek(fd, header->data_offset + header->data_size, SEEK_SET);
539 539
540 header->frozen = 1; 540 header->frozen = 1;
541 return 0; 541 return 0;
542 } 542 }
543 543
544 static int perf_header__getbuffer64(struct perf_header *header, 544 static int perf_header__getbuffer64(struct perf_header *header,
545 int fd, void *buf, size_t size) 545 int fd, void *buf, size_t size)
546 { 546 {
547 if (readn(fd, buf, size) <= 0) 547 if (readn(fd, buf, size) <= 0)
548 return -1; 548 return -1;
549 549
550 if (header->needs_swap) 550 if (header->needs_swap)
551 mem_bswap_64(buf, size); 551 mem_bswap_64(buf, size);
552 552
553 return 0; 553 return 0;
554 } 554 }
555 555
556 int perf_header__process_sections(struct perf_header *header, int fd, 556 int perf_header__process_sections(struct perf_header *header, int fd,
557 int (*process)(struct perf_file_section *section, 557 int (*process)(struct perf_file_section *section,
558 struct perf_header *ph, 558 struct perf_header *ph,
559 int feat, int fd)) 559 int feat, int fd))
560 { 560 {
561 struct perf_file_section *feat_sec; 561 struct perf_file_section *feat_sec;
562 int nr_sections; 562 int nr_sections;
563 int sec_size; 563 int sec_size;
564 int idx = 0; 564 int idx = 0;
565 int err = -1, feat = 1; 565 int err = -1, feat = 1;
566 566
567 nr_sections = bitmap_weight(header->adds_features, HEADER_FEAT_BITS); 567 nr_sections = bitmap_weight(header->adds_features, HEADER_FEAT_BITS);
568 if (!nr_sections) 568 if (!nr_sections)
569 return 0; 569 return 0;
570 570
571 feat_sec = calloc(sizeof(*feat_sec), nr_sections); 571 feat_sec = calloc(sizeof(*feat_sec), nr_sections);
572 if (!feat_sec) 572 if (!feat_sec)
573 return -1; 573 return -1;
574 574
575 sec_size = sizeof(*feat_sec) * nr_sections; 575 sec_size = sizeof(*feat_sec) * nr_sections;
576 576
577 lseek(fd, header->data_offset + header->data_size, SEEK_SET); 577 lseek(fd, header->data_offset + header->data_size, SEEK_SET);
578 578
579 if (perf_header__getbuffer64(header, fd, feat_sec, sec_size)) 579 if (perf_header__getbuffer64(header, fd, feat_sec, sec_size))
580 goto out_free; 580 goto out_free;
581 581
582 err = 0; 582 err = 0;
583 while (idx < nr_sections && feat < HEADER_LAST_FEATURE) { 583 while (idx < nr_sections && feat < HEADER_LAST_FEATURE) {
584 if (perf_header__has_feat(header, feat)) { 584 if (perf_header__has_feat(header, feat)) {
585 struct perf_file_section *sec = &feat_sec[idx++]; 585 struct perf_file_section *sec = &feat_sec[idx++];
586 586
587 err = process(sec, header, feat, fd); 587 err = process(sec, header, feat, fd);
588 if (err < 0) 588 if (err < 0)
589 break; 589 break;
590 } 590 }
591 ++feat; 591 ++feat;
592 } 592 }
593 out_free: 593 out_free:
594 free(feat_sec); 594 free(feat_sec);
595 return err; 595 return err;
596 } 596 }
597 597
598 int perf_file_header__read(struct perf_file_header *header, 598 int perf_file_header__read(struct perf_file_header *header,
599 struct perf_header *ph, int fd) 599 struct perf_header *ph, int fd)
600 { 600 {
601 lseek(fd, 0, SEEK_SET); 601 lseek(fd, 0, SEEK_SET);
602 602
603 if (readn(fd, header, sizeof(*header)) <= 0 || 603 if (readn(fd, header, sizeof(*header)) <= 0 ||
604 memcmp(&header->magic, __perf_magic, sizeof(header->magic))) 604 memcmp(&header->magic, __perf_magic, sizeof(header->magic)))
605 return -1; 605 return -1;
606 606
607 if (header->attr_size != sizeof(struct perf_file_attr)) { 607 if (header->attr_size != sizeof(struct perf_file_attr)) {
608 u64 attr_size = bswap_64(header->attr_size); 608 u64 attr_size = bswap_64(header->attr_size);
609 609
610 if (attr_size != sizeof(struct perf_file_attr)) 610 if (attr_size != sizeof(struct perf_file_attr))
611 return -1; 611 return -1;
612 612
613 mem_bswap_64(header, offsetof(struct perf_file_header, 613 mem_bswap_64(header, offsetof(struct perf_file_header,
614 adds_features)); 614 adds_features));
615 ph->needs_swap = true; 615 ph->needs_swap = true;
616 } 616 }
617 617
618 if (header->size != sizeof(*header)) { 618 if (header->size != sizeof(*header)) {
619 /* Support the previous format */ 619 /* Support the previous format */
620 if (header->size == offsetof(typeof(*header), adds_features)) 620 if (header->size == offsetof(typeof(*header), adds_features))
621 bitmap_zero(header->adds_features, HEADER_FEAT_BITS); 621 bitmap_zero(header->adds_features, HEADER_FEAT_BITS);
622 else 622 else
623 return -1; 623 return -1;
624 } 624 }
625 625
626 memcpy(&ph->adds_features, &header->adds_features, 626 memcpy(&ph->adds_features, &header->adds_features,
627 sizeof(ph->adds_features)); 627 sizeof(ph->adds_features));
628 /* 628 /*
629 * FIXME: hack that assumes that if we need swap the perf.data file 629 * FIXME: hack that assumes that if we need swap the perf.data file
630 * may be coming from an arch with a different word-size, ergo different 630 * may be coming from an arch with a different word-size, ergo different
631 * DEFINE_BITMAP format, investigate more later, but for now its mostly 631 * DEFINE_BITMAP format, investigate more later, but for now its mostly
632 * safe to assume that we have a build-id section. Trace files probably 632 * safe to assume that we have a build-id section. Trace files probably
633 * have several other issues in this realm anyway... 633 * have several other issues in this realm anyway...
634 */ 634 */
635 if (ph->needs_swap) { 635 if (ph->needs_swap) {
636 memset(&ph->adds_features, 0, sizeof(ph->adds_features)); 636 memset(&ph->adds_features, 0, sizeof(ph->adds_features));
637 perf_header__set_feat(ph, HEADER_BUILD_ID); 637 perf_header__set_feat(ph, HEADER_BUILD_ID);
638 } 638 }
639 639
640 ph->event_offset = header->event_types.offset; 640 ph->event_offset = header->event_types.offset;
641 ph->event_size = header->event_types.size; 641 ph->event_size = header->event_types.size;
642 ph->data_offset = header->data.offset; 642 ph->data_offset = header->data.offset;
643 ph->data_size = header->data.size; 643 ph->data_size = header->data.size;
644 return 0; 644 return 0;
645 } 645 }
646 646
647 static int __event_process_build_id(struct build_id_event *bev, 647 static int __event_process_build_id(struct build_id_event *bev,
648 char *filename, 648 char *filename,
649 struct perf_session *session) 649 struct perf_session *session)
650 { 650 {
651 int err = -1; 651 int err = -1;
652 struct list_head *head; 652 struct list_head *head;
653 struct machine *machine; 653 struct machine *machine;
654 u16 misc; 654 u16 misc;
655 struct dso *dso; 655 struct dso *dso;
656 enum dso_kernel_type dso_type; 656 enum dso_kernel_type dso_type;
657 657
658 machine = perf_session__findnew_machine(session, bev->pid); 658 machine = perf_session__findnew_machine(session, bev->pid);
659 if (!machine) 659 if (!machine)
660 goto out; 660 goto out;
661 661
662 misc = bev->header.misc & PERF_RECORD_MISC_CPUMODE_MASK; 662 misc = bev->header.misc & PERF_RECORD_MISC_CPUMODE_MASK;
663 663
664 switch (misc) { 664 switch (misc) {
665 case PERF_RECORD_MISC_KERNEL: 665 case PERF_RECORD_MISC_KERNEL:
666 dso_type = DSO_TYPE_KERNEL; 666 dso_type = DSO_TYPE_KERNEL;
667 head = &machine->kernel_dsos; 667 head = &machine->kernel_dsos;
668 break; 668 break;
669 case PERF_RECORD_MISC_GUEST_KERNEL: 669 case PERF_RECORD_MISC_GUEST_KERNEL:
670 dso_type = DSO_TYPE_GUEST_KERNEL; 670 dso_type = DSO_TYPE_GUEST_KERNEL;
671 head = &machine->kernel_dsos; 671 head = &machine->kernel_dsos;
672 break; 672 break;
673 case PERF_RECORD_MISC_USER: 673 case PERF_RECORD_MISC_USER:
674 case PERF_RECORD_MISC_GUEST_USER: 674 case PERF_RECORD_MISC_GUEST_USER:
675 dso_type = DSO_TYPE_USER; 675 dso_type = DSO_TYPE_USER;
676 head = &machine->user_dsos; 676 head = &machine->user_dsos;
677 break; 677 break;
678 default: 678 default:
679 goto out; 679 goto out;
680 } 680 }
681 681
682 dso = __dsos__findnew(head, filename); 682 dso = __dsos__findnew(head, filename);
683 if (dso != NULL) { 683 if (dso != NULL) {
684 char sbuild_id[BUILD_ID_SIZE * 2 + 1]; 684 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
685 685
686 dso__set_build_id(dso, &bev->build_id); 686 dso__set_build_id(dso, &bev->build_id);
687 687
688 if (filename[0] == '[') 688 if (filename[0] == '[')
689 dso->kernel = dso_type; 689 dso->kernel = dso_type;
690 690
691 build_id__sprintf(dso->build_id, sizeof(dso->build_id), 691 build_id__sprintf(dso->build_id, sizeof(dso->build_id),
692 sbuild_id); 692 sbuild_id);
693 pr_debug("build id event received for %s: %s\n", 693 pr_debug("build id event received for %s: %s\n",
694 dso->long_name, sbuild_id); 694 dso->long_name, sbuild_id);
695 } 695 }
696 696
697 err = 0; 697 err = 0;
698 out: 698 out:
699 return err; 699 return err;
700 } 700 }
701 701
702 static int perf_header__read_build_ids_abi_quirk(struct perf_header *header, 702 static int perf_header__read_build_ids_abi_quirk(struct perf_header *header,
703 int input, u64 offset, u64 size) 703 int input, u64 offset, u64 size)
704 { 704 {
705 struct perf_session *session = container_of(header, struct perf_session, header); 705 struct perf_session *session = container_of(header, struct perf_session, header);
706 struct { 706 struct {
707 struct perf_event_header header; 707 struct perf_event_header header;
708 u8 build_id[ALIGN(BUILD_ID_SIZE, sizeof(u64))]; 708 u8 build_id[ALIGN(BUILD_ID_SIZE, sizeof(u64))];
709 char filename[0]; 709 char filename[0];
710 } old_bev; 710 } old_bev;
711 struct build_id_event bev; 711 struct build_id_event bev;
712 char filename[PATH_MAX]; 712 char filename[PATH_MAX];
713 u64 limit = offset + size; 713 u64 limit = offset + size;
714 714
715 while (offset < limit) { 715 while (offset < limit) {
716 ssize_t len; 716 ssize_t len;
717 717
718 if (read(input, &old_bev, sizeof(old_bev)) != sizeof(old_bev)) 718 if (read(input, &old_bev, sizeof(old_bev)) != sizeof(old_bev))
719 return -1; 719 return -1;
720 720
721 if (header->needs_swap) 721 if (header->needs_swap)
722 perf_event_header__bswap(&old_bev.header); 722 perf_event_header__bswap(&old_bev.header);
723 723
724 len = old_bev.header.size - sizeof(old_bev); 724 len = old_bev.header.size - sizeof(old_bev);
725 if (read(input, filename, len) != len) 725 if (read(input, filename, len) != len)
726 return -1; 726 return -1;
727 727
728 bev.header = old_bev.header; 728 bev.header = old_bev.header;
729 bev.pid = 0; 729 bev.pid = 0;
730 memcpy(bev.build_id, old_bev.build_id, sizeof(bev.build_id)); 730 memcpy(bev.build_id, old_bev.build_id, sizeof(bev.build_id));
731 __event_process_build_id(&bev, filename, session); 731 __event_process_build_id(&bev, filename, session);
732 732
733 offset += bev.header.size; 733 offset += bev.header.size;
734 } 734 }
735 735
736 return 0; 736 return 0;
737 } 737 }
738 738
739 static int perf_header__read_build_ids(struct perf_header *header, 739 static int perf_header__read_build_ids(struct perf_header *header,
740 int input, u64 offset, u64 size) 740 int input, u64 offset, u64 size)
741 { 741 {
742 struct perf_session *session = container_of(header, struct perf_session, header); 742 struct perf_session *session = container_of(header, struct perf_session, header);
743 struct build_id_event bev; 743 struct build_id_event bev;
744 char filename[PATH_MAX]; 744 char filename[PATH_MAX];
745 u64 limit = offset + size, orig_offset = offset; 745 u64 limit = offset + size, orig_offset = offset;
746 int err = -1; 746 int err = -1;
747 747
748 while (offset < limit) { 748 while (offset < limit) {
749 ssize_t len; 749 ssize_t len;
750 750
751 if (read(input, &bev, sizeof(bev)) != sizeof(bev)) 751 if (read(input, &bev, sizeof(bev)) != sizeof(bev))
752 goto out; 752 goto out;
753 753
754 if (header->needs_swap) 754 if (header->needs_swap)
755 perf_event_header__bswap(&bev.header); 755 perf_event_header__bswap(&bev.header);
756 756
757 len = bev.header.size - sizeof(bev); 757 len = bev.header.size - sizeof(bev);
758 if (read(input, filename, len) != len) 758 if (read(input, filename, len) != len)
759 goto out; 759 goto out;
760 /* 760 /*
761 * The a1645ce1 changeset: 761 * The a1645ce1 changeset:
762 * 762 *
763 * "perf: 'perf kvm' tool for monitoring guest performance from host" 763 * "perf: 'perf kvm' tool for monitoring guest performance from host"
764 * 764 *
765 * Added a field to struct build_id_event that broke the file 765 * Added a field to struct build_id_event that broke the file
766 * format. 766 * format.
767 * 767 *
768 * Since the kernel build-id is the first entry, process the 768 * Since the kernel build-id is the first entry, process the
769 * table using the old format if the well known 769 * table using the old format if the well known
770 * '[kernel.kallsyms]' string for the kernel build-id has the 770 * '[kernel.kallsyms]' string for the kernel build-id has the
771 * first 4 characters chopped off (where the pid_t sits). 771 * first 4 characters chopped off (where the pid_t sits).
772 */ 772 */
773 if (memcmp(filename, "nel.kallsyms]", 13) == 0) { 773 if (memcmp(filename, "nel.kallsyms]", 13) == 0) {
774 if (lseek(input, orig_offset, SEEK_SET) == (off_t)-1) 774 if (lseek(input, orig_offset, SEEK_SET) == (off_t)-1)
775 return -1; 775 return -1;
776 return perf_header__read_build_ids_abi_quirk(header, input, offset, size); 776 return perf_header__read_build_ids_abi_quirk(header, input, offset, size);
777 } 777 }
778 778
779 __event_process_build_id(&bev, filename, session); 779 __event_process_build_id(&bev, filename, session);
780 780
781 offset += bev.header.size; 781 offset += bev.header.size;
782 } 782 }
783 err = 0; 783 err = 0;
784 out: 784 out:
785 return err; 785 return err;
786 } 786 }
787 787
788 static int perf_file_section__process(struct perf_file_section *section, 788 static int perf_file_section__process(struct perf_file_section *section,
789 struct perf_header *ph, 789 struct perf_header *ph,
790 int feat, int fd) 790 int feat, int fd)
791 { 791 {
792 if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) { 792 if (lseek(fd, section->offset, SEEK_SET) == (off_t)-1) {
793 pr_debug("Failed to lseek to %" PRIu64 " offset for feature " 793 pr_debug("Failed to lseek to %" PRIu64 " offset for feature "
794 "%d, continuing...\n", section->offset, feat); 794 "%d, continuing...\n", section->offset, feat);
795 return 0; 795 return 0;
796 } 796 }
797 797
798 switch (feat) { 798 switch (feat) {
799 case HEADER_TRACE_INFO: 799 case HEADER_TRACE_INFO:
800 trace_report(fd, false); 800 trace_report(fd, false);
801 break; 801 break;
802 802
803 case HEADER_BUILD_ID: 803 case HEADER_BUILD_ID:
804 if (perf_header__read_build_ids(ph, fd, section->offset, section->size)) 804 if (perf_header__read_build_ids(ph, fd, section->offset, section->size))
805 pr_debug("Failed to read buildids, continuing...\n"); 805 pr_debug("Failed to read buildids, continuing...\n");
806 break; 806 break;
807 default: 807 default:
808 pr_debug("unknown feature %d, continuing...\n", feat); 808 pr_debug("unknown feature %d, continuing...\n", feat);
809 } 809 }
810 810
811 return 0; 811 return 0;
812 } 812 }
813 813
814 static int perf_file_header__read_pipe(struct perf_pipe_file_header *header, 814 static int perf_file_header__read_pipe(struct perf_pipe_file_header *header,
815 struct perf_header *ph, int fd, 815 struct perf_header *ph, int fd,
816 bool repipe) 816 bool repipe)
817 { 817 {
818 if (readn(fd, header, sizeof(*header)) <= 0 || 818 if (readn(fd, header, sizeof(*header)) <= 0 ||
819 memcmp(&header->magic, __perf_magic, sizeof(header->magic))) 819 memcmp(&header->magic, __perf_magic, sizeof(header->magic)))
820 return -1; 820 return -1;
821 821
822 if (repipe && do_write(STDOUT_FILENO, header, sizeof(*header)) < 0) 822 if (repipe && do_write(STDOUT_FILENO, header, sizeof(*header)) < 0)
823 return -1; 823 return -1;
824 824
825 if (header->size != sizeof(*header)) { 825 if (header->size != sizeof(*header)) {
826 u64 size = bswap_64(header->size); 826 u64 size = bswap_64(header->size);
827 827
828 if (size != sizeof(*header)) 828 if (size != sizeof(*header))
829 return -1; 829 return -1;
830 830
831 ph->needs_swap = true; 831 ph->needs_swap = true;
832 } 832 }
833 833
834 return 0; 834 return 0;
835 } 835 }
836 836
837 static int perf_header__read_pipe(struct perf_session *session, int fd) 837 static int perf_header__read_pipe(struct perf_session *session, int fd)
838 { 838 {
839 struct perf_header *header = &session->header; 839 struct perf_header *header = &session->header;
840 struct perf_pipe_file_header f_header; 840 struct perf_pipe_file_header f_header;
841 841
842 if (perf_file_header__read_pipe(&f_header, header, fd, 842 if (perf_file_header__read_pipe(&f_header, header, fd,
843 session->repipe) < 0) { 843 session->repipe) < 0) {
844 pr_debug("incompatible file format\n"); 844 pr_debug("incompatible file format\n");
845 return -EINVAL; 845 return -EINVAL;
846 } 846 }
847 847
848 session->fd = fd; 848 session->fd = fd;
849 849
850 return 0; 850 return 0;
851 } 851 }
852 852
853 int perf_session__read_header(struct perf_session *session, int fd) 853 int perf_session__read_header(struct perf_session *session, int fd)
854 { 854 {
855 struct perf_header *header = &session->header; 855 struct perf_header *header = &session->header;
856 struct perf_file_header f_header; 856 struct perf_file_header f_header;
857 struct perf_file_attr f_attr; 857 struct perf_file_attr f_attr;
858 u64 f_id; 858 u64 f_id;
859 int nr_attrs, nr_ids, i, j; 859 int nr_attrs, nr_ids, i, j;
860 860
861 session->evlist = perf_evlist__new(NULL, NULL); 861 session->evlist = perf_evlist__new(NULL, NULL);
862 if (session->evlist == NULL) 862 if (session->evlist == NULL)
863 return -ENOMEM; 863 return -ENOMEM;
864 864
865 if (session->fd_pipe) 865 if (session->fd_pipe)
866 return perf_header__read_pipe(session, fd); 866 return perf_header__read_pipe(session, fd);
867 867
868 if (perf_file_header__read(&f_header, header, fd) < 0) { 868 if (perf_file_header__read(&f_header, header, fd) < 0) {
869 pr_debug("incompatible file format\n"); 869 pr_debug("incompatible file format\n");
870 return -EINVAL; 870 return -EINVAL;
871 } 871 }
872 872
873 nr_attrs = f_header.attrs.size / sizeof(f_attr); 873 nr_attrs = f_header.attrs.size / sizeof(f_attr);
874 lseek(fd, f_header.attrs.offset, SEEK_SET); 874 lseek(fd, f_header.attrs.offset, SEEK_SET);
875 875
876 for (i = 0; i < nr_attrs; i++) { 876 for (i = 0; i < nr_attrs; i++) {
877 struct perf_evsel *evsel; 877 struct perf_evsel *evsel;
878 off_t tmp; 878 off_t tmp;
879 879
880 if (readn(fd, &f_attr, sizeof(f_attr)) <= 0) 880 if (readn(fd, &f_attr, sizeof(f_attr)) <= 0)
881 goto out_errno; 881 goto out_errno;
882 882
883 if (header->needs_swap) 883 if (header->needs_swap)
884 perf_event__attr_swap(&f_attr.attr); 884 perf_event__attr_swap(&f_attr.attr);
885 885
886 tmp = lseek(fd, 0, SEEK_CUR); 886 tmp = lseek(fd, 0, SEEK_CUR);
887 evsel = perf_evsel__new(&f_attr.attr, i); 887 evsel = perf_evsel__new(&f_attr.attr, i);
888 888
889 if (evsel == NULL) 889 if (evsel == NULL)
890 goto out_delete_evlist; 890 goto out_delete_evlist;
891 /* 891 /*
892 * Do it before so that if perf_evsel__alloc_id fails, this 892 * Do it before so that if perf_evsel__alloc_id fails, this
893 * entry gets purged too at perf_evlist__delete(). 893 * entry gets purged too at perf_evlist__delete().
894 */ 894 */
895 perf_evlist__add(session->evlist, evsel); 895 perf_evlist__add(session->evlist, evsel);
896 896
897 nr_ids = f_attr.ids.size / sizeof(u64); 897 nr_ids = f_attr.ids.size / sizeof(u64);
898 /* 898 /*
899 * We don't have the cpu and thread maps on the header, so 899 * We don't have the cpu and thread maps on the header, so
900 * for allocating the perf_sample_id table we fake 1 cpu and 900 * for allocating the perf_sample_id table we fake 1 cpu and
901 * hattr->ids threads. 901 * hattr->ids threads.
902 */ 902 */
903 if (perf_evsel__alloc_id(evsel, 1, nr_ids)) 903 if (perf_evsel__alloc_id(evsel, 1, nr_ids))
904 goto out_delete_evlist; 904 goto out_delete_evlist;
905 905
906 lseek(fd, f_attr.ids.offset, SEEK_SET); 906 lseek(fd, f_attr.ids.offset, SEEK_SET);
907 907
908 for (j = 0; j < nr_ids; j++) { 908 for (j = 0; j < nr_ids; j++) {
909 if (perf_header__getbuffer64(header, fd, &f_id, sizeof(f_id))) 909 if (perf_header__getbuffer64(header, fd, &f_id, sizeof(f_id)))
910 goto out_errno; 910 goto out_errno;
911 911
912 perf_evlist__id_add(session->evlist, evsel, 0, j, f_id); 912 perf_evlist__id_add(session->evlist, evsel, 0, j, f_id);
913 } 913 }
914 914
915 lseek(fd, tmp, SEEK_SET); 915 lseek(fd, tmp, SEEK_SET);
916 } 916 }
917 917
918 if (f_header.event_types.size) { 918 if (f_header.event_types.size) {
919 lseek(fd, f_header.event_types.offset, SEEK_SET); 919 lseek(fd, f_header.event_types.offset, SEEK_SET);
920 events = malloc(f_header.event_types.size); 920 events = malloc(f_header.event_types.size);
921 if (events == NULL) 921 if (events == NULL)
922 return -ENOMEM; 922 return -ENOMEM;
923 if (perf_header__getbuffer64(header, fd, events, 923 if (perf_header__getbuffer64(header, fd, events,
924 f_header.event_types.size)) 924 f_header.event_types.size))
925 goto out_errno; 925 goto out_errno;
926 event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type); 926 event_count = f_header.event_types.size / sizeof(struct perf_trace_event_type);
927 } 927 }
928 928
929 perf_header__process_sections(header, fd, perf_file_section__process); 929 perf_header__process_sections(header, fd, perf_file_section__process);
930 930
931 lseek(fd, header->data_offset, SEEK_SET); 931 lseek(fd, header->data_offset, SEEK_SET);
932 932
933 header->frozen = 1; 933 header->frozen = 1;
934 return 0; 934 return 0;
935 out_errno: 935 out_errno:
936 return -errno; 936 return -errno;
937 937
938 out_delete_evlist: 938 out_delete_evlist:
939 perf_evlist__delete(session->evlist); 939 perf_evlist__delete(session->evlist);
940 session->evlist = NULL; 940 session->evlist = NULL;
941 return -ENOMEM; 941 return -ENOMEM;
942 } 942 }
943 943
944 int perf_event__synthesize_attr(struct perf_event_attr *attr, u16 ids, u64 *id, 944 int perf_event__synthesize_attr(struct perf_event_attr *attr, u16 ids, u64 *id,
945 perf_event__handler_t process, 945 perf_event__handler_t process,
946 struct perf_session *session) 946 struct perf_session *session)
947 { 947 {
948 union perf_event *ev; 948 union perf_event *ev;
949 size_t size; 949 size_t size;
950 int err; 950 int err;
951 951
952 size = sizeof(struct perf_event_attr); 952 size = sizeof(struct perf_event_attr);
953 size = ALIGN(size, sizeof(u64)); 953 size = ALIGN(size, sizeof(u64));
954 size += sizeof(struct perf_event_header); 954 size += sizeof(struct perf_event_header);
955 size += ids * sizeof(u64); 955 size += ids * sizeof(u64);
956 956
957 ev = malloc(size); 957 ev = malloc(size);
958 958
959 if (ev == NULL) 959 if (ev == NULL)
960 return -ENOMEM; 960 return -ENOMEM;
961 961
962 ev->attr.attr = *attr; 962 ev->attr.attr = *attr;
963 memcpy(ev->attr.id, id, ids * sizeof(u64)); 963 memcpy(ev->attr.id, id, ids * sizeof(u64));
964 964
965 ev->attr.header.type = PERF_RECORD_HEADER_ATTR; 965 ev->attr.header.type = PERF_RECORD_HEADER_ATTR;
966 ev->attr.header.size = size; 966 ev->attr.header.size = size;
967 967
968 err = process(ev, NULL, session); 968 err = process(ev, NULL, session);
969 969
970 free(ev); 970 free(ev);
971 971
972 return err; 972 return err;
973 } 973 }
974 974
975 int perf_session__synthesize_attrs(struct perf_session *session, 975 int perf_session__synthesize_attrs(struct perf_session *session,
976 perf_event__handler_t process) 976 perf_event__handler_t process)
977 { 977 {
978 struct perf_evsel *attr; 978 struct perf_evsel *attr;
979 int err = 0; 979 int err = 0;
980 980
981 list_for_each_entry(attr, &session->evlist->entries, node) { 981 list_for_each_entry(attr, &session->evlist->entries, node) {
982 err = perf_event__synthesize_attr(&attr->attr, attr->ids, 982 err = perf_event__synthesize_attr(&attr->attr, attr->ids,
983 attr->id, process, session); 983 attr->id, process, session);
984 if (err) { 984 if (err) {
985 pr_debug("failed to create perf header attribute\n"); 985 pr_debug("failed to create perf header attribute\n");
986 return err; 986 return err;
987 } 987 }
988 } 988 }
989 989
990 return err; 990 return err;
991 } 991 }
992 992
993 int perf_event__process_attr(union perf_event *event, 993 int perf_event__process_attr(union perf_event *event,
994 struct perf_session *session) 994 struct perf_session *session)
995 { 995 {
996 unsigned int i, ids, n_ids; 996 unsigned int i, ids, n_ids;
997 struct perf_evsel *evsel; 997 struct perf_evsel *evsel;
998 998
999 if (session->evlist == NULL) { 999 if (session->evlist == NULL) {
1000 session->evlist = perf_evlist__new(NULL, NULL); 1000 session->evlist = perf_evlist__new(NULL, NULL);
1001 if (session->evlist == NULL) 1001 if (session->evlist == NULL)
1002 return -ENOMEM; 1002 return -ENOMEM;
1003 } 1003 }
1004 1004
1005 evsel = perf_evsel__new(&event->attr.attr, 1005 evsel = perf_evsel__new(&event->attr.attr,
1006 session->evlist->nr_entries); 1006 session->evlist->nr_entries);
1007 if (evsel == NULL) 1007 if (evsel == NULL)
1008 return -ENOMEM; 1008 return -ENOMEM;
1009 1009
1010 perf_evlist__add(session->evlist, evsel); 1010 perf_evlist__add(session->evlist, evsel);
1011 1011
1012 ids = event->header.size; 1012 ids = event->header.size;
1013 ids -= (void *)&event->attr.id - (void *)event; 1013 ids -= (void *)&event->attr.id - (void *)event;
1014 n_ids = ids / sizeof(u64); 1014 n_ids = ids / sizeof(u64);
1015 /* 1015 /*
1016 * We don't have the cpu and thread maps on the header, so 1016 * We don't have the cpu and thread maps on the header, so
1017 * for allocating the perf_sample_id table we fake 1 cpu and 1017 * for allocating the perf_sample_id table we fake 1 cpu and
1018 * hattr->ids threads. 1018 * hattr->ids threads.
1019 */ 1019 */
1020 if (perf_evsel__alloc_id(evsel, 1, n_ids)) 1020 if (perf_evsel__alloc_id(evsel, 1, n_ids))
1021 return -ENOMEM; 1021 return -ENOMEM;
1022 1022
1023 for (i = 0; i < n_ids; i++) { 1023 for (i = 0; i < n_ids; i++) {
1024 perf_evlist__id_add(session->evlist, evsel, 0, i, 1024 perf_evlist__id_add(session->evlist, evsel, 0, i,
1025 event->attr.id[i]); 1025 event->attr.id[i]);
1026 } 1026 }
1027 1027
1028 perf_session__update_sample_type(session); 1028 perf_session__update_sample_type(session);
1029 1029
1030 return 0; 1030 return 0;
1031 } 1031 }
1032 1032
1033 int perf_event__synthesize_event_type(u64 event_id, char *name, 1033 int perf_event__synthesize_event_type(u64 event_id, char *name,
1034 perf_event__handler_t process, 1034 perf_event__handler_t process,
1035 struct perf_session *session) 1035 struct perf_session *session)
1036 { 1036 {
1037 union perf_event ev; 1037 union perf_event ev;
1038 size_t size = 0; 1038 size_t size = 0;
1039 int err = 0; 1039 int err = 0;
1040 1040
1041 memset(&ev, 0, sizeof(ev)); 1041 memset(&ev, 0, sizeof(ev));
1042 1042
1043 ev.event_type.event_type.event_id = event_id; 1043 ev.event_type.event_type.event_id = event_id;
1044 memset(ev.event_type.event_type.name, 0, MAX_EVENT_NAME); 1044 memset(ev.event_type.event_type.name, 0, MAX_EVENT_NAME);
1045 strncpy(ev.event_type.event_type.name, name, MAX_EVENT_NAME - 1); 1045 strncpy(ev.event_type.event_type.name, name, MAX_EVENT_NAME - 1);
1046 1046
1047 ev.event_type.header.type = PERF_RECORD_HEADER_EVENT_TYPE; 1047 ev.event_type.header.type = PERF_RECORD_HEADER_EVENT_TYPE;
1048 size = strlen(name); 1048 size = strlen(name);
1049 size = ALIGN(size, sizeof(u64)); 1049 size = ALIGN(size, sizeof(u64));
1050 ev.event_type.header.size = sizeof(ev.event_type) - 1050 ev.event_type.header.size = sizeof(ev.event_type) -
1051 (sizeof(ev.event_type.event_type.name) - size); 1051 (sizeof(ev.event_type.event_type.name) - size);
1052 1052
1053 err = process(&ev, NULL, session); 1053 err = process(&ev, NULL, session);
1054 1054
1055 return err; 1055 return err;
1056 } 1056 }
1057 1057
1058 int perf_event__synthesize_event_types(perf_event__handler_t process, 1058 int perf_event__synthesize_event_types(perf_event__handler_t process,
1059 struct perf_session *session) 1059 struct perf_session *session)
1060 { 1060 {
1061 struct perf_trace_event_type *type; 1061 struct perf_trace_event_type *type;
1062 int i, err = 0; 1062 int i, err = 0;
1063 1063
1064 for (i = 0; i < event_count; i++) { 1064 for (i = 0; i < event_count; i++) {
1065 type = &events[i]; 1065 type = &events[i];
1066 1066
1067 err = perf_event__synthesize_event_type(type->event_id, 1067 err = perf_event__synthesize_event_type(type->event_id,
1068 type->name, process, 1068 type->name, process,
1069 session); 1069 session);
1070 if (err) { 1070 if (err) {
1071 pr_debug("failed to create perf header event type\n"); 1071 pr_debug("failed to create perf header event type\n");
1072 return err; 1072 return err;
1073 } 1073 }
1074 } 1074 }
1075 1075
1076 return err; 1076 return err;
1077 } 1077 }
1078 1078
1079 int perf_event__process_event_type(union perf_event *event, 1079 int perf_event__process_event_type(union perf_event *event,
1080 struct perf_session *session __unused) 1080 struct perf_session *session __unused)
1081 { 1081 {
1082 if (perf_header__push_event(event->event_type.event_type.event_id, 1082 if (perf_header__push_event(event->event_type.event_type.event_id,
1083 event->event_type.event_type.name) < 0) 1083 event->event_type.event_type.name) < 0)
1084 return -ENOMEM; 1084 return -ENOMEM;
1085 1085
1086 return 0; 1086 return 0;
1087 } 1087 }
1088 1088
1089 int perf_event__synthesize_tracing_data(int fd, struct perf_evlist *evlist, 1089 int perf_event__synthesize_tracing_data(int fd, struct perf_evlist *evlist,
1090 perf_event__handler_t process, 1090 perf_event__handler_t process,
1091 struct perf_session *session __unused) 1091 struct perf_session *session __unused)
1092 { 1092 {
1093 union perf_event ev; 1093 union perf_event ev;
1094 ssize_t size = 0, aligned_size = 0, padding; 1094 ssize_t size = 0, aligned_size = 0, padding;
1095 int err __used = 0; 1095 int err __used = 0;
1096 1096
1097 memset(&ev, 0, sizeof(ev)); 1097 memset(&ev, 0, sizeof(ev));
1098 1098
1099 ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA; 1099 ev.tracing_data.header.type = PERF_RECORD_HEADER_TRACING_DATA;
1100 size = read_tracing_data_size(fd, &evlist->entries); 1100 size = read_tracing_data_size(fd, &evlist->entries);
1101 if (size <= 0) 1101 if (size <= 0)
1102 return size; 1102 return size;
1103 aligned_size = ALIGN(size, sizeof(u64)); 1103 aligned_size = ALIGN(size, sizeof(u64));
1104 padding = aligned_size - size; 1104 padding = aligned_size - size;
1105 ev.tracing_data.header.size = sizeof(ev.tracing_data); 1105 ev.tracing_data.header.size = sizeof(ev.tracing_data);
1106 ev.tracing_data.size = aligned_size; 1106 ev.tracing_data.size = aligned_size;
1107 1107
1108 process(&ev, NULL, session); 1108 process(&ev, NULL, session);
1109 1109
1110 err = read_tracing_data(fd, &evlist->entries); 1110 err = read_tracing_data(fd, &evlist->entries);
1111 write_padded(fd, NULL, 0, padding); 1111 write_padded(fd, NULL, 0, padding);
1112 1112
1113 return aligned_size; 1113 return aligned_size;
1114 } 1114 }
1115 1115
1116 int perf_event__process_tracing_data(union perf_event *event, 1116 int perf_event__process_tracing_data(union perf_event *event,
1117 struct perf_session *session) 1117 struct perf_session *session)
1118 { 1118 {
1119 ssize_t size_read, padding, size = event->tracing_data.size; 1119 ssize_t size_read, padding, size = event->tracing_data.size;
1120 off_t offset = lseek(session->fd, 0, SEEK_CUR); 1120 off_t offset = lseek(session->fd, 0, SEEK_CUR);
1121 char buf[BUFSIZ]; 1121 char buf[BUFSIZ];
1122 1122
1123 /* setup for reading amidst mmap */ 1123 /* setup for reading amidst mmap */
1124 lseek(session->fd, offset + sizeof(struct tracing_data_event), 1124 lseek(session->fd, offset + sizeof(struct tracing_data_event),
1125 SEEK_SET); 1125 SEEK_SET);
1126 1126
1127 size_read = trace_report(session->fd, session->repipe); 1127 size_read = trace_report(session->fd, session->repipe);
1128 1128
1129 padding = ALIGN(size_read, sizeof(u64)) - size_read; 1129 padding = ALIGN(size_read, sizeof(u64)) - size_read;
1130 1130
1131 if (read(session->fd, buf, padding) < 0) 1131 if (read(session->fd, buf, padding) < 0)
1132 die("reading input file"); 1132 die("reading input file");
1133 if (session->repipe) { 1133 if (session->repipe) {
1134 int retw = write(STDOUT_FILENO, buf, padding); 1134 int retw = write(STDOUT_FILENO, buf, padding);
1135 if (retw <= 0 || retw != padding) 1135 if (retw <= 0 || retw != padding)
1136 die("repiping tracing data padding"); 1136 die("repiping tracing data padding");
1137 } 1137 }
1138 1138
1139 if (size_read + padding != size) 1139 if (size_read + padding != size)
1140 die("tracing data size mismatch"); 1140 die("tracing data size mismatch");
1141 1141
1142 return size_read + padding; 1142 return size_read + padding;
1143 } 1143 }
1144 1144
1145 int perf_event__synthesize_build_id(struct dso *pos, u16 misc, 1145 int perf_event__synthesize_build_id(struct dso *pos, u16 misc,
1146 perf_event__handler_t process, 1146 perf_event__handler_t process,
1147 struct machine *machine, 1147 struct machine *machine,
1148 struct perf_session *session) 1148 struct perf_session *session)
1149 { 1149 {
1150 union perf_event ev; 1150 union perf_event ev;
1151 size_t len; 1151 size_t len;
1152 int err = 0; 1152 int err = 0;
1153 1153
1154 if (!pos->hit) 1154 if (!pos->hit)
1155 return err; 1155 return err;
1156 1156
1157 memset(&ev, 0, sizeof(ev)); 1157 memset(&ev, 0, sizeof(ev));
1158 1158
1159 len = pos->long_name_len + 1; 1159 len = pos->long_name_len + 1;
1160 len = ALIGN(len, NAME_ALIGN); 1160 len = ALIGN(len, NAME_ALIGN);
1161 memcpy(&ev.build_id.build_id, pos->build_id, sizeof(pos->build_id)); 1161 memcpy(&ev.build_id.build_id, pos->build_id, sizeof(pos->build_id));
1162 ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID; 1162 ev.build_id.header.type = PERF_RECORD_HEADER_BUILD_ID;
1163 ev.build_id.header.misc = misc; 1163 ev.build_id.header.misc = misc;
1164 ev.build_id.pid = machine->pid; 1164 ev.build_id.pid = machine->pid;
1165 ev.build_id.header.size = sizeof(ev.build_id) + len; 1165 ev.build_id.header.size = sizeof(ev.build_id) + len;
1166 memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len); 1166 memcpy(&ev.build_id.filename, pos->long_name, pos->long_name_len);
1167 1167
1168 err = process(&ev, NULL, session); 1168 err = process(&ev, NULL, session);
1169 1169
1170 return err; 1170 return err;
1171 } 1171 }
1172 1172
1173 int perf_event__process_build_id(union perf_event *event, 1173 int perf_event__process_build_id(union perf_event *event,
1174 struct perf_session *session) 1174 struct perf_session *session)
1175 { 1175 {
1176 __event_process_build_id(&event->build_id, 1176 __event_process_build_id(&event->build_id,
1177 event->build_id.filename, 1177 event->build_id.filename,
1178 session); 1178 session);
1179 return 0; 1179 return 0;
1180 } 1180 }
1181 1181
1182 void disable_buildid_cache(void) 1182 void disable_buildid_cache(void)
1183 { 1183 {
1184 no_buildid_cache = true; 1184 no_buildid_cache = true;
1185 } 1185 }
1186 1186
tools/perf/util/probe-event.c
1 /* 1 /*
2 * probe-event.c : perf-probe definition to probe_events format converter 2 * probe-event.c : perf-probe definition to probe_events format converter
3 * 3 *
4 * Written by Masami Hiramatsu <mhiramat@redhat.com> 4 * Written by Masami Hiramatsu <mhiramat@redhat.com>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by 7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or 8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version. 9 * (at your option) any later version.
10 * 10 *
11 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details. 14 * GNU General Public License for more details.
15 * 15 *
16 * You should have received a copy of the GNU General Public License 16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 * 19 *
20 */ 20 */
21 21
22 #define _GNU_SOURCE 22 #define _GNU_SOURCE
23 #include <sys/utsname.h> 23 #include <sys/utsname.h>
24 #include <sys/types.h> 24 #include <sys/types.h>
25 #include <sys/stat.h> 25 #include <sys/stat.h>
26 #include <fcntl.h> 26 #include <fcntl.h>
27 #include <errno.h> 27 #include <errno.h>
28 #include <stdio.h> 28 #include <stdio.h>
29 #include <unistd.h> 29 #include <unistd.h>
30 #include <stdlib.h> 30 #include <stdlib.h>
31 #include <string.h> 31 #include <string.h>
32 #include <stdarg.h> 32 #include <stdarg.h>
33 #include <limits.h> 33 #include <limits.h>
34 #include <elf.h> 34 #include <elf.h>
35 35
36 #undef _GNU_SOURCE 36 #undef _GNU_SOURCE
37 #include "util.h" 37 #include "util.h"
38 #include "event.h" 38 #include "event.h"
39 #include "string.h" 39 #include "string.h"
40 #include "strlist.h" 40 #include "strlist.h"
41 #include "debug.h" 41 #include "debug.h"
42 #include "cache.h" 42 #include "cache.h"
43 #include "color.h" 43 #include "color.h"
44 #include "symbol.h" 44 #include "symbol.h"
45 #include "thread.h" 45 #include "thread.h"
46 #include "debugfs.h" 46 #include "debugfs.h"
47 #include "trace-event.h" /* For __unused */ 47 #include "trace-event.h" /* For __unused */
48 #include "probe-event.h" 48 #include "probe-event.h"
49 #include "probe-finder.h" 49 #include "probe-finder.h"
50 50
51 #define MAX_CMDLEN 256 51 #define MAX_CMDLEN 256
52 #define MAX_PROBE_ARGS 128 52 #define MAX_PROBE_ARGS 128
53 #define PERFPROBE_GROUP "probe" 53 #define PERFPROBE_GROUP "probe"
54 54
55 bool probe_event_dry_run; /* Dry run flag */ 55 bool probe_event_dry_run; /* Dry run flag */
56 56
57 #define semantic_error(msg ...) pr_err("Semantic error :" msg) 57 #define semantic_error(msg ...) pr_err("Semantic error :" msg)
58 58
59 /* If there is no space to write, returns -E2BIG. */ 59 /* If there is no space to write, returns -E2BIG. */
60 static int e_snprintf(char *str, size_t size, const char *format, ...) 60 static int e_snprintf(char *str, size_t size, const char *format, ...)
61 __attribute__((format(printf, 3, 4))); 61 __attribute__((format(printf, 3, 4)));
62 62
63 static int e_snprintf(char *str, size_t size, const char *format, ...) 63 static int e_snprintf(char *str, size_t size, const char *format, ...)
64 { 64 {
65 int ret; 65 int ret;
66 va_list ap; 66 va_list ap;
67 va_start(ap, format); 67 va_start(ap, format);
68 ret = vsnprintf(str, size, format, ap); 68 ret = vsnprintf(str, size, format, ap);
69 va_end(ap); 69 va_end(ap);
70 if (ret >= (int)size) 70 if (ret >= (int)size)
71 ret = -E2BIG; 71 ret = -E2BIG;
72 return ret; 72 return ret;
73 } 73 }
74 74
75 static char *synthesize_perf_probe_point(struct perf_probe_point *pp); 75 static char *synthesize_perf_probe_point(struct perf_probe_point *pp);
76 static struct machine machine; 76 static struct machine machine;
77 77
78 /* Initialize symbol maps and path of vmlinux/modules */ 78 /* Initialize symbol maps and path of vmlinux/modules */
79 static int init_vmlinux(void) 79 static int init_vmlinux(void)
80 { 80 {
81 int ret; 81 int ret;
82 82
83 symbol_conf.sort_by_name = true; 83 symbol_conf.sort_by_name = true;
84 if (symbol_conf.vmlinux_name == NULL) 84 if (symbol_conf.vmlinux_name == NULL)
85 symbol_conf.try_vmlinux_path = true; 85 symbol_conf.try_vmlinux_path = true;
86 else 86 else
87 pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name); 87 pr_debug("Use vmlinux: %s\n", symbol_conf.vmlinux_name);
88 ret = symbol__init(); 88 ret = symbol__init();
89 if (ret < 0) { 89 if (ret < 0) {
90 pr_debug("Failed to init symbol map.\n"); 90 pr_debug("Failed to init symbol map.\n");
91 goto out; 91 goto out;
92 } 92 }
93 93
94 ret = machine__init(&machine, "", HOST_KERNEL_ID); 94 ret = machine__init(&machine, "", HOST_KERNEL_ID);
95 if (ret < 0) 95 if (ret < 0)
96 goto out; 96 goto out;
97 97
98 if (machine__create_kernel_maps(&machine) < 0) { 98 if (machine__create_kernel_maps(&machine) < 0) {
99 pr_debug("machine__create_kernel_maps() failed.\n"); 99 pr_debug("machine__create_kernel_maps() failed.\n");
100 goto out; 100 goto out;
101 } 101 }
102 out: 102 out:
103 if (ret < 0) 103 if (ret < 0)
104 pr_warning("Failed to init vmlinux path.\n"); 104 pr_warning("Failed to init vmlinux path.\n");
105 return ret; 105 return ret;
106 } 106 }
107 107
108 static struct symbol *__find_kernel_function_by_name(const char *name, 108 static struct symbol *__find_kernel_function_by_name(const char *name,
109 struct map **mapp) 109 struct map **mapp)
110 { 110 {
111 return machine__find_kernel_function_by_name(&machine, name, mapp, 111 return machine__find_kernel_function_by_name(&machine, name, mapp,
112 NULL); 112 NULL);
113 } 113 }
114 114
115 static struct map *kernel_get_module_map(const char *module) 115 static struct map *kernel_get_module_map(const char *module)
116 { 116 {
117 struct rb_node *nd; 117 struct rb_node *nd;
118 struct map_groups *grp = &machine.kmaps; 118 struct map_groups *grp = &machine.kmaps;
119 119
120 /* A file path -- this is an offline module */ 120 /* A file path -- this is an offline module */
121 if (module && strchr(module, '/')) 121 if (module && strchr(module, '/'))
122 return machine__new_module(&machine, 0, module); 122 return machine__new_module(&machine, 0, module);
123 123
124 if (!module) 124 if (!module)
125 module = "kernel"; 125 module = "kernel";
126 126
127 for (nd = rb_first(&grp->maps[MAP__FUNCTION]); nd; nd = rb_next(nd)) { 127 for (nd = rb_first(&grp->maps[MAP__FUNCTION]); nd; nd = rb_next(nd)) {
128 struct map *pos = rb_entry(nd, struct map, rb_node); 128 struct map *pos = rb_entry(nd, struct map, rb_node);
129 if (strncmp(pos->dso->short_name + 1, module, 129 if (strncmp(pos->dso->short_name + 1, module,
130 pos->dso->short_name_len - 2) == 0) { 130 pos->dso->short_name_len - 2) == 0) {
131 return pos; 131 return pos;
132 } 132 }
133 } 133 }
134 return NULL; 134 return NULL;
135 } 135 }
136 136
137 static struct dso *kernel_get_module_dso(const char *module) 137 static struct dso *kernel_get_module_dso(const char *module)
138 { 138 {
139 struct dso *dso; 139 struct dso *dso;
140 struct map *map; 140 struct map *map;
141 const char *vmlinux_name; 141 const char *vmlinux_name;
142 142
143 if (module) { 143 if (module) {
144 list_for_each_entry(dso, &machine.kernel_dsos, node) { 144 list_for_each_entry(dso, &machine.kernel_dsos, node) {
145 if (strncmp(dso->short_name + 1, module, 145 if (strncmp(dso->short_name + 1, module,
146 dso->short_name_len - 2) == 0) 146 dso->short_name_len - 2) == 0)
147 goto found; 147 goto found;
148 } 148 }
149 pr_debug("Failed to find module %s.\n", module); 149 pr_debug("Failed to find module %s.\n", module);
150 return NULL; 150 return NULL;
151 } 151 }
152 152
153 map = machine.vmlinux_maps[MAP__FUNCTION]; 153 map = machine.vmlinux_maps[MAP__FUNCTION];
154 dso = map->dso; 154 dso = map->dso;
155 155
156 vmlinux_name = symbol_conf.vmlinux_name; 156 vmlinux_name = symbol_conf.vmlinux_name;
157 if (vmlinux_name) { 157 if (vmlinux_name) {
158 if (dso__load_vmlinux(dso, map, vmlinux_name, NULL) <= 0) 158 if (dso__load_vmlinux(dso, map, vmlinux_name, NULL) <= 0)
159 return NULL; 159 return NULL;
160 } else { 160 } else {
161 if (dso__load_vmlinux_path(dso, map, NULL) <= 0) { 161 if (dso__load_vmlinux_path(dso, map, NULL) <= 0) {
162 pr_debug("Failed to load kernel map.\n"); 162 pr_debug("Failed to load kernel map.\n");
163 return NULL; 163 return NULL;
164 } 164 }
165 } 165 }
166 found: 166 found:
167 return dso; 167 return dso;
168 } 168 }
169 169
170 const char *kernel_get_module_path(const char *module) 170 const char *kernel_get_module_path(const char *module)
171 { 171 {
172 struct dso *dso = kernel_get_module_dso(module); 172 struct dso *dso = kernel_get_module_dso(module);
173 return (dso) ? dso->long_name : NULL; 173 return (dso) ? dso->long_name : NULL;
174 } 174 }
175 175
176 #ifdef DWARF_SUPPORT 176 #ifdef DWARF_SUPPORT
177 /* Open new debuginfo of given module */ 177 /* Open new debuginfo of given module */
178 static struct debuginfo *open_debuginfo(const char *module) 178 static struct debuginfo *open_debuginfo(const char *module)
179 { 179 {
180 const char *path; 180 const char *path;
181 181
182 /* A file path -- this is an offline module */ 182 /* A file path -- this is an offline module */
183 if (module && strchr(module, '/')) 183 if (module && strchr(module, '/'))
184 path = module; 184 path = module;
185 else { 185 else {
186 path = kernel_get_module_path(module); 186 path = kernel_get_module_path(module);
187 187
188 if (!path) { 188 if (!path) {
189 pr_err("Failed to find path of %s module.\n", 189 pr_err("Failed to find path of %s module.\n",
190 module ?: "kernel"); 190 module ?: "kernel");
191 return NULL; 191 return NULL;
192 } 192 }
193 } 193 }
194 return debuginfo__new(path); 194 return debuginfo__new(path);
195 } 195 }
196 196
197 /* 197 /*
198 * Convert trace point to probe point with debuginfo 198 * Convert trace point to probe point with debuginfo
199 * Currently only handles kprobes. 199 * Currently only handles kprobes.
200 */ 200 */
201 static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp, 201 static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
202 struct perf_probe_point *pp) 202 struct perf_probe_point *pp)
203 { 203 {
204 struct symbol *sym; 204 struct symbol *sym;
205 struct map *map; 205 struct map *map;
206 u64 addr; 206 u64 addr;
207 int ret = -ENOENT; 207 int ret = -ENOENT;
208 struct debuginfo *dinfo; 208 struct debuginfo *dinfo;
209 209
210 sym = __find_kernel_function_by_name(tp->symbol, &map); 210 sym = __find_kernel_function_by_name(tp->symbol, &map);
211 if (sym) { 211 if (sym) {
212 addr = map->unmap_ip(map, sym->start + tp->offset); 212 addr = map->unmap_ip(map, sym->start + tp->offset);
213 pr_debug("try to find %s+%ld@%" PRIx64 "\n", tp->symbol, 213 pr_debug("try to find %s+%ld@%" PRIx64 "\n", tp->symbol,
214 tp->offset, addr); 214 tp->offset, addr);
215 215
216 dinfo = debuginfo__new_online_kernel(addr); 216 dinfo = debuginfo__new_online_kernel(addr);
217 if (dinfo) { 217 if (dinfo) {
218 ret = debuginfo__find_probe_point(dinfo, 218 ret = debuginfo__find_probe_point(dinfo,
219 (unsigned long)addr, pp); 219 (unsigned long)addr, pp);
220 debuginfo__delete(dinfo); 220 debuginfo__delete(dinfo);
221 } else { 221 } else {
222 pr_debug("Failed to open debuginfo at 0x%" PRIx64 "\n", 222 pr_debug("Failed to open debuginfo at 0x%" PRIx64 "\n",
223 addr); 223 addr);
224 ret = -ENOENT; 224 ret = -ENOENT;
225 } 225 }
226 } 226 }
227 if (ret <= 0) { 227 if (ret <= 0) {
228 pr_debug("Failed to find corresponding probes from " 228 pr_debug("Failed to find corresponding probes from "
229 "debuginfo. Use kprobe event information.\n"); 229 "debuginfo. Use kprobe event information.\n");
230 pp->function = strdup(tp->symbol); 230 pp->function = strdup(tp->symbol);
231 if (pp->function == NULL) 231 if (pp->function == NULL)
232 return -ENOMEM; 232 return -ENOMEM;
233 pp->offset = tp->offset; 233 pp->offset = tp->offset;
234 } 234 }
235 pp->retprobe = tp->retprobe; 235 pp->retprobe = tp->retprobe;
236 236
237 return 0; 237 return 0;
238 } 238 }
239 239
240 static int add_module_to_probe_trace_events(struct probe_trace_event *tevs, 240 static int add_module_to_probe_trace_events(struct probe_trace_event *tevs,
241 int ntevs, const char *module) 241 int ntevs, const char *module)
242 { 242 {
243 int i, ret = 0; 243 int i, ret = 0;
244 char *tmp; 244 char *tmp;
245 245
246 if (!module) 246 if (!module)
247 return 0; 247 return 0;
248 248
249 tmp = strrchr(module, '/'); 249 tmp = strrchr(module, '/');
250 if (tmp) { 250 if (tmp) {
251 /* This is a module path -- get the module name */ 251 /* This is a module path -- get the module name */
252 module = strdup(tmp + 1); 252 module = strdup(tmp + 1);
253 if (!module) 253 if (!module)
254 return -ENOMEM; 254 return -ENOMEM;
255 tmp = strchr(module, '.'); 255 tmp = strchr(module, '.');
256 if (tmp) 256 if (tmp)
257 *tmp = '\0'; 257 *tmp = '\0';
258 tmp = (char *)module; /* For free() */ 258 tmp = (char *)module; /* For free() */
259 } 259 }
260 260
261 for (i = 0; i < ntevs; i++) { 261 for (i = 0; i < ntevs; i++) {
262 tevs[i].point.module = strdup(module); 262 tevs[i].point.module = strdup(module);
263 if (!tevs[i].point.module) { 263 if (!tevs[i].point.module) {
264 ret = -ENOMEM; 264 ret = -ENOMEM;
265 break; 265 break;
266 } 266 }
267 } 267 }
268 268
269 if (tmp) 269 if (tmp)
270 free(tmp); 270 free(tmp);
271 271
272 return ret; 272 return ret;
273 } 273 }
274 274
275 /* Try to find perf_probe_event with debuginfo */ 275 /* Try to find perf_probe_event with debuginfo */
276 static int try_to_find_probe_trace_events(struct perf_probe_event *pev, 276 static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
277 struct probe_trace_event **tevs, 277 struct probe_trace_event **tevs,
278 int max_tevs, const char *module) 278 int max_tevs, const char *module)
279 { 279 {
280 bool need_dwarf = perf_probe_event_need_dwarf(pev); 280 bool need_dwarf = perf_probe_event_need_dwarf(pev);
281 struct debuginfo *dinfo = open_debuginfo(module); 281 struct debuginfo *dinfo = open_debuginfo(module);
282 int ntevs, ret = 0; 282 int ntevs, ret = 0;
283 283
284 if (!dinfo) { 284 if (!dinfo) {
285 if (need_dwarf) { 285 if (need_dwarf) {
286 pr_warning("Failed to open debuginfo file.\n"); 286 pr_warning("Failed to open debuginfo file.\n");
287 return -ENOENT; 287 return -ENOENT;
288 } 288 }
289 pr_debug("Could not open debuginfo. Try to use symbols.\n"); 289 pr_debug("Could not open debuginfo. Try to use symbols.\n");
290 return 0; 290 return 0;
291 } 291 }
292 292
293 /* Searching trace events corresponding to a probe event */ 293 /* Searching trace events corresponding to a probe event */
294 ntevs = debuginfo__find_trace_events(dinfo, pev, tevs, max_tevs); 294 ntevs = debuginfo__find_trace_events(dinfo, pev, tevs, max_tevs);
295 295
296 debuginfo__delete(dinfo); 296 debuginfo__delete(dinfo);
297 297
298 if (ntevs > 0) { /* Succeeded to find trace events */ 298 if (ntevs > 0) { /* Succeeded to find trace events */
299 pr_debug("find %d probe_trace_events.\n", ntevs); 299 pr_debug("find %d probe_trace_events.\n", ntevs);
300 if (module) 300 if (module)
301 ret = add_module_to_probe_trace_events(*tevs, ntevs, 301 ret = add_module_to_probe_trace_events(*tevs, ntevs,
302 module); 302 module);
303 return ret < 0 ? ret : ntevs; 303 return ret < 0 ? ret : ntevs;
304 } 304 }
305 305
306 if (ntevs == 0) { /* No error but failed to find probe point. */ 306 if (ntevs == 0) { /* No error but failed to find probe point. */
307 pr_warning("Probe point '%s' not found.\n", 307 pr_warning("Probe point '%s' not found.\n",
308 synthesize_perf_probe_point(&pev->point)); 308 synthesize_perf_probe_point(&pev->point));
309 return -ENOENT; 309 return -ENOENT;
310 } 310 }
311 /* Error path : ntevs < 0 */ 311 /* Error path : ntevs < 0 */
312 pr_debug("An error occurred in debuginfo analysis (%d).\n", ntevs); 312 pr_debug("An error occurred in debuginfo analysis (%d).\n", ntevs);
313 if (ntevs == -EBADF) { 313 if (ntevs == -EBADF) {
314 pr_warning("Warning: No dwarf info found in the vmlinux - " 314 pr_warning("Warning: No dwarf info found in the vmlinux - "
315 "please rebuild kernel with CONFIG_DEBUG_INFO=y.\n"); 315 "please rebuild kernel with CONFIG_DEBUG_INFO=y.\n");
316 if (!need_dwarf) { 316 if (!need_dwarf) {
317 pr_debug("Trying to use symbols.\n"); 317 pr_debug("Trying to use symbols.\n");
318 return 0; 318 return 0;
319 } 319 }
320 } 320 }
321 return ntevs; 321 return ntevs;
322 } 322 }
323 323
324 /* 324 /*
325 * Find a src file from a DWARF tag path. Prepend optional source path prefix 325 * Find a src file from a DWARF tag path. Prepend optional source path prefix
326 * and chop off leading directories that do not exist. Result is passed back as 326 * and chop off leading directories that do not exist. Result is passed back as
327 * a newly allocated path on success. 327 * a newly allocated path on success.
328 * Return 0 if file was found and readable, -errno otherwise. 328 * Return 0 if file was found and readable, -errno otherwise.
329 */ 329 */
330 static int get_real_path(const char *raw_path, const char *comp_dir, 330 static int get_real_path(const char *raw_path, const char *comp_dir,
331 char **new_path) 331 char **new_path)
332 { 332 {
333 const char *prefix = symbol_conf.source_prefix; 333 const char *prefix = symbol_conf.source_prefix;
334 334
335 if (!prefix) { 335 if (!prefix) {
336 if (raw_path[0] != '/' && comp_dir) 336 if (raw_path[0] != '/' && comp_dir)
337 /* If not an absolute path, try to use comp_dir */ 337 /* If not an absolute path, try to use comp_dir */
338 prefix = comp_dir; 338 prefix = comp_dir;
339 else { 339 else {
340 if (access(raw_path, R_OK) == 0) { 340 if (access(raw_path, R_OK) == 0) {
341 *new_path = strdup(raw_path); 341 *new_path = strdup(raw_path);
342 return 0; 342 return 0;
343 } else 343 } else
344 return -errno; 344 return -errno;
345 } 345 }
346 } 346 }
347 347
348 *new_path = malloc((strlen(prefix) + strlen(raw_path) + 2)); 348 *new_path = malloc((strlen(prefix) + strlen(raw_path) + 2));
349 if (!*new_path) 349 if (!*new_path)
350 return -ENOMEM; 350 return -ENOMEM;
351 351
352 for (;;) { 352 for (;;) {
353 sprintf(*new_path, "%s/%s", prefix, raw_path); 353 sprintf(*new_path, "%s/%s", prefix, raw_path);
354 354
355 if (access(*new_path, R_OK) == 0) 355 if (access(*new_path, R_OK) == 0)
356 return 0; 356 return 0;
357 357
358 if (!symbol_conf.source_prefix) 358 if (!symbol_conf.source_prefix)
359 /* In case of searching comp_dir, don't retry */ 359 /* In case of searching comp_dir, don't retry */
360 return -errno; 360 return -errno;
361 361
362 switch (errno) { 362 switch (errno) {
363 case ENAMETOOLONG: 363 case ENAMETOOLONG:
364 case ENOENT: 364 case ENOENT:
365 case EROFS: 365 case EROFS:
366 case EFAULT: 366 case EFAULT:
367 raw_path = strchr(++raw_path, '/'); 367 raw_path = strchr(++raw_path, '/');
368 if (!raw_path) { 368 if (!raw_path) {
369 free(*new_path); 369 free(*new_path);
370 *new_path = NULL; 370 *new_path = NULL;
371 return -ENOENT; 371 return -ENOENT;
372 } 372 }
373 continue; 373 continue;
374 374
375 default: 375 default:
376 free(*new_path); 376 free(*new_path);
377 *new_path = NULL; 377 *new_path = NULL;
378 return -errno; 378 return -errno;
379 } 379 }
380 } 380 }
381 } 381 }
382 382
383 #define LINEBUF_SIZE 256 383 #define LINEBUF_SIZE 256
384 #define NR_ADDITIONAL_LINES 2 384 #define NR_ADDITIONAL_LINES 2
385 385
386 static int __show_one_line(FILE *fp, int l, bool skip, bool show_num) 386 static int __show_one_line(FILE *fp, int l, bool skip, bool show_num)
387 { 387 {
388 char buf[LINEBUF_SIZE]; 388 char buf[LINEBUF_SIZE];
389 const char *color = show_num ? "" : PERF_COLOR_BLUE; 389 const char *color = show_num ? "" : PERF_COLOR_BLUE;
390 const char *prefix = NULL; 390 const char *prefix = NULL;
391 391
392 do { 392 do {
393 if (fgets(buf, LINEBUF_SIZE, fp) == NULL) 393 if (fgets(buf, LINEBUF_SIZE, fp) == NULL)
394 goto error; 394 goto error;
395 if (skip) 395 if (skip)
396 continue; 396 continue;
397 if (!prefix) { 397 if (!prefix) {
398 prefix = show_num ? "%7d " : " "; 398 prefix = show_num ? "%7d " : " ";
399 color_fprintf(stdout, color, prefix, l); 399 color_fprintf(stdout, color, prefix, l);
400 } 400 }
401 color_fprintf(stdout, color, "%s", buf); 401 color_fprintf(stdout, color, "%s", buf);
402 402
403 } while (strchr(buf, '\n') == NULL); 403 } while (strchr(buf, '\n') == NULL);
404 404
405 return 1; 405 return 1;
406 error: 406 error:
407 if (ferror(fp)) { 407 if (ferror(fp)) {
408 pr_warning("File read error: %s\n", strerror(errno)); 408 pr_warning("File read error: %s\n", strerror(errno));
409 return -1; 409 return -1;
410 } 410 }
411 return 0; 411 return 0;
412 } 412 }
413 413
414 static int _show_one_line(FILE *fp, int l, bool skip, bool show_num) 414 static int _show_one_line(FILE *fp, int l, bool skip, bool show_num)
415 { 415 {
416 int rv = __show_one_line(fp, l, skip, show_num); 416 int rv = __show_one_line(fp, l, skip, show_num);
417 if (rv == 0) { 417 if (rv == 0) {
418 pr_warning("Source file is shorter than expected.\n"); 418 pr_warning("Source file is shorter than expected.\n");
419 rv = -1; 419 rv = -1;
420 } 420 }
421 return rv; 421 return rv;
422 } 422 }
423 423
424 #define show_one_line_with_num(f,l) _show_one_line(f,l,false,true) 424 #define show_one_line_with_num(f,l) _show_one_line(f,l,false,true)
425 #define show_one_line(f,l) _show_one_line(f,l,false,false) 425 #define show_one_line(f,l) _show_one_line(f,l,false,false)
426 #define skip_one_line(f,l) _show_one_line(f,l,true,false) 426 #define skip_one_line(f,l) _show_one_line(f,l,true,false)
427 #define show_one_line_or_eof(f,l) __show_one_line(f,l,false,false) 427 #define show_one_line_or_eof(f,l) __show_one_line(f,l,false,false)
428 428
429 /* 429 /*
430 * Show line-range always requires debuginfo to find source file and 430 * Show line-range always requires debuginfo to find source file and
431 * line number. 431 * line number.
432 */ 432 */
433 int show_line_range(struct line_range *lr, const char *module) 433 int show_line_range(struct line_range *lr, const char *module)
434 { 434 {
435 int l = 1; 435 int l = 1;
436 struct line_node *ln; 436 struct line_node *ln;
437 struct debuginfo *dinfo; 437 struct debuginfo *dinfo;
438 FILE *fp; 438 FILE *fp;
439 int ret; 439 int ret;
440 char *tmp; 440 char *tmp;
441 441
442 /* Search a line range */ 442 /* Search a line range */
443 ret = init_vmlinux(); 443 ret = init_vmlinux();
444 if (ret < 0) 444 if (ret < 0)
445 return ret; 445 return ret;
446 446
447 dinfo = open_debuginfo(module); 447 dinfo = open_debuginfo(module);
448 if (!dinfo) { 448 if (!dinfo) {
449 pr_warning("Failed to open debuginfo file.\n"); 449 pr_warning("Failed to open debuginfo file.\n");
450 return -ENOENT; 450 return -ENOENT;
451 } 451 }
452 452
453 ret = debuginfo__find_line_range(dinfo, lr); 453 ret = debuginfo__find_line_range(dinfo, lr);
454 debuginfo__delete(dinfo); 454 debuginfo__delete(dinfo);
455 if (ret == 0) { 455 if (ret == 0) {
456 pr_warning("Specified source line is not found.\n"); 456 pr_warning("Specified source line is not found.\n");
457 return -ENOENT; 457 return -ENOENT;
458 } else if (ret < 0) { 458 } else if (ret < 0) {
459 pr_warning("Debuginfo analysis failed. (%d)\n", ret); 459 pr_warning("Debuginfo analysis failed. (%d)\n", ret);
460 return ret; 460 return ret;
461 } 461 }
462 462
463 /* Convert source file path */ 463 /* Convert source file path */
464 tmp = lr->path; 464 tmp = lr->path;
465 ret = get_real_path(tmp, lr->comp_dir, &lr->path); 465 ret = get_real_path(tmp, lr->comp_dir, &lr->path);
466 free(tmp); /* Free old path */ 466 free(tmp); /* Free old path */
467 if (ret < 0) { 467 if (ret < 0) {
468 pr_warning("Failed to find source file. (%d)\n", ret); 468 pr_warning("Failed to find source file. (%d)\n", ret);
469 return ret; 469 return ret;
470 } 470 }
471 471
472 setup_pager(); 472 setup_pager();
473 473
474 if (lr->function) 474 if (lr->function)
475 fprintf(stdout, "<%s@%s:%d>\n", lr->function, lr->path, 475 fprintf(stdout, "<%s@%s:%d>\n", lr->function, lr->path,
476 lr->start - lr->offset); 476 lr->start - lr->offset);
477 else 477 else
478 fprintf(stdout, "<%s:%d>\n", lr->path, lr->start); 478 fprintf(stdout, "<%s:%d>\n", lr->path, lr->start);
479 479
480 fp = fopen(lr->path, "r"); 480 fp = fopen(lr->path, "r");
481 if (fp == NULL) { 481 if (fp == NULL) {
482 pr_warning("Failed to open %s: %s\n", lr->path, 482 pr_warning("Failed to open %s: %s\n", lr->path,
483 strerror(errno)); 483 strerror(errno));
484 return -errno; 484 return -errno;
485 } 485 }
486 /* Skip to starting line number */ 486 /* Skip to starting line number */
487 while (l < lr->start) { 487 while (l < lr->start) {
488 ret = skip_one_line(fp, l++); 488 ret = skip_one_line(fp, l++);
489 if (ret < 0) 489 if (ret < 0)
490 goto end; 490 goto end;
491 } 491 }
492 492
493 list_for_each_entry(ln, &lr->line_list, list) { 493 list_for_each_entry(ln, &lr->line_list, list) {
494 for (; ln->line > l; l++) { 494 for (; ln->line > l; l++) {
495 ret = show_one_line(fp, l - lr->offset); 495 ret = show_one_line(fp, l - lr->offset);
496 if (ret < 0) 496 if (ret < 0)
497 goto end; 497 goto end;
498 } 498 }
499 ret = show_one_line_with_num(fp, l++ - lr->offset); 499 ret = show_one_line_with_num(fp, l++ - lr->offset);
500 if (ret < 0) 500 if (ret < 0)
501 goto end; 501 goto end;
502 } 502 }
503 503
504 if (lr->end == INT_MAX) 504 if (lr->end == INT_MAX)
505 lr->end = l + NR_ADDITIONAL_LINES; 505 lr->end = l + NR_ADDITIONAL_LINES;
506 while (l <= lr->end) { 506 while (l <= lr->end) {
507 ret = show_one_line_or_eof(fp, l++ - lr->offset); 507 ret = show_one_line_or_eof(fp, l++ - lr->offset);
508 if (ret <= 0) 508 if (ret <= 0)
509 break; 509 break;
510 } 510 }
511 end: 511 end:
512 fclose(fp); 512 fclose(fp);
513 return ret; 513 return ret;
514 } 514 }
515 515
516 static int show_available_vars_at(struct debuginfo *dinfo, 516 static int show_available_vars_at(struct debuginfo *dinfo,
517 struct perf_probe_event *pev, 517 struct perf_probe_event *pev,
518 int max_vls, struct strfilter *_filter, 518 int max_vls, struct strfilter *_filter,
519 bool externs) 519 bool externs)
520 { 520 {
521 char *buf; 521 char *buf;
522 int ret, i, nvars; 522 int ret, i, nvars;
523 struct str_node *node; 523 struct str_node *node;
524 struct variable_list *vls = NULL, *vl; 524 struct variable_list *vls = NULL, *vl;
525 const char *var; 525 const char *var;
526 526
527 buf = synthesize_perf_probe_point(&pev->point); 527 buf = synthesize_perf_probe_point(&pev->point);
528 if (!buf) 528 if (!buf)
529 return -EINVAL; 529 return -EINVAL;
530 pr_debug("Searching variables at %s\n", buf); 530 pr_debug("Searching variables at %s\n", buf);
531 531
532 ret = debuginfo__find_available_vars_at(dinfo, pev, &vls, 532 ret = debuginfo__find_available_vars_at(dinfo, pev, &vls,
533 max_vls, externs); 533 max_vls, externs);
534 if (ret <= 0) { 534 if (ret <= 0) {
535 pr_err("Failed to find variables at %s (%d)\n", buf, ret); 535 pr_err("Failed to find variables at %s (%d)\n", buf, ret);
536 goto end; 536 goto end;
537 } 537 }
538 /* Some variables are found */ 538 /* Some variables are found */
539 fprintf(stdout, "Available variables at %s\n", buf); 539 fprintf(stdout, "Available variables at %s\n", buf);
540 for (i = 0; i < ret; i++) { 540 for (i = 0; i < ret; i++) {
541 vl = &vls[i]; 541 vl = &vls[i];
542 /* 542 /*
543 * A probe point might be converted to 543 * A probe point might be converted to
544 * several trace points. 544 * several trace points.
545 */ 545 */
546 fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol, 546 fprintf(stdout, "\t@<%s+%lu>\n", vl->point.symbol,
547 vl->point.offset); 547 vl->point.offset);
548 free(vl->point.symbol); 548 free(vl->point.symbol);
549 nvars = 0; 549 nvars = 0;
550 if (vl->vars) { 550 if (vl->vars) {
551 strlist__for_each(node, vl->vars) { 551 strlist__for_each(node, vl->vars) {
552 var = strchr(node->s, '\t') + 1; 552 var = strchr(node->s, '\t') + 1;
553 if (strfilter__compare(_filter, var)) { 553 if (strfilter__compare(_filter, var)) {
554 fprintf(stdout, "\t\t%s\n", node->s); 554 fprintf(stdout, "\t\t%s\n", node->s);
555 nvars++; 555 nvars++;
556 } 556 }
557 } 557 }
558 strlist__delete(vl->vars); 558 strlist__delete(vl->vars);
559 } 559 }
560 if (nvars == 0) 560 if (nvars == 0)
561 fprintf(stdout, "\t\t(No matched variables)\n"); 561 fprintf(stdout, "\t\t(No matched variables)\n");
562 } 562 }
563 free(vls); 563 free(vls);
564 end: 564 end:
565 free(buf); 565 free(buf);
566 return ret; 566 return ret;
567 } 567 }
568 568
569 /* Show available variables on given probe point */ 569 /* Show available variables on given probe point */
570 int show_available_vars(struct perf_probe_event *pevs, int npevs, 570 int show_available_vars(struct perf_probe_event *pevs, int npevs,
571 int max_vls, const char *module, 571 int max_vls, const char *module,
572 struct strfilter *_filter, bool externs) 572 struct strfilter *_filter, bool externs)
573 { 573 {
574 int i, ret = 0; 574 int i, ret = 0;
575 struct debuginfo *dinfo; 575 struct debuginfo *dinfo;
576 576
577 ret = init_vmlinux(); 577 ret = init_vmlinux();
578 if (ret < 0) 578 if (ret < 0)
579 return ret; 579 return ret;
580 580
581 dinfo = open_debuginfo(module); 581 dinfo = open_debuginfo(module);
582 if (!dinfo) { 582 if (!dinfo) {
583 pr_warning("Failed to open debuginfo file.\n"); 583 pr_warning("Failed to open debuginfo file.\n");
584 return -ENOENT; 584 return -ENOENT;
585 } 585 }
586 586
587 setup_pager(); 587 setup_pager();
588 588
589 for (i = 0; i < npevs && ret >= 0; i++) 589 for (i = 0; i < npevs && ret >= 0; i++)
590 ret = show_available_vars_at(dinfo, &pevs[i], max_vls, _filter, 590 ret = show_available_vars_at(dinfo, &pevs[i], max_vls, _filter,
591 externs); 591 externs);
592 592
593 debuginfo__delete(dinfo); 593 debuginfo__delete(dinfo);
594 return ret; 594 return ret;
595 } 595 }
596 596
597 #else /* !DWARF_SUPPORT */ 597 #else /* !DWARF_SUPPORT */
598 598
599 static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp, 599 static int kprobe_convert_to_perf_probe(struct probe_trace_point *tp,
600 struct perf_probe_point *pp) 600 struct perf_probe_point *pp)
601 { 601 {
602 struct symbol *sym; 602 struct symbol *sym;
603 603
604 sym = __find_kernel_function_by_name(tp->symbol, NULL); 604 sym = __find_kernel_function_by_name(tp->symbol, NULL);
605 if (!sym) { 605 if (!sym) {
606 pr_err("Failed to find symbol %s in kernel.\n", tp->symbol); 606 pr_err("Failed to find symbol %s in kernel.\n", tp->symbol);
607 return -ENOENT; 607 return -ENOENT;
608 } 608 }
609 pp->function = strdup(tp->symbol); 609 pp->function = strdup(tp->symbol);
610 if (pp->function == NULL) 610 if (pp->function == NULL)
611 return -ENOMEM; 611 return -ENOMEM;
612 pp->offset = tp->offset; 612 pp->offset = tp->offset;
613 pp->retprobe = tp->retprobe; 613 pp->retprobe = tp->retprobe;
614 614
615 return 0; 615 return 0;
616 } 616 }
617 617
618 static int try_to_find_probe_trace_events(struct perf_probe_event *pev, 618 static int try_to_find_probe_trace_events(struct perf_probe_event *pev,
619 struct probe_trace_event **tevs __unused, 619 struct probe_trace_event **tevs __unused,
620 int max_tevs __unused, const char *mod __unused) 620 int max_tevs __unused, const char *mod __unused)
621 { 621 {
622 if (perf_probe_event_need_dwarf(pev)) { 622 if (perf_probe_event_need_dwarf(pev)) {
623 pr_warning("Debuginfo-analysis is not supported.\n"); 623 pr_warning("Debuginfo-analysis is not supported.\n");
624 return -ENOSYS; 624 return -ENOSYS;
625 } 625 }
626 return 0; 626 return 0;
627 } 627 }
628 628
629 int show_line_range(struct line_range *lr __unused, const char *module __unused) 629 int show_line_range(struct line_range *lr __unused, const char *module __unused)
630 { 630 {
631 pr_warning("Debuginfo-analysis is not supported.\n"); 631 pr_warning("Debuginfo-analysis is not supported.\n");
632 return -ENOSYS; 632 return -ENOSYS;
633 } 633 }
634 634
635 int show_available_vars(struct perf_probe_event *pevs __unused, 635 int show_available_vars(struct perf_probe_event *pevs __unused,
636 int npevs __unused, int max_vls __unused, 636 int npevs __unused, int max_vls __unused,
637 const char *module __unused, 637 const char *module __unused,
638 struct strfilter *filter __unused, 638 struct strfilter *filter __unused,
639 bool externs __unused) 639 bool externs __unused)
640 { 640 {
641 pr_warning("Debuginfo-analysis is not supported.\n"); 641 pr_warning("Debuginfo-analysis is not supported.\n");
642 return -ENOSYS; 642 return -ENOSYS;
643 } 643 }
644 #endif 644 #endif
645 645
646 static int parse_line_num(char **ptr, int *val, const char *what) 646 static int parse_line_num(char **ptr, int *val, const char *what)
647 { 647 {
648 const char *start = *ptr; 648 const char *start = *ptr;
649 649
650 errno = 0; 650 errno = 0;
651 *val = strtol(*ptr, ptr, 0); 651 *val = strtol(*ptr, ptr, 0);
652 if (errno || *ptr == start) { 652 if (errno || *ptr == start) {
653 semantic_error("'%s' is not a valid number.\n", what); 653 semantic_error("'%s' is not a valid number.\n", what);
654 return -EINVAL; 654 return -EINVAL;
655 } 655 }
656 return 0; 656 return 0;
657 } 657 }
658 658
659 /* 659 /*
660 * Stuff 'lr' according to the line range described by 'arg'. 660 * Stuff 'lr' according to the line range described by 'arg'.
661 * The line range syntax is described by: 661 * The line range syntax is described by:
662 * 662 *
663 * SRC[:SLN[+NUM|-ELN]] 663 * SRC[:SLN[+NUM|-ELN]]
664 * FNC[@SRC][:SLN[+NUM|-ELN]] 664 * FNC[@SRC][:SLN[+NUM|-ELN]]
665 */ 665 */
666 int parse_line_range_desc(const char *arg, struct line_range *lr) 666 int parse_line_range_desc(const char *arg, struct line_range *lr)
667 { 667 {
668 char *range, *file, *name = strdup(arg); 668 char *range, *file, *name = strdup(arg);
669 int err; 669 int err;
670 670
671 if (!name) 671 if (!name)
672 return -ENOMEM; 672 return -ENOMEM;
673 673
674 lr->start = 0; 674 lr->start = 0;
675 lr->end = INT_MAX; 675 lr->end = INT_MAX;
676 676
677 range = strchr(name, ':'); 677 range = strchr(name, ':');
678 if (range) { 678 if (range) {
679 *range++ = '\0'; 679 *range++ = '\0';
680 680
681 err = parse_line_num(&range, &lr->start, "start line"); 681 err = parse_line_num(&range, &lr->start, "start line");
682 if (err) 682 if (err)
683 goto err; 683 goto err;
684 684
685 if (*range == '+' || *range == '-') { 685 if (*range == '+' || *range == '-') {
686 const char c = *range++; 686 const char c = *range++;
687 687
688 err = parse_line_num(&range, &lr->end, "end line"); 688 err = parse_line_num(&range, &lr->end, "end line");
689 if (err) 689 if (err)
690 goto err; 690 goto err;
691 691
692 if (c == '+') { 692 if (c == '+') {
693 lr->end += lr->start; 693 lr->end += lr->start;
694 /* 694 /*
695 * Adjust the number of lines here. 695 * Adjust the number of lines here.
696 * If the number of lines == 1, the 696 * If the number of lines == 1, the
697 * the end of line should be equal to 697 * the end of line should be equal to
698 * the start of line. 698 * the start of line.
699 */ 699 */
700 lr->end--; 700 lr->end--;
701 } 701 }
702 } 702 }
703 703
704 pr_debug("Line range is %d to %d\n", lr->start, lr->end); 704 pr_debug("Line range is %d to %d\n", lr->start, lr->end);
705 705
706 err = -EINVAL; 706 err = -EINVAL;
707 if (lr->start > lr->end) { 707 if (lr->start > lr->end) {
708 semantic_error("Start line must be smaller" 708 semantic_error("Start line must be smaller"
709 " than end line.\n"); 709 " than end line.\n");
710 goto err; 710 goto err;
711 } 711 }
712 if (*range != '\0') { 712 if (*range != '\0') {
713 semantic_error("Tailing with invalid str '%s'.\n", range); 713 semantic_error("Tailing with invalid str '%s'.\n", range);
714 goto err; 714 goto err;
715 } 715 }
716 } 716 }
717 717
718 file = strchr(name, '@'); 718 file = strchr(name, '@');
719 if (file) { 719 if (file) {
720 *file = '\0'; 720 *file = '\0';
721 lr->file = strdup(++file); 721 lr->file = strdup(++file);
722 if (lr->file == NULL) { 722 if (lr->file == NULL) {
723 err = -ENOMEM; 723 err = -ENOMEM;
724 goto err; 724 goto err;
725 } 725 }
726 lr->function = name; 726 lr->function = name;
727 } else if (strchr(name, '.')) 727 } else if (strchr(name, '.'))
728 lr->file = name; 728 lr->file = name;
729 else 729 else
730 lr->function = name; 730 lr->function = name;
731 731
732 return 0; 732 return 0;
733 err: 733 err:
734 free(name); 734 free(name);
735 return err; 735 return err;
736 } 736 }
737 737
738 /* Check the name is good for event/group */ 738 /* Check the name is good for event/group */
739 static bool check_event_name(const char *name) 739 static bool check_event_name(const char *name)
740 { 740 {
741 if (!isalpha(*name) && *name != '_') 741 if (!isalpha(*name) && *name != '_')
742 return false; 742 return false;
743 while (*++name != '\0') { 743 while (*++name != '\0') {
744 if (!isalpha(*name) && !isdigit(*name) && *name != '_') 744 if (!isalpha(*name) && !isdigit(*name) && *name != '_')
745 return false; 745 return false;
746 } 746 }
747 return true; 747 return true;
748 } 748 }
749 749
750 /* Parse probepoint definition. */ 750 /* Parse probepoint definition. */
751 static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev) 751 static int parse_perf_probe_point(char *arg, struct perf_probe_event *pev)
752 { 752 {
753 struct perf_probe_point *pp = &pev->point; 753 struct perf_probe_point *pp = &pev->point;
754 char *ptr, *tmp; 754 char *ptr, *tmp;
755 char c, nc = 0; 755 char c, nc = 0;
756 /* 756 /*
757 * <Syntax> 757 * <Syntax>
758 * perf probe [EVENT=]SRC[:LN|;PTN] 758 * perf probe [EVENT=]SRC[:LN|;PTN]
759 * perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT] 759 * perf probe [EVENT=]FUNC[@SRC][+OFFS|%return|:LN|;PAT]
760 * 760 *
761 * TODO:Group name support 761 * TODO:Group name support
762 */ 762 */
763 763
764 ptr = strpbrk(arg, ";=@+%"); 764 ptr = strpbrk(arg, ";=@+%");
765 if (ptr && *ptr == '=') { /* Event name */ 765 if (ptr && *ptr == '=') { /* Event name */
766 *ptr = '\0'; 766 *ptr = '\0';
767 tmp = ptr + 1; 767 tmp = ptr + 1;
768 if (strchr(arg, ':')) { 768 if (strchr(arg, ':')) {
769 semantic_error("Group name is not supported yet.\n"); 769 semantic_error("Group name is not supported yet.\n");
770 return -ENOTSUP; 770 return -ENOTSUP;
771 } 771 }
772 if (!check_event_name(arg)) { 772 if (!check_event_name(arg)) {
773 semantic_error("%s is bad for event name -it must " 773 semantic_error("%s is bad for event name -it must "
774 "follow C symbol-naming rule.\n", arg); 774 "follow C symbol-naming rule.\n", arg);
775 return -EINVAL; 775 return -EINVAL;
776 } 776 }
777 pev->event = strdup(arg); 777 pev->event = strdup(arg);
778 if (pev->event == NULL) 778 if (pev->event == NULL)
779 return -ENOMEM; 779 return -ENOMEM;
780 pev->group = NULL; 780 pev->group = NULL;
781 arg = tmp; 781 arg = tmp;
782 } 782 }
783 783
784 ptr = strpbrk(arg, ";:+@%"); 784 ptr = strpbrk(arg, ";:+@%");
785 if (ptr) { 785 if (ptr) {
786 nc = *ptr; 786 nc = *ptr;
787 *ptr++ = '\0'; 787 *ptr++ = '\0';
788 } 788 }
789 789
790 tmp = strdup(arg); 790 tmp = strdup(arg);
791 if (tmp == NULL) 791 if (tmp == NULL)
792 return -ENOMEM; 792 return -ENOMEM;
793 793
794 /* Check arg is function or file and copy it */ 794 /* Check arg is function or file and copy it */
795 if (strchr(tmp, '.')) /* File */ 795 if (strchr(tmp, '.')) /* File */
796 pp->file = tmp; 796 pp->file = tmp;
797 else /* Function */ 797 else /* Function */
798 pp->function = tmp; 798 pp->function = tmp;
799 799
800 /* Parse other options */ 800 /* Parse other options */
801 while (ptr) { 801 while (ptr) {
802 arg = ptr; 802 arg = ptr;
803 c = nc; 803 c = nc;
804 if (c == ';') { /* Lazy pattern must be the last part */ 804 if (c == ';') { /* Lazy pattern must be the last part */
805 pp->lazy_line = strdup(arg); 805 pp->lazy_line = strdup(arg);
806 if (pp->lazy_line == NULL) 806 if (pp->lazy_line == NULL)
807 return -ENOMEM; 807 return -ENOMEM;
808 break; 808 break;
809 } 809 }
810 ptr = strpbrk(arg, ";:+@%"); 810 ptr = strpbrk(arg, ";:+@%");
811 if (ptr) { 811 if (ptr) {
812 nc = *ptr; 812 nc = *ptr;
813 *ptr++ = '\0'; 813 *ptr++ = '\0';
814 } 814 }
815 switch (c) { 815 switch (c) {
816 case ':': /* Line number */ 816 case ':': /* Line number */
817 pp->line = strtoul(arg, &tmp, 0); 817 pp->line = strtoul(arg, &tmp, 0);
818 if (*tmp != '\0') { 818 if (*tmp != '\0') {
819 semantic_error("There is non-digit char" 819 semantic_error("There is non-digit char"
820 " in line number.\n"); 820 " in line number.\n");
821 return -EINVAL; 821 return -EINVAL;
822 } 822 }
823 break; 823 break;
824 case '+': /* Byte offset from a symbol */ 824 case '+': /* Byte offset from a symbol */
825 pp->offset = strtoul(arg, &tmp, 0); 825 pp->offset = strtoul(arg, &tmp, 0);
826 if (*tmp != '\0') { 826 if (*tmp != '\0') {
827 semantic_error("There is non-digit character" 827 semantic_error("There is non-digit character"
828 " in offset.\n"); 828 " in offset.\n");
829 return -EINVAL; 829 return -EINVAL;
830 } 830 }
831 break; 831 break;
832 case '@': /* File name */ 832 case '@': /* File name */
833 if (pp->file) { 833 if (pp->file) {
834 semantic_error("SRC@SRC is not allowed.\n"); 834 semantic_error("SRC@SRC is not allowed.\n");
835 return -EINVAL; 835 return -EINVAL;
836 } 836 }
837 pp->file = strdup(arg); 837 pp->file = strdup(arg);
838 if (pp->file == NULL) 838 if (pp->file == NULL)
839 return -ENOMEM; 839 return -ENOMEM;
840 break; 840 break;
841 case '%': /* Probe places */ 841 case '%': /* Probe places */
842 if (strcmp(arg, "return") == 0) { 842 if (strcmp(arg, "return") == 0) {
843 pp->retprobe = 1; 843 pp->retprobe = 1;
844 } else { /* Others not supported yet */ 844 } else { /* Others not supported yet */
845 semantic_error("%%%s is not supported.\n", arg); 845 semantic_error("%%%s is not supported.\n", arg);
846 return -ENOTSUP; 846 return -ENOTSUP;
847 } 847 }
848 break; 848 break;
849 default: /* Buggy case */ 849 default: /* Buggy case */
850 pr_err("This program has a bug at %s:%d.\n", 850 pr_err("This program has a bug at %s:%d.\n",
851 __FILE__, __LINE__); 851 __FILE__, __LINE__);
852 return -ENOTSUP; 852 return -ENOTSUP;
853 break; 853 break;
854 } 854 }
855 } 855 }
856 856
857 /* Exclusion check */ 857 /* Exclusion check */
858 if (pp->lazy_line && pp->line) { 858 if (pp->lazy_line && pp->line) {
859 semantic_error("Lazy pattern can't be used with" 859 semantic_error("Lazy pattern can't be used with"
860 " line number.\n"); 860 " line number.\n");
861 return -EINVAL; 861 return -EINVAL;
862 } 862 }
863 863
864 if (pp->lazy_line && pp->offset) { 864 if (pp->lazy_line && pp->offset) {
865 semantic_error("Lazy pattern can't be used with offset.\n"); 865 semantic_error("Lazy pattern can't be used with offset.\n");
866 return -EINVAL; 866 return -EINVAL;
867 } 867 }
868 868
869 if (pp->line && pp->offset) { 869 if (pp->line && pp->offset) {
870 semantic_error("Offset can't be used with line number.\n"); 870 semantic_error("Offset can't be used with line number.\n");
871 return -EINVAL; 871 return -EINVAL;
872 } 872 }
873 873
874 if (!pp->line && !pp->lazy_line && pp->file && !pp->function) { 874 if (!pp->line && !pp->lazy_line && pp->file && !pp->function) {
875 semantic_error("File always requires line number or " 875 semantic_error("File always requires line number or "
876 "lazy pattern.\n"); 876 "lazy pattern.\n");
877 return -EINVAL; 877 return -EINVAL;
878 } 878 }
879 879
880 if (pp->offset && !pp->function) { 880 if (pp->offset && !pp->function) {
881 semantic_error("Offset requires an entry function.\n"); 881 semantic_error("Offset requires an entry function.\n");
882 return -EINVAL; 882 return -EINVAL;
883 } 883 }
884 884
885 if (pp->retprobe && !pp->function) { 885 if (pp->retprobe && !pp->function) {
886 semantic_error("Return probe requires an entry function.\n"); 886 semantic_error("Return probe requires an entry function.\n");
887 return -EINVAL; 887 return -EINVAL;
888 } 888 }
889 889
890 if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) { 890 if ((pp->offset || pp->line || pp->lazy_line) && pp->retprobe) {
891 semantic_error("Offset/Line/Lazy pattern can't be used with " 891 semantic_error("Offset/Line/Lazy pattern can't be used with "
892 "return probe.\n"); 892 "return probe.\n");
893 return -EINVAL; 893 return -EINVAL;
894 } 894 }
895 895
896 pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n", 896 pr_debug("symbol:%s file:%s line:%d offset:%lu return:%d lazy:%s\n",
897 pp->function, pp->file, pp->line, pp->offset, pp->retprobe, 897 pp->function, pp->file, pp->line, pp->offset, pp->retprobe,
898 pp->lazy_line); 898 pp->lazy_line);
899 return 0; 899 return 0;
900 } 900 }
901 901
902 /* Parse perf-probe event argument */ 902 /* Parse perf-probe event argument */
903 static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg) 903 static int parse_perf_probe_arg(char *str, struct perf_probe_arg *arg)
904 { 904 {
905 char *tmp, *goodname; 905 char *tmp, *goodname;
906 struct perf_probe_arg_field **fieldp; 906 struct perf_probe_arg_field **fieldp;
907 907
908 pr_debug("parsing arg: %s into ", str); 908 pr_debug("parsing arg: %s into ", str);
909 909
910 tmp = strchr(str, '='); 910 tmp = strchr(str, '=');
911 if (tmp) { 911 if (tmp) {
912 arg->name = strndup(str, tmp - str); 912 arg->name = strndup(str, tmp - str);
913 if (arg->name == NULL) 913 if (arg->name == NULL)
914 return -ENOMEM; 914 return -ENOMEM;
915 pr_debug("name:%s ", arg->name); 915 pr_debug("name:%s ", arg->name);
916 str = tmp + 1; 916 str = tmp + 1;
917 } 917 }
918 918
919 tmp = strchr(str, ':'); 919 tmp = strchr(str, ':');
920 if (tmp) { /* Type setting */ 920 if (tmp) { /* Type setting */
921 *tmp = '\0'; 921 *tmp = '\0';
922 arg->type = strdup(tmp + 1); 922 arg->type = strdup(tmp + 1);
923 if (arg->type == NULL) 923 if (arg->type == NULL)
924 return -ENOMEM; 924 return -ENOMEM;
925 pr_debug("type:%s ", arg->type); 925 pr_debug("type:%s ", arg->type);
926 } 926 }
927 927
928 tmp = strpbrk(str, "-.["); 928 tmp = strpbrk(str, "-.[");
929 if (!is_c_varname(str) || !tmp) { 929 if (!is_c_varname(str) || !tmp) {
930 /* A variable, register, symbol or special value */ 930 /* A variable, register, symbol or special value */
931 arg->var = strdup(str); 931 arg->var = strdup(str);
932 if (arg->var == NULL) 932 if (arg->var == NULL)
933 return -ENOMEM; 933 return -ENOMEM;
934 pr_debug("%s\n", arg->var); 934 pr_debug("%s\n", arg->var);
935 return 0; 935 return 0;
936 } 936 }
937 937
938 /* Structure fields or array element */ 938 /* Structure fields or array element */
939 arg->var = strndup(str, tmp - str); 939 arg->var = strndup(str, tmp - str);
940 if (arg->var == NULL) 940 if (arg->var == NULL)
941 return -ENOMEM; 941 return -ENOMEM;
942 goodname = arg->var; 942 goodname = arg->var;
943 pr_debug("%s, ", arg->var); 943 pr_debug("%s, ", arg->var);
944 fieldp = &arg->field; 944 fieldp = &arg->field;
945 945
946 do { 946 do {
947 *fieldp = zalloc(sizeof(struct perf_probe_arg_field)); 947 *fieldp = zalloc(sizeof(struct perf_probe_arg_field));
948 if (*fieldp == NULL) 948 if (*fieldp == NULL)
949 return -ENOMEM; 949 return -ENOMEM;
950 if (*tmp == '[') { /* Array */ 950 if (*tmp == '[') { /* Array */
951 str = tmp; 951 str = tmp;
952 (*fieldp)->index = strtol(str + 1, &tmp, 0); 952 (*fieldp)->index = strtol(str + 1, &tmp, 0);
953 (*fieldp)->ref = true; 953 (*fieldp)->ref = true;
954 if (*tmp != ']' || tmp == str + 1) { 954 if (*tmp != ']' || tmp == str + 1) {
955 semantic_error("Array index must be a" 955 semantic_error("Array index must be a"
956 " number.\n"); 956 " number.\n");
957 return -EINVAL; 957 return -EINVAL;
958 } 958 }
959 tmp++; 959 tmp++;
960 if (*tmp == '\0') 960 if (*tmp == '\0')
961 tmp = NULL; 961 tmp = NULL;
962 } else { /* Structure */ 962 } else { /* Structure */
963 if (*tmp == '.') { 963 if (*tmp == '.') {
964 str = tmp + 1; 964 str = tmp + 1;
965 (*fieldp)->ref = false; 965 (*fieldp)->ref = false;
966 } else if (tmp[1] == '>') { 966 } else if (tmp[1] == '>') {
967 str = tmp + 2; 967 str = tmp + 2;
968 (*fieldp)->ref = true; 968 (*fieldp)->ref = true;
969 } else { 969 } else {
970 semantic_error("Argument parse error: %s\n", 970 semantic_error("Argument parse error: %s\n",
971 str); 971 str);
972 return -EINVAL; 972 return -EINVAL;
973 } 973 }
974 tmp = strpbrk(str, "-.["); 974 tmp = strpbrk(str, "-.[");
975 } 975 }
976 if (tmp) { 976 if (tmp) {
977 (*fieldp)->name = strndup(str, tmp - str); 977 (*fieldp)->name = strndup(str, tmp - str);
978 if ((*fieldp)->name == NULL) 978 if ((*fieldp)->name == NULL)
979 return -ENOMEM; 979 return -ENOMEM;
980 if (*str != '[') 980 if (*str != '[')
981 goodname = (*fieldp)->name; 981 goodname = (*fieldp)->name;
982 pr_debug("%s(%d), ", (*fieldp)->name, (*fieldp)->ref); 982 pr_debug("%s(%d), ", (*fieldp)->name, (*fieldp)->ref);
983 fieldp = &(*fieldp)->next; 983 fieldp = &(*fieldp)->next;
984 } 984 }
985 } while (tmp); 985 } while (tmp);
986 (*fieldp)->name = strdup(str); 986 (*fieldp)->name = strdup(str);
987 if ((*fieldp)->name == NULL) 987 if ((*fieldp)->name == NULL)
988 return -ENOMEM; 988 return -ENOMEM;
989 if (*str != '[') 989 if (*str != '[')
990 goodname = (*fieldp)->name; 990 goodname = (*fieldp)->name;
991 pr_debug("%s(%d)\n", (*fieldp)->name, (*fieldp)->ref); 991 pr_debug("%s(%d)\n", (*fieldp)->name, (*fieldp)->ref);
992 992
993 /* If no name is specified, set the last field name (not array index)*/ 993 /* If no name is specified, set the last field name (not array index)*/
994 if (!arg->name) { 994 if (!arg->name) {
995 arg->name = strdup(goodname); 995 arg->name = strdup(goodname);
996 if (arg->name == NULL) 996 if (arg->name == NULL)
997 return -ENOMEM; 997 return -ENOMEM;
998 } 998 }
999 return 0; 999 return 0;
1000 } 1000 }
1001 1001
1002 /* Parse perf-probe event command */ 1002 /* Parse perf-probe event command */
1003 int parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev) 1003 int parse_perf_probe_command(const char *cmd, struct perf_probe_event *pev)
1004 { 1004 {
1005 char **argv; 1005 char **argv;
1006 int argc, i, ret = 0; 1006 int argc, i, ret = 0;
1007 1007
1008 argv = argv_split(cmd, &argc); 1008 argv = argv_split(cmd, &argc);
1009 if (!argv) { 1009 if (!argv) {
1010 pr_debug("Failed to split arguments.\n"); 1010 pr_debug("Failed to split arguments.\n");
1011 return -ENOMEM; 1011 return -ENOMEM;
1012 } 1012 }
1013 if (argc - 1 > MAX_PROBE_ARGS) { 1013 if (argc - 1 > MAX_PROBE_ARGS) {
1014 semantic_error("Too many probe arguments (%d).\n", argc - 1); 1014 semantic_error("Too many probe arguments (%d).\n", argc - 1);
1015 ret = -ERANGE; 1015 ret = -ERANGE;
1016 goto out; 1016 goto out;
1017 } 1017 }
1018 /* Parse probe point */ 1018 /* Parse probe point */
1019 ret = parse_perf_probe_point(argv[0], pev); 1019 ret = parse_perf_probe_point(argv[0], pev);
1020 if (ret < 0) 1020 if (ret < 0)
1021 goto out; 1021 goto out;
1022 1022
1023 /* Copy arguments and ensure return probe has no C argument */ 1023 /* Copy arguments and ensure return probe has no C argument */
1024 pev->nargs = argc - 1; 1024 pev->nargs = argc - 1;
1025 pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs); 1025 pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
1026 if (pev->args == NULL) { 1026 if (pev->args == NULL) {
1027 ret = -ENOMEM; 1027 ret = -ENOMEM;
1028 goto out; 1028 goto out;
1029 } 1029 }
1030 for (i = 0; i < pev->nargs && ret >= 0; i++) { 1030 for (i = 0; i < pev->nargs && ret >= 0; i++) {
1031 ret = parse_perf_probe_arg(argv[i + 1], &pev->args[i]); 1031 ret = parse_perf_probe_arg(argv[i + 1], &pev->args[i]);
1032 if (ret >= 0 && 1032 if (ret >= 0 &&
1033 is_c_varname(pev->args[i].var) && pev->point.retprobe) { 1033 is_c_varname(pev->args[i].var) && pev->point.retprobe) {
1034 semantic_error("You can't specify local variable for" 1034 semantic_error("You can't specify local variable for"
1035 " kretprobe.\n"); 1035 " kretprobe.\n");
1036 ret = -EINVAL; 1036 ret = -EINVAL;
1037 } 1037 }
1038 } 1038 }
1039 out: 1039 out:
1040 argv_free(argv); 1040 argv_free(argv);
1041 1041
1042 return ret; 1042 return ret;
1043 } 1043 }
1044 1044
1045 /* Return true if this perf_probe_event requires debuginfo */ 1045 /* Return true if this perf_probe_event requires debuginfo */
1046 bool perf_probe_event_need_dwarf(struct perf_probe_event *pev) 1046 bool perf_probe_event_need_dwarf(struct perf_probe_event *pev)
1047 { 1047 {
1048 int i; 1048 int i;
1049 1049
1050 if (pev->point.file || pev->point.line || pev->point.lazy_line) 1050 if (pev->point.file || pev->point.line || pev->point.lazy_line)
1051 return true; 1051 return true;
1052 1052
1053 for (i = 0; i < pev->nargs; i++) 1053 for (i = 0; i < pev->nargs; i++)
1054 if (is_c_varname(pev->args[i].var)) 1054 if (is_c_varname(pev->args[i].var))
1055 return true; 1055 return true;
1056 1056
1057 return false; 1057 return false;
1058 } 1058 }
1059 1059
1060 /* Parse probe_events event into struct probe_point */ 1060 /* Parse probe_events event into struct probe_point */
1061 static int parse_probe_trace_command(const char *cmd, 1061 static int parse_probe_trace_command(const char *cmd,
1062 struct probe_trace_event *tev) 1062 struct probe_trace_event *tev)
1063 { 1063 {
1064 struct probe_trace_point *tp = &tev->point; 1064 struct probe_trace_point *tp = &tev->point;
1065 char pr; 1065 char pr;
1066 char *p; 1066 char *p;
1067 int ret, i, argc; 1067 int ret, i, argc;
1068 char **argv; 1068 char **argv;
1069 1069
1070 pr_debug("Parsing probe_events: %s\n", cmd); 1070 pr_debug("Parsing probe_events: %s\n", cmd);
1071 argv = argv_split(cmd, &argc); 1071 argv = argv_split(cmd, &argc);
1072 if (!argv) { 1072 if (!argv) {
1073 pr_debug("Failed to split arguments.\n"); 1073 pr_debug("Failed to split arguments.\n");
1074 return -ENOMEM; 1074 return -ENOMEM;
1075 } 1075 }
1076 if (argc < 2) { 1076 if (argc < 2) {
1077 semantic_error("Too few probe arguments.\n"); 1077 semantic_error("Too few probe arguments.\n");
1078 ret = -ERANGE; 1078 ret = -ERANGE;
1079 goto out; 1079 goto out;
1080 } 1080 }
1081 1081
1082 /* Scan event and group name. */ 1082 /* Scan event and group name. */
1083 ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]", 1083 ret = sscanf(argv[0], "%c:%a[^/ \t]/%a[^ \t]",
1084 &pr, (float *)(void *)&tev->group, 1084 &pr, (float *)(void *)&tev->group,
1085 (float *)(void *)&tev->event); 1085 (float *)(void *)&tev->event);
1086 if (ret != 3) { 1086 if (ret != 3) {
1087 semantic_error("Failed to parse event name: %s\n", argv[0]); 1087 semantic_error("Failed to parse event name: %s\n", argv[0]);
1088 ret = -EINVAL; 1088 ret = -EINVAL;
1089 goto out; 1089 goto out;
1090 } 1090 }
1091 pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr); 1091 pr_debug("Group:%s Event:%s probe:%c\n", tev->group, tev->event, pr);
1092 1092
1093 tp->retprobe = (pr == 'r'); 1093 tp->retprobe = (pr == 'r');
1094 1094
1095 /* Scan module name(if there), function name and offset */ 1095 /* Scan module name(if there), function name and offset */
1096 p = strchr(argv[1], ':'); 1096 p = strchr(argv[1], ':');
1097 if (p) { 1097 if (p) {
1098 tp->module = strndup(argv[1], p - argv[1]); 1098 tp->module = strndup(argv[1], p - argv[1]);
1099 p++; 1099 p++;
1100 } else 1100 } else
1101 p = argv[1]; 1101 p = argv[1];
1102 ret = sscanf(p, "%a[^+]+%lu", (float *)(void *)&tp->symbol, 1102 ret = sscanf(p, "%a[^+]+%lu", (float *)(void *)&tp->symbol,
1103 &tp->offset); 1103 &tp->offset);
1104 if (ret == 1) 1104 if (ret == 1)
1105 tp->offset = 0; 1105 tp->offset = 0;
1106 1106
1107 tev->nargs = argc - 2; 1107 tev->nargs = argc - 2;
1108 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs); 1108 tev->args = zalloc(sizeof(struct probe_trace_arg) * tev->nargs);
1109 if (tev->args == NULL) { 1109 if (tev->args == NULL) {
1110 ret = -ENOMEM; 1110 ret = -ENOMEM;
1111 goto out; 1111 goto out;
1112 } 1112 }
1113 for (i = 0; i < tev->nargs; i++) { 1113 for (i = 0; i < tev->nargs; i++) {
1114 p = strchr(argv[i + 2], '='); 1114 p = strchr(argv[i + 2], '=');
1115 if (p) /* We don't need which register is assigned. */ 1115 if (p) /* We don't need which register is assigned. */
1116 *p++ = '\0'; 1116 *p++ = '\0';
1117 else 1117 else
1118 p = argv[i + 2]; 1118 p = argv[i + 2];
1119 tev->args[i].name = strdup(argv[i + 2]); 1119 tev->args[i].name = strdup(argv[i + 2]);
1120 /* TODO: parse regs and offset */ 1120 /* TODO: parse regs and offset */
1121 tev->args[i].value = strdup(p); 1121 tev->args[i].value = strdup(p);
1122 if (tev->args[i].name == NULL || tev->args[i].value == NULL) { 1122 if (tev->args[i].name == NULL || tev->args[i].value == NULL) {
1123 ret = -ENOMEM; 1123 ret = -ENOMEM;
1124 goto out; 1124 goto out;
1125 } 1125 }
1126 } 1126 }
1127 ret = 0; 1127 ret = 0;
1128 out: 1128 out:
1129 argv_free(argv); 1129 argv_free(argv);
1130 return ret; 1130 return ret;
1131 } 1131 }
1132 1132
1133 /* Compose only probe arg */ 1133 /* Compose only probe arg */
1134 int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len) 1134 int synthesize_perf_probe_arg(struct perf_probe_arg *pa, char *buf, size_t len)
1135 { 1135 {
1136 struct perf_probe_arg_field *field = pa->field; 1136 struct perf_probe_arg_field *field = pa->field;
1137 int ret; 1137 int ret;
1138 char *tmp = buf; 1138 char *tmp = buf;
1139 1139
1140 if (pa->name && pa->var) 1140 if (pa->name && pa->var)
1141 ret = e_snprintf(tmp, len, "%s=%s", pa->name, pa->var); 1141 ret = e_snprintf(tmp, len, "%s=%s", pa->name, pa->var);
1142 else 1142 else
1143 ret = e_snprintf(tmp, len, "%s", pa->name ? pa->name : pa->var); 1143 ret = e_snprintf(tmp, len, "%s", pa->name ? pa->name : pa->var);
1144 if (ret <= 0) 1144 if (ret <= 0)
1145 goto error; 1145 goto error;
1146 tmp += ret; 1146 tmp += ret;
1147 len -= ret; 1147 len -= ret;
1148 1148
1149 while (field) { 1149 while (field) {
1150 if (field->name[0] == '[') 1150 if (field->name[0] == '[')
1151 ret = e_snprintf(tmp, len, "%s", field->name); 1151 ret = e_snprintf(tmp, len, "%s", field->name);
1152 else 1152 else
1153 ret = e_snprintf(tmp, len, "%s%s", 1153 ret = e_snprintf(tmp, len, "%s%s",
1154 field->ref ? "->" : ".", field->name); 1154 field->ref ? "->" : ".", field->name);
1155 if (ret <= 0) 1155 if (ret <= 0)
1156 goto error; 1156 goto error;
1157 tmp += ret; 1157 tmp += ret;
1158 len -= ret; 1158 len -= ret;
1159 field = field->next; 1159 field = field->next;
1160 } 1160 }
1161 1161
1162 if (pa->type) { 1162 if (pa->type) {
1163 ret = e_snprintf(tmp, len, ":%s", pa->type); 1163 ret = e_snprintf(tmp, len, ":%s", pa->type);
1164 if (ret <= 0) 1164 if (ret <= 0)
1165 goto error; 1165 goto error;
1166 tmp += ret; 1166 tmp += ret;
1167 len -= ret; 1167 len -= ret;
1168 } 1168 }
1169 1169
1170 return tmp - buf; 1170 return tmp - buf;
1171 error: 1171 error:
1172 pr_debug("Failed to synthesize perf probe argument: %s\n", 1172 pr_debug("Failed to synthesize perf probe argument: %s\n",
1173 strerror(-ret)); 1173 strerror(-ret));
1174 return ret; 1174 return ret;
1175 } 1175 }
1176 1176
1177 /* Compose only probe point (not argument) */ 1177 /* Compose only probe point (not argument) */
1178 static char *synthesize_perf_probe_point(struct perf_probe_point *pp) 1178 static char *synthesize_perf_probe_point(struct perf_probe_point *pp)
1179 { 1179 {
1180 char *buf, *tmp; 1180 char *buf, *tmp;
1181 char offs[32] = "", line[32] = "", file[32] = ""; 1181 char offs[32] = "", line[32] = "", file[32] = "";
1182 int ret, len; 1182 int ret, len;
1183 1183
1184 buf = zalloc(MAX_CMDLEN); 1184 buf = zalloc(MAX_CMDLEN);
1185 if (buf == NULL) { 1185 if (buf == NULL) {
1186 ret = -ENOMEM; 1186 ret = -ENOMEM;
1187 goto error; 1187 goto error;
1188 } 1188 }
1189 if (pp->offset) { 1189 if (pp->offset) {
1190 ret = e_snprintf(offs, 32, "+%lu", pp->offset); 1190 ret = e_snprintf(offs, 32, "+%lu", pp->offset);
1191 if (ret <= 0) 1191 if (ret <= 0)
1192 goto error; 1192 goto error;
1193 } 1193 }
1194 if (pp->line) { 1194 if (pp->line) {
1195 ret = e_snprintf(line, 32, ":%d", pp->line); 1195 ret = e_snprintf(line, 32, ":%d", pp->line);
1196 if (ret <= 0) 1196 if (ret <= 0)
1197 goto error; 1197 goto error;
1198 } 1198 }
1199 if (pp->file) { 1199 if (pp->file) {
1200 tmp = pp->file; 1200 tmp = pp->file;
1201 len = strlen(tmp); 1201 len = strlen(tmp);
1202 if (len > 30) { 1202 if (len > 30) {
1203 tmp = strchr(pp->file + len - 30, '/'); 1203 tmp = strchr(pp->file + len - 30, '/');
1204 tmp = tmp ? tmp + 1 : pp->file + len - 30; 1204 tmp = tmp ? tmp + 1 : pp->file + len - 30;
1205 } 1205 }
1206 ret = e_snprintf(file, 32, "@%s", tmp); 1206 ret = e_snprintf(file, 32, "@%s", tmp);
1207 if (ret <= 0) 1207 if (ret <= 0)
1208 goto error; 1208 goto error;
1209 } 1209 }
1210 1210
1211 if (pp->function) 1211 if (pp->function)
1212 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s%s", pp->function, 1212 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s%s%s%s", pp->function,
1213 offs, pp->retprobe ? "%return" : "", line, 1213 offs, pp->retprobe ? "%return" : "", line,
1214 file); 1214 file);
1215 else 1215 else
1216 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", file, line); 1216 ret = e_snprintf(buf, MAX_CMDLEN, "%s%s", file, line);
1217 if (ret <= 0) 1217 if (ret <= 0)
1218 goto error; 1218 goto error;
1219 1219
1220 return buf; 1220 return buf;
1221 error: 1221 error:
1222 pr_debug("Failed to synthesize perf probe point: %s\n", 1222 pr_debug("Failed to synthesize perf probe point: %s\n",
1223 strerror(-ret)); 1223 strerror(-ret));
1224 if (buf) 1224 if (buf)
1225 free(buf); 1225 free(buf);
1226 return NULL; 1226 return NULL;
1227 } 1227 }
1228 1228
1229 #if 0 1229 #if 0
1230 char *synthesize_perf_probe_command(struct perf_probe_event *pev) 1230 char *synthesize_perf_probe_command(struct perf_probe_event *pev)
1231 { 1231 {
1232 char *buf; 1232 char *buf;
1233 int i, len, ret; 1233 int i, len, ret;
1234 1234
1235 buf = synthesize_perf_probe_point(&pev->point); 1235 buf = synthesize_perf_probe_point(&pev->point);
1236 if (!buf) 1236 if (!buf)
1237 return NULL; 1237 return NULL;
1238 1238
1239 len = strlen(buf); 1239 len = strlen(buf);
1240 for (i = 0; i < pev->nargs; i++) { 1240 for (i = 0; i < pev->nargs; i++) {
1241 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s", 1241 ret = e_snprintf(&buf[len], MAX_CMDLEN - len, " %s",
1242 pev->args[i].name); 1242 pev->args[i].name);
1243 if (ret <= 0) { 1243 if (ret <= 0) {
1244 free(buf); 1244 free(buf);
1245 return NULL; 1245 return NULL;
1246 } 1246 }
1247 len += ret; 1247 len += ret;
1248 } 1248 }
1249 1249
1250 return buf; 1250 return buf;
1251 } 1251 }
1252 #endif 1252 #endif
1253 1253
1254 static int __synthesize_probe_trace_arg_ref(struct probe_trace_arg_ref *ref, 1254 static int __synthesize_probe_trace_arg_ref(struct probe_trace_arg_ref *ref,
1255 char **buf, size_t *buflen, 1255 char **buf, size_t *buflen,
1256 int depth) 1256 int depth)
1257 { 1257 {
1258 int ret; 1258 int ret;
1259 if (ref->next) { 1259 if (ref->next) {
1260 depth = __synthesize_probe_trace_arg_ref(ref->next, buf, 1260 depth = __synthesize_probe_trace_arg_ref(ref->next, buf,
1261 buflen, depth + 1); 1261 buflen, depth + 1);
1262 if (depth < 0) 1262 if (depth < 0)
1263 goto out; 1263 goto out;
1264 } 1264 }
1265 1265
1266 ret = e_snprintf(*buf, *buflen, "%+ld(", ref->offset); 1266 ret = e_snprintf(*buf, *buflen, "%+ld(", ref->offset);
1267 if (ret < 0) 1267 if (ret < 0)
1268 depth = ret; 1268 depth = ret;
1269 else { 1269 else {
1270 *buf += ret; 1270 *buf += ret;
1271 *buflen -= ret; 1271 *buflen -= ret;
1272 } 1272 }
1273 out: 1273 out:
1274 return depth; 1274 return depth;
1275 1275
1276 } 1276 }
1277 1277
1278 static int synthesize_probe_trace_arg(struct probe_trace_arg *arg, 1278 static int synthesize_probe_trace_arg(struct probe_trace_arg *arg,
1279 char *buf, size_t buflen) 1279 char *buf, size_t buflen)
1280 { 1280 {
1281 struct probe_trace_arg_ref *ref = arg->ref; 1281 struct probe_trace_arg_ref *ref = arg->ref;
1282 int ret, depth = 0; 1282 int ret, depth = 0;
1283 char *tmp = buf; 1283 char *tmp = buf;
1284 1284
1285 /* Argument name or separator */ 1285 /* Argument name or separator */
1286 if (arg->name) 1286 if (arg->name)
1287 ret = e_snprintf(buf, buflen, " %s=", arg->name); 1287 ret = e_snprintf(buf, buflen, " %s=", arg->name);
1288 else 1288 else
1289 ret = e_snprintf(buf, buflen, " "); 1289 ret = e_snprintf(buf, buflen, " ");
1290 if (ret < 0) 1290 if (ret < 0)
1291 return ret; 1291 return ret;
1292 buf += ret; 1292 buf += ret;
1293 buflen -= ret; 1293 buflen -= ret;
1294 1294
1295 /* Special case: @XXX */ 1295 /* Special case: @XXX */
1296 if (arg->value[0] == '@' && arg->ref) 1296 if (arg->value[0] == '@' && arg->ref)
1297 ref = ref->next; 1297 ref = ref->next;
1298 1298
1299 /* Dereferencing arguments */ 1299 /* Dereferencing arguments */
1300 if (ref) { 1300 if (ref) {
1301 depth = __synthesize_probe_trace_arg_ref(ref, &buf, 1301 depth = __synthesize_probe_trace_arg_ref(ref, &buf,
1302 &buflen, 1); 1302 &buflen, 1);
1303 if (depth < 0) 1303 if (depth < 0)
1304 return depth; 1304 return depth;
1305 } 1305 }
1306 1306
1307 /* Print argument value */ 1307 /* Print argument value */
1308 if (arg->value[0] == '@' && arg->ref) 1308 if (arg->value[0] == '@' && arg->ref)
1309 ret = e_snprintf(buf, buflen, "%s%+ld", arg->value, 1309 ret = e_snprintf(buf, buflen, "%s%+ld", arg->value,
1310 arg->ref->offset); 1310 arg->ref->offset);
1311 else 1311 else
1312 ret = e_snprintf(buf, buflen, "%s", arg->value); 1312 ret = e_snprintf(buf, buflen, "%s", arg->value);
1313 if (ret < 0) 1313 if (ret < 0)
1314 return ret; 1314 return ret;
1315 buf += ret; 1315 buf += ret;
1316 buflen -= ret; 1316 buflen -= ret;
1317 1317
1318 /* Closing */ 1318 /* Closing */
1319 while (depth--) { 1319 while (depth--) {
1320 ret = e_snprintf(buf, buflen, ")"); 1320 ret = e_snprintf(buf, buflen, ")");
1321 if (ret < 0) 1321 if (ret < 0)
1322 return ret; 1322 return ret;
1323 buf += ret; 1323 buf += ret;
1324 buflen -= ret; 1324 buflen -= ret;
1325 } 1325 }
1326 /* Print argument type */ 1326 /* Print argument type */
1327 if (arg->type) { 1327 if (arg->type) {
1328 ret = e_snprintf(buf, buflen, ":%s", arg->type); 1328 ret = e_snprintf(buf, buflen, ":%s", arg->type);
1329 if (ret <= 0) 1329 if (ret <= 0)
1330 return ret; 1330 return ret;
1331 buf += ret; 1331 buf += ret;
1332 } 1332 }
1333 1333
1334 return buf - tmp; 1334 return buf - tmp;
1335 } 1335 }
1336 1336
1337 char *synthesize_probe_trace_command(struct probe_trace_event *tev) 1337 char *synthesize_probe_trace_command(struct probe_trace_event *tev)
1338 { 1338 {
1339 struct probe_trace_point *tp = &tev->point; 1339 struct probe_trace_point *tp = &tev->point;
1340 char *buf; 1340 char *buf;
1341 int i, len, ret; 1341 int i, len, ret;
1342 1342
1343 buf = zalloc(MAX_CMDLEN); 1343 buf = zalloc(MAX_CMDLEN);
1344 if (buf == NULL) 1344 if (buf == NULL)
1345 return NULL; 1345 return NULL;
1346 1346
1347 len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s%s%s+%lu", 1347 len = e_snprintf(buf, MAX_CMDLEN, "%c:%s/%s %s%s%s+%lu",
1348 tp->retprobe ? 'r' : 'p', 1348 tp->retprobe ? 'r' : 'p',
1349 tev->group, tev->event, 1349 tev->group, tev->event,
1350 tp->module ?: "", tp->module ? ":" : "", 1350 tp->module ?: "", tp->module ? ":" : "",
1351 tp->symbol, tp->offset); 1351 tp->symbol, tp->offset);
1352 if (len <= 0) 1352 if (len <= 0)
1353 goto error; 1353 goto error;
1354 1354
1355 for (i = 0; i < tev->nargs; i++) { 1355 for (i = 0; i < tev->nargs; i++) {
1356 ret = synthesize_probe_trace_arg(&tev->args[i], buf + len, 1356 ret = synthesize_probe_trace_arg(&tev->args[i], buf + len,
1357 MAX_CMDLEN - len); 1357 MAX_CMDLEN - len);
1358 if (ret <= 0) 1358 if (ret <= 0)
1359 goto error; 1359 goto error;
1360 len += ret; 1360 len += ret;
1361 } 1361 }
1362 1362
1363 return buf; 1363 return buf;
1364 error: 1364 error:
1365 free(buf); 1365 free(buf);
1366 return NULL; 1366 return NULL;
1367 } 1367 }
1368 1368
1369 static int convert_to_perf_probe_event(struct probe_trace_event *tev, 1369 static int convert_to_perf_probe_event(struct probe_trace_event *tev,
1370 struct perf_probe_event *pev) 1370 struct perf_probe_event *pev)
1371 { 1371 {
1372 char buf[64] = ""; 1372 char buf[64] = "";
1373 int i, ret; 1373 int i, ret;
1374 1374
1375 /* Convert event/group name */ 1375 /* Convert event/group name */
1376 pev->event = strdup(tev->event); 1376 pev->event = strdup(tev->event);
1377 pev->group = strdup(tev->group); 1377 pev->group = strdup(tev->group);
1378 if (pev->event == NULL || pev->group == NULL) 1378 if (pev->event == NULL || pev->group == NULL)
1379 return -ENOMEM; 1379 return -ENOMEM;
1380 1380
1381 /* Convert trace_point to probe_point */ 1381 /* Convert trace_point to probe_point */
1382 ret = kprobe_convert_to_perf_probe(&tev->point, &pev->point); 1382 ret = kprobe_convert_to_perf_probe(&tev->point, &pev->point);
1383 if (ret < 0) 1383 if (ret < 0)
1384 return ret; 1384 return ret;
1385 1385
1386 /* Convert trace_arg to probe_arg */ 1386 /* Convert trace_arg to probe_arg */
1387 pev->nargs = tev->nargs; 1387 pev->nargs = tev->nargs;
1388 pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs); 1388 pev->args = zalloc(sizeof(struct perf_probe_arg) * pev->nargs);
1389 if (pev->args == NULL) 1389 if (pev->args == NULL)
1390 return -ENOMEM; 1390 return -ENOMEM;
1391 for (i = 0; i < tev->nargs && ret >= 0; i++) { 1391 for (i = 0; i < tev->nargs && ret >= 0; i++) {
1392 if (tev->args[i].name) 1392 if (tev->args[i].name)
1393 pev->args[i].name = strdup(tev->args[i].name); 1393 pev->args[i].name = strdup(tev->args[i].name);
1394 else { 1394 else {
1395 ret = synthesize_probe_trace_arg(&tev->args[i], 1395 ret = synthesize_probe_trace_arg(&tev->args[i],
1396 buf, 64); 1396 buf, 64);
1397 pev->args[i].name = strdup(buf); 1397 pev->args[i].name = strdup(buf);
1398 } 1398 }
1399 if (pev->args[i].name == NULL && ret >= 0) 1399 if (pev->args[i].name == NULL && ret >= 0)
1400 ret = -ENOMEM; 1400 ret = -ENOMEM;
1401 } 1401 }
1402 1402
1403 if (ret < 0) 1403 if (ret < 0)
1404 clear_perf_probe_event(pev); 1404 clear_perf_probe_event(pev);
1405 1405
1406 return ret; 1406 return ret;
1407 } 1407 }
1408 1408
1409 void clear_perf_probe_event(struct perf_probe_event *pev) 1409 void clear_perf_probe_event(struct perf_probe_event *pev)
1410 { 1410 {
1411 struct perf_probe_point *pp = &pev->point; 1411 struct perf_probe_point *pp = &pev->point;
1412 struct perf_probe_arg_field *field, *next; 1412 struct perf_probe_arg_field *field, *next;
1413 int i; 1413 int i;
1414 1414
1415 if (pev->event) 1415 if (pev->event)
1416 free(pev->event); 1416 free(pev->event);
1417 if (pev->group) 1417 if (pev->group)
1418 free(pev->group); 1418 free(pev->group);
1419 if (pp->file) 1419 if (pp->file)
1420 free(pp->file); 1420 free(pp->file);
1421 if (pp->function) 1421 if (pp->function)
1422 free(pp->function); 1422 free(pp->function);
1423 if (pp->lazy_line) 1423 if (pp->lazy_line)
1424 free(pp->lazy_line); 1424 free(pp->lazy_line);
1425 for (i = 0; i < pev->nargs; i++) { 1425 for (i = 0; i < pev->nargs; i++) {
1426 if (pev->args[i].name) 1426 if (pev->args[i].name)
1427 free(pev->args[i].name); 1427 free(pev->args[i].name);
1428 if (pev->args[i].var) 1428 if (pev->args[i].var)
1429 free(pev->args[i].var); 1429 free(pev->args[i].var);
1430 if (pev->args[i].type) 1430 if (pev->args[i].type)
1431 free(pev->args[i].type); 1431 free(pev->args[i].type);
1432 field = pev->args[i].field; 1432 field = pev->args[i].field;
1433 while (field) { 1433 while (field) {
1434 next = field->next; 1434 next = field->next;
1435 if (field->name) 1435 if (field->name)
1436 free(field->name); 1436 free(field->name);
1437 free(field); 1437 free(field);
1438 field = next; 1438 field = next;
1439 } 1439 }
1440 } 1440 }
1441 if (pev->args) 1441 if (pev->args)
1442 free(pev->args); 1442 free(pev->args);
1443 memset(pev, 0, sizeof(*pev)); 1443 memset(pev, 0, sizeof(*pev));
1444 } 1444 }
1445 1445
1446 static void clear_probe_trace_event(struct probe_trace_event *tev) 1446 static void clear_probe_trace_event(struct probe_trace_event *tev)
1447 { 1447 {
1448 struct probe_trace_arg_ref *ref, *next; 1448 struct probe_trace_arg_ref *ref, *next;
1449 int i; 1449 int i;
1450 1450
1451 if (tev->event) 1451 if (tev->event)
1452 free(tev->event); 1452 free(tev->event);
1453 if (tev->group) 1453 if (tev->group)
1454 free(tev->group); 1454 free(tev->group);
1455 if (tev->point.symbol) 1455 if (tev->point.symbol)
1456 free(tev->point.symbol); 1456 free(tev->point.symbol);
1457 if (tev->point.module) 1457 if (tev->point.module)
1458 free(tev->point.module); 1458 free(tev->point.module);
1459 for (i = 0; i < tev->nargs; i++) { 1459 for (i = 0; i < tev->nargs; i++) {
1460 if (tev->args[i].name) 1460 if (tev->args[i].name)
1461 free(tev->args[i].name); 1461 free(tev->args[i].name);
1462 if (tev->args[i].value) 1462 if (tev->args[i].value)
1463 free(tev->args[i].value); 1463 free(tev->args[i].value);
1464 if (tev->args[i].type) 1464 if (tev->args[i].type)
1465 free(tev->args[i].type); 1465 free(tev->args[i].type);
1466 ref = tev->args[i].ref; 1466 ref = tev->args[i].ref;
1467 while (ref) { 1467 while (ref) {
1468 next = ref->next; 1468 next = ref->next;
1469 free(ref); 1469 free(ref);
1470 ref = next; 1470 ref = next;
1471 } 1471 }
1472 } 1472 }
1473 if (tev->args) 1473 if (tev->args)
1474 free(tev->args); 1474 free(tev->args);
1475 memset(tev, 0, sizeof(*tev)); 1475 memset(tev, 0, sizeof(*tev));
1476 } 1476 }
1477 1477
1478 static int open_kprobe_events(bool readwrite) 1478 static int open_kprobe_events(bool readwrite)
1479 { 1479 {
1480 char buf[PATH_MAX]; 1480 char buf[PATH_MAX];
1481 const char *__debugfs; 1481 const char *__debugfs;
1482 int ret; 1482 int ret;
1483 1483
1484 __debugfs = debugfs_find_mountpoint(); 1484 __debugfs = debugfs_find_mountpoint();
1485 if (__debugfs == NULL) { 1485 if (__debugfs == NULL) {
1486 pr_warning("Debugfs is not mounted.\n"); 1486 pr_warning("Debugfs is not mounted.\n");
1487 return -ENOENT; 1487 return -ENOENT;
1488 } 1488 }
1489 1489
1490 ret = e_snprintf(buf, PATH_MAX, "%stracing/kprobe_events", __debugfs); 1490 ret = e_snprintf(buf, PATH_MAX, "%stracing/kprobe_events", __debugfs);
1491 if (ret >= 0) { 1491 if (ret >= 0) {
1492 pr_debug("Opening %s write=%d\n", buf, readwrite); 1492 pr_debug("Opening %s write=%d\n", buf, readwrite);
1493 if (readwrite && !probe_event_dry_run) 1493 if (readwrite && !probe_event_dry_run)
1494 ret = open(buf, O_RDWR, O_APPEND); 1494 ret = open(buf, O_RDWR, O_APPEND);
1495 else 1495 else
1496 ret = open(buf, O_RDONLY, 0); 1496 ret = open(buf, O_RDONLY, 0);
1497 } 1497 }
1498 1498
1499 if (ret < 0) { 1499 if (ret < 0) {
1500 if (errno == ENOENT) 1500 if (errno == ENOENT)
1501 pr_warning("kprobe_events file does not exist - please" 1501 pr_warning("kprobe_events file does not exist - please"
1502 " rebuild kernel with CONFIG_KPROBE_EVENT.\n"); 1502 " rebuild kernel with CONFIG_KPROBE_EVENT.\n");
1503 else 1503 else
1504 pr_warning("Failed to open kprobe_events file: %s\n", 1504 pr_warning("Failed to open kprobe_events file: %s\n",
1505 strerror(errno)); 1505 strerror(errno));
1506 } 1506 }
1507 return ret; 1507 return ret;
1508 } 1508 }
1509 1509
1510 /* Get raw string list of current kprobe_events */ 1510 /* Get raw string list of current kprobe_events */
1511 static struct strlist *get_probe_trace_command_rawlist(int fd) 1511 static struct strlist *get_probe_trace_command_rawlist(int fd)
1512 { 1512 {
1513 int ret, idx; 1513 int ret, idx;
1514 FILE *fp; 1514 FILE *fp;
1515 char buf[MAX_CMDLEN]; 1515 char buf[MAX_CMDLEN];
1516 char *p; 1516 char *p;
1517 struct strlist *sl; 1517 struct strlist *sl;
1518 1518
1519 sl = strlist__new(true, NULL); 1519 sl = strlist__new(true, NULL);
1520 1520
1521 fp = fdopen(dup(fd), "r"); 1521 fp = fdopen(dup(fd), "r");
1522 while (!feof(fp)) { 1522 while (!feof(fp)) {
1523 p = fgets(buf, MAX_CMDLEN, fp); 1523 p = fgets(buf, MAX_CMDLEN, fp);
1524 if (!p) 1524 if (!p)
1525 break; 1525 break;
1526 1526
1527 idx = strlen(p) - 1; 1527 idx = strlen(p) - 1;
1528 if (p[idx] == '\n') 1528 if (p[idx] == '\n')
1529 p[idx] = '\0'; 1529 p[idx] = '\0';
1530 ret = strlist__add(sl, buf); 1530 ret = strlist__add(sl, buf);
1531 if (ret < 0) { 1531 if (ret < 0) {
1532 pr_debug("strlist__add failed: %s\n", strerror(-ret)); 1532 pr_debug("strlist__add failed: %s\n", strerror(-ret));
1533 strlist__delete(sl); 1533 strlist__delete(sl);
1534 return NULL; 1534 return NULL;
1535 } 1535 }
1536 } 1536 }
1537 fclose(fp); 1537 fclose(fp);
1538 1538
1539 return sl; 1539 return sl;
1540 } 1540 }
1541 1541
1542 /* Show an event */ 1542 /* Show an event */
1543 static int show_perf_probe_event(struct perf_probe_event *pev) 1543 static int show_perf_probe_event(struct perf_probe_event *pev)
1544 { 1544 {
1545 int i, ret; 1545 int i, ret;
1546 char buf[128]; 1546 char buf[128];
1547 char *place; 1547 char *place;
1548 1548
1549 /* Synthesize only event probe point */ 1549 /* Synthesize only event probe point */
1550 place = synthesize_perf_probe_point(&pev->point); 1550 place = synthesize_perf_probe_point(&pev->point);
1551 if (!place) 1551 if (!place)
1552 return -EINVAL; 1552 return -EINVAL;
1553 1553
1554 ret = e_snprintf(buf, 128, "%s:%s", pev->group, pev->event); 1554 ret = e_snprintf(buf, 128, "%s:%s", pev->group, pev->event);
1555 if (ret < 0) 1555 if (ret < 0)
1556 return ret; 1556 return ret;
1557 1557
1558 printf(" %-20s (on %s", buf, place); 1558 printf(" %-20s (on %s", buf, place);
1559 1559
1560 if (pev->nargs > 0) { 1560 if (pev->nargs > 0) {
1561 printf(" with"); 1561 printf(" with");
1562 for (i = 0; i < pev->nargs; i++) { 1562 for (i = 0; i < pev->nargs; i++) {
1563 ret = synthesize_perf_probe_arg(&pev->args[i], 1563 ret = synthesize_perf_probe_arg(&pev->args[i],
1564 buf, 128); 1564 buf, 128);
1565 if (ret < 0) 1565 if (ret < 0)
1566 break; 1566 break;
1567 printf(" %s", buf); 1567 printf(" %s", buf);
1568 } 1568 }
1569 } 1569 }
1570 printf(")\n"); 1570 printf(")\n");
1571 free(place); 1571 free(place);
1572 return ret; 1572 return ret;
1573 } 1573 }
1574 1574
1575 /* List up current perf-probe events */ 1575 /* List up current perf-probe events */
1576 int show_perf_probe_events(void) 1576 int show_perf_probe_events(void)
1577 { 1577 {
1578 int fd, ret; 1578 int fd, ret;
1579 struct probe_trace_event tev; 1579 struct probe_trace_event tev;
1580 struct perf_probe_event pev; 1580 struct perf_probe_event pev;
1581 struct strlist *rawlist; 1581 struct strlist *rawlist;
1582 struct str_node *ent; 1582 struct str_node *ent;
1583 1583
1584 setup_pager(); 1584 setup_pager();
1585 ret = init_vmlinux(); 1585 ret = init_vmlinux();
1586 if (ret < 0) 1586 if (ret < 0)
1587 return ret; 1587 return ret;
1588 1588
1589 memset(&tev, 0, sizeof(tev)); 1589 memset(&tev, 0, sizeof(tev));
1590 memset(&pev, 0, sizeof(pev)); 1590 memset(&pev, 0, sizeof(pev));
1591 1591
1592 fd = open_kprobe_events(false); 1592 fd = open_kprobe_events(false);
1593 if (fd < 0) 1593 if (fd < 0)
1594 return fd; 1594 return fd;
1595 1595
1596 rawlist = get_probe_trace_command_rawlist(fd); 1596 rawlist = get_probe_trace_command_rawlist(fd);
1597 close(fd); 1597 close(fd);
1598 if (!rawlist) 1598 if (!rawlist)
1599 return -ENOENT; 1599 return -ENOENT;
1600 1600
1601 strlist__for_each(ent, rawlist) { 1601 strlist__for_each(ent, rawlist) {
1602 ret = parse_probe_trace_command(ent->s, &tev); 1602 ret = parse_probe_trace_command(ent->s, &tev);
1603 if (ret >= 0) { 1603 if (ret >= 0) {
1604 ret = convert_to_perf_probe_event(&tev, &pev); 1604 ret = convert_to_perf_probe_event(&tev, &pev);
1605 if (ret >= 0) 1605 if (ret >= 0)
1606 ret = show_perf_probe_event(&pev); 1606 ret = show_perf_probe_event(&pev);
1607 } 1607 }
1608 clear_perf_probe_event(&pev); 1608 clear_perf_probe_event(&pev);
1609 clear_probe_trace_event(&tev); 1609 clear_probe_trace_event(&tev);
1610 if (ret < 0) 1610 if (ret < 0)
1611 break; 1611 break;
1612 } 1612 }
1613 strlist__delete(rawlist); 1613 strlist__delete(rawlist);
1614 1614
1615 return ret; 1615 return ret;
1616 } 1616 }
1617 1617
1618 /* Get current perf-probe event names */ 1618 /* Get current perf-probe event names */
1619 static struct strlist *get_probe_trace_event_names(int fd, bool include_group) 1619 static struct strlist *get_probe_trace_event_names(int fd, bool include_group)
1620 { 1620 {
1621 char buf[128]; 1621 char buf[128];
1622 struct strlist *sl, *rawlist; 1622 struct strlist *sl, *rawlist;
1623 struct str_node *ent; 1623 struct str_node *ent;
1624 struct probe_trace_event tev; 1624 struct probe_trace_event tev;
1625 int ret = 0; 1625 int ret = 0;
1626 1626
1627 memset(&tev, 0, sizeof(tev)); 1627 memset(&tev, 0, sizeof(tev));
1628 rawlist = get_probe_trace_command_rawlist(fd); 1628 rawlist = get_probe_trace_command_rawlist(fd);
1629 sl = strlist__new(true, NULL); 1629 sl = strlist__new(true, NULL);
1630 strlist__for_each(ent, rawlist) { 1630 strlist__for_each(ent, rawlist) {
1631 ret = parse_probe_trace_command(ent->s, &tev); 1631 ret = parse_probe_trace_command(ent->s, &tev);
1632 if (ret < 0) 1632 if (ret < 0)
1633 break; 1633 break;
1634 if (include_group) { 1634 if (include_group) {
1635 ret = e_snprintf(buf, 128, "%s:%s", tev.group, 1635 ret = e_snprintf(buf, 128, "%s:%s", tev.group,
1636 tev.event); 1636 tev.event);
1637 if (ret >= 0) 1637 if (ret >= 0)
1638 ret = strlist__add(sl, buf); 1638 ret = strlist__add(sl, buf);
1639 } else 1639 } else
1640 ret = strlist__add(sl, tev.event); 1640 ret = strlist__add(sl, tev.event);
1641 clear_probe_trace_event(&tev); 1641 clear_probe_trace_event(&tev);
1642 if (ret < 0) 1642 if (ret < 0)
1643 break; 1643 break;
1644 } 1644 }
1645 strlist__delete(rawlist); 1645 strlist__delete(rawlist);
1646 1646
1647 if (ret < 0) { 1647 if (ret < 0) {
1648 strlist__delete(sl); 1648 strlist__delete(sl);
1649 return NULL; 1649 return NULL;
1650 } 1650 }
1651 return sl; 1651 return sl;
1652 } 1652 }
1653 1653
1654 static int write_probe_trace_event(int fd, struct probe_trace_event *tev) 1654 static int write_probe_trace_event(int fd, struct probe_trace_event *tev)
1655 { 1655 {
1656 int ret = 0; 1656 int ret = 0;
1657 char *buf = synthesize_probe_trace_command(tev); 1657 char *buf = synthesize_probe_trace_command(tev);
1658 1658
1659 if (!buf) { 1659 if (!buf) {
1660 pr_debug("Failed to synthesize probe trace event.\n"); 1660 pr_debug("Failed to synthesize probe trace event.\n");
1661 return -EINVAL; 1661 return -EINVAL;
1662 } 1662 }
1663 1663
1664 pr_debug("Writing event: %s\n", buf); 1664 pr_debug("Writing event: %s\n", buf);
1665 if (!probe_event_dry_run) { 1665 if (!probe_event_dry_run) {
1666 ret = write(fd, buf, strlen(buf)); 1666 ret = write(fd, buf, strlen(buf));
1667 if (ret <= 0) 1667 if (ret <= 0)
1668 pr_warning("Failed to write event: %s\n", 1668 pr_warning("Failed to write event: %s\n",
1669 strerror(errno)); 1669 strerror(errno));
1670 } 1670 }
1671 free(buf); 1671 free(buf);
1672 return ret; 1672 return ret;
1673 } 1673 }
1674 1674
1675 static int get_new_event_name(char *buf, size_t len, const char *base, 1675 static int get_new_event_name(char *buf, size_t len, const char *base,
1676 struct strlist *namelist, bool allow_suffix) 1676 struct strlist *namelist, bool allow_suffix)
1677 { 1677 {
1678 int i, ret; 1678 int i, ret;
1679 1679
1680 /* Try no suffix */ 1680 /* Try no suffix */
1681 ret = e_snprintf(buf, len, "%s", base); 1681 ret = e_snprintf(buf, len, "%s", base);
1682 if (ret < 0) { 1682 if (ret < 0) {
1683 pr_debug("snprintf() failed: %s\n", strerror(-ret)); 1683 pr_debug("snprintf() failed: %s\n", strerror(-ret));
1684 return ret; 1684 return ret;
1685 } 1685 }
1686 if (!strlist__has_entry(namelist, buf)) 1686 if (!strlist__has_entry(namelist, buf))
1687 return 0; 1687 return 0;
1688 1688
1689 if (!allow_suffix) { 1689 if (!allow_suffix) {
1690 pr_warning("Error: event \"%s\" already exists. " 1690 pr_warning("Error: event \"%s\" already exists. "
1691 "(Use -f to force duplicates.)\n", base); 1691 "(Use -f to force duplicates.)\n", base);
1692 return -EEXIST; 1692 return -EEXIST;
1693 } 1693 }
1694 1694
1695 /* Try to add suffix */ 1695 /* Try to add suffix */
1696 for (i = 1; i < MAX_EVENT_INDEX; i++) { 1696 for (i = 1; i < MAX_EVENT_INDEX; i++) {
1697 ret = e_snprintf(buf, len, "%s_%d", base, i); 1697 ret = e_snprintf(buf, len, "%s_%d", base, i);
1698 if (ret < 0) { 1698 if (ret < 0) {
1699 pr_debug("snprintf() failed: %s\n", strerror(-ret)); 1699 pr_debug("snprintf() failed: %s\n", strerror(-ret));
1700 return ret; 1700 return ret;
1701 } 1701 }
1702 if (!strlist__has_entry(namelist, buf)) 1702 if (!strlist__has_entry(namelist, buf))
1703 break; 1703 break;
1704 } 1704 }
1705 if (i == MAX_EVENT_INDEX) { 1705 if (i == MAX_EVENT_INDEX) {
1706 pr_warning("Too many events are on the same function.\n"); 1706 pr_warning("Too many events are on the same function.\n");
1707 ret = -ERANGE; 1707 ret = -ERANGE;
1708 } 1708 }
1709 1709
1710 return ret; 1710 return ret;
1711 } 1711 }
1712 1712
1713 static int __add_probe_trace_events(struct perf_probe_event *pev, 1713 static int __add_probe_trace_events(struct perf_probe_event *pev,
1714 struct probe_trace_event *tevs, 1714 struct probe_trace_event *tevs,
1715 int ntevs, bool allow_suffix) 1715 int ntevs, bool allow_suffix)
1716 { 1716 {
1717 int i, fd, ret; 1717 int i, fd, ret;
1718 struct probe_trace_event *tev = NULL; 1718 struct probe_trace_event *tev = NULL;
1719 char buf[64]; 1719 char buf[64];
1720 const char *event, *group; 1720 const char *event, *group;
1721 struct strlist *namelist; 1721 struct strlist *namelist;
1722 1722
1723 fd = open_kprobe_events(true); 1723 fd = open_kprobe_events(true);
1724 if (fd < 0) 1724 if (fd < 0)
1725 return fd; 1725 return fd;
1726 /* Get current event names */ 1726 /* Get current event names */
1727 namelist = get_probe_trace_event_names(fd, false); 1727 namelist = get_probe_trace_event_names(fd, false);
1728 if (!namelist) { 1728 if (!namelist) {
1729 pr_debug("Failed to get current event list.\n"); 1729 pr_debug("Failed to get current event list.\n");
1730 return -EIO; 1730 return -EIO;
1731 } 1731 }
1732 1732
1733 ret = 0; 1733 ret = 0;
1734 printf("Add new event%s\n", (ntevs > 1) ? "s:" : ":"); 1734 printf("Add new event%s\n", (ntevs > 1) ? "s:" : ":");
1735 for (i = 0; i < ntevs; i++) { 1735 for (i = 0; i < ntevs; i++) {
1736 tev = &tevs[i]; 1736 tev = &tevs[i];
1737 if (pev->event) 1737 if (pev->event)
1738 event = pev->event; 1738 event = pev->event;
1739 else 1739 else
1740 if (pev->point.function) 1740 if (pev->point.function)
1741 event = pev->point.function; 1741 event = pev->point.function;
1742 else 1742 else
1743 event = tev->point.symbol; 1743 event = tev->point.symbol;
1744 if (pev->group) 1744 if (pev->group)
1745 group = pev->group; 1745 group = pev->group;
1746 else 1746 else
1747 group = PERFPROBE_GROUP; 1747 group = PERFPROBE_GROUP;
1748 1748
1749 /* Get an unused new event name */ 1749 /* Get an unused new event name */
1750 ret = get_new_event_name(buf, 64, event, 1750 ret = get_new_event_name(buf, 64, event,
1751 namelist, allow_suffix); 1751 namelist, allow_suffix);
1752 if (ret < 0) 1752 if (ret < 0)
1753 break; 1753 break;
1754 event = buf; 1754 event = buf;
1755 1755
1756 tev->event = strdup(event); 1756 tev->event = strdup(event);
1757 tev->group = strdup(group); 1757 tev->group = strdup(group);
1758 if (tev->event == NULL || tev->group == NULL) { 1758 if (tev->event == NULL || tev->group == NULL) {
1759 ret = -ENOMEM; 1759 ret = -ENOMEM;
1760 break; 1760 break;
1761 } 1761 }
1762 ret = write_probe_trace_event(fd, tev); 1762 ret = write_probe_trace_event(fd, tev);
1763 if (ret < 0) 1763 if (ret < 0)
1764 break; 1764 break;
1765 /* Add added event name to namelist */ 1765 /* Add added event name to namelist */
1766 strlist__add(namelist, event); 1766 strlist__add(namelist, event);
1767 1767
1768 /* Trick here - save current event/group */ 1768 /* Trick here - save current event/group */
1769 event = pev->event; 1769 event = pev->event;
1770 group = pev->group; 1770 group = pev->group;
1771 pev->event = tev->event; 1771 pev->event = tev->event;
1772 pev->group = tev->group; 1772 pev->group = tev->group;
1773 show_perf_probe_event(pev); 1773 show_perf_probe_event(pev);
1774 /* Trick here - restore current event/group */ 1774 /* Trick here - restore current event/group */
1775 pev->event = (char *)event; 1775 pev->event = (char *)event;
1776 pev->group = (char *)group; 1776 pev->group = (char *)group;
1777 1777
1778 /* 1778 /*
1779 * Probes after the first probe which comes from same 1779 * Probes after the first probe which comes from same
1780 * user input are always allowed to add suffix, because 1780 * user input are always allowed to add suffix, because
1781 * there might be several addresses corresponding to 1781 * there might be several addresses corresponding to
1782 * one code line. 1782 * one code line.
1783 */ 1783 */
1784 allow_suffix = true; 1784 allow_suffix = true;
1785 } 1785 }
1786 1786
1787 if (ret >= 0) { 1787 if (ret >= 0) {
1788 /* Show how to use the event. */ 1788 /* Show how to use the event. */
1789 printf("\nYou can now use it on all perf tools, such as:\n\n"); 1789 printf("\nYou can now use it on all perf tools, such as:\n\n");
1790 printf("\tperf record -e %s:%s -aR sleep 1\n\n", tev->group, 1790 printf("\tperf record -e %s:%s -aR sleep 1\n\n", tev->group,
1791 tev->event); 1791 tev->event);
1792 } 1792 }
1793 1793
1794 strlist__delete(namelist); 1794 strlist__delete(namelist);
1795 close(fd); 1795 close(fd);
1796 return ret; 1796 return ret;
1797 } 1797 }
1798 1798
1799 static int convert_to_probe_trace_events(struct perf_probe_event *pev, 1799 static int convert_to_probe_trace_events(struct perf_probe_event *pev,
1800 struct probe_trace_event **tevs, 1800 struct probe_trace_event **tevs,
1801 int max_tevs, const char *module) 1801 int max_tevs, const char *module)
1802 { 1802 {
1803 struct symbol *sym; 1803 struct symbol *sym;
1804 int ret = 0, i; 1804 int ret = 0, i;
1805 struct probe_trace_event *tev; 1805 struct probe_trace_event *tev;
1806 1806
1807 /* Convert perf_probe_event with debuginfo */ 1807 /* Convert perf_probe_event with debuginfo */
1808 ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, module); 1808 ret = try_to_find_probe_trace_events(pev, tevs, max_tevs, module);
1809 if (ret != 0) 1809 if (ret != 0)
1810 return ret; /* Found in debuginfo or got an error */ 1810 return ret; /* Found in debuginfo or got an error */
1811 1811
1812 /* Allocate trace event buffer */ 1812 /* Allocate trace event buffer */
1813 tev = *tevs = zalloc(sizeof(struct probe_trace_event)); 1813 tev = *tevs = zalloc(sizeof(struct probe_trace_event));
1814 if (tev == NULL) 1814 if (tev == NULL)
1815 return -ENOMEM; 1815 return -ENOMEM;
1816 1816
1817 /* Copy parameters */ 1817 /* Copy parameters */
1818 tev->point.symbol = strdup(pev->point.function); 1818 tev->point.symbol = strdup(pev->point.function);
1819 if (tev->point.symbol == NULL) { 1819 if (tev->point.symbol == NULL) {
1820 ret = -ENOMEM; 1820 ret = -ENOMEM;
1821 goto error; 1821 goto error;
1822 } 1822 }
1823 tev->point.module = strdup(module); 1823
1824 if (tev->point.module == NULL) { 1824 if (module) {
1825 ret = -ENOMEM; 1825 tev->point.module = strdup(module);
1826 goto error; 1826 if (tev->point.module == NULL) {
1827 ret = -ENOMEM;
1828 goto error;
1829 }
1827 } 1830 }
1831
1828 tev->point.offset = pev->point.offset; 1832 tev->point.offset = pev->point.offset;
1829 tev->point.retprobe = pev->point.retprobe; 1833 tev->point.retprobe = pev->point.retprobe;
1830 tev->nargs = pev->nargs; 1834 tev->nargs = pev->nargs;
1831 if (tev->nargs) { 1835 if (tev->nargs) {
1832 tev->args = zalloc(sizeof(struct probe_trace_arg) 1836 tev->args = zalloc(sizeof(struct probe_trace_arg)
1833 * tev->nargs); 1837 * tev->nargs);
1834 if (tev->args == NULL) { 1838 if (tev->args == NULL) {
1835 ret = -ENOMEM; 1839 ret = -ENOMEM;
1836 goto error; 1840 goto error;
1837 } 1841 }
1838 for (i = 0; i < tev->nargs; i++) { 1842 for (i = 0; i < tev->nargs; i++) {
1839 if (pev->args[i].name) { 1843 if (pev->args[i].name) {
1840 tev->args[i].name = strdup(pev->args[i].name); 1844 tev->args[i].name = strdup(pev->args[i].name);
1841 if (tev->args[i].name == NULL) { 1845 if (tev->args[i].name == NULL) {
1842 ret = -ENOMEM; 1846 ret = -ENOMEM;
1843 goto error; 1847 goto error;
1844 } 1848 }
1845 } 1849 }
1846 tev->args[i].value = strdup(pev->args[i].var); 1850 tev->args[i].value = strdup(pev->args[i].var);
1847 if (tev->args[i].value == NULL) { 1851 if (tev->args[i].value == NULL) {
1848 ret = -ENOMEM; 1852 ret = -ENOMEM;
1849 goto error; 1853 goto error;
1850 } 1854 }
1851 if (pev->args[i].type) { 1855 if (pev->args[i].type) {
1852 tev->args[i].type = strdup(pev->args[i].type); 1856 tev->args[i].type = strdup(pev->args[i].type);
1853 if (tev->args[i].type == NULL) { 1857 if (tev->args[i].type == NULL) {
1854 ret = -ENOMEM; 1858 ret = -ENOMEM;
1855 goto error; 1859 goto error;
1856 } 1860 }
1857 } 1861 }
1858 } 1862 }
1859 } 1863 }
1860 1864
1861 /* Currently just checking function name from symbol map */ 1865 /* Currently just checking function name from symbol map */
1862 sym = __find_kernel_function_by_name(tev->point.symbol, NULL); 1866 sym = __find_kernel_function_by_name(tev->point.symbol, NULL);
1863 if (!sym) { 1867 if (!sym) {
1864 pr_warning("Kernel symbol \'%s\' not found.\n", 1868 pr_warning("Kernel symbol \'%s\' not found.\n",
1865 tev->point.symbol); 1869 tev->point.symbol);
1866 ret = -ENOENT; 1870 ret = -ENOENT;
1867 goto error; 1871 goto error;
1868 } 1872 }
1869 1873
1870 return 1; 1874 return 1;
1871 error: 1875 error:
1872 clear_probe_trace_event(tev); 1876 clear_probe_trace_event(tev);
1873 free(tev); 1877 free(tev);
1874 *tevs = NULL; 1878 *tevs = NULL;
1875 return ret; 1879 return ret;
1876 } 1880 }
1877 1881
1878 struct __event_package { 1882 struct __event_package {
1879 struct perf_probe_event *pev; 1883 struct perf_probe_event *pev;
1880 struct probe_trace_event *tevs; 1884 struct probe_trace_event *tevs;
1881 int ntevs; 1885 int ntevs;
1882 }; 1886 };
1883 1887
1884 int add_perf_probe_events(struct perf_probe_event *pevs, int npevs, 1888 int add_perf_probe_events(struct perf_probe_event *pevs, int npevs,
1885 int max_tevs, const char *module, bool force_add) 1889 int max_tevs, const char *module, bool force_add)
1886 { 1890 {
1887 int i, j, ret; 1891 int i, j, ret;
1888 struct __event_package *pkgs; 1892 struct __event_package *pkgs;
1889 1893
1890 pkgs = zalloc(sizeof(struct __event_package) * npevs); 1894 pkgs = zalloc(sizeof(struct __event_package) * npevs);
1891 if (pkgs == NULL) 1895 if (pkgs == NULL)
1892 return -ENOMEM; 1896 return -ENOMEM;
1893 1897
1894 /* Init vmlinux path */ 1898 /* Init vmlinux path */
1895 ret = init_vmlinux(); 1899 ret = init_vmlinux();
1896 if (ret < 0) { 1900 if (ret < 0) {
1897 free(pkgs); 1901 free(pkgs);
1898 return ret; 1902 return ret;
1899 } 1903 }
1900 1904
1901 /* Loop 1: convert all events */ 1905 /* Loop 1: convert all events */
1902 for (i = 0; i < npevs; i++) { 1906 for (i = 0; i < npevs; i++) {
1903 pkgs[i].pev = &pevs[i]; 1907 pkgs[i].pev = &pevs[i];
1904 /* Convert with or without debuginfo */ 1908 /* Convert with or without debuginfo */
1905 ret = convert_to_probe_trace_events(pkgs[i].pev, 1909 ret = convert_to_probe_trace_events(pkgs[i].pev,
1906 &pkgs[i].tevs, 1910 &pkgs[i].tevs,
1907 max_tevs, 1911 max_tevs,
1908 module); 1912 module);
1909 if (ret < 0) 1913 if (ret < 0)
1910 goto end; 1914 goto end;
1911 pkgs[i].ntevs = ret; 1915 pkgs[i].ntevs = ret;
1912 } 1916 }
1913 1917
1914 /* Loop 2: add all events */ 1918 /* Loop 2: add all events */
1915 for (i = 0; i < npevs; i++) { 1919 for (i = 0; i < npevs; i++) {
1916 ret = __add_probe_trace_events(pkgs[i].pev, pkgs[i].tevs, 1920 ret = __add_probe_trace_events(pkgs[i].pev, pkgs[i].tevs,
1917 pkgs[i].ntevs, force_add); 1921 pkgs[i].ntevs, force_add);
1918 if (ret < 0) 1922 if (ret < 0)
1919 break; 1923 break;
1920 } 1924 }
1921 end: 1925 end:
1922 /* Loop 3: cleanup and free trace events */ 1926 /* Loop 3: cleanup and free trace events */
1923 for (i = 0; i < npevs; i++) { 1927 for (i = 0; i < npevs; i++) {
1924 for (j = 0; j < pkgs[i].ntevs; j++) 1928 for (j = 0; j < pkgs[i].ntevs; j++)
1925 clear_probe_trace_event(&pkgs[i].tevs[j]); 1929 clear_probe_trace_event(&pkgs[i].tevs[j]);
1926 free(pkgs[i].tevs); 1930 free(pkgs[i].tevs);
1927 } 1931 }
1928 free(pkgs); 1932 free(pkgs);
1929 1933
1930 return ret; 1934 return ret;
1931 } 1935 }
1932 1936
1933 static int __del_trace_probe_event(int fd, struct str_node *ent) 1937 static int __del_trace_probe_event(int fd, struct str_node *ent)
1934 { 1938 {
1935 char *p; 1939 char *p;
1936 char buf[128]; 1940 char buf[128];
1937 int ret; 1941 int ret;
1938 1942
1939 /* Convert from perf-probe event to trace-probe event */ 1943 /* Convert from perf-probe event to trace-probe event */
1940 ret = e_snprintf(buf, 128, "-:%s", ent->s); 1944 ret = e_snprintf(buf, 128, "-:%s", ent->s);
1941 if (ret < 0) 1945 if (ret < 0)
1942 goto error; 1946 goto error;
1943 1947
1944 p = strchr(buf + 2, ':'); 1948 p = strchr(buf + 2, ':');
1945 if (!p) { 1949 if (!p) {
1946 pr_debug("Internal error: %s should have ':' but not.\n", 1950 pr_debug("Internal error: %s should have ':' but not.\n",
1947 ent->s); 1951 ent->s);
1948 ret = -ENOTSUP; 1952 ret = -ENOTSUP;
1949 goto error; 1953 goto error;
1950 } 1954 }
1951 *p = '/'; 1955 *p = '/';
1952 1956
1953 pr_debug("Writing event: %s\n", buf); 1957 pr_debug("Writing event: %s\n", buf);
1954 ret = write(fd, buf, strlen(buf)); 1958 ret = write(fd, buf, strlen(buf));
1955 if (ret < 0) 1959 if (ret < 0)
1956 goto error; 1960 goto error;
1957 1961
1958 printf("Remove event: %s\n", ent->s); 1962 printf("Remove event: %s\n", ent->s);
1959 return 0; 1963 return 0;
1960 error: 1964 error:
1961 pr_warning("Failed to delete event: %s\n", strerror(-ret)); 1965 pr_warning("Failed to delete event: %s\n", strerror(-ret));
1962 return ret; 1966 return ret;
1963 } 1967 }
1964 1968
1965 static int del_trace_probe_event(int fd, const char *group, 1969 static int del_trace_probe_event(int fd, const char *group,
1966 const char *event, struct strlist *namelist) 1970 const char *event, struct strlist *namelist)
1967 { 1971 {
1968 char buf[128]; 1972 char buf[128];
1969 struct str_node *ent, *n; 1973 struct str_node *ent, *n;
1970 int found = 0, ret = 0; 1974 int found = 0, ret = 0;
1971 1975
1972 ret = e_snprintf(buf, 128, "%s:%s", group, event); 1976 ret = e_snprintf(buf, 128, "%s:%s", group, event);
1973 if (ret < 0) { 1977 if (ret < 0) {
1974 pr_err("Failed to copy event.\n"); 1978 pr_err("Failed to copy event.\n");
1975 return ret; 1979 return ret;
1976 } 1980 }
1977 1981
1978 if (strpbrk(buf, "*?")) { /* Glob-exp */ 1982 if (strpbrk(buf, "*?")) { /* Glob-exp */
1979 strlist__for_each_safe(ent, n, namelist) 1983 strlist__for_each_safe(ent, n, namelist)
1980 if (strglobmatch(ent->s, buf)) { 1984 if (strglobmatch(ent->s, buf)) {
1981 found++; 1985 found++;
1982 ret = __del_trace_probe_event(fd, ent); 1986 ret = __del_trace_probe_event(fd, ent);
1983 if (ret < 0) 1987 if (ret < 0)
1984 break; 1988 break;
1985 strlist__remove(namelist, ent); 1989 strlist__remove(namelist, ent);
1986 } 1990 }
1987 } else { 1991 } else {
1988 ent = strlist__find(namelist, buf); 1992 ent = strlist__find(namelist, buf);
1989 if (ent) { 1993 if (ent) {
1990 found++; 1994 found++;
1991 ret = __del_trace_probe_event(fd, ent); 1995 ret = __del_trace_probe_event(fd, ent);
1992 if (ret >= 0) 1996 if (ret >= 0)
1993 strlist__remove(namelist, ent); 1997 strlist__remove(namelist, ent);
1994 } 1998 }
1995 } 1999 }
1996 if (found == 0 && ret >= 0) 2000 if (found == 0 && ret >= 0)
1997 pr_info("Info: Event \"%s\" does not exist.\n", buf); 2001 pr_info("Info: Event \"%s\" does not exist.\n", buf);
1998 2002
1999 return ret; 2003 return ret;
2000 } 2004 }
2001 2005
2002 int del_perf_probe_events(struct strlist *dellist) 2006 int del_perf_probe_events(struct strlist *dellist)
2003 { 2007 {
2004 int fd, ret = 0; 2008 int fd, ret = 0;
2005 const char *group, *event; 2009 const char *group, *event;
2006 char *p, *str; 2010 char *p, *str;
2007 struct str_node *ent; 2011 struct str_node *ent;
2008 struct strlist *namelist; 2012 struct strlist *namelist;
2009 2013
2010 fd = open_kprobe_events(true); 2014 fd = open_kprobe_events(true);
2011 if (fd < 0) 2015 if (fd < 0)
2012 return fd; 2016 return fd;
2013 2017
2014 /* Get current event names */ 2018 /* Get current event names */
2015 namelist = get_probe_trace_event_names(fd, true); 2019 namelist = get_probe_trace_event_names(fd, true);
2016 if (namelist == NULL) 2020 if (namelist == NULL)
2017 return -EINVAL; 2021 return -EINVAL;
2018 2022
2019 strlist__for_each(ent, dellist) { 2023 strlist__for_each(ent, dellist) {
2020 str = strdup(ent->s); 2024 str = strdup(ent->s);
2021 if (str == NULL) { 2025 if (str == NULL) {
2022 ret = -ENOMEM; 2026 ret = -ENOMEM;
2023 break; 2027 break;
2024 } 2028 }
2025 pr_debug("Parsing: %s\n", str); 2029 pr_debug("Parsing: %s\n", str);
2026 p = strchr(str, ':'); 2030 p = strchr(str, ':');
2027 if (p) { 2031 if (p) {
2028 group = str; 2032 group = str;
2029 *p = '\0'; 2033 *p = '\0';
2030 event = p + 1; 2034 event = p + 1;
2031 } else { 2035 } else {
2032 group = "*"; 2036 group = "*";
2033 event = str; 2037 event = str;
2034 } 2038 }
2035 pr_debug("Group: %s, Event: %s\n", group, event); 2039 pr_debug("Group: %s, Event: %s\n", group, event);
2036 ret = del_trace_probe_event(fd, group, event, namelist); 2040 ret = del_trace_probe_event(fd, group, event, namelist);
2037 free(str); 2041 free(str);
2038 if (ret < 0) 2042 if (ret < 0)
2039 break; 2043 break;
2040 } 2044 }
2041 strlist__delete(namelist); 2045 strlist__delete(namelist);
2042 close(fd); 2046 close(fd);
2043 2047
2044 return ret; 2048 return ret;
2045 } 2049 }
2046 /* TODO: don't use a global variable for filter ... */ 2050 /* TODO: don't use a global variable for filter ... */
2047 static struct strfilter *available_func_filter; 2051 static struct strfilter *available_func_filter;
2048 2052
2049 /* 2053 /*
2050 * If a symbol corresponds to a function with global binding and 2054 * If a symbol corresponds to a function with global binding and
2051 * matches filter return 0. For all others return 1. 2055 * matches filter return 0. For all others return 1.
2052 */ 2056 */
2053 static int filter_available_functions(struct map *map __unused, 2057 static int filter_available_functions(struct map *map __unused,
2054 struct symbol *sym) 2058 struct symbol *sym)
2055 { 2059 {
2056 if (sym->binding == STB_GLOBAL && 2060 if (sym->binding == STB_GLOBAL &&
2057 strfilter__compare(available_func_filter, sym->name)) 2061 strfilter__compare(available_func_filter, sym->name))
2058 return 0; 2062 return 0;
2059 return 1; 2063 return 1;
2060 } 2064 }
2061 2065
2062 int show_available_funcs(const char *module, struct strfilter *_filter) 2066 int show_available_funcs(const char *module, struct strfilter *_filter)
2063 { 2067 {
2064 struct map *map; 2068 struct map *map;
2065 int ret; 2069 int ret;
2066 2070
2067 setup_pager(); 2071 setup_pager();
2068 2072
2069 ret = init_vmlinux(); 2073 ret = init_vmlinux();
2070 if (ret < 0) 2074 if (ret < 0)
2071 return ret; 2075 return ret;
2072 2076
2073 map = kernel_get_module_map(module); 2077 map = kernel_get_module_map(module);
2074 if (!map) { 2078 if (!map) {
2075 pr_err("Failed to find %s map.\n", (module) ? : "kernel"); 2079 pr_err("Failed to find %s map.\n", (module) ? : "kernel");
2076 return -EINVAL; 2080 return -EINVAL;
2077 } 2081 }
2078 available_func_filter = _filter; 2082 available_func_filter = _filter;
2079 if (map__load(map, filter_available_functions)) { 2083 if (map__load(map, filter_available_functions)) {
2080 pr_err("Failed to load map.\n"); 2084 pr_err("Failed to load map.\n");
2081 return -EINVAL; 2085 return -EINVAL;
2082 } 2086 }
2083 if (!dso__sorted_by_name(map->dso, map->type)) 2087 if (!dso__sorted_by_name(map->dso, map->type))
2084 dso__sort_by_name(map->dso, map->type); 2088 dso__sort_by_name(map->dso, map->type);
2085 2089
2086 dso__fprintf_symbols_by_name(map->dso, map->type, stdout); 2090 dso__fprintf_symbols_by_name(map->dso, map->type, stdout);
2087 return 0; 2091 return 0;
2088 } 2092 }
2089 2093
tools/perf/util/python.c
1 #include <Python.h> 1 #include <Python.h>
2 #include <structmember.h> 2 #include <structmember.h>
3 #include <inttypes.h> 3 #include <inttypes.h>
4 #include <poll.h> 4 #include <poll.h>
5 #include "evlist.h" 5 #include "evlist.h"
6 #include "evsel.h" 6 #include "evsel.h"
7 #include "event.h" 7 #include "event.h"
8 #include "cpumap.h" 8 #include "cpumap.h"
9 #include "thread_map.h" 9 #include "thread_map.h"
10 10
11 /* Define PyVarObject_HEAD_INIT for python 2.5 */ 11 /* Define PyVarObject_HEAD_INIT for python 2.5 */
12 #ifndef PyVarObject_HEAD_INIT 12 #ifndef PyVarObject_HEAD_INIT
13 # define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size, 13 # define PyVarObject_HEAD_INIT(type, size) PyObject_HEAD_INIT(type) size,
14 #endif 14 #endif
15 15
16 struct throttle_event { 16 struct throttle_event {
17 struct perf_event_header header; 17 struct perf_event_header header;
18 u64 time; 18 u64 time;
19 u64 id; 19 u64 id;
20 u64 stream_id; 20 u64 stream_id;
21 }; 21 };
22 22
23 PyMODINIT_FUNC initperf(void); 23 PyMODINIT_FUNC initperf(void);
24 24
25 #define member_def(type, member, ptype, help) \ 25 #define member_def(type, member, ptype, help) \
26 { #member, ptype, \ 26 { #member, ptype, \
27 offsetof(struct pyrf_event, event) + offsetof(struct type, member), \ 27 offsetof(struct pyrf_event, event) + offsetof(struct type, member), \
28 0, help } 28 0, help }
29 29
30 #define sample_member_def(name, member, ptype, help) \ 30 #define sample_member_def(name, member, ptype, help) \
31 { #name, ptype, \ 31 { #name, ptype, \
32 offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \ 32 offsetof(struct pyrf_event, sample) + offsetof(struct perf_sample, member), \
33 0, help } 33 0, help }
34 34
35 struct pyrf_event { 35 struct pyrf_event {
36 PyObject_HEAD 36 PyObject_HEAD
37 struct perf_sample sample; 37 struct perf_sample sample;
38 union perf_event event; 38 union perf_event event;
39 }; 39 };
40 40
41 #define sample_members \ 41 #define sample_members \
42 sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"), \ 42 sample_member_def(sample_ip, ip, T_ULONGLONG, "event type"), \
43 sample_member_def(sample_pid, pid, T_INT, "event pid"), \ 43 sample_member_def(sample_pid, pid, T_INT, "event pid"), \
44 sample_member_def(sample_tid, tid, T_INT, "event tid"), \ 44 sample_member_def(sample_tid, tid, T_INT, "event tid"), \
45 sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"), \ 45 sample_member_def(sample_time, time, T_ULONGLONG, "event timestamp"), \
46 sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"), \ 46 sample_member_def(sample_addr, addr, T_ULONGLONG, "event addr"), \
47 sample_member_def(sample_id, id, T_ULONGLONG, "event id"), \ 47 sample_member_def(sample_id, id, T_ULONGLONG, "event id"), \
48 sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \ 48 sample_member_def(sample_stream_id, stream_id, T_ULONGLONG, "event stream id"), \
49 sample_member_def(sample_period, period, T_ULONGLONG, "event period"), \ 49 sample_member_def(sample_period, period, T_ULONGLONG, "event period"), \
50 sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"), 50 sample_member_def(sample_cpu, cpu, T_UINT, "event cpu"),
51 51
52 static char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object."); 52 static char pyrf_mmap_event__doc[] = PyDoc_STR("perf mmap event object.");
53 53
54 static PyMemberDef pyrf_mmap_event__members[] = { 54 static PyMemberDef pyrf_mmap_event__members[] = {
55 sample_members 55 sample_members
56 member_def(perf_event_header, type, T_UINT, "event type"), 56 member_def(perf_event_header, type, T_UINT, "event type"),
57 member_def(mmap_event, pid, T_UINT, "event pid"), 57 member_def(mmap_event, pid, T_UINT, "event pid"),
58 member_def(mmap_event, tid, T_UINT, "event tid"), 58 member_def(mmap_event, tid, T_UINT, "event tid"),
59 member_def(mmap_event, start, T_ULONGLONG, "start of the map"), 59 member_def(mmap_event, start, T_ULONGLONG, "start of the map"),
60 member_def(mmap_event, len, T_ULONGLONG, "map length"), 60 member_def(mmap_event, len, T_ULONGLONG, "map length"),
61 member_def(mmap_event, pgoff, T_ULONGLONG, "page offset"), 61 member_def(mmap_event, pgoff, T_ULONGLONG, "page offset"),
62 member_def(mmap_event, filename, T_STRING_INPLACE, "backing store"), 62 member_def(mmap_event, filename, T_STRING_INPLACE, "backing store"),
63 { .name = NULL, }, 63 { .name = NULL, },
64 }; 64 };
65 65
66 static PyObject *pyrf_mmap_event__repr(struct pyrf_event *pevent) 66 static PyObject *pyrf_mmap_event__repr(struct pyrf_event *pevent)
67 { 67 {
68 PyObject *ret; 68 PyObject *ret;
69 char *s; 69 char *s;
70 70
71 if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRIx64 ", " 71 if (asprintf(&s, "{ type: mmap, pid: %u, tid: %u, start: %#" PRIx64 ", "
72 "length: %#" PRIx64 ", offset: %#" PRIx64 ", " 72 "length: %#" PRIx64 ", offset: %#" PRIx64 ", "
73 "filename: %s }", 73 "filename: %s }",
74 pevent->event.mmap.pid, pevent->event.mmap.tid, 74 pevent->event.mmap.pid, pevent->event.mmap.tid,
75 pevent->event.mmap.start, pevent->event.mmap.len, 75 pevent->event.mmap.start, pevent->event.mmap.len,
76 pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) { 76 pevent->event.mmap.pgoff, pevent->event.mmap.filename) < 0) {
77 ret = PyErr_NoMemory(); 77 ret = PyErr_NoMemory();
78 } else { 78 } else {
79 ret = PyString_FromString(s); 79 ret = PyString_FromString(s);
80 free(s); 80 free(s);
81 } 81 }
82 return ret; 82 return ret;
83 } 83 }
84 84
85 static PyTypeObject pyrf_mmap_event__type = { 85 static PyTypeObject pyrf_mmap_event__type = {
86 PyVarObject_HEAD_INIT(NULL, 0) 86 PyVarObject_HEAD_INIT(NULL, 0)
87 .tp_name = "perf.mmap_event", 87 .tp_name = "perf.mmap_event",
88 .tp_basicsize = sizeof(struct pyrf_event), 88 .tp_basicsize = sizeof(struct pyrf_event),
89 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 89 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
90 .tp_doc = pyrf_mmap_event__doc, 90 .tp_doc = pyrf_mmap_event__doc,
91 .tp_members = pyrf_mmap_event__members, 91 .tp_members = pyrf_mmap_event__members,
92 .tp_repr = (reprfunc)pyrf_mmap_event__repr, 92 .tp_repr = (reprfunc)pyrf_mmap_event__repr,
93 }; 93 };
94 94
95 static char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object."); 95 static char pyrf_task_event__doc[] = PyDoc_STR("perf task (fork/exit) event object.");
96 96
97 static PyMemberDef pyrf_task_event__members[] = { 97 static PyMemberDef pyrf_task_event__members[] = {
98 sample_members 98 sample_members
99 member_def(perf_event_header, type, T_UINT, "event type"), 99 member_def(perf_event_header, type, T_UINT, "event type"),
100 member_def(fork_event, pid, T_UINT, "event pid"), 100 member_def(fork_event, pid, T_UINT, "event pid"),
101 member_def(fork_event, ppid, T_UINT, "event ppid"), 101 member_def(fork_event, ppid, T_UINT, "event ppid"),
102 member_def(fork_event, tid, T_UINT, "event tid"), 102 member_def(fork_event, tid, T_UINT, "event tid"),
103 member_def(fork_event, ptid, T_UINT, "event ptid"), 103 member_def(fork_event, ptid, T_UINT, "event ptid"),
104 member_def(fork_event, time, T_ULONGLONG, "timestamp"), 104 member_def(fork_event, time, T_ULONGLONG, "timestamp"),
105 { .name = NULL, }, 105 { .name = NULL, },
106 }; 106 };
107 107
108 static PyObject *pyrf_task_event__repr(struct pyrf_event *pevent) 108 static PyObject *pyrf_task_event__repr(struct pyrf_event *pevent)
109 { 109 {
110 return PyString_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, " 110 return PyString_FromFormat("{ type: %s, pid: %u, ppid: %u, tid: %u, "
111 "ptid: %u, time: %" PRIu64 "}", 111 "ptid: %u, time: %" PRIu64 "}",
112 pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit", 112 pevent->event.header.type == PERF_RECORD_FORK ? "fork" : "exit",
113 pevent->event.fork.pid, 113 pevent->event.fork.pid,
114 pevent->event.fork.ppid, 114 pevent->event.fork.ppid,
115 pevent->event.fork.tid, 115 pevent->event.fork.tid,
116 pevent->event.fork.ptid, 116 pevent->event.fork.ptid,
117 pevent->event.fork.time); 117 pevent->event.fork.time);
118 } 118 }
119 119
120 static PyTypeObject pyrf_task_event__type = { 120 static PyTypeObject pyrf_task_event__type = {
121 PyVarObject_HEAD_INIT(NULL, 0) 121 PyVarObject_HEAD_INIT(NULL, 0)
122 .tp_name = "perf.task_event", 122 .tp_name = "perf.task_event",
123 .tp_basicsize = sizeof(struct pyrf_event), 123 .tp_basicsize = sizeof(struct pyrf_event),
124 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 124 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
125 .tp_doc = pyrf_task_event__doc, 125 .tp_doc = pyrf_task_event__doc,
126 .tp_members = pyrf_task_event__members, 126 .tp_members = pyrf_task_event__members,
127 .tp_repr = (reprfunc)pyrf_task_event__repr, 127 .tp_repr = (reprfunc)pyrf_task_event__repr,
128 }; 128 };
129 129
130 static char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object."); 130 static char pyrf_comm_event__doc[] = PyDoc_STR("perf comm event object.");
131 131
132 static PyMemberDef pyrf_comm_event__members[] = { 132 static PyMemberDef pyrf_comm_event__members[] = {
133 sample_members 133 sample_members
134 member_def(perf_event_header, type, T_UINT, "event type"), 134 member_def(perf_event_header, type, T_UINT, "event type"),
135 member_def(comm_event, pid, T_UINT, "event pid"), 135 member_def(comm_event, pid, T_UINT, "event pid"),
136 member_def(comm_event, tid, T_UINT, "event tid"), 136 member_def(comm_event, tid, T_UINT, "event tid"),
137 member_def(comm_event, comm, T_STRING_INPLACE, "process name"), 137 member_def(comm_event, comm, T_STRING_INPLACE, "process name"),
138 { .name = NULL, }, 138 { .name = NULL, },
139 }; 139 };
140 140
141 static PyObject *pyrf_comm_event__repr(struct pyrf_event *pevent) 141 static PyObject *pyrf_comm_event__repr(struct pyrf_event *pevent)
142 { 142 {
143 return PyString_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }", 143 return PyString_FromFormat("{ type: comm, pid: %u, tid: %u, comm: %s }",
144 pevent->event.comm.pid, 144 pevent->event.comm.pid,
145 pevent->event.comm.tid, 145 pevent->event.comm.tid,
146 pevent->event.comm.comm); 146 pevent->event.comm.comm);
147 } 147 }
148 148
149 static PyTypeObject pyrf_comm_event__type = { 149 static PyTypeObject pyrf_comm_event__type = {
150 PyVarObject_HEAD_INIT(NULL, 0) 150 PyVarObject_HEAD_INIT(NULL, 0)
151 .tp_name = "perf.comm_event", 151 .tp_name = "perf.comm_event",
152 .tp_basicsize = sizeof(struct pyrf_event), 152 .tp_basicsize = sizeof(struct pyrf_event),
153 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 153 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
154 .tp_doc = pyrf_comm_event__doc, 154 .tp_doc = pyrf_comm_event__doc,
155 .tp_members = pyrf_comm_event__members, 155 .tp_members = pyrf_comm_event__members,
156 .tp_repr = (reprfunc)pyrf_comm_event__repr, 156 .tp_repr = (reprfunc)pyrf_comm_event__repr,
157 }; 157 };
158 158
159 static char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object."); 159 static char pyrf_throttle_event__doc[] = PyDoc_STR("perf throttle event object.");
160 160
161 static PyMemberDef pyrf_throttle_event__members[] = { 161 static PyMemberDef pyrf_throttle_event__members[] = {
162 sample_members 162 sample_members
163 member_def(perf_event_header, type, T_UINT, "event type"), 163 member_def(perf_event_header, type, T_UINT, "event type"),
164 member_def(throttle_event, time, T_ULONGLONG, "timestamp"), 164 member_def(throttle_event, time, T_ULONGLONG, "timestamp"),
165 member_def(throttle_event, id, T_ULONGLONG, "event id"), 165 member_def(throttle_event, id, T_ULONGLONG, "event id"),
166 member_def(throttle_event, stream_id, T_ULONGLONG, "event stream id"), 166 member_def(throttle_event, stream_id, T_ULONGLONG, "event stream id"),
167 { .name = NULL, }, 167 { .name = NULL, },
168 }; 168 };
169 169
170 static PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent) 170 static PyObject *pyrf_throttle_event__repr(struct pyrf_event *pevent)
171 { 171 {
172 struct throttle_event *te = (struct throttle_event *)(&pevent->event.header + 1); 172 struct throttle_event *te = (struct throttle_event *)(&pevent->event.header + 1);
173 173
174 return PyString_FromFormat("{ type: %sthrottle, time: %" PRIu64 ", id: %" PRIu64 174 return PyString_FromFormat("{ type: %sthrottle, time: %" PRIu64 ", id: %" PRIu64
175 ", stream_id: %" PRIu64 " }", 175 ", stream_id: %" PRIu64 " }",
176 pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un", 176 pevent->event.header.type == PERF_RECORD_THROTTLE ? "" : "un",
177 te->time, te->id, te->stream_id); 177 te->time, te->id, te->stream_id);
178 } 178 }
179 179
180 static PyTypeObject pyrf_throttle_event__type = { 180 static PyTypeObject pyrf_throttle_event__type = {
181 PyVarObject_HEAD_INIT(NULL, 0) 181 PyVarObject_HEAD_INIT(NULL, 0)
182 .tp_name = "perf.throttle_event", 182 .tp_name = "perf.throttle_event",
183 .tp_basicsize = sizeof(struct pyrf_event), 183 .tp_basicsize = sizeof(struct pyrf_event),
184 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 184 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
185 .tp_doc = pyrf_throttle_event__doc, 185 .tp_doc = pyrf_throttle_event__doc,
186 .tp_members = pyrf_throttle_event__members, 186 .tp_members = pyrf_throttle_event__members,
187 .tp_repr = (reprfunc)pyrf_throttle_event__repr, 187 .tp_repr = (reprfunc)pyrf_throttle_event__repr,
188 }; 188 };
189 189
190 static char pyrf_lost_event__doc[] = PyDoc_STR("perf lost event object.");
191
192 static PyMemberDef pyrf_lost_event__members[] = {
193 sample_members
194 member_def(lost_event, id, T_ULONGLONG, "event id"),
195 member_def(lost_event, lost, T_ULONGLONG, "number of lost events"),
196 { .name = NULL, },
197 };
198
199 static PyObject *pyrf_lost_event__repr(struct pyrf_event *pevent)
200 {
201 PyObject *ret;
202 char *s;
203
204 if (asprintf(&s, "{ type: lost, id: %#" PRIx64 ", "
205 "lost: %#" PRIx64 " }",
206 pevent->event.lost.id, pevent->event.lost.lost) < 0) {
207 ret = PyErr_NoMemory();
208 } else {
209 ret = PyString_FromString(s);
210 free(s);
211 }
212 return ret;
213 }
214
215 static PyTypeObject pyrf_lost_event__type = {
216 PyVarObject_HEAD_INIT(NULL, 0)
217 .tp_name = "perf.lost_event",
218 .tp_basicsize = sizeof(struct pyrf_event),
219 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
220 .tp_doc = pyrf_lost_event__doc,
221 .tp_members = pyrf_lost_event__members,
222 .tp_repr = (reprfunc)pyrf_lost_event__repr,
223 };
224
225 static char pyrf_read_event__doc[] = PyDoc_STR("perf read event object.");
226
227 static PyMemberDef pyrf_read_event__members[] = {
228 sample_members
229 member_def(read_event, pid, T_UINT, "event pid"),
230 member_def(read_event, tid, T_UINT, "event tid"),
231 { .name = NULL, },
232 };
233
234 static PyObject *pyrf_read_event__repr(struct pyrf_event *pevent)
235 {
236 return PyString_FromFormat("{ type: read, pid: %u, tid: %u }",
237 pevent->event.read.pid,
238 pevent->event.read.tid);
239 /*
240 * FIXME: return the array of read values,
241 * making this method useful ;-)
242 */
243 }
244
245 static PyTypeObject pyrf_read_event__type = {
246 PyVarObject_HEAD_INIT(NULL, 0)
247 .tp_name = "perf.read_event",
248 .tp_basicsize = sizeof(struct pyrf_event),
249 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
250 .tp_doc = pyrf_read_event__doc,
251 .tp_members = pyrf_read_event__members,
252 .tp_repr = (reprfunc)pyrf_read_event__repr,
253 };
254
255 static char pyrf_sample_event__doc[] = PyDoc_STR("perf sample event object.");
256
257 static PyMemberDef pyrf_sample_event__members[] = {
258 sample_members
259 member_def(perf_event_header, type, T_UINT, "event type"),
260 { .name = NULL, },
261 };
262
263 static PyObject *pyrf_sample_event__repr(struct pyrf_event *pevent)
264 {
265 PyObject *ret;
266 char *s;
267
268 if (asprintf(&s, "{ type: sample }") < 0) {
269 ret = PyErr_NoMemory();
270 } else {
271 ret = PyString_FromString(s);
272 free(s);
273 }
274 return ret;
275 }
276
277 static PyTypeObject pyrf_sample_event__type = {
278 PyVarObject_HEAD_INIT(NULL, 0)
279 .tp_name = "perf.sample_event",
280 .tp_basicsize = sizeof(struct pyrf_event),
281 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
282 .tp_doc = pyrf_sample_event__doc,
283 .tp_members = pyrf_sample_event__members,
284 .tp_repr = (reprfunc)pyrf_sample_event__repr,
285 };
286
190 static int pyrf_event__setup_types(void) 287 static int pyrf_event__setup_types(void)
191 { 288 {
192 int err; 289 int err;
193 pyrf_mmap_event__type.tp_new = 290 pyrf_mmap_event__type.tp_new =
194 pyrf_task_event__type.tp_new = 291 pyrf_task_event__type.tp_new =
195 pyrf_comm_event__type.tp_new = 292 pyrf_comm_event__type.tp_new =
293 pyrf_lost_event__type.tp_new =
294 pyrf_read_event__type.tp_new =
295 pyrf_sample_event__type.tp_new =
196 pyrf_throttle_event__type.tp_new = PyType_GenericNew; 296 pyrf_throttle_event__type.tp_new = PyType_GenericNew;
197 err = PyType_Ready(&pyrf_mmap_event__type); 297 err = PyType_Ready(&pyrf_mmap_event__type);
198 if (err < 0) 298 if (err < 0)
199 goto out; 299 goto out;
300 err = PyType_Ready(&pyrf_lost_event__type);
301 if (err < 0)
302 goto out;
200 err = PyType_Ready(&pyrf_task_event__type); 303 err = PyType_Ready(&pyrf_task_event__type);
201 if (err < 0) 304 if (err < 0)
202 goto out; 305 goto out;
203 err = PyType_Ready(&pyrf_comm_event__type); 306 err = PyType_Ready(&pyrf_comm_event__type);
204 if (err < 0) 307 if (err < 0)
205 goto out; 308 goto out;
206 err = PyType_Ready(&pyrf_throttle_event__type); 309 err = PyType_Ready(&pyrf_throttle_event__type);
207 if (err < 0) 310 if (err < 0)
208 goto out; 311 goto out;
312 err = PyType_Ready(&pyrf_read_event__type);
313 if (err < 0)
314 goto out;
315 err = PyType_Ready(&pyrf_sample_event__type);
316 if (err < 0)
317 goto out;
209 out: 318 out:
210 return err; 319 return err;
211 } 320 }
212 321
213 static PyTypeObject *pyrf_event__type[] = { 322 static PyTypeObject *pyrf_event__type[] = {
214 [PERF_RECORD_MMAP] = &pyrf_mmap_event__type, 323 [PERF_RECORD_MMAP] = &pyrf_mmap_event__type,
215 [PERF_RECORD_LOST] = &pyrf_mmap_event__type, 324 [PERF_RECORD_LOST] = &pyrf_lost_event__type,
216 [PERF_RECORD_COMM] = &pyrf_comm_event__type, 325 [PERF_RECORD_COMM] = &pyrf_comm_event__type,
217 [PERF_RECORD_EXIT] = &pyrf_task_event__type, 326 [PERF_RECORD_EXIT] = &pyrf_task_event__type,
218 [PERF_RECORD_THROTTLE] = &pyrf_throttle_event__type, 327 [PERF_RECORD_THROTTLE] = &pyrf_throttle_event__type,
219 [PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type, 328 [PERF_RECORD_UNTHROTTLE] = &pyrf_throttle_event__type,
220 [PERF_RECORD_FORK] = &pyrf_task_event__type, 329 [PERF_RECORD_FORK] = &pyrf_task_event__type,
221 [PERF_RECORD_READ] = &pyrf_mmap_event__type, 330 [PERF_RECORD_READ] = &pyrf_read_event__type,
222 [PERF_RECORD_SAMPLE] = &pyrf_mmap_event__type, 331 [PERF_RECORD_SAMPLE] = &pyrf_sample_event__type,
223 }; 332 };
224 333
225 static PyObject *pyrf_event__new(union perf_event *event) 334 static PyObject *pyrf_event__new(union perf_event *event)
226 { 335 {
227 struct pyrf_event *pevent; 336 struct pyrf_event *pevent;
228 PyTypeObject *ptype; 337 PyTypeObject *ptype;
229 338
230 if (event->header.type < PERF_RECORD_MMAP || 339 if (event->header.type < PERF_RECORD_MMAP ||
231 event->header.type > PERF_RECORD_SAMPLE) 340 event->header.type > PERF_RECORD_SAMPLE)
232 return NULL; 341 return NULL;
233 342
234 ptype = pyrf_event__type[event->header.type]; 343 ptype = pyrf_event__type[event->header.type];
235 pevent = PyObject_New(struct pyrf_event, ptype); 344 pevent = PyObject_New(struct pyrf_event, ptype);
236 if (pevent != NULL) 345 if (pevent != NULL)
237 memcpy(&pevent->event, event, event->header.size); 346 memcpy(&pevent->event, event, event->header.size);
238 return (PyObject *)pevent; 347 return (PyObject *)pevent;
239 } 348 }
240 349
241 struct pyrf_cpu_map { 350 struct pyrf_cpu_map {
242 PyObject_HEAD 351 PyObject_HEAD
243 352
244 struct cpu_map *cpus; 353 struct cpu_map *cpus;
245 }; 354 };
246 355
247 static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus, 356 static int pyrf_cpu_map__init(struct pyrf_cpu_map *pcpus,
248 PyObject *args, PyObject *kwargs) 357 PyObject *args, PyObject *kwargs)
249 { 358 {
250 static char *kwlist[] = { "cpustr", NULL }; 359 static char *kwlist[] = { "cpustr", NULL };
251 char *cpustr = NULL; 360 char *cpustr = NULL;
252 361
253 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s", 362 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|s",
254 kwlist, &cpustr)) 363 kwlist, &cpustr))
255 return -1; 364 return -1;
256 365
257 pcpus->cpus = cpu_map__new(cpustr); 366 pcpus->cpus = cpu_map__new(cpustr);
258 if (pcpus->cpus == NULL) 367 if (pcpus->cpus == NULL)
259 return -1; 368 return -1;
260 return 0; 369 return 0;
261 } 370 }
262 371
263 static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus) 372 static void pyrf_cpu_map__delete(struct pyrf_cpu_map *pcpus)
264 { 373 {
265 cpu_map__delete(pcpus->cpus); 374 cpu_map__delete(pcpus->cpus);
266 pcpus->ob_type->tp_free((PyObject*)pcpus); 375 pcpus->ob_type->tp_free((PyObject*)pcpus);
267 } 376 }
268 377
269 static Py_ssize_t pyrf_cpu_map__length(PyObject *obj) 378 static Py_ssize_t pyrf_cpu_map__length(PyObject *obj)
270 { 379 {
271 struct pyrf_cpu_map *pcpus = (void *)obj; 380 struct pyrf_cpu_map *pcpus = (void *)obj;
272 381
273 return pcpus->cpus->nr; 382 return pcpus->cpus->nr;
274 } 383 }
275 384
276 static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i) 385 static PyObject *pyrf_cpu_map__item(PyObject *obj, Py_ssize_t i)
277 { 386 {
278 struct pyrf_cpu_map *pcpus = (void *)obj; 387 struct pyrf_cpu_map *pcpus = (void *)obj;
279 388
280 if (i >= pcpus->cpus->nr) 389 if (i >= pcpus->cpus->nr)
281 return NULL; 390 return NULL;
282 391
283 return Py_BuildValue("i", pcpus->cpus->map[i]); 392 return Py_BuildValue("i", pcpus->cpus->map[i]);
284 } 393 }
285 394
286 static PySequenceMethods pyrf_cpu_map__sequence_methods = { 395 static PySequenceMethods pyrf_cpu_map__sequence_methods = {
287 .sq_length = pyrf_cpu_map__length, 396 .sq_length = pyrf_cpu_map__length,
288 .sq_item = pyrf_cpu_map__item, 397 .sq_item = pyrf_cpu_map__item,
289 }; 398 };
290 399
291 static char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object."); 400 static char pyrf_cpu_map__doc[] = PyDoc_STR("cpu map object.");
292 401
293 static PyTypeObject pyrf_cpu_map__type = { 402 static PyTypeObject pyrf_cpu_map__type = {
294 PyVarObject_HEAD_INIT(NULL, 0) 403 PyVarObject_HEAD_INIT(NULL, 0)
295 .tp_name = "perf.cpu_map", 404 .tp_name = "perf.cpu_map",
296 .tp_basicsize = sizeof(struct pyrf_cpu_map), 405 .tp_basicsize = sizeof(struct pyrf_cpu_map),
297 .tp_dealloc = (destructor)pyrf_cpu_map__delete, 406 .tp_dealloc = (destructor)pyrf_cpu_map__delete,
298 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 407 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
299 .tp_doc = pyrf_cpu_map__doc, 408 .tp_doc = pyrf_cpu_map__doc,
300 .tp_as_sequence = &pyrf_cpu_map__sequence_methods, 409 .tp_as_sequence = &pyrf_cpu_map__sequence_methods,
301 .tp_init = (initproc)pyrf_cpu_map__init, 410 .tp_init = (initproc)pyrf_cpu_map__init,
302 }; 411 };
303 412
304 static int pyrf_cpu_map__setup_types(void) 413 static int pyrf_cpu_map__setup_types(void)
305 { 414 {
306 pyrf_cpu_map__type.tp_new = PyType_GenericNew; 415 pyrf_cpu_map__type.tp_new = PyType_GenericNew;
307 return PyType_Ready(&pyrf_cpu_map__type); 416 return PyType_Ready(&pyrf_cpu_map__type);
308 } 417 }
309 418
310 struct pyrf_thread_map { 419 struct pyrf_thread_map {
311 PyObject_HEAD 420 PyObject_HEAD
312 421
313 struct thread_map *threads; 422 struct thread_map *threads;
314 }; 423 };
315 424
316 static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads, 425 static int pyrf_thread_map__init(struct pyrf_thread_map *pthreads,
317 PyObject *args, PyObject *kwargs) 426 PyObject *args, PyObject *kwargs)
318 { 427 {
319 static char *kwlist[] = { "pid", "tid", NULL }; 428 static char *kwlist[] = { "pid", "tid", NULL };
320 int pid = -1, tid = -1; 429 int pid = -1, tid = -1;
321 430
322 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", 431 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii",
323 kwlist, &pid, &tid)) 432 kwlist, &pid, &tid))
324 return -1; 433 return -1;
325 434
326 pthreads->threads = thread_map__new(pid, tid); 435 pthreads->threads = thread_map__new(pid, tid);
327 if (pthreads->threads == NULL) 436 if (pthreads->threads == NULL)
328 return -1; 437 return -1;
329 return 0; 438 return 0;
330 } 439 }
331 440
332 static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads) 441 static void pyrf_thread_map__delete(struct pyrf_thread_map *pthreads)
333 { 442 {
334 thread_map__delete(pthreads->threads); 443 thread_map__delete(pthreads->threads);
335 pthreads->ob_type->tp_free((PyObject*)pthreads); 444 pthreads->ob_type->tp_free((PyObject*)pthreads);
336 } 445 }
337 446
338 static Py_ssize_t pyrf_thread_map__length(PyObject *obj) 447 static Py_ssize_t pyrf_thread_map__length(PyObject *obj)
339 { 448 {
340 struct pyrf_thread_map *pthreads = (void *)obj; 449 struct pyrf_thread_map *pthreads = (void *)obj;
341 450
342 return pthreads->threads->nr; 451 return pthreads->threads->nr;
343 } 452 }
344 453
345 static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i) 454 static PyObject *pyrf_thread_map__item(PyObject *obj, Py_ssize_t i)
346 { 455 {
347 struct pyrf_thread_map *pthreads = (void *)obj; 456 struct pyrf_thread_map *pthreads = (void *)obj;
348 457
349 if (i >= pthreads->threads->nr) 458 if (i >= pthreads->threads->nr)
350 return NULL; 459 return NULL;
351 460
352 return Py_BuildValue("i", pthreads->threads->map[i]); 461 return Py_BuildValue("i", pthreads->threads->map[i]);
353 } 462 }
354 463
355 static PySequenceMethods pyrf_thread_map__sequence_methods = { 464 static PySequenceMethods pyrf_thread_map__sequence_methods = {
356 .sq_length = pyrf_thread_map__length, 465 .sq_length = pyrf_thread_map__length,
357 .sq_item = pyrf_thread_map__item, 466 .sq_item = pyrf_thread_map__item,
358 }; 467 };
359 468
360 static char pyrf_thread_map__doc[] = PyDoc_STR("thread map object."); 469 static char pyrf_thread_map__doc[] = PyDoc_STR("thread map object.");
361 470
362 static PyTypeObject pyrf_thread_map__type = { 471 static PyTypeObject pyrf_thread_map__type = {
363 PyVarObject_HEAD_INIT(NULL, 0) 472 PyVarObject_HEAD_INIT(NULL, 0)
364 .tp_name = "perf.thread_map", 473 .tp_name = "perf.thread_map",
365 .tp_basicsize = sizeof(struct pyrf_thread_map), 474 .tp_basicsize = sizeof(struct pyrf_thread_map),
366 .tp_dealloc = (destructor)pyrf_thread_map__delete, 475 .tp_dealloc = (destructor)pyrf_thread_map__delete,
367 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 476 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
368 .tp_doc = pyrf_thread_map__doc, 477 .tp_doc = pyrf_thread_map__doc,
369 .tp_as_sequence = &pyrf_thread_map__sequence_methods, 478 .tp_as_sequence = &pyrf_thread_map__sequence_methods,
370 .tp_init = (initproc)pyrf_thread_map__init, 479 .tp_init = (initproc)pyrf_thread_map__init,
371 }; 480 };
372 481
373 static int pyrf_thread_map__setup_types(void) 482 static int pyrf_thread_map__setup_types(void)
374 { 483 {
375 pyrf_thread_map__type.tp_new = PyType_GenericNew; 484 pyrf_thread_map__type.tp_new = PyType_GenericNew;
376 return PyType_Ready(&pyrf_thread_map__type); 485 return PyType_Ready(&pyrf_thread_map__type);
377 } 486 }
378 487
379 struct pyrf_evsel { 488 struct pyrf_evsel {
380 PyObject_HEAD 489 PyObject_HEAD
381 490
382 struct perf_evsel evsel; 491 struct perf_evsel evsel;
383 }; 492 };
384 493
385 static int pyrf_evsel__init(struct pyrf_evsel *pevsel, 494 static int pyrf_evsel__init(struct pyrf_evsel *pevsel,
386 PyObject *args, PyObject *kwargs) 495 PyObject *args, PyObject *kwargs)
387 { 496 {
388 struct perf_event_attr attr = { 497 struct perf_event_attr attr = {
389 .type = PERF_TYPE_HARDWARE, 498 .type = PERF_TYPE_HARDWARE,
390 .config = PERF_COUNT_HW_CPU_CYCLES, 499 .config = PERF_COUNT_HW_CPU_CYCLES,
391 .sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID, 500 .sample_type = PERF_SAMPLE_PERIOD | PERF_SAMPLE_TID,
392 }; 501 };
393 static char *kwlist[] = { 502 static char *kwlist[] = {
394 "type", 503 "type",
395 "config", 504 "config",
396 "sample_freq", 505 "sample_freq",
397 "sample_period", 506 "sample_period",
398 "sample_type", 507 "sample_type",
399 "read_format", 508 "read_format",
400 "disabled", 509 "disabled",
401 "inherit", 510 "inherit",
402 "pinned", 511 "pinned",
403 "exclusive", 512 "exclusive",
404 "exclude_user", 513 "exclude_user",
405 "exclude_kernel", 514 "exclude_kernel",
406 "exclude_hv", 515 "exclude_hv",
407 "exclude_idle", 516 "exclude_idle",
408 "mmap", 517 "mmap",
409 "comm", 518 "comm",
410 "freq", 519 "freq",
411 "inherit_stat", 520 "inherit_stat",
412 "enable_on_exec", 521 "enable_on_exec",
413 "task", 522 "task",
414 "watermark", 523 "watermark",
415 "precise_ip", 524 "precise_ip",
416 "mmap_data", 525 "mmap_data",
417 "sample_id_all", 526 "sample_id_all",
418 "wakeup_events", 527 "wakeup_events",
419 "bp_type", 528 "bp_type",
420 "bp_addr", 529 "bp_addr",
421 "bp_len", 530 "bp_len",
422 NULL 531 NULL
423 }; 532 };
424 u64 sample_period = 0; 533 u64 sample_period = 0;
425 u32 disabled = 0, 534 u32 disabled = 0,
426 inherit = 0, 535 inherit = 0,
427 pinned = 0, 536 pinned = 0,
428 exclusive = 0, 537 exclusive = 0,
429 exclude_user = 0, 538 exclude_user = 0,
430 exclude_kernel = 0, 539 exclude_kernel = 0,
431 exclude_hv = 0, 540 exclude_hv = 0,
432 exclude_idle = 0, 541 exclude_idle = 0,
433 mmap = 0, 542 mmap = 0,
434 comm = 0, 543 comm = 0,
435 freq = 1, 544 freq = 1,
436 inherit_stat = 0, 545 inherit_stat = 0,
437 enable_on_exec = 0, 546 enable_on_exec = 0,
438 task = 0, 547 task = 0,
439 watermark = 0, 548 watermark = 0,
440 precise_ip = 0, 549 precise_ip = 0,
441 mmap_data = 0, 550 mmap_data = 0,
442 sample_id_all = 1; 551 sample_id_all = 1;
443 int idx = 0; 552 int idx = 0;
444 553
445 if (!PyArg_ParseTupleAndKeywords(args, kwargs, 554 if (!PyArg_ParseTupleAndKeywords(args, kwargs,
446 "|iKiKKiiiiiiiiiiiiiiiiiiiiiKK", kwlist, 555 "|iKiKKiiiiiiiiiiiiiiiiiiiiiKK", kwlist,
447 &attr.type, &attr.config, &attr.sample_freq, 556 &attr.type, &attr.config, &attr.sample_freq,
448 &sample_period, &attr.sample_type, 557 &sample_period, &attr.sample_type,
449 &attr.read_format, &disabled, &inherit, 558 &attr.read_format, &disabled, &inherit,
450 &pinned, &exclusive, &exclude_user, 559 &pinned, &exclusive, &exclude_user,
451 &exclude_kernel, &exclude_hv, &exclude_idle, 560 &exclude_kernel, &exclude_hv, &exclude_idle,
452 &mmap, &comm, &freq, &inherit_stat, 561 &mmap, &comm, &freq, &inherit_stat,
453 &enable_on_exec, &task, &watermark, 562 &enable_on_exec, &task, &watermark,
454 &precise_ip, &mmap_data, &sample_id_all, 563 &precise_ip, &mmap_data, &sample_id_all,
455 &attr.wakeup_events, &attr.bp_type, 564 &attr.wakeup_events, &attr.bp_type,
456 &attr.bp_addr, &attr.bp_len, &idx)) 565 &attr.bp_addr, &attr.bp_len, &idx))
457 return -1; 566 return -1;
458 567
459 /* union... */ 568 /* union... */
460 if (sample_period != 0) { 569 if (sample_period != 0) {
461 if (attr.sample_freq != 0) 570 if (attr.sample_freq != 0)
462 return -1; /* FIXME: throw right exception */ 571 return -1; /* FIXME: throw right exception */
463 attr.sample_period = sample_period; 572 attr.sample_period = sample_period;
464 } 573 }
465 574
466 /* Bitfields */ 575 /* Bitfields */
467 attr.disabled = disabled; 576 attr.disabled = disabled;
468 attr.inherit = inherit; 577 attr.inherit = inherit;
469 attr.pinned = pinned; 578 attr.pinned = pinned;
470 attr.exclusive = exclusive; 579 attr.exclusive = exclusive;
471 attr.exclude_user = exclude_user; 580 attr.exclude_user = exclude_user;
472 attr.exclude_kernel = exclude_kernel; 581 attr.exclude_kernel = exclude_kernel;
473 attr.exclude_hv = exclude_hv; 582 attr.exclude_hv = exclude_hv;
474 attr.exclude_idle = exclude_idle; 583 attr.exclude_idle = exclude_idle;
475 attr.mmap = mmap; 584 attr.mmap = mmap;
476 attr.comm = comm; 585 attr.comm = comm;
477 attr.freq = freq; 586 attr.freq = freq;
478 attr.inherit_stat = inherit_stat; 587 attr.inherit_stat = inherit_stat;
479 attr.enable_on_exec = enable_on_exec; 588 attr.enable_on_exec = enable_on_exec;
480 attr.task = task; 589 attr.task = task;
481 attr.watermark = watermark; 590 attr.watermark = watermark;
482 attr.precise_ip = precise_ip; 591 attr.precise_ip = precise_ip;
483 attr.mmap_data = mmap_data; 592 attr.mmap_data = mmap_data;
484 attr.sample_id_all = sample_id_all; 593 attr.sample_id_all = sample_id_all;
485 594
486 perf_evsel__init(&pevsel->evsel, &attr, idx); 595 perf_evsel__init(&pevsel->evsel, &attr, idx);
487 return 0; 596 return 0;
488 } 597 }
489 598
490 static void pyrf_evsel__delete(struct pyrf_evsel *pevsel) 599 static void pyrf_evsel__delete(struct pyrf_evsel *pevsel)
491 { 600 {
492 perf_evsel__exit(&pevsel->evsel); 601 perf_evsel__exit(&pevsel->evsel);
493 pevsel->ob_type->tp_free((PyObject*)pevsel); 602 pevsel->ob_type->tp_free((PyObject*)pevsel);
494 } 603 }
495 604
496 static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel, 605 static PyObject *pyrf_evsel__open(struct pyrf_evsel *pevsel,
497 PyObject *args, PyObject *kwargs) 606 PyObject *args, PyObject *kwargs)
498 { 607 {
499 struct perf_evsel *evsel = &pevsel->evsel; 608 struct perf_evsel *evsel = &pevsel->evsel;
500 struct cpu_map *cpus = NULL; 609 struct cpu_map *cpus = NULL;
501 struct thread_map *threads = NULL; 610 struct thread_map *threads = NULL;
502 PyObject *pcpus = NULL, *pthreads = NULL; 611 PyObject *pcpus = NULL, *pthreads = NULL;
503 int group = 0, inherit = 0; 612 int group = 0, inherit = 0;
504 static char *kwlist[] = { "cpus", "threads", "group", "inherit", NULL }; 613 static char *kwlist[] = { "cpus", "threads", "group", "inherit", NULL };
505 614
506 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist, 615 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|OOii", kwlist,
507 &pcpus, &pthreads, &group, &inherit)) 616 &pcpus, &pthreads, &group, &inherit))
508 return NULL; 617 return NULL;
509 618
510 if (pthreads != NULL) 619 if (pthreads != NULL)
511 threads = ((struct pyrf_thread_map *)pthreads)->threads; 620 threads = ((struct pyrf_thread_map *)pthreads)->threads;
512 621
513 if (pcpus != NULL) 622 if (pcpus != NULL)
514 cpus = ((struct pyrf_cpu_map *)pcpus)->cpus; 623 cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
515 624
516 evsel->attr.inherit = inherit; 625 evsel->attr.inherit = inherit;
517 if (perf_evsel__open(evsel, cpus, threads, group) < 0) { 626 if (perf_evsel__open(evsel, cpus, threads, group) < 0) {
518 PyErr_SetFromErrno(PyExc_OSError); 627 PyErr_SetFromErrno(PyExc_OSError);
519 return NULL; 628 return NULL;
520 } 629 }
521 630
522 Py_INCREF(Py_None); 631 Py_INCREF(Py_None);
523 return Py_None; 632 return Py_None;
524 } 633 }
525 634
526 static PyMethodDef pyrf_evsel__methods[] = { 635 static PyMethodDef pyrf_evsel__methods[] = {
527 { 636 {
528 .ml_name = "open", 637 .ml_name = "open",
529 .ml_meth = (PyCFunction)pyrf_evsel__open, 638 .ml_meth = (PyCFunction)pyrf_evsel__open,
530 .ml_flags = METH_VARARGS | METH_KEYWORDS, 639 .ml_flags = METH_VARARGS | METH_KEYWORDS,
531 .ml_doc = PyDoc_STR("open the event selector file descriptor table.") 640 .ml_doc = PyDoc_STR("open the event selector file descriptor table.")
532 }, 641 },
533 { .ml_name = NULL, } 642 { .ml_name = NULL, }
534 }; 643 };
535 644
536 static char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object."); 645 static char pyrf_evsel__doc[] = PyDoc_STR("perf event selector list object.");
537 646
538 static PyTypeObject pyrf_evsel__type = { 647 static PyTypeObject pyrf_evsel__type = {
539 PyVarObject_HEAD_INIT(NULL, 0) 648 PyVarObject_HEAD_INIT(NULL, 0)
540 .tp_name = "perf.evsel", 649 .tp_name = "perf.evsel",
541 .tp_basicsize = sizeof(struct pyrf_evsel), 650 .tp_basicsize = sizeof(struct pyrf_evsel),
542 .tp_dealloc = (destructor)pyrf_evsel__delete, 651 .tp_dealloc = (destructor)pyrf_evsel__delete,
543 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 652 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
544 .tp_doc = pyrf_evsel__doc, 653 .tp_doc = pyrf_evsel__doc,
545 .tp_methods = pyrf_evsel__methods, 654 .tp_methods = pyrf_evsel__methods,
546 .tp_init = (initproc)pyrf_evsel__init, 655 .tp_init = (initproc)pyrf_evsel__init,
547 }; 656 };
548 657
549 static int pyrf_evsel__setup_types(void) 658 static int pyrf_evsel__setup_types(void)
550 { 659 {
551 pyrf_evsel__type.tp_new = PyType_GenericNew; 660 pyrf_evsel__type.tp_new = PyType_GenericNew;
552 return PyType_Ready(&pyrf_evsel__type); 661 return PyType_Ready(&pyrf_evsel__type);
553 } 662 }
554 663
555 struct pyrf_evlist { 664 struct pyrf_evlist {
556 PyObject_HEAD 665 PyObject_HEAD
557 666
558 struct perf_evlist evlist; 667 struct perf_evlist evlist;
559 }; 668 };
560 669
561 static int pyrf_evlist__init(struct pyrf_evlist *pevlist, 670 static int pyrf_evlist__init(struct pyrf_evlist *pevlist,
562 PyObject *args, PyObject *kwargs __used) 671 PyObject *args, PyObject *kwargs __used)
563 { 672 {
564 PyObject *pcpus = NULL, *pthreads = NULL; 673 PyObject *pcpus = NULL, *pthreads = NULL;
565 struct cpu_map *cpus; 674 struct cpu_map *cpus;
566 struct thread_map *threads; 675 struct thread_map *threads;
567 676
568 if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads)) 677 if (!PyArg_ParseTuple(args, "OO", &pcpus, &pthreads))
569 return -1; 678 return -1;
570 679
571 threads = ((struct pyrf_thread_map *)pthreads)->threads; 680 threads = ((struct pyrf_thread_map *)pthreads)->threads;
572 cpus = ((struct pyrf_cpu_map *)pcpus)->cpus; 681 cpus = ((struct pyrf_cpu_map *)pcpus)->cpus;
573 perf_evlist__init(&pevlist->evlist, cpus, threads); 682 perf_evlist__init(&pevlist->evlist, cpus, threads);
574 return 0; 683 return 0;
575 } 684 }
576 685
577 static void pyrf_evlist__delete(struct pyrf_evlist *pevlist) 686 static void pyrf_evlist__delete(struct pyrf_evlist *pevlist)
578 { 687 {
579 perf_evlist__exit(&pevlist->evlist); 688 perf_evlist__exit(&pevlist->evlist);
580 pevlist->ob_type->tp_free((PyObject*)pevlist); 689 pevlist->ob_type->tp_free((PyObject*)pevlist);
581 } 690 }
582 691
583 static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist, 692 static PyObject *pyrf_evlist__mmap(struct pyrf_evlist *pevlist,
584 PyObject *args, PyObject *kwargs) 693 PyObject *args, PyObject *kwargs)
585 { 694 {
586 struct perf_evlist *evlist = &pevlist->evlist; 695 struct perf_evlist *evlist = &pevlist->evlist;
587 static char *kwlist[] = { "pages", "overwrite", NULL }; 696 static char *kwlist[] = { "pages", "overwrite", NULL };
588 int pages = 128, overwrite = false; 697 int pages = 128, overwrite = false;
589 698
590 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist, 699 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|ii", kwlist,
591 &pages, &overwrite)) 700 &pages, &overwrite))
592 return NULL; 701 return NULL;
593 702
594 if (perf_evlist__mmap(evlist, pages, overwrite) < 0) { 703 if (perf_evlist__mmap(evlist, pages, overwrite) < 0) {
595 PyErr_SetFromErrno(PyExc_OSError); 704 PyErr_SetFromErrno(PyExc_OSError);
596 return NULL; 705 return NULL;
597 } 706 }
598 707
599 Py_INCREF(Py_None); 708 Py_INCREF(Py_None);
600 return Py_None; 709 return Py_None;
601 } 710 }
602 711
603 static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist, 712 static PyObject *pyrf_evlist__poll(struct pyrf_evlist *pevlist,
604 PyObject *args, PyObject *kwargs) 713 PyObject *args, PyObject *kwargs)
605 { 714 {
606 struct perf_evlist *evlist = &pevlist->evlist; 715 struct perf_evlist *evlist = &pevlist->evlist;
607 static char *kwlist[] = { "timeout", NULL }; 716 static char *kwlist[] = { "timeout", NULL };
608 int timeout = -1, n; 717 int timeout = -1, n;
609 718
610 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout)) 719 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "|i", kwlist, &timeout))
611 return NULL; 720 return NULL;
612 721
613 n = poll(evlist->pollfd, evlist->nr_fds, timeout); 722 n = poll(evlist->pollfd, evlist->nr_fds, timeout);
614 if (n < 0) { 723 if (n < 0) {
615 PyErr_SetFromErrno(PyExc_OSError); 724 PyErr_SetFromErrno(PyExc_OSError);
616 return NULL; 725 return NULL;
617 } 726 }
618 727
619 return Py_BuildValue("i", n); 728 return Py_BuildValue("i", n);
620 } 729 }
621 730
622 static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist, 731 static PyObject *pyrf_evlist__get_pollfd(struct pyrf_evlist *pevlist,
623 PyObject *args __used, PyObject *kwargs __used) 732 PyObject *args __used, PyObject *kwargs __used)
624 { 733 {
625 struct perf_evlist *evlist = &pevlist->evlist; 734 struct perf_evlist *evlist = &pevlist->evlist;
626 PyObject *list = PyList_New(0); 735 PyObject *list = PyList_New(0);
627 int i; 736 int i;
628 737
629 for (i = 0; i < evlist->nr_fds; ++i) { 738 for (i = 0; i < evlist->nr_fds; ++i) {
630 PyObject *file; 739 PyObject *file;
631 FILE *fp = fdopen(evlist->pollfd[i].fd, "r"); 740 FILE *fp = fdopen(evlist->pollfd[i].fd, "r");
632 741
633 if (fp == NULL) 742 if (fp == NULL)
634 goto free_list; 743 goto free_list;
635 744
636 file = PyFile_FromFile(fp, "perf", "r", NULL); 745 file = PyFile_FromFile(fp, "perf", "r", NULL);
637 if (file == NULL) 746 if (file == NULL)
638 goto free_list; 747 goto free_list;
639 748
640 if (PyList_Append(list, file) != 0) { 749 if (PyList_Append(list, file) != 0) {
641 Py_DECREF(file); 750 Py_DECREF(file);
642 goto free_list; 751 goto free_list;
643 } 752 }
644 753
645 Py_DECREF(file); 754 Py_DECREF(file);
646 } 755 }
647 756
648 return list; 757 return list;
649 free_list: 758 free_list:
650 return PyErr_NoMemory(); 759 return PyErr_NoMemory();
651 } 760 }
652 761
653 762
654 static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist, 763 static PyObject *pyrf_evlist__add(struct pyrf_evlist *pevlist,
655 PyObject *args, PyObject *kwargs __used) 764 PyObject *args, PyObject *kwargs __used)
656 { 765 {
657 struct perf_evlist *evlist = &pevlist->evlist; 766 struct perf_evlist *evlist = &pevlist->evlist;
658 PyObject *pevsel; 767 PyObject *pevsel;
659 struct perf_evsel *evsel; 768 struct perf_evsel *evsel;
660 769
661 if (!PyArg_ParseTuple(args, "O", &pevsel)) 770 if (!PyArg_ParseTuple(args, "O", &pevsel))
662 return NULL; 771 return NULL;
663 772
664 Py_INCREF(pevsel); 773 Py_INCREF(pevsel);
665 evsel = &((struct pyrf_evsel *)pevsel)->evsel; 774 evsel = &((struct pyrf_evsel *)pevsel)->evsel;
666 evsel->idx = evlist->nr_entries; 775 evsel->idx = evlist->nr_entries;
667 perf_evlist__add(evlist, evsel); 776 perf_evlist__add(evlist, evsel);
668 777
669 return Py_BuildValue("i", evlist->nr_entries); 778 return Py_BuildValue("i", evlist->nr_entries);
670 } 779 }
671 780
672 static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, 781 static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist,
673 PyObject *args, PyObject *kwargs) 782 PyObject *args, PyObject *kwargs)
674 { 783 {
675 struct perf_evlist *evlist = &pevlist->evlist; 784 struct perf_evlist *evlist = &pevlist->evlist;
676 union perf_event *event; 785 union perf_event *event;
677 int sample_id_all = 1, cpu; 786 int sample_id_all = 1, cpu;
678 static char *kwlist[] = { "cpu", "sample_id_all", NULL }; 787 static char *kwlist[] = { "cpu", "sample_id_all", NULL };
679 int err; 788 int err;
680 789
681 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist, 790 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i|i", kwlist,
682 &cpu, &sample_id_all)) 791 &cpu, &sample_id_all))
683 return NULL; 792 return NULL;
684 793
685 event = perf_evlist__mmap_read(evlist, cpu); 794 event = perf_evlist__mmap_read(evlist, cpu);
686 if (event != NULL) { 795 if (event != NULL) {
687 struct perf_evsel *first; 796 struct perf_evsel *first;
688 PyObject *pyevent = pyrf_event__new(event); 797 PyObject *pyevent = pyrf_event__new(event);
689 struct pyrf_event *pevent = (struct pyrf_event *)pyevent; 798 struct pyrf_event *pevent = (struct pyrf_event *)pyevent;
690 799
691 if (pyevent == NULL) 800 if (pyevent == NULL)
692 return PyErr_NoMemory(); 801 return PyErr_NoMemory();
693 802
694 first = list_entry(evlist->entries.next, struct perf_evsel, node); 803 first = list_entry(evlist->entries.next, struct perf_evsel, node);
695 err = perf_event__parse_sample(event, first->attr.sample_type, 804 err = perf_event__parse_sample(event, first->attr.sample_type,
696 perf_evsel__sample_size(first), 805 perf_evsel__sample_size(first),
697 sample_id_all, &pevent->sample); 806 sample_id_all, &pevent->sample);
698 if (err) 807 if (err)
699 return PyErr_Format(PyExc_OSError, 808 return PyErr_Format(PyExc_OSError,
700 "perf: can't parse sample, err=%d", err); 809 "perf: can't parse sample, err=%d", err);
701 return pyevent; 810 return pyevent;
702 } 811 }
703 812
704 Py_INCREF(Py_None); 813 Py_INCREF(Py_None);
705 return Py_None; 814 return Py_None;
706 } 815 }
707 816
708 static PyMethodDef pyrf_evlist__methods[] = { 817 static PyMethodDef pyrf_evlist__methods[] = {
709 { 818 {
710 .ml_name = "mmap", 819 .ml_name = "mmap",
711 .ml_meth = (PyCFunction)pyrf_evlist__mmap, 820 .ml_meth = (PyCFunction)pyrf_evlist__mmap,
712 .ml_flags = METH_VARARGS | METH_KEYWORDS, 821 .ml_flags = METH_VARARGS | METH_KEYWORDS,
713 .ml_doc = PyDoc_STR("mmap the file descriptor table.") 822 .ml_doc = PyDoc_STR("mmap the file descriptor table.")
714 }, 823 },
715 { 824 {
716 .ml_name = "poll", 825 .ml_name = "poll",
717 .ml_meth = (PyCFunction)pyrf_evlist__poll, 826 .ml_meth = (PyCFunction)pyrf_evlist__poll,
718 .ml_flags = METH_VARARGS | METH_KEYWORDS, 827 .ml_flags = METH_VARARGS | METH_KEYWORDS,
719 .ml_doc = PyDoc_STR("poll the file descriptor table.") 828 .ml_doc = PyDoc_STR("poll the file descriptor table.")
720 }, 829 },
721 { 830 {
722 .ml_name = "get_pollfd", 831 .ml_name = "get_pollfd",
723 .ml_meth = (PyCFunction)pyrf_evlist__get_pollfd, 832 .ml_meth = (PyCFunction)pyrf_evlist__get_pollfd,
724 .ml_flags = METH_VARARGS | METH_KEYWORDS, 833 .ml_flags = METH_VARARGS | METH_KEYWORDS,
725 .ml_doc = PyDoc_STR("get the poll file descriptor table.") 834 .ml_doc = PyDoc_STR("get the poll file descriptor table.")
726 }, 835 },
727 { 836 {
728 .ml_name = "add", 837 .ml_name = "add",
729 .ml_meth = (PyCFunction)pyrf_evlist__add, 838 .ml_meth = (PyCFunction)pyrf_evlist__add,
730 .ml_flags = METH_VARARGS | METH_KEYWORDS, 839 .ml_flags = METH_VARARGS | METH_KEYWORDS,
731 .ml_doc = PyDoc_STR("adds an event selector to the list.") 840 .ml_doc = PyDoc_STR("adds an event selector to the list.")
732 }, 841 },
733 { 842 {
734 .ml_name = "read_on_cpu", 843 .ml_name = "read_on_cpu",
735 .ml_meth = (PyCFunction)pyrf_evlist__read_on_cpu, 844 .ml_meth = (PyCFunction)pyrf_evlist__read_on_cpu,
736 .ml_flags = METH_VARARGS | METH_KEYWORDS, 845 .ml_flags = METH_VARARGS | METH_KEYWORDS,
737 .ml_doc = PyDoc_STR("reads an event.") 846 .ml_doc = PyDoc_STR("reads an event.")
738 }, 847 },
739 { .ml_name = NULL, } 848 { .ml_name = NULL, }
740 }; 849 };
741 850
742 static Py_ssize_t pyrf_evlist__length(PyObject *obj) 851 static Py_ssize_t pyrf_evlist__length(PyObject *obj)
743 { 852 {
744 struct pyrf_evlist *pevlist = (void *)obj; 853 struct pyrf_evlist *pevlist = (void *)obj;
745 854
746 return pevlist->evlist.nr_entries; 855 return pevlist->evlist.nr_entries;
747 } 856 }
748 857
749 static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i) 858 static PyObject *pyrf_evlist__item(PyObject *obj, Py_ssize_t i)
750 { 859 {
751 struct pyrf_evlist *pevlist = (void *)obj; 860 struct pyrf_evlist *pevlist = (void *)obj;
752 struct perf_evsel *pos; 861 struct perf_evsel *pos;
753 862
754 if (i >= pevlist->evlist.nr_entries) 863 if (i >= pevlist->evlist.nr_entries)
755 return NULL; 864 return NULL;
756 865
757 list_for_each_entry(pos, &pevlist->evlist.entries, node) 866 list_for_each_entry(pos, &pevlist->evlist.entries, node)
758 if (i-- == 0) 867 if (i-- == 0)
759 break; 868 break;
760 869
761 return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel)); 870 return Py_BuildValue("O", container_of(pos, struct pyrf_evsel, evsel));
762 } 871 }
763 872
764 static PySequenceMethods pyrf_evlist__sequence_methods = { 873 static PySequenceMethods pyrf_evlist__sequence_methods = {
765 .sq_length = pyrf_evlist__length, 874 .sq_length = pyrf_evlist__length,
766 .sq_item = pyrf_evlist__item, 875 .sq_item = pyrf_evlist__item,
767 }; 876 };
768 877
769 static char pyrf_evlist__doc[] = PyDoc_STR("perf event selector list object."); 878 static char pyrf_evlist__doc[] = PyDoc_STR("perf event selector list object.");
770 879
771 static PyTypeObject pyrf_evlist__type = { 880 static PyTypeObject pyrf_evlist__type = {
772 PyVarObject_HEAD_INIT(NULL, 0) 881 PyVarObject_HEAD_INIT(NULL, 0)
773 .tp_name = "perf.evlist", 882 .tp_name = "perf.evlist",
774 .tp_basicsize = sizeof(struct pyrf_evlist), 883 .tp_basicsize = sizeof(struct pyrf_evlist),
775 .tp_dealloc = (destructor)pyrf_evlist__delete, 884 .tp_dealloc = (destructor)pyrf_evlist__delete,
776 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE, 885 .tp_flags = Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,
777 .tp_as_sequence = &pyrf_evlist__sequence_methods, 886 .tp_as_sequence = &pyrf_evlist__sequence_methods,
778 .tp_doc = pyrf_evlist__doc, 887 .tp_doc = pyrf_evlist__doc,
779 .tp_methods = pyrf_evlist__methods, 888 .tp_methods = pyrf_evlist__methods,
780 .tp_init = (initproc)pyrf_evlist__init, 889 .tp_init = (initproc)pyrf_evlist__init,
781 }; 890 };
782 891
783 static int pyrf_evlist__setup_types(void) 892 static int pyrf_evlist__setup_types(void)
784 { 893 {
785 pyrf_evlist__type.tp_new = PyType_GenericNew; 894 pyrf_evlist__type.tp_new = PyType_GenericNew;
786 return PyType_Ready(&pyrf_evlist__type); 895 return PyType_Ready(&pyrf_evlist__type);
787 } 896 }
788 897
789 static struct { 898 static struct {
790 const char *name; 899 const char *name;
791 int value; 900 int value;
792 } perf__constants[] = { 901 } perf__constants[] = {
793 { "TYPE_HARDWARE", PERF_TYPE_HARDWARE }, 902 { "TYPE_HARDWARE", PERF_TYPE_HARDWARE },
794 { "TYPE_SOFTWARE", PERF_TYPE_SOFTWARE }, 903 { "TYPE_SOFTWARE", PERF_TYPE_SOFTWARE },
795 { "TYPE_TRACEPOINT", PERF_TYPE_TRACEPOINT }, 904 { "TYPE_TRACEPOINT", PERF_TYPE_TRACEPOINT },
796 { "TYPE_HW_CACHE", PERF_TYPE_HW_CACHE }, 905 { "TYPE_HW_CACHE", PERF_TYPE_HW_CACHE },
797 { "TYPE_RAW", PERF_TYPE_RAW }, 906 { "TYPE_RAW", PERF_TYPE_RAW },
798 { "TYPE_BREAKPOINT", PERF_TYPE_BREAKPOINT }, 907 { "TYPE_BREAKPOINT", PERF_TYPE_BREAKPOINT },
799 908
800 { "COUNT_HW_CPU_CYCLES", PERF_COUNT_HW_CPU_CYCLES }, 909 { "COUNT_HW_CPU_CYCLES", PERF_COUNT_HW_CPU_CYCLES },
801 { "COUNT_HW_INSTRUCTIONS", PERF_COUNT_HW_INSTRUCTIONS }, 910 { "COUNT_HW_INSTRUCTIONS", PERF_COUNT_HW_INSTRUCTIONS },
802 { "COUNT_HW_CACHE_REFERENCES", PERF_COUNT_HW_CACHE_REFERENCES }, 911 { "COUNT_HW_CACHE_REFERENCES", PERF_COUNT_HW_CACHE_REFERENCES },
803 { "COUNT_HW_CACHE_MISSES", PERF_COUNT_HW_CACHE_MISSES }, 912 { "COUNT_HW_CACHE_MISSES", PERF_COUNT_HW_CACHE_MISSES },
804 { "COUNT_HW_BRANCH_INSTRUCTIONS", PERF_COUNT_HW_BRANCH_INSTRUCTIONS }, 913 { "COUNT_HW_BRANCH_INSTRUCTIONS", PERF_COUNT_HW_BRANCH_INSTRUCTIONS },
805 { "COUNT_HW_BRANCH_MISSES", PERF_COUNT_HW_BRANCH_MISSES }, 914 { "COUNT_HW_BRANCH_MISSES", PERF_COUNT_HW_BRANCH_MISSES },
806 { "COUNT_HW_BUS_CYCLES", PERF_COUNT_HW_BUS_CYCLES }, 915 { "COUNT_HW_BUS_CYCLES", PERF_COUNT_HW_BUS_CYCLES },
807 { "COUNT_HW_CACHE_L1D", PERF_COUNT_HW_CACHE_L1D }, 916 { "COUNT_HW_CACHE_L1D", PERF_COUNT_HW_CACHE_L1D },
808 { "COUNT_HW_CACHE_L1I", PERF_COUNT_HW_CACHE_L1I }, 917 { "COUNT_HW_CACHE_L1I", PERF_COUNT_HW_CACHE_L1I },
809 { "COUNT_HW_CACHE_LL", PERF_COUNT_HW_CACHE_LL }, 918 { "COUNT_HW_CACHE_LL", PERF_COUNT_HW_CACHE_LL },
810 { "COUNT_HW_CACHE_DTLB", PERF_COUNT_HW_CACHE_DTLB }, 919 { "COUNT_HW_CACHE_DTLB", PERF_COUNT_HW_CACHE_DTLB },
811 { "COUNT_HW_CACHE_ITLB", PERF_COUNT_HW_CACHE_ITLB }, 920 { "COUNT_HW_CACHE_ITLB", PERF_COUNT_HW_CACHE_ITLB },
812 { "COUNT_HW_CACHE_BPU", PERF_COUNT_HW_CACHE_BPU }, 921 { "COUNT_HW_CACHE_BPU", PERF_COUNT_HW_CACHE_BPU },
813 { "COUNT_HW_CACHE_OP_READ", PERF_COUNT_HW_CACHE_OP_READ }, 922 { "COUNT_HW_CACHE_OP_READ", PERF_COUNT_HW_CACHE_OP_READ },
814 { "COUNT_HW_CACHE_OP_WRITE", PERF_COUNT_HW_CACHE_OP_WRITE }, 923 { "COUNT_HW_CACHE_OP_WRITE", PERF_COUNT_HW_CACHE_OP_WRITE },
815 { "COUNT_HW_CACHE_OP_PREFETCH", PERF_COUNT_HW_CACHE_OP_PREFETCH }, 924 { "COUNT_HW_CACHE_OP_PREFETCH", PERF_COUNT_HW_CACHE_OP_PREFETCH },
816 { "COUNT_HW_CACHE_RESULT_ACCESS", PERF_COUNT_HW_CACHE_RESULT_ACCESS }, 925 { "COUNT_HW_CACHE_RESULT_ACCESS", PERF_COUNT_HW_CACHE_RESULT_ACCESS },
817 { "COUNT_HW_CACHE_RESULT_MISS", PERF_COUNT_HW_CACHE_RESULT_MISS }, 926 { "COUNT_HW_CACHE_RESULT_MISS", PERF_COUNT_HW_CACHE_RESULT_MISS },
818 927
819 { "COUNT_HW_STALLED_CYCLES_FRONTEND", PERF_COUNT_HW_STALLED_CYCLES_FRONTEND }, 928 { "COUNT_HW_STALLED_CYCLES_FRONTEND", PERF_COUNT_HW_STALLED_CYCLES_FRONTEND },
820 { "COUNT_HW_STALLED_CYCLES_BACKEND", PERF_COUNT_HW_STALLED_CYCLES_BACKEND }, 929 { "COUNT_HW_STALLED_CYCLES_BACKEND", PERF_COUNT_HW_STALLED_CYCLES_BACKEND },
821 930
822 { "COUNT_SW_CPU_CLOCK", PERF_COUNT_SW_CPU_CLOCK }, 931 { "COUNT_SW_CPU_CLOCK", PERF_COUNT_SW_CPU_CLOCK },
823 { "COUNT_SW_TASK_CLOCK", PERF_COUNT_SW_TASK_CLOCK }, 932 { "COUNT_SW_TASK_CLOCK", PERF_COUNT_SW_TASK_CLOCK },
824 { "COUNT_SW_PAGE_FAULTS", PERF_COUNT_SW_PAGE_FAULTS }, 933 { "COUNT_SW_PAGE_FAULTS", PERF_COUNT_SW_PAGE_FAULTS },
825 { "COUNT_SW_CONTEXT_SWITCHES", PERF_COUNT_SW_CONTEXT_SWITCHES }, 934 { "COUNT_SW_CONTEXT_SWITCHES", PERF_COUNT_SW_CONTEXT_SWITCHES },
826 { "COUNT_SW_CPU_MIGRATIONS", PERF_COUNT_SW_CPU_MIGRATIONS }, 935 { "COUNT_SW_CPU_MIGRATIONS", PERF_COUNT_SW_CPU_MIGRATIONS },
827 { "COUNT_SW_PAGE_FAULTS_MIN", PERF_COUNT_SW_PAGE_FAULTS_MIN }, 936 { "COUNT_SW_PAGE_FAULTS_MIN", PERF_COUNT_SW_PAGE_FAULTS_MIN },
828 { "COUNT_SW_PAGE_FAULTS_MAJ", PERF_COUNT_SW_PAGE_FAULTS_MAJ }, 937 { "COUNT_SW_PAGE_FAULTS_MAJ", PERF_COUNT_SW_PAGE_FAULTS_MAJ },
829 { "COUNT_SW_ALIGNMENT_FAULTS", PERF_COUNT_SW_ALIGNMENT_FAULTS }, 938 { "COUNT_SW_ALIGNMENT_FAULTS", PERF_COUNT_SW_ALIGNMENT_FAULTS },
830 { "COUNT_SW_EMULATION_FAULTS", PERF_COUNT_SW_EMULATION_FAULTS }, 939 { "COUNT_SW_EMULATION_FAULTS", PERF_COUNT_SW_EMULATION_FAULTS },
831 940
832 { "SAMPLE_IP", PERF_SAMPLE_IP }, 941 { "SAMPLE_IP", PERF_SAMPLE_IP },
833 { "SAMPLE_TID", PERF_SAMPLE_TID }, 942 { "SAMPLE_TID", PERF_SAMPLE_TID },
834 { "SAMPLE_TIME", PERF_SAMPLE_TIME }, 943 { "SAMPLE_TIME", PERF_SAMPLE_TIME },
835 { "SAMPLE_ADDR", PERF_SAMPLE_ADDR }, 944 { "SAMPLE_ADDR", PERF_SAMPLE_ADDR },
836 { "SAMPLE_READ", PERF_SAMPLE_READ }, 945 { "SAMPLE_READ", PERF_SAMPLE_READ },
837 { "SAMPLE_CALLCHAIN", PERF_SAMPLE_CALLCHAIN }, 946 { "SAMPLE_CALLCHAIN", PERF_SAMPLE_CALLCHAIN },
838 { "SAMPLE_ID", PERF_SAMPLE_ID }, 947 { "SAMPLE_ID", PERF_SAMPLE_ID },
839 { "SAMPLE_CPU", PERF_SAMPLE_CPU }, 948 { "SAMPLE_CPU", PERF_SAMPLE_CPU },
840 { "SAMPLE_PERIOD", PERF_SAMPLE_PERIOD }, 949 { "SAMPLE_PERIOD", PERF_SAMPLE_PERIOD },
841 { "SAMPLE_STREAM_ID", PERF_SAMPLE_STREAM_ID }, 950 { "SAMPLE_STREAM_ID", PERF_SAMPLE_STREAM_ID },
842 { "SAMPLE_RAW", PERF_SAMPLE_RAW }, 951 { "SAMPLE_RAW", PERF_SAMPLE_RAW },
843 952
844 { "FORMAT_TOTAL_TIME_ENABLED", PERF_FORMAT_TOTAL_TIME_ENABLED }, 953 { "FORMAT_TOTAL_TIME_ENABLED", PERF_FORMAT_TOTAL_TIME_ENABLED },
845 { "FORMAT_TOTAL_TIME_RUNNING", PERF_FORMAT_TOTAL_TIME_RUNNING }, 954 { "FORMAT_TOTAL_TIME_RUNNING", PERF_FORMAT_TOTAL_TIME_RUNNING },
846 { "FORMAT_ID", PERF_FORMAT_ID }, 955 { "FORMAT_ID", PERF_FORMAT_ID },
847 { "FORMAT_GROUP", PERF_FORMAT_GROUP }, 956 { "FORMAT_GROUP", PERF_FORMAT_GROUP },
848 957
849 { "RECORD_MMAP", PERF_RECORD_MMAP }, 958 { "RECORD_MMAP", PERF_RECORD_MMAP },
850 { "RECORD_LOST", PERF_RECORD_LOST }, 959 { "RECORD_LOST", PERF_RECORD_LOST },
851 { "RECORD_COMM", PERF_RECORD_COMM }, 960 { "RECORD_COMM", PERF_RECORD_COMM },
852 { "RECORD_EXIT", PERF_RECORD_EXIT }, 961 { "RECORD_EXIT", PERF_RECORD_EXIT },
853 { "RECORD_THROTTLE", PERF_RECORD_THROTTLE }, 962 { "RECORD_THROTTLE", PERF_RECORD_THROTTLE },
854 { "RECORD_UNTHROTTLE", PERF_RECORD_UNTHROTTLE }, 963 { "RECORD_UNTHROTTLE", PERF_RECORD_UNTHROTTLE },
855 { "RECORD_FORK", PERF_RECORD_FORK }, 964 { "RECORD_FORK", PERF_RECORD_FORK },
856 { "RECORD_READ", PERF_RECORD_READ }, 965 { "RECORD_READ", PERF_RECORD_READ },
857 { "RECORD_SAMPLE", PERF_RECORD_SAMPLE }, 966 { "RECORD_SAMPLE", PERF_RECORD_SAMPLE },
858 { .name = NULL, }, 967 { .name = NULL, },
859 }; 968 };
860 969
861 static PyMethodDef perf__methods[] = { 970 static PyMethodDef perf__methods[] = {
862 { .ml_name = NULL, } 971 { .ml_name = NULL, }
863 }; 972 };
864 973
865 PyMODINIT_FUNC initperf(void) 974 PyMODINIT_FUNC initperf(void)
866 { 975 {
867 PyObject *obj; 976 PyObject *obj;
868 int i; 977 int i;
869 PyObject *dict, *module = Py_InitModule("perf", perf__methods); 978 PyObject *dict, *module = Py_InitModule("perf", perf__methods);
870 979
871 if (module == NULL || 980 if (module == NULL ||
872 pyrf_event__setup_types() < 0 || 981 pyrf_event__setup_types() < 0 ||
873 pyrf_evlist__setup_types() < 0 || 982 pyrf_evlist__setup_types() < 0 ||
874 pyrf_evsel__setup_types() < 0 || 983 pyrf_evsel__setup_types() < 0 ||
875 pyrf_thread_map__setup_types() < 0 || 984 pyrf_thread_map__setup_types() < 0 ||
876 pyrf_cpu_map__setup_types() < 0) 985 pyrf_cpu_map__setup_types() < 0)
877 return; 986 return;
878 987
879 Py_INCREF(&pyrf_evlist__type); 988 Py_INCREF(&pyrf_evlist__type);
880 PyModule_AddObject(module, "evlist", (PyObject*)&pyrf_evlist__type); 989 PyModule_AddObject(module, "evlist", (PyObject*)&pyrf_evlist__type);
881 990
882 Py_INCREF(&pyrf_evsel__type); 991 Py_INCREF(&pyrf_evsel__type);
883 PyModule_AddObject(module, "evsel", (PyObject*)&pyrf_evsel__type); 992 PyModule_AddObject(module, "evsel", (PyObject*)&pyrf_evsel__type);
884 993
885 Py_INCREF(&pyrf_thread_map__type); 994 Py_INCREF(&pyrf_thread_map__type);
886 PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type); 995 PyModule_AddObject(module, "thread_map", (PyObject*)&pyrf_thread_map__type);
887 996
888 Py_INCREF(&pyrf_cpu_map__type); 997 Py_INCREF(&pyrf_cpu_map__type);
889 PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type); 998 PyModule_AddObject(module, "cpu_map", (PyObject*)&pyrf_cpu_map__type);
890 999
891 dict = PyModule_GetDict(module); 1000 dict = PyModule_GetDict(module);
892 if (dict == NULL) 1001 if (dict == NULL)
893 goto error; 1002 goto error;
894 1003
895 for (i = 0; perf__constants[i].name != NULL; i++) { 1004 for (i = 0; perf__constants[i].name != NULL; i++) {
896 obj = PyInt_FromLong(perf__constants[i].value); 1005 obj = PyInt_FromLong(perf__constants[i].value);
897 if (obj == NULL) 1006 if (obj == NULL)
898 goto error; 1007 goto error;
899 PyDict_SetItemString(dict, perf__constants[i].name, obj); 1008 PyDict_SetItemString(dict, perf__constants[i].name, obj);
900 Py_DECREF(obj); 1009 Py_DECREF(obj);
901 } 1010 }
902 1011
903 error: 1012 error:
904 if (PyErr_Occurred()) 1013 if (PyErr_Occurred())
905 PyErr_SetString(PyExc_ImportError, "perf: Init failed!"); 1014 PyErr_SetString(PyExc_ImportError, "perf: Init failed!");
906 } 1015 }
907 1016
tools/perf/util/setup.py
1 #!/usr/bin/python2 1 #!/usr/bin/python2
2 2
3 from distutils.core import setup, Extension 3 from distutils.core import setup, Extension
4 from os import getenv 4 from os import getenv
5 5
6 from distutils.command.build_ext import build_ext as _build_ext
7 from distutils.command.install_lib import install_lib as _install_lib
8
9 class build_ext(_build_ext):
10 def finalize_options(self):
11 _build_ext.finalize_options(self)
12 self.build_lib = build_lib
13 self.build_temp = build_tmp
14
15 class install_lib(_install_lib):
16 def finalize_options(self):
17 _install_lib.finalize_options(self)
18 self.build_dir = build_lib
19
20
6 cflags = ['-fno-strict-aliasing', '-Wno-write-strings'] 21 cflags = ['-fno-strict-aliasing', '-Wno-write-strings']
7 cflags += getenv('CFLAGS', '').split() 22 cflags += getenv('CFLAGS', '').split()
8 23
24 build_lib = getenv('PYTHON_EXTBUILD_LIB')
25 build_tmp = getenv('PYTHON_EXTBUILD_TMP')
26
9 perf = Extension('perf', 27 perf = Extension('perf',
10 sources = ['util/python.c', 'util/ctype.c', 'util/evlist.c', 28 sources = ['util/python.c', 'util/ctype.c', 'util/evlist.c',
11 'util/evsel.c', 'util/cpumap.c', 'util/thread_map.c', 29 'util/evsel.c', 'util/cpumap.c', 'util/thread_map.c',
12 'util/util.c', 'util/xyarray.c', 'util/cgroup.c'], 30 'util/util.c', 'util/xyarray.c', 'util/cgroup.c'],
13 include_dirs = ['util/include'], 31 include_dirs = ['util/include'],
14 extra_compile_args = cflags, 32 extra_compile_args = cflags,
15 ) 33 )
16 34
17 setup(name='perf', 35 setup(name='perf',
18 version='0.1', 36 version='0.1',
19 description='Interface with the Linux profiling infrastructure', 37 description='Interface with the Linux profiling infrastructure',
20 author='Arnaldo Carvalho de Melo', 38 author='Arnaldo Carvalho de Melo',
21 author_email='acme@redhat.com', 39 author_email='acme@redhat.com',
22 license='GPLv2', 40 license='GPLv2',
23 url='http://perf.wiki.kernel.org', 41 url='http://perf.wiki.kernel.org',
24 ext_modules=[perf]) 42 ext_modules=[perf],
43 cmdclass={'build_ext': build_ext, 'install_lib': install_lib})
25 44
tools/perf/util/symbol.c
1 #define _GNU_SOURCE 1 #define _GNU_SOURCE
2 #include <ctype.h> 2 #include <ctype.h>
3 #include <dirent.h> 3 #include <dirent.h>
4 #include <errno.h> 4 #include <errno.h>
5 #include <libgen.h> 5 #include <libgen.h>
6 #include <stdlib.h> 6 #include <stdlib.h>
7 #include <stdio.h> 7 #include <stdio.h>
8 #include <string.h> 8 #include <string.h>
9 #include <sys/types.h> 9 #include <sys/types.h>
10 #include <sys/stat.h> 10 #include <sys/stat.h>
11 #include <sys/param.h> 11 #include <sys/param.h>
12 #include <fcntl.h> 12 #include <fcntl.h>
13 #include <unistd.h> 13 #include <unistd.h>
14 #include <inttypes.h> 14 #include <inttypes.h>
15 #include "build-id.h" 15 #include "build-id.h"
16 #include "debug.h" 16 #include "debug.h"
17 #include "symbol.h" 17 #include "symbol.h"
18 #include "strlist.h" 18 #include "strlist.h"
19 19
20 #include <libelf.h> 20 #include <libelf.h>
21 #include <gelf.h> 21 #include <gelf.h>
22 #include <elf.h> 22 #include <elf.h>
23 #include <limits.h> 23 #include <limits.h>
24 #include <sys/utsname.h> 24 #include <sys/utsname.h>
25 25
26 #ifndef KSYM_NAME_LEN 26 #ifndef KSYM_NAME_LEN
27 #define KSYM_NAME_LEN 128 27 #define KSYM_NAME_LEN 128
28 #endif 28 #endif
29 29
30 #ifndef NT_GNU_BUILD_ID 30 #ifndef NT_GNU_BUILD_ID
31 #define NT_GNU_BUILD_ID 3 31 #define NT_GNU_BUILD_ID 3
32 #endif 32 #endif
33 33
34 static bool dso__build_id_equal(const struct dso *dso, u8 *build_id); 34 static bool dso__build_id_equal(const struct dso *dso, u8 *build_id);
35 static int elf_read_build_id(Elf *elf, void *bf, size_t size); 35 static int elf_read_build_id(Elf *elf, void *bf, size_t size);
36 static void dsos__add(struct list_head *head, struct dso *dso); 36 static void dsos__add(struct list_head *head, struct dso *dso);
37 static struct map *map__new2(u64 start, struct dso *dso, enum map_type type); 37 static struct map *map__new2(u64 start, struct dso *dso, enum map_type type);
38 static int dso__load_kernel_sym(struct dso *dso, struct map *map, 38 static int dso__load_kernel_sym(struct dso *dso, struct map *map,
39 symbol_filter_t filter); 39 symbol_filter_t filter);
40 static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map, 40 static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
41 symbol_filter_t filter); 41 symbol_filter_t filter);
42 static int vmlinux_path__nr_entries; 42 static int vmlinux_path__nr_entries;
43 static char **vmlinux_path; 43 static char **vmlinux_path;
44 44
45 struct symbol_conf symbol_conf = { 45 struct symbol_conf symbol_conf = {
46 .exclude_other = true, 46 .exclude_other = true,
47 .use_modules = true, 47 .use_modules = true,
48 .try_vmlinux_path = true, 48 .try_vmlinux_path = true,
49 .symfs = "", 49 .symfs = "",
50 }; 50 };
51 51
52 int dso__name_len(const struct dso *dso) 52 int dso__name_len(const struct dso *dso)
53 { 53 {
54 if (verbose) 54 if (verbose)
55 return dso->long_name_len; 55 return dso->long_name_len;
56 56
57 return dso->short_name_len; 57 return dso->short_name_len;
58 } 58 }
59 59
60 bool dso__loaded(const struct dso *dso, enum map_type type) 60 bool dso__loaded(const struct dso *dso, enum map_type type)
61 { 61 {
62 return dso->loaded & (1 << type); 62 return dso->loaded & (1 << type);
63 } 63 }
64 64
65 bool dso__sorted_by_name(const struct dso *dso, enum map_type type) 65 bool dso__sorted_by_name(const struct dso *dso, enum map_type type)
66 { 66 {
67 return dso->sorted_by_name & (1 << type); 67 return dso->sorted_by_name & (1 << type);
68 } 68 }
69 69
70 static void dso__set_sorted_by_name(struct dso *dso, enum map_type type) 70 static void dso__set_sorted_by_name(struct dso *dso, enum map_type type)
71 { 71 {
72 dso->sorted_by_name |= (1 << type); 72 dso->sorted_by_name |= (1 << type);
73 } 73 }
74 74
75 bool symbol_type__is_a(char symbol_type, enum map_type map_type) 75 bool symbol_type__is_a(char symbol_type, enum map_type map_type)
76 { 76 {
77 switch (map_type) { 77 switch (map_type) {
78 case MAP__FUNCTION: 78 case MAP__FUNCTION:
79 return symbol_type == 'T' || symbol_type == 'W'; 79 return symbol_type == 'T' || symbol_type == 'W';
80 case MAP__VARIABLE: 80 case MAP__VARIABLE:
81 return symbol_type == 'D' || symbol_type == 'd'; 81 return symbol_type == 'D' || symbol_type == 'd';
82 default: 82 default:
83 return false; 83 return false;
84 } 84 }
85 } 85 }
86 86
87 static void symbols__fixup_end(struct rb_root *symbols) 87 static void symbols__fixup_end(struct rb_root *symbols)
88 { 88 {
89 struct rb_node *nd, *prevnd = rb_first(symbols); 89 struct rb_node *nd, *prevnd = rb_first(symbols);
90 struct symbol *curr, *prev; 90 struct symbol *curr, *prev;
91 91
92 if (prevnd == NULL) 92 if (prevnd == NULL)
93 return; 93 return;
94 94
95 curr = rb_entry(prevnd, struct symbol, rb_node); 95 curr = rb_entry(prevnd, struct symbol, rb_node);
96 96
97 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) { 97 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
98 prev = curr; 98 prev = curr;
99 curr = rb_entry(nd, struct symbol, rb_node); 99 curr = rb_entry(nd, struct symbol, rb_node);
100 100
101 if (prev->end == prev->start && prev->end != curr->start) 101 if (prev->end == prev->start && prev->end != curr->start)
102 prev->end = curr->start - 1; 102 prev->end = curr->start - 1;
103 } 103 }
104 104
105 /* Last entry */ 105 /* Last entry */
106 if (curr->end == curr->start) 106 if (curr->end == curr->start)
107 curr->end = roundup(curr->start, 4096); 107 curr->end = roundup(curr->start, 4096);
108 } 108 }
109 109
110 static void __map_groups__fixup_end(struct map_groups *mg, enum map_type type) 110 static void __map_groups__fixup_end(struct map_groups *mg, enum map_type type)
111 { 111 {
112 struct map *prev, *curr; 112 struct map *prev, *curr;
113 struct rb_node *nd, *prevnd = rb_first(&mg->maps[type]); 113 struct rb_node *nd, *prevnd = rb_first(&mg->maps[type]);
114 114
115 if (prevnd == NULL) 115 if (prevnd == NULL)
116 return; 116 return;
117 117
118 curr = rb_entry(prevnd, struct map, rb_node); 118 curr = rb_entry(prevnd, struct map, rb_node);
119 119
120 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) { 120 for (nd = rb_next(prevnd); nd; nd = rb_next(nd)) {
121 prev = curr; 121 prev = curr;
122 curr = rb_entry(nd, struct map, rb_node); 122 curr = rb_entry(nd, struct map, rb_node);
123 prev->end = curr->start - 1; 123 prev->end = curr->start - 1;
124 } 124 }
125 125
126 /* 126 /*
127 * We still haven't the actual symbols, so guess the 127 * We still haven't the actual symbols, so guess the
128 * last map final address. 128 * last map final address.
129 */ 129 */
130 curr->end = ~0ULL; 130 curr->end = ~0ULL;
131 } 131 }
132 132
133 static void map_groups__fixup_end(struct map_groups *mg) 133 static void map_groups__fixup_end(struct map_groups *mg)
134 { 134 {
135 int i; 135 int i;
136 for (i = 0; i < MAP__NR_TYPES; ++i) 136 for (i = 0; i < MAP__NR_TYPES; ++i)
137 __map_groups__fixup_end(mg, i); 137 __map_groups__fixup_end(mg, i);
138 } 138 }
139 139
140 static struct symbol *symbol__new(u64 start, u64 len, u8 binding, 140 static struct symbol *symbol__new(u64 start, u64 len, u8 binding,
141 const char *name) 141 const char *name)
142 { 142 {
143 size_t namelen = strlen(name) + 1; 143 size_t namelen = strlen(name) + 1;
144 struct symbol *sym = calloc(1, (symbol_conf.priv_size + 144 struct symbol *sym = calloc(1, (symbol_conf.priv_size +
145 sizeof(*sym) + namelen)); 145 sizeof(*sym) + namelen));
146 if (sym == NULL) 146 if (sym == NULL)
147 return NULL; 147 return NULL;
148 148
149 if (symbol_conf.priv_size) 149 if (symbol_conf.priv_size)
150 sym = ((void *)sym) + symbol_conf.priv_size; 150 sym = ((void *)sym) + symbol_conf.priv_size;
151 151
152 sym->start = start; 152 sym->start = start;
153 sym->end = len ? start + len - 1 : start; 153 sym->end = len ? start + len - 1 : start;
154 sym->binding = binding; 154 sym->binding = binding;
155 sym->namelen = namelen - 1; 155 sym->namelen = namelen - 1;
156 156
157 pr_debug4("%s: %s %#" PRIx64 "-%#" PRIx64 "\n", 157 pr_debug4("%s: %s %#" PRIx64 "-%#" PRIx64 "\n",
158 __func__, name, start, sym->end); 158 __func__, name, start, sym->end);
159 memcpy(sym->name, name, namelen); 159 memcpy(sym->name, name, namelen);
160 160
161 return sym; 161 return sym;
162 } 162 }
163 163
164 void symbol__delete(struct symbol *sym) 164 void symbol__delete(struct symbol *sym)
165 { 165 {
166 free(((void *)sym) - symbol_conf.priv_size); 166 free(((void *)sym) - symbol_conf.priv_size);
167 } 167 }
168 168
169 static size_t symbol__fprintf(struct symbol *sym, FILE *fp) 169 static size_t symbol__fprintf(struct symbol *sym, FILE *fp)
170 { 170 {
171 return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n", 171 return fprintf(fp, " %" PRIx64 "-%" PRIx64 " %c %s\n",
172 sym->start, sym->end, 172 sym->start, sym->end,
173 sym->binding == STB_GLOBAL ? 'g' : 173 sym->binding == STB_GLOBAL ? 'g' :
174 sym->binding == STB_LOCAL ? 'l' : 'w', 174 sym->binding == STB_LOCAL ? 'l' : 'w',
175 sym->name); 175 sym->name);
176 } 176 }
177 177
178 void dso__set_long_name(struct dso *dso, char *name) 178 void dso__set_long_name(struct dso *dso, char *name)
179 { 179 {
180 if (name == NULL) 180 if (name == NULL)
181 return; 181 return;
182 dso->long_name = name; 182 dso->long_name = name;
183 dso->long_name_len = strlen(name); 183 dso->long_name_len = strlen(name);
184 } 184 }
185 185
186 static void dso__set_short_name(struct dso *dso, const char *name) 186 static void dso__set_short_name(struct dso *dso, const char *name)
187 { 187 {
188 if (name == NULL) 188 if (name == NULL)
189 return; 189 return;
190 dso->short_name = name; 190 dso->short_name = name;
191 dso->short_name_len = strlen(name); 191 dso->short_name_len = strlen(name);
192 } 192 }
193 193
194 static void dso__set_basename(struct dso *dso) 194 static void dso__set_basename(struct dso *dso)
195 { 195 {
196 dso__set_short_name(dso, basename(dso->long_name)); 196 dso__set_short_name(dso, basename(dso->long_name));
197 } 197 }
198 198
199 struct dso *dso__new(const char *name) 199 struct dso *dso__new(const char *name)
200 { 200 {
201 struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1); 201 struct dso *dso = calloc(1, sizeof(*dso) + strlen(name) + 1);
202 202
203 if (dso != NULL) { 203 if (dso != NULL) {
204 int i; 204 int i;
205 strcpy(dso->name, name); 205 strcpy(dso->name, name);
206 dso__set_long_name(dso, dso->name); 206 dso__set_long_name(dso, dso->name);
207 dso__set_short_name(dso, dso->name); 207 dso__set_short_name(dso, dso->name);
208 for (i = 0; i < MAP__NR_TYPES; ++i) 208 for (i = 0; i < MAP__NR_TYPES; ++i)
209 dso->symbols[i] = dso->symbol_names[i] = RB_ROOT; 209 dso->symbols[i] = dso->symbol_names[i] = RB_ROOT;
210 dso->symtab_type = SYMTAB__NOT_FOUND; 210 dso->symtab_type = SYMTAB__NOT_FOUND;
211 dso->loaded = 0; 211 dso->loaded = 0;
212 dso->sorted_by_name = 0; 212 dso->sorted_by_name = 0;
213 dso->has_build_id = 0; 213 dso->has_build_id = 0;
214 dso->kernel = DSO_TYPE_USER; 214 dso->kernel = DSO_TYPE_USER;
215 INIT_LIST_HEAD(&dso->node); 215 INIT_LIST_HEAD(&dso->node);
216 } 216 }
217 217
218 return dso; 218 return dso;
219 } 219 }
220 220
221 static void symbols__delete(struct rb_root *symbols) 221 static void symbols__delete(struct rb_root *symbols)
222 { 222 {
223 struct symbol *pos; 223 struct symbol *pos;
224 struct rb_node *next = rb_first(symbols); 224 struct rb_node *next = rb_first(symbols);
225 225
226 while (next) { 226 while (next) {
227 pos = rb_entry(next, struct symbol, rb_node); 227 pos = rb_entry(next, struct symbol, rb_node);
228 next = rb_next(&pos->rb_node); 228 next = rb_next(&pos->rb_node);
229 rb_erase(&pos->rb_node, symbols); 229 rb_erase(&pos->rb_node, symbols);
230 symbol__delete(pos); 230 symbol__delete(pos);
231 } 231 }
232 } 232 }
233 233
234 void dso__delete(struct dso *dso) 234 void dso__delete(struct dso *dso)
235 { 235 {
236 int i; 236 int i;
237 for (i = 0; i < MAP__NR_TYPES; ++i) 237 for (i = 0; i < MAP__NR_TYPES; ++i)
238 symbols__delete(&dso->symbols[i]); 238 symbols__delete(&dso->symbols[i]);
239 if (dso->sname_alloc) 239 if (dso->sname_alloc)
240 free((char *)dso->short_name); 240 free((char *)dso->short_name);
241 if (dso->lname_alloc) 241 if (dso->lname_alloc)
242 free(dso->long_name); 242 free(dso->long_name);
243 free(dso); 243 free(dso);
244 } 244 }
245 245
246 void dso__set_build_id(struct dso *dso, void *build_id) 246 void dso__set_build_id(struct dso *dso, void *build_id)
247 { 247 {
248 memcpy(dso->build_id, build_id, sizeof(dso->build_id)); 248 memcpy(dso->build_id, build_id, sizeof(dso->build_id));
249 dso->has_build_id = 1; 249 dso->has_build_id = 1;
250 } 250 }
251 251
252 static void symbols__insert(struct rb_root *symbols, struct symbol *sym) 252 static void symbols__insert(struct rb_root *symbols, struct symbol *sym)
253 { 253 {
254 struct rb_node **p = &symbols->rb_node; 254 struct rb_node **p = &symbols->rb_node;
255 struct rb_node *parent = NULL; 255 struct rb_node *parent = NULL;
256 const u64 ip = sym->start; 256 const u64 ip = sym->start;
257 struct symbol *s; 257 struct symbol *s;
258 258
259 while (*p != NULL) { 259 while (*p != NULL) {
260 parent = *p; 260 parent = *p;
261 s = rb_entry(parent, struct symbol, rb_node); 261 s = rb_entry(parent, struct symbol, rb_node);
262 if (ip < s->start) 262 if (ip < s->start)
263 p = &(*p)->rb_left; 263 p = &(*p)->rb_left;
264 else 264 else
265 p = &(*p)->rb_right; 265 p = &(*p)->rb_right;
266 } 266 }
267 rb_link_node(&sym->rb_node, parent, p); 267 rb_link_node(&sym->rb_node, parent, p);
268 rb_insert_color(&sym->rb_node, symbols); 268 rb_insert_color(&sym->rb_node, symbols);
269 } 269 }
270 270
271 static struct symbol *symbols__find(struct rb_root *symbols, u64 ip) 271 static struct symbol *symbols__find(struct rb_root *symbols, u64 ip)
272 { 272 {
273 struct rb_node *n; 273 struct rb_node *n;
274 274
275 if (symbols == NULL) 275 if (symbols == NULL)
276 return NULL; 276 return NULL;
277 277
278 n = symbols->rb_node; 278 n = symbols->rb_node;
279 279
280 while (n) { 280 while (n) {
281 struct symbol *s = rb_entry(n, struct symbol, rb_node); 281 struct symbol *s = rb_entry(n, struct symbol, rb_node);
282 282
283 if (ip < s->start) 283 if (ip < s->start)
284 n = n->rb_left; 284 n = n->rb_left;
285 else if (ip > s->end) 285 else if (ip > s->end)
286 n = n->rb_right; 286 n = n->rb_right;
287 else 287 else
288 return s; 288 return s;
289 } 289 }
290 290
291 return NULL; 291 return NULL;
292 } 292 }
293 293
294 struct symbol_name_rb_node { 294 struct symbol_name_rb_node {
295 struct rb_node rb_node; 295 struct rb_node rb_node;
296 struct symbol sym; 296 struct symbol sym;
297 }; 297 };
298 298
299 static void symbols__insert_by_name(struct rb_root *symbols, struct symbol *sym) 299 static void symbols__insert_by_name(struct rb_root *symbols, struct symbol *sym)
300 { 300 {
301 struct rb_node **p = &symbols->rb_node; 301 struct rb_node **p = &symbols->rb_node;
302 struct rb_node *parent = NULL; 302 struct rb_node *parent = NULL;
303 struct symbol_name_rb_node *symn, *s; 303 struct symbol_name_rb_node *symn, *s;
304 304
305 symn = container_of(sym, struct symbol_name_rb_node, sym); 305 symn = container_of(sym, struct symbol_name_rb_node, sym);
306 306
307 while (*p != NULL) { 307 while (*p != NULL) {
308 parent = *p; 308 parent = *p;
309 s = rb_entry(parent, struct symbol_name_rb_node, rb_node); 309 s = rb_entry(parent, struct symbol_name_rb_node, rb_node);
310 if (strcmp(sym->name, s->sym.name) < 0) 310 if (strcmp(sym->name, s->sym.name) < 0)
311 p = &(*p)->rb_left; 311 p = &(*p)->rb_left;
312 else 312 else
313 p = &(*p)->rb_right; 313 p = &(*p)->rb_right;
314 } 314 }
315 rb_link_node(&symn->rb_node, parent, p); 315 rb_link_node(&symn->rb_node, parent, p);
316 rb_insert_color(&symn->rb_node, symbols); 316 rb_insert_color(&symn->rb_node, symbols);
317 } 317 }
318 318
319 static void symbols__sort_by_name(struct rb_root *symbols, 319 static void symbols__sort_by_name(struct rb_root *symbols,
320 struct rb_root *source) 320 struct rb_root *source)
321 { 321 {
322 struct rb_node *nd; 322 struct rb_node *nd;
323 323
324 for (nd = rb_first(source); nd; nd = rb_next(nd)) { 324 for (nd = rb_first(source); nd; nd = rb_next(nd)) {
325 struct symbol *pos = rb_entry(nd, struct symbol, rb_node); 325 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
326 symbols__insert_by_name(symbols, pos); 326 symbols__insert_by_name(symbols, pos);
327 } 327 }
328 } 328 }
329 329
330 static struct symbol *symbols__find_by_name(struct rb_root *symbols, 330 static struct symbol *symbols__find_by_name(struct rb_root *symbols,
331 const char *name) 331 const char *name)
332 { 332 {
333 struct rb_node *n; 333 struct rb_node *n;
334 334
335 if (symbols == NULL) 335 if (symbols == NULL)
336 return NULL; 336 return NULL;
337 337
338 n = symbols->rb_node; 338 n = symbols->rb_node;
339 339
340 while (n) { 340 while (n) {
341 struct symbol_name_rb_node *s; 341 struct symbol_name_rb_node *s;
342 int cmp; 342 int cmp;
343 343
344 s = rb_entry(n, struct symbol_name_rb_node, rb_node); 344 s = rb_entry(n, struct symbol_name_rb_node, rb_node);
345 cmp = strcmp(name, s->sym.name); 345 cmp = strcmp(name, s->sym.name);
346 346
347 if (cmp < 0) 347 if (cmp < 0)
348 n = n->rb_left; 348 n = n->rb_left;
349 else if (cmp > 0) 349 else if (cmp > 0)
350 n = n->rb_right; 350 n = n->rb_right;
351 else 351 else
352 return &s->sym; 352 return &s->sym;
353 } 353 }
354 354
355 return NULL; 355 return NULL;
356 } 356 }
357 357
358 struct symbol *dso__find_symbol(struct dso *dso, 358 struct symbol *dso__find_symbol(struct dso *dso,
359 enum map_type type, u64 addr) 359 enum map_type type, u64 addr)
360 { 360 {
361 return symbols__find(&dso->symbols[type], addr); 361 return symbols__find(&dso->symbols[type], addr);
362 } 362 }
363 363
364 struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type, 364 struct symbol *dso__find_symbol_by_name(struct dso *dso, enum map_type type,
365 const char *name) 365 const char *name)
366 { 366 {
367 return symbols__find_by_name(&dso->symbol_names[type], name); 367 return symbols__find_by_name(&dso->symbol_names[type], name);
368 } 368 }
369 369
370 void dso__sort_by_name(struct dso *dso, enum map_type type) 370 void dso__sort_by_name(struct dso *dso, enum map_type type)
371 { 371 {
372 dso__set_sorted_by_name(dso, type); 372 dso__set_sorted_by_name(dso, type);
373 return symbols__sort_by_name(&dso->symbol_names[type], 373 return symbols__sort_by_name(&dso->symbol_names[type],
374 &dso->symbols[type]); 374 &dso->symbols[type]);
375 } 375 }
376 376
377 int build_id__sprintf(const u8 *build_id, int len, char *bf) 377 int build_id__sprintf(const u8 *build_id, int len, char *bf)
378 { 378 {
379 char *bid = bf; 379 char *bid = bf;
380 const u8 *raw = build_id; 380 const u8 *raw = build_id;
381 int i; 381 int i;
382 382
383 for (i = 0; i < len; ++i) { 383 for (i = 0; i < len; ++i) {
384 sprintf(bid, "%02x", *raw); 384 sprintf(bid, "%02x", *raw);
385 ++raw; 385 ++raw;
386 bid += 2; 386 bid += 2;
387 } 387 }
388 388
389 return raw - build_id; 389 return raw - build_id;
390 } 390 }
391 391
392 size_t dso__fprintf_buildid(struct dso *dso, FILE *fp) 392 size_t dso__fprintf_buildid(struct dso *dso, FILE *fp)
393 { 393 {
394 char sbuild_id[BUILD_ID_SIZE * 2 + 1]; 394 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
395 395
396 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id); 396 build_id__sprintf(dso->build_id, sizeof(dso->build_id), sbuild_id);
397 return fprintf(fp, "%s", sbuild_id); 397 return fprintf(fp, "%s", sbuild_id);
398 } 398 }
399 399
400 size_t dso__fprintf_symbols_by_name(struct dso *dso, 400 size_t dso__fprintf_symbols_by_name(struct dso *dso,
401 enum map_type type, FILE *fp) 401 enum map_type type, FILE *fp)
402 { 402 {
403 size_t ret = 0; 403 size_t ret = 0;
404 struct rb_node *nd; 404 struct rb_node *nd;
405 struct symbol_name_rb_node *pos; 405 struct symbol_name_rb_node *pos;
406 406
407 for (nd = rb_first(&dso->symbol_names[type]); nd; nd = rb_next(nd)) { 407 for (nd = rb_first(&dso->symbol_names[type]); nd; nd = rb_next(nd)) {
408 pos = rb_entry(nd, struct symbol_name_rb_node, rb_node); 408 pos = rb_entry(nd, struct symbol_name_rb_node, rb_node);
409 fprintf(fp, "%s\n", pos->sym.name); 409 fprintf(fp, "%s\n", pos->sym.name);
410 } 410 }
411 411
412 return ret; 412 return ret;
413 } 413 }
414 414
415 size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp) 415 size_t dso__fprintf(struct dso *dso, enum map_type type, FILE *fp)
416 { 416 {
417 struct rb_node *nd; 417 struct rb_node *nd;
418 size_t ret = fprintf(fp, "dso: %s (", dso->short_name); 418 size_t ret = fprintf(fp, "dso: %s (", dso->short_name);
419 419
420 if (dso->short_name != dso->long_name) 420 if (dso->short_name != dso->long_name)
421 ret += fprintf(fp, "%s, ", dso->long_name); 421 ret += fprintf(fp, "%s, ", dso->long_name);
422 ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type], 422 ret += fprintf(fp, "%s, %sloaded, ", map_type__name[type],
423 dso->loaded ? "" : "NOT "); 423 dso->loaded ? "" : "NOT ");
424 ret += dso__fprintf_buildid(dso, fp); 424 ret += dso__fprintf_buildid(dso, fp);
425 ret += fprintf(fp, ")\n"); 425 ret += fprintf(fp, ")\n");
426 for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) { 426 for (nd = rb_first(&dso->symbols[type]); nd; nd = rb_next(nd)) {
427 struct symbol *pos = rb_entry(nd, struct symbol, rb_node); 427 struct symbol *pos = rb_entry(nd, struct symbol, rb_node);
428 ret += symbol__fprintf(pos, fp); 428 ret += symbol__fprintf(pos, fp);
429 } 429 }
430 430
431 return ret; 431 return ret;
432 } 432 }
433 433
434 int kallsyms__parse(const char *filename, void *arg, 434 int kallsyms__parse(const char *filename, void *arg,
435 int (*process_symbol)(void *arg, const char *name, 435 int (*process_symbol)(void *arg, const char *name,
436 char type, u64 start, u64 end)) 436 char type, u64 start, u64 end))
437 { 437 {
438 char *line = NULL; 438 char *line = NULL;
439 size_t n; 439 size_t n;
440 int err = -1; 440 int err = -1;
441 u64 prev_start = 0; 441 u64 prev_start = 0;
442 char prev_symbol_type = 0; 442 char prev_symbol_type = 0;
443 char *prev_symbol_name; 443 char *prev_symbol_name;
444 FILE *file = fopen(filename, "r"); 444 FILE *file = fopen(filename, "r");
445 445
446 if (file == NULL) 446 if (file == NULL)
447 goto out_failure; 447 goto out_failure;
448 448
449 prev_symbol_name = malloc(KSYM_NAME_LEN); 449 prev_symbol_name = malloc(KSYM_NAME_LEN);
450 if (prev_symbol_name == NULL) 450 if (prev_symbol_name == NULL)
451 goto out_close; 451 goto out_close;
452 452
453 err = 0; 453 err = 0;
454 454
455 while (!feof(file)) { 455 while (!feof(file)) {
456 u64 start; 456 u64 start;
457 int line_len, len; 457 int line_len, len;
458 char symbol_type; 458 char symbol_type;
459 char *symbol_name; 459 char *symbol_name;
460 460
461 line_len = getline(&line, &n, file); 461 line_len = getline(&line, &n, file);
462 if (line_len < 0 || !line) 462 if (line_len < 0 || !line)
463 break; 463 break;
464 464
465 line[--line_len] = '\0'; /* \n */ 465 line[--line_len] = '\0'; /* \n */
466 466
467 len = hex2u64(line, &start); 467 len = hex2u64(line, &start);
468 468
469 len++; 469 len++;
470 if (len + 2 >= line_len) 470 if (len + 2 >= line_len)
471 continue; 471 continue;
472 472
473 symbol_type = toupper(line[len]); 473 symbol_type = toupper(line[len]);
474 len += 2; 474 len += 2;
475 symbol_name = line + len; 475 symbol_name = line + len;
476 len = line_len - len; 476 len = line_len - len;
477 477
478 if (len >= KSYM_NAME_LEN) { 478 if (len >= KSYM_NAME_LEN) {
479 err = -1; 479 err = -1;
480 break; 480 break;
481 } 481 }
482 482
483 if (prev_symbol_type) { 483 if (prev_symbol_type) {
484 u64 end = start; 484 u64 end = start;
485 if (end != prev_start) 485 if (end != prev_start)
486 --end; 486 --end;
487 err = process_symbol(arg, prev_symbol_name, 487 err = process_symbol(arg, prev_symbol_name,
488 prev_symbol_type, prev_start, end); 488 prev_symbol_type, prev_start, end);
489 if (err) 489 if (err)
490 break; 490 break;
491 } 491 }
492 492
493 memcpy(prev_symbol_name, symbol_name, len + 1); 493 memcpy(prev_symbol_name, symbol_name, len + 1);
494 prev_symbol_type = symbol_type; 494 prev_symbol_type = symbol_type;
495 prev_start = start; 495 prev_start = start;
496 } 496 }
497 497
498 free(prev_symbol_name); 498 free(prev_symbol_name);
499 free(line); 499 free(line);
500 out_close: 500 out_close:
501 fclose(file); 501 fclose(file);
502 return err; 502 return err;
503 503
504 out_failure: 504 out_failure:
505 return -1; 505 return -1;
506 } 506 }
507 507
508 struct process_kallsyms_args { 508 struct process_kallsyms_args {
509 struct map *map; 509 struct map *map;
510 struct dso *dso; 510 struct dso *dso;
511 }; 511 };
512 512
513 static u8 kallsyms2elf_type(char type) 513 static u8 kallsyms2elf_type(char type)
514 { 514 {
515 if (type == 'W') 515 if (type == 'W')
516 return STB_WEAK; 516 return STB_WEAK;
517 517
518 return isupper(type) ? STB_GLOBAL : STB_LOCAL; 518 return isupper(type) ? STB_GLOBAL : STB_LOCAL;
519 } 519 }
520 520
521 static int map__process_kallsym_symbol(void *arg, const char *name, 521 static int map__process_kallsym_symbol(void *arg, const char *name,
522 char type, u64 start, u64 end) 522 char type, u64 start, u64 end)
523 { 523 {
524 struct symbol *sym; 524 struct symbol *sym;
525 struct process_kallsyms_args *a = arg; 525 struct process_kallsyms_args *a = arg;
526 struct rb_root *root = &a->dso->symbols[a->map->type]; 526 struct rb_root *root = &a->dso->symbols[a->map->type];
527 527
528 if (!symbol_type__is_a(type, a->map->type)) 528 if (!symbol_type__is_a(type, a->map->type))
529 return 0; 529 return 0;
530 530
531 sym = symbol__new(start, end - start + 1, 531 sym = symbol__new(start, end - start + 1,
532 kallsyms2elf_type(type), name); 532 kallsyms2elf_type(type), name);
533 if (sym == NULL) 533 if (sym == NULL)
534 return -ENOMEM; 534 return -ENOMEM;
535 /* 535 /*
536 * We will pass the symbols to the filter later, in 536 * We will pass the symbols to the filter later, in
537 * map__split_kallsyms, when we have split the maps per module 537 * map__split_kallsyms, when we have split the maps per module
538 */ 538 */
539 symbols__insert(root, sym); 539 symbols__insert(root, sym);
540 540
541 return 0; 541 return 0;
542 } 542 }
543 543
544 /* 544 /*
545 * Loads the function entries in /proc/kallsyms into kernel_map->dso, 545 * Loads the function entries in /proc/kallsyms into kernel_map->dso,
546 * so that we can in the next step set the symbol ->end address and then 546 * so that we can in the next step set the symbol ->end address and then
547 * call kernel_maps__split_kallsyms. 547 * call kernel_maps__split_kallsyms.
548 */ 548 */
549 static int dso__load_all_kallsyms(struct dso *dso, const char *filename, 549 static int dso__load_all_kallsyms(struct dso *dso, const char *filename,
550 struct map *map) 550 struct map *map)
551 { 551 {
552 struct process_kallsyms_args args = { .map = map, .dso = dso, }; 552 struct process_kallsyms_args args = { .map = map, .dso = dso, };
553 return kallsyms__parse(filename, &args, map__process_kallsym_symbol); 553 return kallsyms__parse(filename, &args, map__process_kallsym_symbol);
554 } 554 }
555 555
556 /* 556 /*
557 * Split the symbols into maps, making sure there are no overlaps, i.e. the 557 * Split the symbols into maps, making sure there are no overlaps, i.e. the
558 * kernel range is broken in several maps, named [kernel].N, as we don't have 558 * kernel range is broken in several maps, named [kernel].N, as we don't have
559 * the original ELF section names vmlinux have. 559 * the original ELF section names vmlinux have.
560 */ 560 */
561 static int dso__split_kallsyms(struct dso *dso, struct map *map, 561 static int dso__split_kallsyms(struct dso *dso, struct map *map,
562 symbol_filter_t filter) 562 symbol_filter_t filter)
563 { 563 {
564 struct map_groups *kmaps = map__kmap(map)->kmaps; 564 struct map_groups *kmaps = map__kmap(map)->kmaps;
565 struct machine *machine = kmaps->machine; 565 struct machine *machine = kmaps->machine;
566 struct map *curr_map = map; 566 struct map *curr_map = map;
567 struct symbol *pos; 567 struct symbol *pos;
568 int count = 0, moved = 0; 568 int count = 0, moved = 0;
569 struct rb_root *root = &dso->symbols[map->type]; 569 struct rb_root *root = &dso->symbols[map->type];
570 struct rb_node *next = rb_first(root); 570 struct rb_node *next = rb_first(root);
571 int kernel_range = 0; 571 int kernel_range = 0;
572 572
573 while (next) { 573 while (next) {
574 char *module; 574 char *module;
575 575
576 pos = rb_entry(next, struct symbol, rb_node); 576 pos = rb_entry(next, struct symbol, rb_node);
577 next = rb_next(&pos->rb_node); 577 next = rb_next(&pos->rb_node);
578 578
579 module = strchr(pos->name, '\t'); 579 module = strchr(pos->name, '\t');
580 if (module) { 580 if (module) {
581 if (!symbol_conf.use_modules) 581 if (!symbol_conf.use_modules)
582 goto discard_symbol; 582 goto discard_symbol;
583 583
584 *module++ = '\0'; 584 *module++ = '\0';
585 585
586 if (strcmp(curr_map->dso->short_name, module)) { 586 if (strcmp(curr_map->dso->short_name, module)) {
587 if (curr_map != map && 587 if (curr_map != map &&
588 dso->kernel == DSO_TYPE_GUEST_KERNEL && 588 dso->kernel == DSO_TYPE_GUEST_KERNEL &&
589 machine__is_default_guest(machine)) { 589 machine__is_default_guest(machine)) {
590 /* 590 /*
591 * We assume all symbols of a module are 591 * We assume all symbols of a module are
592 * continuous in * kallsyms, so curr_map 592 * continuous in * kallsyms, so curr_map
593 * points to a module and all its 593 * points to a module and all its
594 * symbols are in its kmap. Mark it as 594 * symbols are in its kmap. Mark it as
595 * loaded. 595 * loaded.
596 */ 596 */
597 dso__set_loaded(curr_map->dso, 597 dso__set_loaded(curr_map->dso,
598 curr_map->type); 598 curr_map->type);
599 } 599 }
600 600
601 curr_map = map_groups__find_by_name(kmaps, 601 curr_map = map_groups__find_by_name(kmaps,
602 map->type, module); 602 map->type, module);
603 if (curr_map == NULL) { 603 if (curr_map == NULL) {
604 pr_debug("%s/proc/{kallsyms,modules} " 604 pr_debug("%s/proc/{kallsyms,modules} "
605 "inconsistency while looking " 605 "inconsistency while looking "
606 "for \"%s\" module!\n", 606 "for \"%s\" module!\n",
607 machine->root_dir, module); 607 machine->root_dir, module);
608 curr_map = map; 608 curr_map = map;
609 goto discard_symbol; 609 goto discard_symbol;
610 } 610 }
611 611
612 if (curr_map->dso->loaded && 612 if (curr_map->dso->loaded &&
613 !machine__is_default_guest(machine)) 613 !machine__is_default_guest(machine))
614 goto discard_symbol; 614 goto discard_symbol;
615 } 615 }
616 /* 616 /*
617 * So that we look just like we get from .ko files, 617 * So that we look just like we get from .ko files,
618 * i.e. not prelinked, relative to map->start. 618 * i.e. not prelinked, relative to map->start.
619 */ 619 */
620 pos->start = curr_map->map_ip(curr_map, pos->start); 620 pos->start = curr_map->map_ip(curr_map, pos->start);
621 pos->end = curr_map->map_ip(curr_map, pos->end); 621 pos->end = curr_map->map_ip(curr_map, pos->end);
622 } else if (curr_map != map) { 622 } else if (curr_map != map) {
623 char dso_name[PATH_MAX]; 623 char dso_name[PATH_MAX];
624 struct dso *ndso; 624 struct dso *ndso;
625 625
626 if (count == 0) { 626 if (count == 0) {
627 curr_map = map; 627 curr_map = map;
628 goto filter_symbol; 628 goto filter_symbol;
629 } 629 }
630 630
631 if (dso->kernel == DSO_TYPE_GUEST_KERNEL) 631 if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
632 snprintf(dso_name, sizeof(dso_name), 632 snprintf(dso_name, sizeof(dso_name),
633 "[guest.kernel].%d", 633 "[guest.kernel].%d",
634 kernel_range++); 634 kernel_range++);
635 else 635 else
636 snprintf(dso_name, sizeof(dso_name), 636 snprintf(dso_name, sizeof(dso_name),
637 "[kernel].%d", 637 "[kernel].%d",
638 kernel_range++); 638 kernel_range++);
639 639
640 ndso = dso__new(dso_name); 640 ndso = dso__new(dso_name);
641 if (ndso == NULL) 641 if (ndso == NULL)
642 return -1; 642 return -1;
643 643
644 ndso->kernel = dso->kernel; 644 ndso->kernel = dso->kernel;
645 645
646 curr_map = map__new2(pos->start, ndso, map->type); 646 curr_map = map__new2(pos->start, ndso, map->type);
647 if (curr_map == NULL) { 647 if (curr_map == NULL) {
648 dso__delete(ndso); 648 dso__delete(ndso);
649 return -1; 649 return -1;
650 } 650 }
651 651
652 curr_map->map_ip = curr_map->unmap_ip = identity__map_ip; 652 curr_map->map_ip = curr_map->unmap_ip = identity__map_ip;
653 map_groups__insert(kmaps, curr_map); 653 map_groups__insert(kmaps, curr_map);
654 ++kernel_range; 654 ++kernel_range;
655 } 655 }
656 filter_symbol: 656 filter_symbol:
657 if (filter && filter(curr_map, pos)) { 657 if (filter && filter(curr_map, pos)) {
658 discard_symbol: rb_erase(&pos->rb_node, root); 658 discard_symbol: rb_erase(&pos->rb_node, root);
659 symbol__delete(pos); 659 symbol__delete(pos);
660 } else { 660 } else {
661 if (curr_map != map) { 661 if (curr_map != map) {
662 rb_erase(&pos->rb_node, root); 662 rb_erase(&pos->rb_node, root);
663 symbols__insert(&curr_map->dso->symbols[curr_map->type], pos); 663 symbols__insert(&curr_map->dso->symbols[curr_map->type], pos);
664 ++moved; 664 ++moved;
665 } else 665 } else
666 ++count; 666 ++count;
667 } 667 }
668 } 668 }
669 669
670 if (curr_map != map && 670 if (curr_map != map &&
671 dso->kernel == DSO_TYPE_GUEST_KERNEL && 671 dso->kernel == DSO_TYPE_GUEST_KERNEL &&
672 machine__is_default_guest(kmaps->machine)) { 672 machine__is_default_guest(kmaps->machine)) {
673 dso__set_loaded(curr_map->dso, curr_map->type); 673 dso__set_loaded(curr_map->dso, curr_map->type);
674 } 674 }
675 675
676 return count + moved; 676 return count + moved;
677 } 677 }
678 678
679 static bool symbol__restricted_filename(const char *filename, 679 static bool symbol__restricted_filename(const char *filename,
680 const char *restricted_filename) 680 const char *restricted_filename)
681 { 681 {
682 bool restricted = false; 682 bool restricted = false;
683 683
684 if (symbol_conf.kptr_restrict) { 684 if (symbol_conf.kptr_restrict) {
685 char *r = realpath(filename, NULL); 685 char *r = realpath(filename, NULL);
686 686
687 if (r != NULL) { 687 if (r != NULL) {
688 restricted = strcmp(r, restricted_filename) == 0; 688 restricted = strcmp(r, restricted_filename) == 0;
689 free(r); 689 free(r);
690 return restricted; 690 return restricted;
691 } 691 }
692 } 692 }
693 693
694 return restricted; 694 return restricted;
695 } 695 }
696 696
697 int dso__load_kallsyms(struct dso *dso, const char *filename, 697 int dso__load_kallsyms(struct dso *dso, const char *filename,
698 struct map *map, symbol_filter_t filter) 698 struct map *map, symbol_filter_t filter)
699 { 699 {
700 if (symbol__restricted_filename(filename, "/proc/kallsyms")) 700 if (symbol__restricted_filename(filename, "/proc/kallsyms"))
701 return -1; 701 return -1;
702 702
703 if (dso__load_all_kallsyms(dso, filename, map) < 0) 703 if (dso__load_all_kallsyms(dso, filename, map) < 0)
704 return -1; 704 return -1;
705 705
706 if (dso->kernel == DSO_TYPE_GUEST_KERNEL) 706 if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
707 dso->symtab_type = SYMTAB__GUEST_KALLSYMS; 707 dso->symtab_type = SYMTAB__GUEST_KALLSYMS;
708 else 708 else
709 dso->symtab_type = SYMTAB__KALLSYMS; 709 dso->symtab_type = SYMTAB__KALLSYMS;
710 710
711 return dso__split_kallsyms(dso, map, filter); 711 return dso__split_kallsyms(dso, map, filter);
712 } 712 }
713 713
714 static int dso__load_perf_map(struct dso *dso, struct map *map, 714 static int dso__load_perf_map(struct dso *dso, struct map *map,
715 symbol_filter_t filter) 715 symbol_filter_t filter)
716 { 716 {
717 char *line = NULL; 717 char *line = NULL;
718 size_t n; 718 size_t n;
719 FILE *file; 719 FILE *file;
720 int nr_syms = 0; 720 int nr_syms = 0;
721 721
722 file = fopen(dso->long_name, "r"); 722 file = fopen(dso->long_name, "r");
723 if (file == NULL) 723 if (file == NULL)
724 goto out_failure; 724 goto out_failure;
725 725
726 while (!feof(file)) { 726 while (!feof(file)) {
727 u64 start, size; 727 u64 start, size;
728 struct symbol *sym; 728 struct symbol *sym;
729 int line_len, len; 729 int line_len, len;
730 730
731 line_len = getline(&line, &n, file); 731 line_len = getline(&line, &n, file);
732 if (line_len < 0) 732 if (line_len < 0)
733 break; 733 break;
734 734
735 if (!line) 735 if (!line)
736 goto out_failure; 736 goto out_failure;
737 737
738 line[--line_len] = '\0'; /* \n */ 738 line[--line_len] = '\0'; /* \n */
739 739
740 len = hex2u64(line, &start); 740 len = hex2u64(line, &start);
741 741
742 len++; 742 len++;
743 if (len + 2 >= line_len) 743 if (len + 2 >= line_len)
744 continue; 744 continue;
745 745
746 len += hex2u64(line + len, &size); 746 len += hex2u64(line + len, &size);
747 747
748 len++; 748 len++;
749 if (len + 2 >= line_len) 749 if (len + 2 >= line_len)
750 continue; 750 continue;
751 751
752 sym = symbol__new(start, size, STB_GLOBAL, line + len); 752 sym = symbol__new(start, size, STB_GLOBAL, line + len);
753 753
754 if (sym == NULL) 754 if (sym == NULL)
755 goto out_delete_line; 755 goto out_delete_line;
756 756
757 if (filter && filter(map, sym)) 757 if (filter && filter(map, sym))
758 symbol__delete(sym); 758 symbol__delete(sym);
759 else { 759 else {
760 symbols__insert(&dso->symbols[map->type], sym); 760 symbols__insert(&dso->symbols[map->type], sym);
761 nr_syms++; 761 nr_syms++;
762 } 762 }
763 } 763 }
764 764
765 free(line); 765 free(line);
766 fclose(file); 766 fclose(file);
767 767
768 return nr_syms; 768 return nr_syms;
769 769
770 out_delete_line: 770 out_delete_line:
771 free(line); 771 free(line);
772 out_failure: 772 out_failure:
773 return -1; 773 return -1;
774 } 774 }
775 775
776 /** 776 /**
777 * elf_symtab__for_each_symbol - iterate thru all the symbols 777 * elf_symtab__for_each_symbol - iterate thru all the symbols
778 * 778 *
779 * @syms: struct elf_symtab instance to iterate 779 * @syms: struct elf_symtab instance to iterate
780 * @idx: uint32_t idx 780 * @idx: uint32_t idx
781 * @sym: GElf_Sym iterator 781 * @sym: GElf_Sym iterator
782 */ 782 */
783 #define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \ 783 #define elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) \
784 for (idx = 0, gelf_getsym(syms, idx, &sym);\ 784 for (idx = 0, gelf_getsym(syms, idx, &sym);\
785 idx < nr_syms; \ 785 idx < nr_syms; \
786 idx++, gelf_getsym(syms, idx, &sym)) 786 idx++, gelf_getsym(syms, idx, &sym))
787 787
788 static inline uint8_t elf_sym__type(const GElf_Sym *sym) 788 static inline uint8_t elf_sym__type(const GElf_Sym *sym)
789 { 789 {
790 return GELF_ST_TYPE(sym->st_info); 790 return GELF_ST_TYPE(sym->st_info);
791 } 791 }
792 792
793 static inline int elf_sym__is_function(const GElf_Sym *sym) 793 static inline int elf_sym__is_function(const GElf_Sym *sym)
794 { 794 {
795 return elf_sym__type(sym) == STT_FUNC && 795 return elf_sym__type(sym) == STT_FUNC &&
796 sym->st_name != 0 && 796 sym->st_name != 0 &&
797 sym->st_shndx != SHN_UNDEF; 797 sym->st_shndx != SHN_UNDEF;
798 } 798 }
799 799
800 static inline bool elf_sym__is_object(const GElf_Sym *sym) 800 static inline bool elf_sym__is_object(const GElf_Sym *sym)
801 { 801 {
802 return elf_sym__type(sym) == STT_OBJECT && 802 return elf_sym__type(sym) == STT_OBJECT &&
803 sym->st_name != 0 && 803 sym->st_name != 0 &&
804 sym->st_shndx != SHN_UNDEF; 804 sym->st_shndx != SHN_UNDEF;
805 } 805 }
806 806
807 static inline int elf_sym__is_label(const GElf_Sym *sym) 807 static inline int elf_sym__is_label(const GElf_Sym *sym)
808 { 808 {
809 return elf_sym__type(sym) == STT_NOTYPE && 809 return elf_sym__type(sym) == STT_NOTYPE &&
810 sym->st_name != 0 && 810 sym->st_name != 0 &&
811 sym->st_shndx != SHN_UNDEF && 811 sym->st_shndx != SHN_UNDEF &&
812 sym->st_shndx != SHN_ABS; 812 sym->st_shndx != SHN_ABS;
813 } 813 }
814 814
815 static inline const char *elf_sec__name(const GElf_Shdr *shdr, 815 static inline const char *elf_sec__name(const GElf_Shdr *shdr,
816 const Elf_Data *secstrs) 816 const Elf_Data *secstrs)
817 { 817 {
818 return secstrs->d_buf + shdr->sh_name; 818 return secstrs->d_buf + shdr->sh_name;
819 } 819 }
820 820
821 static inline int elf_sec__is_text(const GElf_Shdr *shdr, 821 static inline int elf_sec__is_text(const GElf_Shdr *shdr,
822 const Elf_Data *secstrs) 822 const Elf_Data *secstrs)
823 { 823 {
824 return strstr(elf_sec__name(shdr, secstrs), "text") != NULL; 824 return strstr(elf_sec__name(shdr, secstrs), "text") != NULL;
825 } 825 }
826 826
827 static inline bool elf_sec__is_data(const GElf_Shdr *shdr, 827 static inline bool elf_sec__is_data(const GElf_Shdr *shdr,
828 const Elf_Data *secstrs) 828 const Elf_Data *secstrs)
829 { 829 {
830 return strstr(elf_sec__name(shdr, secstrs), "data") != NULL; 830 return strstr(elf_sec__name(shdr, secstrs), "data") != NULL;
831 } 831 }
832 832
833 static inline const char *elf_sym__name(const GElf_Sym *sym, 833 static inline const char *elf_sym__name(const GElf_Sym *sym,
834 const Elf_Data *symstrs) 834 const Elf_Data *symstrs)
835 { 835 {
836 return symstrs->d_buf + sym->st_name; 836 return symstrs->d_buf + sym->st_name;
837 } 837 }
838 838
839 static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep, 839 static Elf_Scn *elf_section_by_name(Elf *elf, GElf_Ehdr *ep,
840 GElf_Shdr *shp, const char *name, 840 GElf_Shdr *shp, const char *name,
841 size_t *idx) 841 size_t *idx)
842 { 842 {
843 Elf_Scn *sec = NULL; 843 Elf_Scn *sec = NULL;
844 size_t cnt = 1; 844 size_t cnt = 1;
845 845
846 while ((sec = elf_nextscn(elf, sec)) != NULL) { 846 while ((sec = elf_nextscn(elf, sec)) != NULL) {
847 char *str; 847 char *str;
848 848
849 gelf_getshdr(sec, shp); 849 gelf_getshdr(sec, shp);
850 str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name); 850 str = elf_strptr(elf, ep->e_shstrndx, shp->sh_name);
851 if (!strcmp(name, str)) { 851 if (!strcmp(name, str)) {
852 if (idx) 852 if (idx)
853 *idx = cnt; 853 *idx = cnt;
854 break; 854 break;
855 } 855 }
856 ++cnt; 856 ++cnt;
857 } 857 }
858 858
859 return sec; 859 return sec;
860 } 860 }
861 861
862 #define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \ 862 #define elf_section__for_each_rel(reldata, pos, pos_mem, idx, nr_entries) \
863 for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \ 863 for (idx = 0, pos = gelf_getrel(reldata, 0, &pos_mem); \
864 idx < nr_entries; \ 864 idx < nr_entries; \
865 ++idx, pos = gelf_getrel(reldata, idx, &pos_mem)) 865 ++idx, pos = gelf_getrel(reldata, idx, &pos_mem))
866 866
867 #define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \ 867 #define elf_section__for_each_rela(reldata, pos, pos_mem, idx, nr_entries) \
868 for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \ 868 for (idx = 0, pos = gelf_getrela(reldata, 0, &pos_mem); \
869 idx < nr_entries; \ 869 idx < nr_entries; \
870 ++idx, pos = gelf_getrela(reldata, idx, &pos_mem)) 870 ++idx, pos = gelf_getrela(reldata, idx, &pos_mem))
871 871
872 /* 872 /*
873 * We need to check if we have a .dynsym, so that we can handle the 873 * We need to check if we have a .dynsym, so that we can handle the
874 * .plt, synthesizing its symbols, that aren't on the symtabs (be it 874 * .plt, synthesizing its symbols, that aren't on the symtabs (be it
875 * .dynsym or .symtab). 875 * .dynsym or .symtab).
876 * And always look at the original dso, not at debuginfo packages, that 876 * And always look at the original dso, not at debuginfo packages, that
877 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS). 877 * have the PLT data stripped out (shdr_rel_plt.sh_type == SHT_NOBITS).
878 */ 878 */
879 static int dso__synthesize_plt_symbols(struct dso *dso, struct map *map, 879 static int dso__synthesize_plt_symbols(struct dso *dso, struct map *map,
880 symbol_filter_t filter) 880 symbol_filter_t filter)
881 { 881 {
882 uint32_t nr_rel_entries, idx; 882 uint32_t nr_rel_entries, idx;
883 GElf_Sym sym; 883 GElf_Sym sym;
884 u64 plt_offset; 884 u64 plt_offset;
885 GElf_Shdr shdr_plt; 885 GElf_Shdr shdr_plt;
886 struct symbol *f; 886 struct symbol *f;
887 GElf_Shdr shdr_rel_plt, shdr_dynsym; 887 GElf_Shdr shdr_rel_plt, shdr_dynsym;
888 Elf_Data *reldata, *syms, *symstrs; 888 Elf_Data *reldata, *syms, *symstrs;
889 Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym; 889 Elf_Scn *scn_plt_rel, *scn_symstrs, *scn_dynsym;
890 size_t dynsym_idx; 890 size_t dynsym_idx;
891 GElf_Ehdr ehdr; 891 GElf_Ehdr ehdr;
892 char sympltname[1024]; 892 char sympltname[1024];
893 Elf *elf; 893 Elf *elf;
894 int nr = 0, symidx, fd, err = 0; 894 int nr = 0, symidx, fd, err = 0;
895 char name[PATH_MAX]; 895 char name[PATH_MAX];
896 896
897 snprintf(name, sizeof(name), "%s%s", 897 snprintf(name, sizeof(name), "%s%s",
898 symbol_conf.symfs, dso->long_name); 898 symbol_conf.symfs, dso->long_name);
899 fd = open(name, O_RDONLY); 899 fd = open(name, O_RDONLY);
900 if (fd < 0) 900 if (fd < 0)
901 goto out; 901 goto out;
902 902
903 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); 903 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
904 if (elf == NULL) 904 if (elf == NULL)
905 goto out_close; 905 goto out_close;
906 906
907 if (gelf_getehdr(elf, &ehdr) == NULL) 907 if (gelf_getehdr(elf, &ehdr) == NULL)
908 goto out_elf_end; 908 goto out_elf_end;
909 909
910 scn_dynsym = elf_section_by_name(elf, &ehdr, &shdr_dynsym, 910 scn_dynsym = elf_section_by_name(elf, &ehdr, &shdr_dynsym,
911 ".dynsym", &dynsym_idx); 911 ".dynsym", &dynsym_idx);
912 if (scn_dynsym == NULL) 912 if (scn_dynsym == NULL)
913 goto out_elf_end; 913 goto out_elf_end;
914 914
915 scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt, 915 scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
916 ".rela.plt", NULL); 916 ".rela.plt", NULL);
917 if (scn_plt_rel == NULL) { 917 if (scn_plt_rel == NULL) {
918 scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt, 918 scn_plt_rel = elf_section_by_name(elf, &ehdr, &shdr_rel_plt,
919 ".rel.plt", NULL); 919 ".rel.plt", NULL);
920 if (scn_plt_rel == NULL) 920 if (scn_plt_rel == NULL)
921 goto out_elf_end; 921 goto out_elf_end;
922 } 922 }
923 923
924 err = -1; 924 err = -1;
925 925
926 if (shdr_rel_plt.sh_link != dynsym_idx) 926 if (shdr_rel_plt.sh_link != dynsym_idx)
927 goto out_elf_end; 927 goto out_elf_end;
928 928
929 if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL) 929 if (elf_section_by_name(elf, &ehdr, &shdr_plt, ".plt", NULL) == NULL)
930 goto out_elf_end; 930 goto out_elf_end;
931 931
932 /* 932 /*
933 * Fetch the relocation section to find the idxes to the GOT 933 * Fetch the relocation section to find the idxes to the GOT
934 * and the symbols in the .dynsym they refer to. 934 * and the symbols in the .dynsym they refer to.
935 */ 935 */
936 reldata = elf_getdata(scn_plt_rel, NULL); 936 reldata = elf_getdata(scn_plt_rel, NULL);
937 if (reldata == NULL) 937 if (reldata == NULL)
938 goto out_elf_end; 938 goto out_elf_end;
939 939
940 syms = elf_getdata(scn_dynsym, NULL); 940 syms = elf_getdata(scn_dynsym, NULL);
941 if (syms == NULL) 941 if (syms == NULL)
942 goto out_elf_end; 942 goto out_elf_end;
943 943
944 scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link); 944 scn_symstrs = elf_getscn(elf, shdr_dynsym.sh_link);
945 if (scn_symstrs == NULL) 945 if (scn_symstrs == NULL)
946 goto out_elf_end; 946 goto out_elf_end;
947 947
948 symstrs = elf_getdata(scn_symstrs, NULL); 948 symstrs = elf_getdata(scn_symstrs, NULL);
949 if (symstrs == NULL) 949 if (symstrs == NULL)
950 goto out_elf_end; 950 goto out_elf_end;
951 951
952 nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize; 952 nr_rel_entries = shdr_rel_plt.sh_size / shdr_rel_plt.sh_entsize;
953 plt_offset = shdr_plt.sh_offset; 953 plt_offset = shdr_plt.sh_offset;
954 954
955 if (shdr_rel_plt.sh_type == SHT_RELA) { 955 if (shdr_rel_plt.sh_type == SHT_RELA) {
956 GElf_Rela pos_mem, *pos; 956 GElf_Rela pos_mem, *pos;
957 957
958 elf_section__for_each_rela(reldata, pos, pos_mem, idx, 958 elf_section__for_each_rela(reldata, pos, pos_mem, idx,
959 nr_rel_entries) { 959 nr_rel_entries) {
960 symidx = GELF_R_SYM(pos->r_info); 960 symidx = GELF_R_SYM(pos->r_info);
961 plt_offset += shdr_plt.sh_entsize; 961 plt_offset += shdr_plt.sh_entsize;
962 gelf_getsym(syms, symidx, &sym); 962 gelf_getsym(syms, symidx, &sym);
963 snprintf(sympltname, sizeof(sympltname), 963 snprintf(sympltname, sizeof(sympltname),
964 "%s@plt", elf_sym__name(&sym, symstrs)); 964 "%s@plt", elf_sym__name(&sym, symstrs));
965 965
966 f = symbol__new(plt_offset, shdr_plt.sh_entsize, 966 f = symbol__new(plt_offset, shdr_plt.sh_entsize,
967 STB_GLOBAL, sympltname); 967 STB_GLOBAL, sympltname);
968 if (!f) 968 if (!f)
969 goto out_elf_end; 969 goto out_elf_end;
970 970
971 if (filter && filter(map, f)) 971 if (filter && filter(map, f))
972 symbol__delete(f); 972 symbol__delete(f);
973 else { 973 else {
974 symbols__insert(&dso->symbols[map->type], f); 974 symbols__insert(&dso->symbols[map->type], f);
975 ++nr; 975 ++nr;
976 } 976 }
977 } 977 }
978 } else if (shdr_rel_plt.sh_type == SHT_REL) { 978 } else if (shdr_rel_plt.sh_type == SHT_REL) {
979 GElf_Rel pos_mem, *pos; 979 GElf_Rel pos_mem, *pos;
980 elf_section__for_each_rel(reldata, pos, pos_mem, idx, 980 elf_section__for_each_rel(reldata, pos, pos_mem, idx,
981 nr_rel_entries) { 981 nr_rel_entries) {
982 symidx = GELF_R_SYM(pos->r_info); 982 symidx = GELF_R_SYM(pos->r_info);
983 plt_offset += shdr_plt.sh_entsize; 983 plt_offset += shdr_plt.sh_entsize;
984 gelf_getsym(syms, symidx, &sym); 984 gelf_getsym(syms, symidx, &sym);
985 snprintf(sympltname, sizeof(sympltname), 985 snprintf(sympltname, sizeof(sympltname),
986 "%s@plt", elf_sym__name(&sym, symstrs)); 986 "%s@plt", elf_sym__name(&sym, symstrs));
987 987
988 f = symbol__new(plt_offset, shdr_plt.sh_entsize, 988 f = symbol__new(plt_offset, shdr_plt.sh_entsize,
989 STB_GLOBAL, sympltname); 989 STB_GLOBAL, sympltname);
990 if (!f) 990 if (!f)
991 goto out_elf_end; 991 goto out_elf_end;
992 992
993 if (filter && filter(map, f)) 993 if (filter && filter(map, f))
994 symbol__delete(f); 994 symbol__delete(f);
995 else { 995 else {
996 symbols__insert(&dso->symbols[map->type], f); 996 symbols__insert(&dso->symbols[map->type], f);
997 ++nr; 997 ++nr;
998 } 998 }
999 } 999 }
1000 } 1000 }
1001 1001
1002 err = 0; 1002 err = 0;
1003 out_elf_end: 1003 out_elf_end:
1004 elf_end(elf); 1004 elf_end(elf);
1005 out_close: 1005 out_close:
1006 close(fd); 1006 close(fd);
1007 1007
1008 if (err == 0) 1008 if (err == 0)
1009 return nr; 1009 return nr;
1010 out: 1010 out:
1011 pr_debug("%s: problems reading %s PLT info.\n", 1011 pr_debug("%s: problems reading %s PLT info.\n",
1012 __func__, dso->long_name); 1012 __func__, dso->long_name);
1013 return 0; 1013 return 0;
1014 } 1014 }
1015 1015
1016 static bool elf_sym__is_a(GElf_Sym *sym, enum map_type type) 1016 static bool elf_sym__is_a(GElf_Sym *sym, enum map_type type)
1017 { 1017 {
1018 switch (type) { 1018 switch (type) {
1019 case MAP__FUNCTION: 1019 case MAP__FUNCTION:
1020 return elf_sym__is_function(sym); 1020 return elf_sym__is_function(sym);
1021 case MAP__VARIABLE: 1021 case MAP__VARIABLE:
1022 return elf_sym__is_object(sym); 1022 return elf_sym__is_object(sym);
1023 default: 1023 default:
1024 return false; 1024 return false;
1025 } 1025 }
1026 } 1026 }
1027 1027
1028 static bool elf_sec__is_a(GElf_Shdr *shdr, Elf_Data *secstrs, 1028 static bool elf_sec__is_a(GElf_Shdr *shdr, Elf_Data *secstrs,
1029 enum map_type type) 1029 enum map_type type)
1030 { 1030 {
1031 switch (type) { 1031 switch (type) {
1032 case MAP__FUNCTION: 1032 case MAP__FUNCTION:
1033 return elf_sec__is_text(shdr, secstrs); 1033 return elf_sec__is_text(shdr, secstrs);
1034 case MAP__VARIABLE: 1034 case MAP__VARIABLE:
1035 return elf_sec__is_data(shdr, secstrs); 1035 return elf_sec__is_data(shdr, secstrs);
1036 default: 1036 default:
1037 return false; 1037 return false;
1038 } 1038 }
1039 } 1039 }
1040 1040
1041 static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr) 1041 static size_t elf_addr_to_index(Elf *elf, GElf_Addr addr)
1042 { 1042 {
1043 Elf_Scn *sec = NULL; 1043 Elf_Scn *sec = NULL;
1044 GElf_Shdr shdr; 1044 GElf_Shdr shdr;
1045 size_t cnt = 1; 1045 size_t cnt = 1;
1046 1046
1047 while ((sec = elf_nextscn(elf, sec)) != NULL) { 1047 while ((sec = elf_nextscn(elf, sec)) != NULL) {
1048 gelf_getshdr(sec, &shdr); 1048 gelf_getshdr(sec, &shdr);
1049 1049
1050 if ((addr >= shdr.sh_addr) && 1050 if ((addr >= shdr.sh_addr) &&
1051 (addr < (shdr.sh_addr + shdr.sh_size))) 1051 (addr < (shdr.sh_addr + shdr.sh_size)))
1052 return cnt; 1052 return cnt;
1053 1053
1054 ++cnt; 1054 ++cnt;
1055 } 1055 }
1056 1056
1057 return -1; 1057 return -1;
1058 } 1058 }
1059 1059
1060 static int dso__load_sym(struct dso *dso, struct map *map, const char *name, 1060 static int dso__load_sym(struct dso *dso, struct map *map, const char *name,
1061 int fd, symbol_filter_t filter, int kmodule, 1061 int fd, symbol_filter_t filter, int kmodule,
1062 int want_symtab) 1062 int want_symtab)
1063 { 1063 {
1064 struct kmap *kmap = dso->kernel ? map__kmap(map) : NULL; 1064 struct kmap *kmap = dso->kernel ? map__kmap(map) : NULL;
1065 struct map *curr_map = map; 1065 struct map *curr_map = map;
1066 struct dso *curr_dso = dso; 1066 struct dso *curr_dso = dso;
1067 Elf_Data *symstrs, *secstrs; 1067 Elf_Data *symstrs, *secstrs;
1068 uint32_t nr_syms; 1068 uint32_t nr_syms;
1069 int err = -1; 1069 int err = -1;
1070 uint32_t idx; 1070 uint32_t idx;
1071 GElf_Ehdr ehdr; 1071 GElf_Ehdr ehdr;
1072 GElf_Shdr shdr, opdshdr; 1072 GElf_Shdr shdr, opdshdr;
1073 Elf_Data *syms, *opddata = NULL; 1073 Elf_Data *syms, *opddata = NULL;
1074 GElf_Sym sym; 1074 GElf_Sym sym;
1075 Elf_Scn *sec, *sec_strndx, *opdsec; 1075 Elf_Scn *sec, *sec_strndx, *opdsec;
1076 Elf *elf; 1076 Elf *elf;
1077 int nr = 0; 1077 int nr = 0;
1078 size_t opdidx = 0; 1078 size_t opdidx = 0;
1079 1079
1080 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); 1080 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
1081 if (elf == NULL) { 1081 if (elf == NULL) {
1082 pr_debug("%s: cannot read %s ELF file.\n", __func__, name); 1082 pr_debug("%s: cannot read %s ELF file.\n", __func__, name);
1083 goto out_close; 1083 goto out_close;
1084 } 1084 }
1085 1085
1086 if (gelf_getehdr(elf, &ehdr) == NULL) { 1086 if (gelf_getehdr(elf, &ehdr) == NULL) {
1087 pr_debug("%s: cannot get elf header.\n", __func__); 1087 pr_debug("%s: cannot get elf header.\n", __func__);
1088 goto out_elf_end; 1088 goto out_elf_end;
1089 } 1089 }
1090 1090
1091 /* Always reject images with a mismatched build-id: */ 1091 /* Always reject images with a mismatched build-id: */
1092 if (dso->has_build_id) { 1092 if (dso->has_build_id) {
1093 u8 build_id[BUILD_ID_SIZE]; 1093 u8 build_id[BUILD_ID_SIZE];
1094 1094
1095 if (elf_read_build_id(elf, build_id, 1095 if (elf_read_build_id(elf, build_id,
1096 BUILD_ID_SIZE) != BUILD_ID_SIZE) 1096 BUILD_ID_SIZE) != BUILD_ID_SIZE)
1097 goto out_elf_end; 1097 goto out_elf_end;
1098 1098
1099 if (!dso__build_id_equal(dso, build_id)) 1099 if (!dso__build_id_equal(dso, build_id))
1100 goto out_elf_end; 1100 goto out_elf_end;
1101 } 1101 }
1102 1102
1103 sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL); 1103 sec = elf_section_by_name(elf, &ehdr, &shdr, ".symtab", NULL);
1104 if (sec == NULL) { 1104 if (sec == NULL) {
1105 if (want_symtab) 1105 if (want_symtab)
1106 goto out_elf_end; 1106 goto out_elf_end;
1107 1107
1108 sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL); 1108 sec = elf_section_by_name(elf, &ehdr, &shdr, ".dynsym", NULL);
1109 if (sec == NULL) 1109 if (sec == NULL)
1110 goto out_elf_end; 1110 goto out_elf_end;
1111 } 1111 }
1112 1112
1113 opdsec = elf_section_by_name(elf, &ehdr, &opdshdr, ".opd", &opdidx); 1113 opdsec = elf_section_by_name(elf, &ehdr, &opdshdr, ".opd", &opdidx);
1114 if (opdsec) 1114 if (opdsec)
1115 opddata = elf_rawdata(opdsec, NULL); 1115 opddata = elf_rawdata(opdsec, NULL);
1116 1116
1117 syms = elf_getdata(sec, NULL); 1117 syms = elf_getdata(sec, NULL);
1118 if (syms == NULL) 1118 if (syms == NULL)
1119 goto out_elf_end; 1119 goto out_elf_end;
1120 1120
1121 sec = elf_getscn(elf, shdr.sh_link); 1121 sec = elf_getscn(elf, shdr.sh_link);
1122 if (sec == NULL) 1122 if (sec == NULL)
1123 goto out_elf_end; 1123 goto out_elf_end;
1124 1124
1125 symstrs = elf_getdata(sec, NULL); 1125 symstrs = elf_getdata(sec, NULL);
1126 if (symstrs == NULL) 1126 if (symstrs == NULL)
1127 goto out_elf_end; 1127 goto out_elf_end;
1128 1128
1129 sec_strndx = elf_getscn(elf, ehdr.e_shstrndx); 1129 sec_strndx = elf_getscn(elf, ehdr.e_shstrndx);
1130 if (sec_strndx == NULL) 1130 if (sec_strndx == NULL)
1131 goto out_elf_end; 1131 goto out_elf_end;
1132 1132
1133 secstrs = elf_getdata(sec_strndx, NULL); 1133 secstrs = elf_getdata(sec_strndx, NULL);
1134 if (secstrs == NULL) 1134 if (secstrs == NULL)
1135 goto out_elf_end; 1135 goto out_elf_end;
1136 1136
1137 nr_syms = shdr.sh_size / shdr.sh_entsize; 1137 nr_syms = shdr.sh_size / shdr.sh_entsize;
1138 1138
1139 memset(&sym, 0, sizeof(sym)); 1139 memset(&sym, 0, sizeof(sym));
1140 if (dso->kernel == DSO_TYPE_USER) { 1140 if (dso->kernel == DSO_TYPE_USER) {
1141 dso->adjust_symbols = (ehdr.e_type == ET_EXEC || 1141 dso->adjust_symbols = (ehdr.e_type == ET_EXEC ||
1142 elf_section_by_name(elf, &ehdr, &shdr, 1142 elf_section_by_name(elf, &ehdr, &shdr,
1143 ".gnu.prelink_undo", 1143 ".gnu.prelink_undo",
1144 NULL) != NULL); 1144 NULL) != NULL);
1145 } else { 1145 } else {
1146 dso->adjust_symbols = 0; 1146 dso->adjust_symbols = 0;
1147 } 1147 }
1148 elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) { 1148 elf_symtab__for_each_symbol(syms, nr_syms, idx, sym) {
1149 struct symbol *f; 1149 struct symbol *f;
1150 const char *elf_name = elf_sym__name(&sym, symstrs); 1150 const char *elf_name = elf_sym__name(&sym, symstrs);
1151 char *demangled = NULL; 1151 char *demangled = NULL;
1152 int is_label = elf_sym__is_label(&sym); 1152 int is_label = elf_sym__is_label(&sym);
1153 const char *section_name; 1153 const char *section_name;
1154 1154
1155 if (kmap && kmap->ref_reloc_sym && kmap->ref_reloc_sym->name && 1155 if (kmap && kmap->ref_reloc_sym && kmap->ref_reloc_sym->name &&
1156 strcmp(elf_name, kmap->ref_reloc_sym->name) == 0) 1156 strcmp(elf_name, kmap->ref_reloc_sym->name) == 0)
1157 kmap->ref_reloc_sym->unrelocated_addr = sym.st_value; 1157 kmap->ref_reloc_sym->unrelocated_addr = sym.st_value;
1158 1158
1159 if (!is_label && !elf_sym__is_a(&sym, map->type)) 1159 if (!is_label && !elf_sym__is_a(&sym, map->type))
1160 continue; 1160 continue;
1161 1161
1162 /* Reject ARM ELF "mapping symbols": these aren't unique and 1162 /* Reject ARM ELF "mapping symbols": these aren't unique and
1163 * don't identify functions, so will confuse the profile 1163 * don't identify functions, so will confuse the profile
1164 * output: */ 1164 * output: */
1165 if (ehdr.e_machine == EM_ARM) { 1165 if (ehdr.e_machine == EM_ARM) {
1166 if (!strcmp(elf_name, "$a") || 1166 if (!strcmp(elf_name, "$a") ||
1167 !strcmp(elf_name, "$d") || 1167 !strcmp(elf_name, "$d") ||
1168 !strcmp(elf_name, "$t")) 1168 !strcmp(elf_name, "$t"))
1169 continue; 1169 continue;
1170 } 1170 }
1171 1171
1172 if (opdsec && sym.st_shndx == opdidx) { 1172 if (opdsec && sym.st_shndx == opdidx) {
1173 u32 offset = sym.st_value - opdshdr.sh_addr; 1173 u32 offset = sym.st_value - opdshdr.sh_addr;
1174 u64 *opd = opddata->d_buf + offset; 1174 u64 *opd = opddata->d_buf + offset;
1175 sym.st_value = *opd; 1175 sym.st_value = *opd;
1176 sym.st_shndx = elf_addr_to_index(elf, sym.st_value); 1176 sym.st_shndx = elf_addr_to_index(elf, sym.st_value);
1177 } 1177 }
1178 1178
1179 sec = elf_getscn(elf, sym.st_shndx); 1179 sec = elf_getscn(elf, sym.st_shndx);
1180 if (!sec) 1180 if (!sec)
1181 goto out_elf_end; 1181 goto out_elf_end;
1182 1182
1183 gelf_getshdr(sec, &shdr); 1183 gelf_getshdr(sec, &shdr);
1184 1184
1185 if (is_label && !elf_sec__is_a(&shdr, secstrs, map->type)) 1185 if (is_label && !elf_sec__is_a(&shdr, secstrs, map->type))
1186 continue; 1186 continue;
1187 1187
1188 section_name = elf_sec__name(&shdr, secstrs); 1188 section_name = elf_sec__name(&shdr, secstrs);
1189 1189
1190 /* On ARM, symbols for thumb functions have 1 added to 1190 /* On ARM, symbols for thumb functions have 1 added to
1191 * the symbol address as a flag - remove it */ 1191 * the symbol address as a flag - remove it */
1192 if ((ehdr.e_machine == EM_ARM) && 1192 if ((ehdr.e_machine == EM_ARM) &&
1193 (map->type == MAP__FUNCTION) && 1193 (map->type == MAP__FUNCTION) &&
1194 (sym.st_value & 1)) 1194 (sym.st_value & 1))
1195 --sym.st_value; 1195 --sym.st_value;
1196 1196
1197 if (dso->kernel != DSO_TYPE_USER || kmodule) { 1197 if (dso->kernel != DSO_TYPE_USER || kmodule) {
1198 char dso_name[PATH_MAX]; 1198 char dso_name[PATH_MAX];
1199 1199
1200 if (strcmp(section_name, 1200 if (strcmp(section_name,
1201 (curr_dso->short_name + 1201 (curr_dso->short_name +
1202 dso->short_name_len)) == 0) 1202 dso->short_name_len)) == 0)
1203 goto new_symbol; 1203 goto new_symbol;
1204 1204
1205 if (strcmp(section_name, ".text") == 0) { 1205 if (strcmp(section_name, ".text") == 0) {
1206 curr_map = map; 1206 curr_map = map;
1207 curr_dso = dso; 1207 curr_dso = dso;
1208 goto new_symbol; 1208 goto new_symbol;
1209 } 1209 }
1210 1210
1211 snprintf(dso_name, sizeof(dso_name), 1211 snprintf(dso_name, sizeof(dso_name),
1212 "%s%s", dso->short_name, section_name); 1212 "%s%s", dso->short_name, section_name);
1213 1213
1214 curr_map = map_groups__find_by_name(kmap->kmaps, map->type, dso_name); 1214 curr_map = map_groups__find_by_name(kmap->kmaps, map->type, dso_name);
1215 if (curr_map == NULL) { 1215 if (curr_map == NULL) {
1216 u64 start = sym.st_value; 1216 u64 start = sym.st_value;
1217 1217
1218 if (kmodule) 1218 if (kmodule)
1219 start += map->start + shdr.sh_offset; 1219 start += map->start + shdr.sh_offset;
1220 1220
1221 curr_dso = dso__new(dso_name); 1221 curr_dso = dso__new(dso_name);
1222 if (curr_dso == NULL) 1222 if (curr_dso == NULL)
1223 goto out_elf_end; 1223 goto out_elf_end;
1224 curr_dso->kernel = dso->kernel; 1224 curr_dso->kernel = dso->kernel;
1225 curr_dso->long_name = dso->long_name; 1225 curr_dso->long_name = dso->long_name;
1226 curr_dso->long_name_len = dso->long_name_len; 1226 curr_dso->long_name_len = dso->long_name_len;
1227 curr_map = map__new2(start, curr_dso, 1227 curr_map = map__new2(start, curr_dso,
1228 map->type); 1228 map->type);
1229 if (curr_map == NULL) { 1229 if (curr_map == NULL) {
1230 dso__delete(curr_dso); 1230 dso__delete(curr_dso);
1231 goto out_elf_end; 1231 goto out_elf_end;
1232 } 1232 }
1233 curr_map->map_ip = identity__map_ip; 1233 curr_map->map_ip = identity__map_ip;
1234 curr_map->unmap_ip = identity__map_ip; 1234 curr_map->unmap_ip = identity__map_ip;
1235 curr_dso->symtab_type = dso->symtab_type; 1235 curr_dso->symtab_type = dso->symtab_type;
1236 map_groups__insert(kmap->kmaps, curr_map); 1236 map_groups__insert(kmap->kmaps, curr_map);
1237 dsos__add(&dso->node, curr_dso); 1237 dsos__add(&dso->node, curr_dso);
1238 dso__set_loaded(curr_dso, map->type); 1238 dso__set_loaded(curr_dso, map->type);
1239 } else 1239 } else
1240 curr_dso = curr_map->dso; 1240 curr_dso = curr_map->dso;
1241 1241
1242 goto new_symbol; 1242 goto new_symbol;
1243 } 1243 }
1244 1244
1245 if (curr_dso->adjust_symbols) { 1245 if (curr_dso->adjust_symbols) {
1246 pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " " 1246 pr_debug4("%s: adjusting symbol: st_value: %#" PRIx64 " "
1247 "sh_addr: %#" PRIx64 " sh_offset: %#" PRIx64 "\n", __func__, 1247 "sh_addr: %#" PRIx64 " sh_offset: %#" PRIx64 "\n", __func__,
1248 (u64)sym.st_value, (u64)shdr.sh_addr, 1248 (u64)sym.st_value, (u64)shdr.sh_addr,
1249 (u64)shdr.sh_offset); 1249 (u64)shdr.sh_offset);
1250 sym.st_value -= shdr.sh_addr - shdr.sh_offset; 1250 sym.st_value -= shdr.sh_addr - shdr.sh_offset;
1251 } 1251 }
1252 /* 1252 /*
1253 * We need to figure out if the object was created from C++ sources 1253 * We need to figure out if the object was created from C++ sources
1254 * DWARF DW_compile_unit has this, but we don't always have access 1254 * DWARF DW_compile_unit has this, but we don't always have access
1255 * to it... 1255 * to it...
1256 */ 1256 */
1257 demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI); 1257 demangled = bfd_demangle(NULL, elf_name, DMGL_PARAMS | DMGL_ANSI);
1258 if (demangled != NULL) 1258 if (demangled != NULL)
1259 elf_name = demangled; 1259 elf_name = demangled;
1260 new_symbol: 1260 new_symbol:
1261 f = symbol__new(sym.st_value, sym.st_size, 1261 f = symbol__new(sym.st_value, sym.st_size,
1262 GELF_ST_BIND(sym.st_info), elf_name); 1262 GELF_ST_BIND(sym.st_info), elf_name);
1263 free(demangled); 1263 free(demangled);
1264 if (!f) 1264 if (!f)
1265 goto out_elf_end; 1265 goto out_elf_end;
1266 1266
1267 if (filter && filter(curr_map, f)) 1267 if (filter && filter(curr_map, f))
1268 symbol__delete(f); 1268 symbol__delete(f);
1269 else { 1269 else {
1270 symbols__insert(&curr_dso->symbols[curr_map->type], f); 1270 symbols__insert(&curr_dso->symbols[curr_map->type], f);
1271 nr++; 1271 nr++;
1272 } 1272 }
1273 } 1273 }
1274 1274
1275 /* 1275 /*
1276 * For misannotated, zeroed, ASM function sizes. 1276 * For misannotated, zeroed, ASM function sizes.
1277 */ 1277 */
1278 if (nr > 0) { 1278 if (nr > 0) {
1279 symbols__fixup_end(&dso->symbols[map->type]); 1279 symbols__fixup_end(&dso->symbols[map->type]);
1280 if (kmap) { 1280 if (kmap) {
1281 /* 1281 /*
1282 * We need to fixup this here too because we create new 1282 * We need to fixup this here too because we create new
1283 * maps here, for things like vsyscall sections. 1283 * maps here, for things like vsyscall sections.
1284 */ 1284 */
1285 __map_groups__fixup_end(kmap->kmaps, map->type); 1285 __map_groups__fixup_end(kmap->kmaps, map->type);
1286 } 1286 }
1287 } 1287 }
1288 err = nr; 1288 err = nr;
1289 out_elf_end: 1289 out_elf_end:
1290 elf_end(elf); 1290 elf_end(elf);
1291 out_close: 1291 out_close:
1292 return err; 1292 return err;
1293 } 1293 }
1294 1294
1295 static bool dso__build_id_equal(const struct dso *dso, u8 *build_id) 1295 static bool dso__build_id_equal(const struct dso *dso, u8 *build_id)
1296 { 1296 {
1297 return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0; 1297 return memcmp(dso->build_id, build_id, sizeof(dso->build_id)) == 0;
1298 } 1298 }
1299 1299
1300 bool __dsos__read_build_ids(struct list_head *head, bool with_hits) 1300 bool __dsos__read_build_ids(struct list_head *head, bool with_hits)
1301 { 1301 {
1302 bool have_build_id = false; 1302 bool have_build_id = false;
1303 struct dso *pos; 1303 struct dso *pos;
1304 1304
1305 list_for_each_entry(pos, head, node) { 1305 list_for_each_entry(pos, head, node) {
1306 if (with_hits && !pos->hit) 1306 if (with_hits && !pos->hit)
1307 continue; 1307 continue;
1308 if (pos->has_build_id) { 1308 if (pos->has_build_id) {
1309 have_build_id = true; 1309 have_build_id = true;
1310 continue; 1310 continue;
1311 } 1311 }
1312 if (filename__read_build_id(pos->long_name, pos->build_id, 1312 if (filename__read_build_id(pos->long_name, pos->build_id,
1313 sizeof(pos->build_id)) > 0) { 1313 sizeof(pos->build_id)) > 0) {
1314 have_build_id = true; 1314 have_build_id = true;
1315 pos->has_build_id = true; 1315 pos->has_build_id = true;
1316 } 1316 }
1317 } 1317 }
1318 1318
1319 return have_build_id; 1319 return have_build_id;
1320 } 1320 }
1321 1321
1322 /* 1322 /*
1323 * Align offset to 4 bytes as needed for note name and descriptor data. 1323 * Align offset to 4 bytes as needed for note name and descriptor data.
1324 */ 1324 */
1325 #define NOTE_ALIGN(n) (((n) + 3) & -4U) 1325 #define NOTE_ALIGN(n) (((n) + 3) & -4U)
1326 1326
1327 static int elf_read_build_id(Elf *elf, void *bf, size_t size) 1327 static int elf_read_build_id(Elf *elf, void *bf, size_t size)
1328 { 1328 {
1329 int err = -1; 1329 int err = -1;
1330 GElf_Ehdr ehdr; 1330 GElf_Ehdr ehdr;
1331 GElf_Shdr shdr; 1331 GElf_Shdr shdr;
1332 Elf_Data *data; 1332 Elf_Data *data;
1333 Elf_Scn *sec; 1333 Elf_Scn *sec;
1334 Elf_Kind ek; 1334 Elf_Kind ek;
1335 void *ptr; 1335 void *ptr;
1336 1336
1337 if (size < BUILD_ID_SIZE) 1337 if (size < BUILD_ID_SIZE)
1338 goto out; 1338 goto out;
1339 1339
1340 ek = elf_kind(elf); 1340 ek = elf_kind(elf);
1341 if (ek != ELF_K_ELF) 1341 if (ek != ELF_K_ELF)
1342 goto out; 1342 goto out;
1343 1343
1344 if (gelf_getehdr(elf, &ehdr) == NULL) { 1344 if (gelf_getehdr(elf, &ehdr) == NULL) {
1345 pr_err("%s: cannot get elf header.\n", __func__); 1345 pr_err("%s: cannot get elf header.\n", __func__);
1346 goto out; 1346 goto out;
1347 } 1347 }
1348 1348
1349 sec = elf_section_by_name(elf, &ehdr, &shdr, 1349 sec = elf_section_by_name(elf, &ehdr, &shdr,
1350 ".note.gnu.build-id", NULL); 1350 ".note.gnu.build-id", NULL);
1351 if (sec == NULL) { 1351 if (sec == NULL) {
1352 sec = elf_section_by_name(elf, &ehdr, &shdr, 1352 sec = elf_section_by_name(elf, &ehdr, &shdr,
1353 ".notes", NULL); 1353 ".notes", NULL);
1354 if (sec == NULL) 1354 if (sec == NULL)
1355 goto out; 1355 goto out;
1356 } 1356 }
1357 1357
1358 data = elf_getdata(sec, NULL); 1358 data = elf_getdata(sec, NULL);
1359 if (data == NULL) 1359 if (data == NULL)
1360 goto out; 1360 goto out;
1361 1361
1362 ptr = data->d_buf; 1362 ptr = data->d_buf;
1363 while (ptr < (data->d_buf + data->d_size)) { 1363 while (ptr < (data->d_buf + data->d_size)) {
1364 GElf_Nhdr *nhdr = ptr; 1364 GElf_Nhdr *nhdr = ptr;
1365 int namesz = NOTE_ALIGN(nhdr->n_namesz), 1365 int namesz = NOTE_ALIGN(nhdr->n_namesz),
1366 descsz = NOTE_ALIGN(nhdr->n_descsz); 1366 descsz = NOTE_ALIGN(nhdr->n_descsz);
1367 const char *name; 1367 const char *name;
1368 1368
1369 ptr += sizeof(*nhdr); 1369 ptr += sizeof(*nhdr);
1370 name = ptr; 1370 name = ptr;
1371 ptr += namesz; 1371 ptr += namesz;
1372 if (nhdr->n_type == NT_GNU_BUILD_ID && 1372 if (nhdr->n_type == NT_GNU_BUILD_ID &&
1373 nhdr->n_namesz == sizeof("GNU")) { 1373 nhdr->n_namesz == sizeof("GNU")) {
1374 if (memcmp(name, "GNU", sizeof("GNU")) == 0) { 1374 if (memcmp(name, "GNU", sizeof("GNU")) == 0) {
1375 memcpy(bf, ptr, BUILD_ID_SIZE); 1375 memcpy(bf, ptr, BUILD_ID_SIZE);
1376 err = BUILD_ID_SIZE; 1376 err = BUILD_ID_SIZE;
1377 break; 1377 break;
1378 } 1378 }
1379 } 1379 }
1380 ptr += descsz; 1380 ptr += descsz;
1381 } 1381 }
1382 1382
1383 out: 1383 out:
1384 return err; 1384 return err;
1385 } 1385 }
1386 1386
1387 int filename__read_build_id(const char *filename, void *bf, size_t size) 1387 int filename__read_build_id(const char *filename, void *bf, size_t size)
1388 { 1388 {
1389 int fd, err = -1; 1389 int fd, err = -1;
1390 Elf *elf; 1390 Elf *elf;
1391 1391
1392 if (size < BUILD_ID_SIZE) 1392 if (size < BUILD_ID_SIZE)
1393 goto out; 1393 goto out;
1394 1394
1395 fd = open(filename, O_RDONLY); 1395 fd = open(filename, O_RDONLY);
1396 if (fd < 0) 1396 if (fd < 0)
1397 goto out; 1397 goto out;
1398 1398
1399 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL); 1399 elf = elf_begin(fd, PERF_ELF_C_READ_MMAP, NULL);
1400 if (elf == NULL) { 1400 if (elf == NULL) {
1401 pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename); 1401 pr_debug2("%s: cannot read %s ELF file.\n", __func__, filename);
1402 goto out_close; 1402 goto out_close;
1403 } 1403 }
1404 1404
1405 err = elf_read_build_id(elf, bf, size); 1405 err = elf_read_build_id(elf, bf, size);
1406 1406
1407 elf_end(elf); 1407 elf_end(elf);
1408 out_close: 1408 out_close:
1409 close(fd); 1409 close(fd);
1410 out: 1410 out:
1411 return err; 1411 return err;
1412 } 1412 }
1413 1413
1414 int sysfs__read_build_id(const char *filename, void *build_id, size_t size) 1414 int sysfs__read_build_id(const char *filename, void *build_id, size_t size)
1415 { 1415 {
1416 int fd, err = -1; 1416 int fd, err = -1;
1417 1417
1418 if (size < BUILD_ID_SIZE) 1418 if (size < BUILD_ID_SIZE)
1419 goto out; 1419 goto out;
1420 1420
1421 fd = open(filename, O_RDONLY); 1421 fd = open(filename, O_RDONLY);
1422 if (fd < 0) 1422 if (fd < 0)
1423 goto out; 1423 goto out;
1424 1424
1425 while (1) { 1425 while (1) {
1426 char bf[BUFSIZ]; 1426 char bf[BUFSIZ];
1427 GElf_Nhdr nhdr; 1427 GElf_Nhdr nhdr;
1428 int namesz, descsz; 1428 int namesz, descsz;
1429 1429
1430 if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr)) 1430 if (read(fd, &nhdr, sizeof(nhdr)) != sizeof(nhdr))
1431 break; 1431 break;
1432 1432
1433 namesz = NOTE_ALIGN(nhdr.n_namesz); 1433 namesz = NOTE_ALIGN(nhdr.n_namesz);
1434 descsz = NOTE_ALIGN(nhdr.n_descsz); 1434 descsz = NOTE_ALIGN(nhdr.n_descsz);
1435 if (nhdr.n_type == NT_GNU_BUILD_ID && 1435 if (nhdr.n_type == NT_GNU_BUILD_ID &&
1436 nhdr.n_namesz == sizeof("GNU")) { 1436 nhdr.n_namesz == sizeof("GNU")) {
1437 if (read(fd, bf, namesz) != namesz) 1437 if (read(fd, bf, namesz) != namesz)
1438 break; 1438 break;
1439 if (memcmp(bf, "GNU", sizeof("GNU")) == 0) { 1439 if (memcmp(bf, "GNU", sizeof("GNU")) == 0) {
1440 if (read(fd, build_id, 1440 if (read(fd, build_id,
1441 BUILD_ID_SIZE) == BUILD_ID_SIZE) { 1441 BUILD_ID_SIZE) == BUILD_ID_SIZE) {
1442 err = 0; 1442 err = 0;
1443 break; 1443 break;
1444 } 1444 }
1445 } else if (read(fd, bf, descsz) != descsz) 1445 } else if (read(fd, bf, descsz) != descsz)
1446 break; 1446 break;
1447 } else { 1447 } else {
1448 int n = namesz + descsz; 1448 int n = namesz + descsz;
1449 if (read(fd, bf, n) != n) 1449 if (read(fd, bf, n) != n)
1450 break; 1450 break;
1451 } 1451 }
1452 } 1452 }
1453 close(fd); 1453 close(fd);
1454 out: 1454 out:
1455 return err; 1455 return err;
1456 } 1456 }
1457 1457
1458 char dso__symtab_origin(const struct dso *dso) 1458 char dso__symtab_origin(const struct dso *dso)
1459 { 1459 {
1460 static const char origin[] = { 1460 static const char origin[] = {
1461 [SYMTAB__KALLSYMS] = 'k', 1461 [SYMTAB__KALLSYMS] = 'k',
1462 [SYMTAB__JAVA_JIT] = 'j', 1462 [SYMTAB__JAVA_JIT] = 'j',
1463 [SYMTAB__BUILD_ID_CACHE] = 'B', 1463 [SYMTAB__BUILD_ID_CACHE] = 'B',
1464 [SYMTAB__FEDORA_DEBUGINFO] = 'f', 1464 [SYMTAB__FEDORA_DEBUGINFO] = 'f',
1465 [SYMTAB__UBUNTU_DEBUGINFO] = 'u', 1465 [SYMTAB__UBUNTU_DEBUGINFO] = 'u',
1466 [SYMTAB__BUILDID_DEBUGINFO] = 'b', 1466 [SYMTAB__BUILDID_DEBUGINFO] = 'b',
1467 [SYMTAB__SYSTEM_PATH_DSO] = 'd', 1467 [SYMTAB__SYSTEM_PATH_DSO] = 'd',
1468 [SYMTAB__SYSTEM_PATH_KMODULE] = 'K', 1468 [SYMTAB__SYSTEM_PATH_KMODULE] = 'K',
1469 [SYMTAB__GUEST_KALLSYMS] = 'g', 1469 [SYMTAB__GUEST_KALLSYMS] = 'g',
1470 [SYMTAB__GUEST_KMODULE] = 'G', 1470 [SYMTAB__GUEST_KMODULE] = 'G',
1471 }; 1471 };
1472 1472
1473 if (dso == NULL || dso->symtab_type == SYMTAB__NOT_FOUND) 1473 if (dso == NULL || dso->symtab_type == SYMTAB__NOT_FOUND)
1474 return '!'; 1474 return '!';
1475 return origin[dso->symtab_type]; 1475 return origin[dso->symtab_type];
1476 } 1476 }
1477 1477
1478 int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter) 1478 int dso__load(struct dso *dso, struct map *map, symbol_filter_t filter)
1479 { 1479 {
1480 int size = PATH_MAX; 1480 int size = PATH_MAX;
1481 char *name; 1481 char *name;
1482 int ret = -1; 1482 int ret = -1;
1483 int fd; 1483 int fd;
1484 struct machine *machine; 1484 struct machine *machine;
1485 const char *root_dir; 1485 const char *root_dir;
1486 int want_symtab; 1486 int want_symtab;
1487 1487
1488 dso__set_loaded(dso, map->type); 1488 dso__set_loaded(dso, map->type);
1489 1489
1490 if (dso->kernel == DSO_TYPE_KERNEL) 1490 if (dso->kernel == DSO_TYPE_KERNEL)
1491 return dso__load_kernel_sym(dso, map, filter); 1491 return dso__load_kernel_sym(dso, map, filter);
1492 else if (dso->kernel == DSO_TYPE_GUEST_KERNEL) 1492 else if (dso->kernel == DSO_TYPE_GUEST_KERNEL)
1493 return dso__load_guest_kernel_sym(dso, map, filter); 1493 return dso__load_guest_kernel_sym(dso, map, filter);
1494 1494
1495 if (map->groups && map->groups->machine) 1495 if (map->groups && map->groups->machine)
1496 machine = map->groups->machine; 1496 machine = map->groups->machine;
1497 else 1497 else
1498 machine = NULL; 1498 machine = NULL;
1499 1499
1500 name = malloc(size); 1500 name = malloc(size);
1501 if (!name) 1501 if (!name)
1502 return -1; 1502 return -1;
1503 1503
1504 dso->adjust_symbols = 0; 1504 dso->adjust_symbols = 0;
1505 1505
1506 if (strncmp(dso->name, "/tmp/perf-", 10) == 0) { 1506 if (strncmp(dso->name, "/tmp/perf-", 10) == 0) {
1507 struct stat st;
1508
1509 if (stat(dso->name, &st) < 0)
1510 return -1;
1511
1512 if (st.st_uid && (st.st_uid != geteuid())) {
1513 pr_warning("File %s not owned by current user or root, "
1514 "ignoring it.\n", dso->name);
1515 return -1;
1516 }
1517
1507 ret = dso__load_perf_map(dso, map, filter); 1518 ret = dso__load_perf_map(dso, map, filter);
1508 dso->symtab_type = ret > 0 ? SYMTAB__JAVA_JIT : 1519 dso->symtab_type = ret > 0 ? SYMTAB__JAVA_JIT :
1509 SYMTAB__NOT_FOUND; 1520 SYMTAB__NOT_FOUND;
1510 return ret; 1521 return ret;
1511 } 1522 }
1512 1523
1513 /* Iterate over candidate debug images. 1524 /* Iterate over candidate debug images.
1514 * On the first pass, only load images if they have a full symtab. 1525 * On the first pass, only load images if they have a full symtab.
1515 * Failing that, do a second pass where we accept .dynsym also 1526 * Failing that, do a second pass where we accept .dynsym also
1516 */ 1527 */
1517 want_symtab = 1; 1528 want_symtab = 1;
1518 restart: 1529 restart:
1519 for (dso->symtab_type = SYMTAB__BUILD_ID_CACHE; 1530 for (dso->symtab_type = SYMTAB__BUILD_ID_CACHE;
1520 dso->symtab_type != SYMTAB__NOT_FOUND; 1531 dso->symtab_type != SYMTAB__NOT_FOUND;
1521 dso->symtab_type++) { 1532 dso->symtab_type++) {
1522 switch (dso->symtab_type) { 1533 switch (dso->symtab_type) {
1523 case SYMTAB__BUILD_ID_CACHE: 1534 case SYMTAB__BUILD_ID_CACHE:
1524 /* skip the locally configured cache if a symfs is given */ 1535 /* skip the locally configured cache if a symfs is given */
1525 if (symbol_conf.symfs[0] || 1536 if (symbol_conf.symfs[0] ||
1526 (dso__build_id_filename(dso, name, size) == NULL)) { 1537 (dso__build_id_filename(dso, name, size) == NULL)) {
1527 continue; 1538 continue;
1528 } 1539 }
1529 break; 1540 break;
1530 case SYMTAB__FEDORA_DEBUGINFO: 1541 case SYMTAB__FEDORA_DEBUGINFO:
1531 snprintf(name, size, "%s/usr/lib/debug%s.debug", 1542 snprintf(name, size, "%s/usr/lib/debug%s.debug",
1532 symbol_conf.symfs, dso->long_name); 1543 symbol_conf.symfs, dso->long_name);
1533 break; 1544 break;
1534 case SYMTAB__UBUNTU_DEBUGINFO: 1545 case SYMTAB__UBUNTU_DEBUGINFO:
1535 snprintf(name, size, "%s/usr/lib/debug%s", 1546 snprintf(name, size, "%s/usr/lib/debug%s",
1536 symbol_conf.symfs, dso->long_name); 1547 symbol_conf.symfs, dso->long_name);
1537 break; 1548 break;
1538 case SYMTAB__BUILDID_DEBUGINFO: { 1549 case SYMTAB__BUILDID_DEBUGINFO: {
1539 char build_id_hex[BUILD_ID_SIZE * 2 + 1]; 1550 char build_id_hex[BUILD_ID_SIZE * 2 + 1];
1540 1551
1541 if (!dso->has_build_id) 1552 if (!dso->has_build_id)
1542 continue; 1553 continue;
1543 1554
1544 build_id__sprintf(dso->build_id, 1555 build_id__sprintf(dso->build_id,
1545 sizeof(dso->build_id), 1556 sizeof(dso->build_id),
1546 build_id_hex); 1557 build_id_hex);
1547 snprintf(name, size, 1558 snprintf(name, size,
1548 "%s/usr/lib/debug/.build-id/%.2s/%s.debug", 1559 "%s/usr/lib/debug/.build-id/%.2s/%s.debug",
1549 symbol_conf.symfs, build_id_hex, build_id_hex + 2); 1560 symbol_conf.symfs, build_id_hex, build_id_hex + 2);
1550 } 1561 }
1551 break; 1562 break;
1552 case SYMTAB__SYSTEM_PATH_DSO: 1563 case SYMTAB__SYSTEM_PATH_DSO:
1553 snprintf(name, size, "%s%s", 1564 snprintf(name, size, "%s%s",
1554 symbol_conf.symfs, dso->long_name); 1565 symbol_conf.symfs, dso->long_name);
1555 break; 1566 break;
1556 case SYMTAB__GUEST_KMODULE: 1567 case SYMTAB__GUEST_KMODULE:
1557 if (map->groups && machine) 1568 if (map->groups && machine)
1558 root_dir = machine->root_dir; 1569 root_dir = machine->root_dir;
1559 else 1570 else
1560 root_dir = ""; 1571 root_dir = "";
1561 snprintf(name, size, "%s%s%s", symbol_conf.symfs, 1572 snprintf(name, size, "%s%s%s", symbol_conf.symfs,
1562 root_dir, dso->long_name); 1573 root_dir, dso->long_name);
1563 break; 1574 break;
1564 1575
1565 case SYMTAB__SYSTEM_PATH_KMODULE: 1576 case SYMTAB__SYSTEM_PATH_KMODULE:
1566 snprintf(name, size, "%s%s", symbol_conf.symfs, 1577 snprintf(name, size, "%s%s", symbol_conf.symfs,
1567 dso->long_name); 1578 dso->long_name);
1568 break; 1579 break;
1569 default:; 1580 default:;
1570 } 1581 }
1571 1582
1572 /* Name is now the name of the next image to try */ 1583 /* Name is now the name of the next image to try */
1573 fd = open(name, O_RDONLY); 1584 fd = open(name, O_RDONLY);
1574 if (fd < 0) 1585 if (fd < 0)
1575 continue; 1586 continue;
1576 1587
1577 ret = dso__load_sym(dso, map, name, fd, filter, 0, 1588 ret = dso__load_sym(dso, map, name, fd, filter, 0,
1578 want_symtab); 1589 want_symtab);
1579 close(fd); 1590 close(fd);
1580 1591
1581 /* 1592 /*
1582 * Some people seem to have debuginfo files _WITHOUT_ debug 1593 * Some people seem to have debuginfo files _WITHOUT_ debug
1583 * info!?!? 1594 * info!?!?
1584 */ 1595 */
1585 if (!ret) 1596 if (!ret)
1586 continue; 1597 continue;
1587 1598
1588 if (ret > 0) { 1599 if (ret > 0) {
1589 int nr_plt = dso__synthesize_plt_symbols(dso, map, 1600 int nr_plt = dso__synthesize_plt_symbols(dso, map,
1590 filter); 1601 filter);
1591 if (nr_plt > 0) 1602 if (nr_plt > 0)
1592 ret += nr_plt; 1603 ret += nr_plt;
1593 break; 1604 break;
1594 } 1605 }
1595 } 1606 }
1596 1607
1597 /* 1608 /*
1598 * If we wanted a full symtab but no image had one, 1609 * If we wanted a full symtab but no image had one,
1599 * relax our requirements and repeat the search. 1610 * relax our requirements and repeat the search.
1600 */ 1611 */
1601 if (ret <= 0 && want_symtab) { 1612 if (ret <= 0 && want_symtab) {
1602 want_symtab = 0; 1613 want_symtab = 0;
1603 goto restart; 1614 goto restart;
1604 } 1615 }
1605 1616
1606 free(name); 1617 free(name);
1607 if (ret < 0 && strstr(dso->name, " (deleted)") != NULL) 1618 if (ret < 0 && strstr(dso->name, " (deleted)") != NULL)
1608 return 0; 1619 return 0;
1609 return ret; 1620 return ret;
1610 } 1621 }
1611 1622
1612 struct map *map_groups__find_by_name(struct map_groups *mg, 1623 struct map *map_groups__find_by_name(struct map_groups *mg,
1613 enum map_type type, const char *name) 1624 enum map_type type, const char *name)
1614 { 1625 {
1615 struct rb_node *nd; 1626 struct rb_node *nd;
1616 1627
1617 for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) { 1628 for (nd = rb_first(&mg->maps[type]); nd; nd = rb_next(nd)) {
1618 struct map *map = rb_entry(nd, struct map, rb_node); 1629 struct map *map = rb_entry(nd, struct map, rb_node);
1619 1630
1620 if (map->dso && strcmp(map->dso->short_name, name) == 0) 1631 if (map->dso && strcmp(map->dso->short_name, name) == 0)
1621 return map; 1632 return map;
1622 } 1633 }
1623 1634
1624 return NULL; 1635 return NULL;
1625 } 1636 }
1626 1637
1627 static int dso__kernel_module_get_build_id(struct dso *dso, 1638 static int dso__kernel_module_get_build_id(struct dso *dso,
1628 const char *root_dir) 1639 const char *root_dir)
1629 { 1640 {
1630 char filename[PATH_MAX]; 1641 char filename[PATH_MAX];
1631 /* 1642 /*
1632 * kernel module short names are of the form "[module]" and 1643 * kernel module short names are of the form "[module]" and
1633 * we need just "module" here. 1644 * we need just "module" here.
1634 */ 1645 */
1635 const char *name = dso->short_name + 1; 1646 const char *name = dso->short_name + 1;
1636 1647
1637 snprintf(filename, sizeof(filename), 1648 snprintf(filename, sizeof(filename),
1638 "%s/sys/module/%.*s/notes/.note.gnu.build-id", 1649 "%s/sys/module/%.*s/notes/.note.gnu.build-id",
1639 root_dir, (int)strlen(name) - 1, name); 1650 root_dir, (int)strlen(name) - 1, name);
1640 1651
1641 if (sysfs__read_build_id(filename, dso->build_id, 1652 if (sysfs__read_build_id(filename, dso->build_id,
1642 sizeof(dso->build_id)) == 0) 1653 sizeof(dso->build_id)) == 0)
1643 dso->has_build_id = true; 1654 dso->has_build_id = true;
1644 1655
1645 return 0; 1656 return 0;
1646 } 1657 }
1647 1658
1648 static int map_groups__set_modules_path_dir(struct map_groups *mg, 1659 static int map_groups__set_modules_path_dir(struct map_groups *mg,
1649 const char *dir_name) 1660 const char *dir_name)
1650 { 1661 {
1651 struct dirent *dent; 1662 struct dirent *dent;
1652 DIR *dir = opendir(dir_name); 1663 DIR *dir = opendir(dir_name);
1653 int ret = 0; 1664 int ret = 0;
1654 1665
1655 if (!dir) { 1666 if (!dir) {
1656 pr_debug("%s: cannot open %s dir\n", __func__, dir_name); 1667 pr_debug("%s: cannot open %s dir\n", __func__, dir_name);
1657 return -1; 1668 return -1;
1658 } 1669 }
1659 1670
1660 while ((dent = readdir(dir)) != NULL) { 1671 while ((dent = readdir(dir)) != NULL) {
1661 char path[PATH_MAX]; 1672 char path[PATH_MAX];
1662 struct stat st; 1673 struct stat st;
1663 1674
1664 /*sshfs might return bad dent->d_type, so we have to stat*/ 1675 /*sshfs might return bad dent->d_type, so we have to stat*/
1665 sprintf(path, "%s/%s", dir_name, dent->d_name); 1676 sprintf(path, "%s/%s", dir_name, dent->d_name);
1666 if (stat(path, &st)) 1677 if (stat(path, &st))
1667 continue; 1678 continue;
1668 1679
1669 if (S_ISDIR(st.st_mode)) { 1680 if (S_ISDIR(st.st_mode)) {
1670 if (!strcmp(dent->d_name, ".") || 1681 if (!strcmp(dent->d_name, ".") ||
1671 !strcmp(dent->d_name, "..")) 1682 !strcmp(dent->d_name, ".."))
1672 continue; 1683 continue;
1673 1684
1674 snprintf(path, sizeof(path), "%s/%s", 1685 snprintf(path, sizeof(path), "%s/%s",
1675 dir_name, dent->d_name); 1686 dir_name, dent->d_name);
1676 ret = map_groups__set_modules_path_dir(mg, path); 1687 ret = map_groups__set_modules_path_dir(mg, path);
1677 if (ret < 0) 1688 if (ret < 0)
1678 goto out; 1689 goto out;
1679 } else { 1690 } else {
1680 char *dot = strrchr(dent->d_name, '.'), 1691 char *dot = strrchr(dent->d_name, '.'),
1681 dso_name[PATH_MAX]; 1692 dso_name[PATH_MAX];
1682 struct map *map; 1693 struct map *map;
1683 char *long_name; 1694 char *long_name;
1684 1695
1685 if (dot == NULL || strcmp(dot, ".ko")) 1696 if (dot == NULL || strcmp(dot, ".ko"))
1686 continue; 1697 continue;
1687 snprintf(dso_name, sizeof(dso_name), "[%.*s]", 1698 snprintf(dso_name, sizeof(dso_name), "[%.*s]",
1688 (int)(dot - dent->d_name), dent->d_name); 1699 (int)(dot - dent->d_name), dent->d_name);
1689 1700
1690 strxfrchar(dso_name, '-', '_'); 1701 strxfrchar(dso_name, '-', '_');
1691 map = map_groups__find_by_name(mg, MAP__FUNCTION, 1702 map = map_groups__find_by_name(mg, MAP__FUNCTION,
1692 dso_name); 1703 dso_name);
1693 if (map == NULL) 1704 if (map == NULL)
1694 continue; 1705 continue;
1695 1706
1696 snprintf(path, sizeof(path), "%s/%s", 1707 snprintf(path, sizeof(path), "%s/%s",
1697 dir_name, dent->d_name); 1708 dir_name, dent->d_name);
1698 1709
1699 long_name = strdup(path); 1710 long_name = strdup(path);
1700 if (long_name == NULL) { 1711 if (long_name == NULL) {
1701 ret = -1; 1712 ret = -1;
1702 goto out; 1713 goto out;
1703 } 1714 }
1704 dso__set_long_name(map->dso, long_name); 1715 dso__set_long_name(map->dso, long_name);
1705 map->dso->lname_alloc = 1; 1716 map->dso->lname_alloc = 1;
1706 dso__kernel_module_get_build_id(map->dso, ""); 1717 dso__kernel_module_get_build_id(map->dso, "");
1707 } 1718 }
1708 } 1719 }
1709 1720
1710 out: 1721 out:
1711 closedir(dir); 1722 closedir(dir);
1712 return ret; 1723 return ret;
1713 } 1724 }
1714 1725
1715 static char *get_kernel_version(const char *root_dir) 1726 static char *get_kernel_version(const char *root_dir)
1716 { 1727 {
1717 char version[PATH_MAX]; 1728 char version[PATH_MAX];
1718 FILE *file; 1729 FILE *file;
1719 char *name, *tmp; 1730 char *name, *tmp;
1720 const char *prefix = "Linux version "; 1731 const char *prefix = "Linux version ";
1721 1732
1722 sprintf(version, "%s/proc/version", root_dir); 1733 sprintf(version, "%s/proc/version", root_dir);
1723 file = fopen(version, "r"); 1734 file = fopen(version, "r");
1724 if (!file) 1735 if (!file)
1725 return NULL; 1736 return NULL;
1726 1737
1727 version[0] = '\0'; 1738 version[0] = '\0';
1728 tmp = fgets(version, sizeof(version), file); 1739 tmp = fgets(version, sizeof(version), file);
1729 fclose(file); 1740 fclose(file);
1730 1741
1731 name = strstr(version, prefix); 1742 name = strstr(version, prefix);
1732 if (!name) 1743 if (!name)
1733 return NULL; 1744 return NULL;
1734 name += strlen(prefix); 1745 name += strlen(prefix);
1735 tmp = strchr(name, ' '); 1746 tmp = strchr(name, ' ');
1736 if (tmp) 1747 if (tmp)
1737 *tmp = '\0'; 1748 *tmp = '\0';
1738 1749
1739 return strdup(name); 1750 return strdup(name);
1740 } 1751 }
1741 1752
1742 static int machine__set_modules_path(struct machine *machine) 1753 static int machine__set_modules_path(struct machine *machine)
1743 { 1754 {
1744 char *version; 1755 char *version;
1745 char modules_path[PATH_MAX]; 1756 char modules_path[PATH_MAX];
1746 1757
1747 version = get_kernel_version(machine->root_dir); 1758 version = get_kernel_version(machine->root_dir);
1748 if (!version) 1759 if (!version)
1749 return -1; 1760 return -1;
1750 1761
1751 snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel", 1762 snprintf(modules_path, sizeof(modules_path), "%s/lib/modules/%s/kernel",
1752 machine->root_dir, version); 1763 machine->root_dir, version);
1753 free(version); 1764 free(version);
1754 1765
1755 return map_groups__set_modules_path_dir(&machine->kmaps, modules_path); 1766 return map_groups__set_modules_path_dir(&machine->kmaps, modules_path);
1756 } 1767 }
1757 1768
1758 /* 1769 /*
1759 * Constructor variant for modules (where we know from /proc/modules where 1770 * Constructor variant for modules (where we know from /proc/modules where
1760 * they are loaded) and for vmlinux, where only after we load all the 1771 * they are loaded) and for vmlinux, where only after we load all the
1761 * symbols we'll know where it starts and ends. 1772 * symbols we'll know where it starts and ends.
1762 */ 1773 */
1763 static struct map *map__new2(u64 start, struct dso *dso, enum map_type type) 1774 static struct map *map__new2(u64 start, struct dso *dso, enum map_type type)
1764 { 1775 {
1765 struct map *map = calloc(1, (sizeof(*map) + 1776 struct map *map = calloc(1, (sizeof(*map) +
1766 (dso->kernel ? sizeof(struct kmap) : 0))); 1777 (dso->kernel ? sizeof(struct kmap) : 0)));
1767 if (map != NULL) { 1778 if (map != NULL) {
1768 /* 1779 /*
1769 * ->end will be filled after we load all the symbols 1780 * ->end will be filled after we load all the symbols
1770 */ 1781 */
1771 map__init(map, type, start, 0, 0, dso); 1782 map__init(map, type, start, 0, 0, dso);
1772 } 1783 }
1773 1784
1774 return map; 1785 return map;
1775 } 1786 }
1776 1787
1777 struct map *machine__new_module(struct machine *machine, u64 start, 1788 struct map *machine__new_module(struct machine *machine, u64 start,
1778 const char *filename) 1789 const char *filename)
1779 { 1790 {
1780 struct map *map; 1791 struct map *map;
1781 struct dso *dso = __dsos__findnew(&machine->kernel_dsos, filename); 1792 struct dso *dso = __dsos__findnew(&machine->kernel_dsos, filename);
1782 1793
1783 if (dso == NULL) 1794 if (dso == NULL)
1784 return NULL; 1795 return NULL;
1785 1796
1786 map = map__new2(start, dso, MAP__FUNCTION); 1797 map = map__new2(start, dso, MAP__FUNCTION);
1787 if (map == NULL) 1798 if (map == NULL)
1788 return NULL; 1799 return NULL;
1789 1800
1790 if (machine__is_host(machine)) 1801 if (machine__is_host(machine))
1791 dso->symtab_type = SYMTAB__SYSTEM_PATH_KMODULE; 1802 dso->symtab_type = SYMTAB__SYSTEM_PATH_KMODULE;
1792 else 1803 else
1793 dso->symtab_type = SYMTAB__GUEST_KMODULE; 1804 dso->symtab_type = SYMTAB__GUEST_KMODULE;
1794 map_groups__insert(&machine->kmaps, map); 1805 map_groups__insert(&machine->kmaps, map);
1795 return map; 1806 return map;
1796 } 1807 }
1797 1808
1798 static int machine__create_modules(struct machine *machine) 1809 static int machine__create_modules(struct machine *machine)
1799 { 1810 {
1800 char *line = NULL; 1811 char *line = NULL;
1801 size_t n; 1812 size_t n;
1802 FILE *file; 1813 FILE *file;
1803 struct map *map; 1814 struct map *map;
1804 const char *modules; 1815 const char *modules;
1805 char path[PATH_MAX]; 1816 char path[PATH_MAX];
1806 1817
1807 if (machine__is_default_guest(machine)) 1818 if (machine__is_default_guest(machine))
1808 modules = symbol_conf.default_guest_modules; 1819 modules = symbol_conf.default_guest_modules;
1809 else { 1820 else {
1810 sprintf(path, "%s/proc/modules", machine->root_dir); 1821 sprintf(path, "%s/proc/modules", machine->root_dir);
1811 modules = path; 1822 modules = path;
1812 } 1823 }
1813 1824
1814 if (symbol__restricted_filename(path, "/proc/modules")) 1825 if (symbol__restricted_filename(path, "/proc/modules"))
1815 return -1; 1826 return -1;
1816 1827
1817 file = fopen(modules, "r"); 1828 file = fopen(modules, "r");
1818 if (file == NULL) 1829 if (file == NULL)
1819 return -1; 1830 return -1;
1820 1831
1821 while (!feof(file)) { 1832 while (!feof(file)) {
1822 char name[PATH_MAX]; 1833 char name[PATH_MAX];
1823 u64 start; 1834 u64 start;
1824 char *sep; 1835 char *sep;
1825 int line_len; 1836 int line_len;
1826 1837
1827 line_len = getline(&line, &n, file); 1838 line_len = getline(&line, &n, file);
1828 if (line_len < 0) 1839 if (line_len < 0)
1829 break; 1840 break;
1830 1841
1831 if (!line) 1842 if (!line)
1832 goto out_failure; 1843 goto out_failure;
1833 1844
1834 line[--line_len] = '\0'; /* \n */ 1845 line[--line_len] = '\0'; /* \n */
1835 1846
1836 sep = strrchr(line, 'x'); 1847 sep = strrchr(line, 'x');
1837 if (sep == NULL) 1848 if (sep == NULL)
1838 continue; 1849 continue;
1839 1850
1840 hex2u64(sep + 1, &start); 1851 hex2u64(sep + 1, &start);
1841 1852
1842 sep = strchr(line, ' '); 1853 sep = strchr(line, ' ');
1843 if (sep == NULL) 1854 if (sep == NULL)
1844 continue; 1855 continue;
1845 1856
1846 *sep = '\0'; 1857 *sep = '\0';
1847 1858
1848 snprintf(name, sizeof(name), "[%s]", line); 1859 snprintf(name, sizeof(name), "[%s]", line);
1849 map = machine__new_module(machine, start, name); 1860 map = machine__new_module(machine, start, name);
1850 if (map == NULL) 1861 if (map == NULL)
1851 goto out_delete_line; 1862 goto out_delete_line;
1852 dso__kernel_module_get_build_id(map->dso, machine->root_dir); 1863 dso__kernel_module_get_build_id(map->dso, machine->root_dir);
1853 } 1864 }
1854 1865
1855 free(line); 1866 free(line);
1856 fclose(file); 1867 fclose(file);
1857 1868
1858 return machine__set_modules_path(machine); 1869 return machine__set_modules_path(machine);
1859 1870
1860 out_delete_line: 1871 out_delete_line:
1861 free(line); 1872 free(line);
1862 out_failure: 1873 out_failure:
1863 return -1; 1874 return -1;
1864 } 1875 }
1865 1876
1866 int dso__load_vmlinux(struct dso *dso, struct map *map, 1877 int dso__load_vmlinux(struct dso *dso, struct map *map,
1867 const char *vmlinux, symbol_filter_t filter) 1878 const char *vmlinux, symbol_filter_t filter)
1868 { 1879 {
1869 int err = -1, fd; 1880 int err = -1, fd;
1870 char symfs_vmlinux[PATH_MAX]; 1881 char symfs_vmlinux[PATH_MAX];
1871 1882
1872 snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s%s", 1883 snprintf(symfs_vmlinux, sizeof(symfs_vmlinux), "%s%s",
1873 symbol_conf.symfs, vmlinux); 1884 symbol_conf.symfs, vmlinux);
1874 fd = open(symfs_vmlinux, O_RDONLY); 1885 fd = open(symfs_vmlinux, O_RDONLY);
1875 if (fd < 0) 1886 if (fd < 0)
1876 return -1; 1887 return -1;
1877 1888
1878 dso__set_long_name(dso, (char *)vmlinux); 1889 dso__set_long_name(dso, (char *)vmlinux);
1879 dso__set_loaded(dso, map->type); 1890 dso__set_loaded(dso, map->type);
1880 err = dso__load_sym(dso, map, symfs_vmlinux, fd, filter, 0, 0); 1891 err = dso__load_sym(dso, map, symfs_vmlinux, fd, filter, 0, 0);
1881 close(fd); 1892 close(fd);
1882 1893
1883 if (err > 0) 1894 if (err > 0)
1884 pr_debug("Using %s for symbols\n", symfs_vmlinux); 1895 pr_debug("Using %s for symbols\n", symfs_vmlinux);
1885 1896
1886 return err; 1897 return err;
1887 } 1898 }
1888 1899
1889 int dso__load_vmlinux_path(struct dso *dso, struct map *map, 1900 int dso__load_vmlinux_path(struct dso *dso, struct map *map,
1890 symbol_filter_t filter) 1901 symbol_filter_t filter)
1891 { 1902 {
1892 int i, err = 0; 1903 int i, err = 0;
1893 char *filename; 1904 char *filename;
1894 1905
1895 pr_debug("Looking at the vmlinux_path (%d entries long)\n", 1906 pr_debug("Looking at the vmlinux_path (%d entries long)\n",
1896 vmlinux_path__nr_entries + 1); 1907 vmlinux_path__nr_entries + 1);
1897 1908
1898 filename = dso__build_id_filename(dso, NULL, 0); 1909 filename = dso__build_id_filename(dso, NULL, 0);
1899 if (filename != NULL) { 1910 if (filename != NULL) {
1900 err = dso__load_vmlinux(dso, map, filename, filter); 1911 err = dso__load_vmlinux(dso, map, filename, filter);
1901 if (err > 0) { 1912 if (err > 0) {
1902 dso__set_long_name(dso, filename); 1913 dso__set_long_name(dso, filename);
1903 goto out; 1914 goto out;
1904 } 1915 }
1905 free(filename); 1916 free(filename);
1906 } 1917 }
1907 1918
1908 for (i = 0; i < vmlinux_path__nr_entries; ++i) { 1919 for (i = 0; i < vmlinux_path__nr_entries; ++i) {
1909 err = dso__load_vmlinux(dso, map, vmlinux_path[i], filter); 1920 err = dso__load_vmlinux(dso, map, vmlinux_path[i], filter);
1910 if (err > 0) { 1921 if (err > 0) {
1911 dso__set_long_name(dso, strdup(vmlinux_path[i])); 1922 dso__set_long_name(dso, strdup(vmlinux_path[i]));
1912 break; 1923 break;
1913 } 1924 }
1914 } 1925 }
1915 out: 1926 out:
1916 return err; 1927 return err;
1917 } 1928 }
1918 1929
1919 static int dso__load_kernel_sym(struct dso *dso, struct map *map, 1930 static int dso__load_kernel_sym(struct dso *dso, struct map *map,
1920 symbol_filter_t filter) 1931 symbol_filter_t filter)
1921 { 1932 {
1922 int err; 1933 int err;
1923 const char *kallsyms_filename = NULL; 1934 const char *kallsyms_filename = NULL;
1924 char *kallsyms_allocated_filename = NULL; 1935 char *kallsyms_allocated_filename = NULL;
1925 /* 1936 /*
1926 * Step 1: if the user specified a kallsyms or vmlinux filename, use 1937 * Step 1: if the user specified a kallsyms or vmlinux filename, use
1927 * it and only it, reporting errors to the user if it cannot be used. 1938 * it and only it, reporting errors to the user if it cannot be used.
1928 * 1939 *
1929 * For instance, try to analyse an ARM perf.data file _without_ a 1940 * For instance, try to analyse an ARM perf.data file _without_ a
1930 * build-id, or if the user specifies the wrong path to the right 1941 * build-id, or if the user specifies the wrong path to the right
1931 * vmlinux file, obviously we can't fallback to another vmlinux (a 1942 * vmlinux file, obviously we can't fallback to another vmlinux (a
1932 * x86_86 one, on the machine where analysis is being performed, say), 1943 * x86_86 one, on the machine where analysis is being performed, say),
1933 * or worse, /proc/kallsyms. 1944 * or worse, /proc/kallsyms.
1934 * 1945 *
1935 * If the specified file _has_ a build-id and there is a build-id 1946 * If the specified file _has_ a build-id and there is a build-id
1936 * section in the perf.data file, we will still do the expected 1947 * section in the perf.data file, we will still do the expected
1937 * validation in dso__load_vmlinux and will bail out if they don't 1948 * validation in dso__load_vmlinux and will bail out if they don't
1938 * match. 1949 * match.
1939 */ 1950 */
1940 if (symbol_conf.kallsyms_name != NULL) { 1951 if (symbol_conf.kallsyms_name != NULL) {
1941 kallsyms_filename = symbol_conf.kallsyms_name; 1952 kallsyms_filename = symbol_conf.kallsyms_name;
1942 goto do_kallsyms; 1953 goto do_kallsyms;
1943 } 1954 }
1944 1955
1945 if (symbol_conf.vmlinux_name != NULL) { 1956 if (symbol_conf.vmlinux_name != NULL) {
1946 err = dso__load_vmlinux(dso, map, 1957 err = dso__load_vmlinux(dso, map,
1947 symbol_conf.vmlinux_name, filter); 1958 symbol_conf.vmlinux_name, filter);
1948 if (err > 0) { 1959 if (err > 0) {
1949 dso__set_long_name(dso, 1960 dso__set_long_name(dso,
1950 strdup(symbol_conf.vmlinux_name)); 1961 strdup(symbol_conf.vmlinux_name));
1951 goto out_fixup; 1962 goto out_fixup;
1952 } 1963 }
1953 return err; 1964 return err;
1954 } 1965 }
1955 1966
1956 if (vmlinux_path != NULL) { 1967 if (vmlinux_path != NULL) {
1957 err = dso__load_vmlinux_path(dso, map, filter); 1968 err = dso__load_vmlinux_path(dso, map, filter);
1958 if (err > 0) 1969 if (err > 0)
1959 goto out_fixup; 1970 goto out_fixup;
1960 } 1971 }
1961 1972
1962 /* do not try local files if a symfs was given */ 1973 /* do not try local files if a symfs was given */
1963 if (symbol_conf.symfs[0] != 0) 1974 if (symbol_conf.symfs[0] != 0)
1964 return -1; 1975 return -1;
1965 1976
1966 /* 1977 /*
1967 * Say the kernel DSO was created when processing the build-id header table, 1978 * Say the kernel DSO was created when processing the build-id header table,
1968 * we have a build-id, so check if it is the same as the running kernel, 1979 * we have a build-id, so check if it is the same as the running kernel,
1969 * using it if it is. 1980 * using it if it is.
1970 */ 1981 */
1971 if (dso->has_build_id) { 1982 if (dso->has_build_id) {
1972 u8 kallsyms_build_id[BUILD_ID_SIZE]; 1983 u8 kallsyms_build_id[BUILD_ID_SIZE];
1973 char sbuild_id[BUILD_ID_SIZE * 2 + 1]; 1984 char sbuild_id[BUILD_ID_SIZE * 2 + 1];
1974 1985
1975 if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id, 1986 if (sysfs__read_build_id("/sys/kernel/notes", kallsyms_build_id,
1976 sizeof(kallsyms_build_id)) == 0) { 1987 sizeof(kallsyms_build_id)) == 0) {
1977 if (dso__build_id_equal(dso, kallsyms_build_id)) { 1988 if (dso__build_id_equal(dso, kallsyms_build_id)) {
1978 kallsyms_filename = "/proc/kallsyms"; 1989 kallsyms_filename = "/proc/kallsyms";
1979 goto do_kallsyms; 1990 goto do_kallsyms;
1980 } 1991 }
1981 } 1992 }
1982 /* 1993 /*
1983 * Now look if we have it on the build-id cache in 1994 * Now look if we have it on the build-id cache in
1984 * $HOME/.debug/[kernel.kallsyms]. 1995 * $HOME/.debug/[kernel.kallsyms].
1985 */ 1996 */
1986 build_id__sprintf(dso->build_id, sizeof(dso->build_id), 1997 build_id__sprintf(dso->build_id, sizeof(dso->build_id),
1987 sbuild_id); 1998 sbuild_id);
1988 1999
1989 if (asprintf(&kallsyms_allocated_filename, 2000 if (asprintf(&kallsyms_allocated_filename,
1990 "%s/.debug/[kernel.kallsyms]/%s", 2001 "%s/.debug/[kernel.kallsyms]/%s",
1991 getenv("HOME"), sbuild_id) == -1) { 2002 getenv("HOME"), sbuild_id) == -1) {
1992 pr_err("Not enough memory for kallsyms file lookup\n"); 2003 pr_err("Not enough memory for kallsyms file lookup\n");
1993 return -1; 2004 return -1;
1994 } 2005 }
1995 2006
1996 kallsyms_filename = kallsyms_allocated_filename; 2007 kallsyms_filename = kallsyms_allocated_filename;
1997 2008
1998 if (access(kallsyms_filename, F_OK)) { 2009 if (access(kallsyms_filename, F_OK)) {
1999 pr_err("No kallsyms or vmlinux with build-id %s " 2010 pr_err("No kallsyms or vmlinux with build-id %s "
2000 "was found\n", sbuild_id); 2011 "was found\n", sbuild_id);
2001 free(kallsyms_allocated_filename); 2012 free(kallsyms_allocated_filename);
2002 return -1; 2013 return -1;
2003 } 2014 }
2004 } else { 2015 } else {
2005 /* 2016 /*
2006 * Last resort, if we don't have a build-id and couldn't find 2017 * Last resort, if we don't have a build-id and couldn't find
2007 * any vmlinux file, try the running kernel kallsyms table. 2018 * any vmlinux file, try the running kernel kallsyms table.
2008 */ 2019 */
2009 kallsyms_filename = "/proc/kallsyms"; 2020 kallsyms_filename = "/proc/kallsyms";
2010 } 2021 }
2011 2022
2012 do_kallsyms: 2023 do_kallsyms:
2013 err = dso__load_kallsyms(dso, kallsyms_filename, map, filter); 2024 err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
2014 if (err > 0) 2025 if (err > 0)
2015 pr_debug("Using %s for symbols\n", kallsyms_filename); 2026 pr_debug("Using %s for symbols\n", kallsyms_filename);
2016 free(kallsyms_allocated_filename); 2027 free(kallsyms_allocated_filename);
2017 2028
2018 if (err > 0) { 2029 if (err > 0) {
2019 out_fixup: 2030 out_fixup:
2020 if (kallsyms_filename != NULL) 2031 if (kallsyms_filename != NULL)
2021 dso__set_long_name(dso, strdup("[kernel.kallsyms]")); 2032 dso__set_long_name(dso, strdup("[kernel.kallsyms]"));
2022 map__fixup_start(map); 2033 map__fixup_start(map);
2023 map__fixup_end(map); 2034 map__fixup_end(map);
2024 } 2035 }
2025 2036
2026 return err; 2037 return err;
2027 } 2038 }
2028 2039
2029 static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map, 2040 static int dso__load_guest_kernel_sym(struct dso *dso, struct map *map,
2030 symbol_filter_t filter) 2041 symbol_filter_t filter)
2031 { 2042 {
2032 int err; 2043 int err;
2033 const char *kallsyms_filename = NULL; 2044 const char *kallsyms_filename = NULL;
2034 struct machine *machine; 2045 struct machine *machine;
2035 char path[PATH_MAX]; 2046 char path[PATH_MAX];
2036 2047
2037 if (!map->groups) { 2048 if (!map->groups) {
2038 pr_debug("Guest kernel map hasn't the point to groups\n"); 2049 pr_debug("Guest kernel map hasn't the point to groups\n");
2039 return -1; 2050 return -1;
2040 } 2051 }
2041 machine = map->groups->machine; 2052 machine = map->groups->machine;
2042 2053
2043 if (machine__is_default_guest(machine)) { 2054 if (machine__is_default_guest(machine)) {
2044 /* 2055 /*
2045 * if the user specified a vmlinux filename, use it and only 2056 * if the user specified a vmlinux filename, use it and only
2046 * it, reporting errors to the user if it cannot be used. 2057 * it, reporting errors to the user if it cannot be used.
2047 * Or use file guest_kallsyms inputted by user on commandline 2058 * Or use file guest_kallsyms inputted by user on commandline
2048 */ 2059 */
2049 if (symbol_conf.default_guest_vmlinux_name != NULL) { 2060 if (symbol_conf.default_guest_vmlinux_name != NULL) {
2050 err = dso__load_vmlinux(dso, map, 2061 err = dso__load_vmlinux(dso, map,
2051 symbol_conf.default_guest_vmlinux_name, filter); 2062 symbol_conf.default_guest_vmlinux_name, filter);
2052 goto out_try_fixup; 2063 goto out_try_fixup;
2053 } 2064 }
2054 2065
2055 kallsyms_filename = symbol_conf.default_guest_kallsyms; 2066 kallsyms_filename = symbol_conf.default_guest_kallsyms;
2056 if (!kallsyms_filename) 2067 if (!kallsyms_filename)
2057 return -1; 2068 return -1;
2058 } else { 2069 } else {
2059 sprintf(path, "%s/proc/kallsyms", machine->root_dir); 2070 sprintf(path, "%s/proc/kallsyms", machine->root_dir);
2060 kallsyms_filename = path; 2071 kallsyms_filename = path;
2061 } 2072 }
2062 2073
2063 err = dso__load_kallsyms(dso, kallsyms_filename, map, filter); 2074 err = dso__load_kallsyms(dso, kallsyms_filename, map, filter);
2064 if (err > 0) 2075 if (err > 0)
2065 pr_debug("Using %s for symbols\n", kallsyms_filename); 2076 pr_debug("Using %s for symbols\n", kallsyms_filename);
2066 2077
2067 out_try_fixup: 2078 out_try_fixup:
2068 if (err > 0) { 2079 if (err > 0) {
2069 if (kallsyms_filename != NULL) { 2080 if (kallsyms_filename != NULL) {
2070 machine__mmap_name(machine, path, sizeof(path)); 2081 machine__mmap_name(machine, path, sizeof(path));
2071 dso__set_long_name(dso, strdup(path)); 2082 dso__set_long_name(dso, strdup(path));
2072 } 2083 }
2073 map__fixup_start(map); 2084 map__fixup_start(map);
2074 map__fixup_end(map); 2085 map__fixup_end(map);
2075 } 2086 }
2076 2087
2077 return err; 2088 return err;
2078 } 2089 }
2079 2090
2080 static void dsos__add(struct list_head *head, struct dso *dso) 2091 static void dsos__add(struct list_head *head, struct dso *dso)
2081 { 2092 {
2082 list_add_tail(&dso->node, head); 2093 list_add_tail(&dso->node, head);
2083 } 2094 }
2084 2095
2085 static struct dso *dsos__find(struct list_head *head, const char *name) 2096 static struct dso *dsos__find(struct list_head *head, const char *name)
2086 { 2097 {
2087 struct dso *pos; 2098 struct dso *pos;
2088 2099
2089 list_for_each_entry(pos, head, node) 2100 list_for_each_entry(pos, head, node)
2090 if (strcmp(pos->long_name, name) == 0) 2101 if (strcmp(pos->long_name, name) == 0)
2091 return pos; 2102 return pos;
2092 return NULL; 2103 return NULL;
2093 } 2104 }
2094 2105
2095 struct dso *__dsos__findnew(struct list_head *head, const char *name) 2106 struct dso *__dsos__findnew(struct list_head *head, const char *name)
2096 { 2107 {
2097 struct dso *dso = dsos__find(head, name); 2108 struct dso *dso = dsos__find(head, name);
2098 2109
2099 if (!dso) { 2110 if (!dso) {
2100 dso = dso__new(name); 2111 dso = dso__new(name);
2101 if (dso != NULL) { 2112 if (dso != NULL) {
2102 dsos__add(head, dso); 2113 dsos__add(head, dso);
2103 dso__set_basename(dso); 2114 dso__set_basename(dso);
2104 } 2115 }
2105 } 2116 }
2106 2117
2107 return dso; 2118 return dso;
2108 } 2119 }
2109 2120
2110 size_t __dsos__fprintf(struct list_head *head, FILE *fp) 2121 size_t __dsos__fprintf(struct list_head *head, FILE *fp)
2111 { 2122 {
2112 struct dso *pos; 2123 struct dso *pos;
2113 size_t ret = 0; 2124 size_t ret = 0;
2114 2125
2115 list_for_each_entry(pos, head, node) { 2126 list_for_each_entry(pos, head, node) {
2116 int i; 2127 int i;
2117 for (i = 0; i < MAP__NR_TYPES; ++i) 2128 for (i = 0; i < MAP__NR_TYPES; ++i)
2118 ret += dso__fprintf(pos, i, fp); 2129 ret += dso__fprintf(pos, i, fp);
2119 } 2130 }
2120 2131
2121 return ret; 2132 return ret;
2122 } 2133 }
2123 2134
2124 size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp) 2135 size_t machines__fprintf_dsos(struct rb_root *machines, FILE *fp)
2125 { 2136 {
2126 struct rb_node *nd; 2137 struct rb_node *nd;
2127 size_t ret = 0; 2138 size_t ret = 0;
2128 2139
2129 for (nd = rb_first(machines); nd; nd = rb_next(nd)) { 2140 for (nd = rb_first(machines); nd; nd = rb_next(nd)) {
2130 struct machine *pos = rb_entry(nd, struct machine, rb_node); 2141 struct machine *pos = rb_entry(nd, struct machine, rb_node);
2131 ret += __dsos__fprintf(&pos->kernel_dsos, fp); 2142 ret += __dsos__fprintf(&pos->kernel_dsos, fp);
2132 ret += __dsos__fprintf(&pos->user_dsos, fp); 2143 ret += __dsos__fprintf(&pos->user_dsos, fp);
2133 } 2144 }
2134 2145
2135 return ret; 2146 return ret;
2136 } 2147 }
2137 2148
2138 static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp, 2149 static size_t __dsos__fprintf_buildid(struct list_head *head, FILE *fp,
2139 bool with_hits) 2150 bool with_hits)
2140 { 2151 {
2141 struct dso *pos; 2152 struct dso *pos;
2142 size_t ret = 0; 2153 size_t ret = 0;
2143 2154
2144 list_for_each_entry(pos, head, node) { 2155 list_for_each_entry(pos, head, node) {
2145 if (with_hits && !pos->hit) 2156 if (with_hits && !pos->hit)
2146 continue; 2157 continue;
2147 ret += dso__fprintf_buildid(pos, fp); 2158 ret += dso__fprintf_buildid(pos, fp);
2148 ret += fprintf(fp, " %s\n", pos->long_name); 2159 ret += fprintf(fp, " %s\n", pos->long_name);
2149 } 2160 }
2150 return ret; 2161 return ret;
2151 } 2162 }
2152 2163
2153 size_t machine__fprintf_dsos_buildid(struct machine *machine, FILE *fp, 2164 size_t machine__fprintf_dsos_buildid(struct machine *machine, FILE *fp,
2154 bool with_hits) 2165 bool with_hits)
2155 { 2166 {
2156 return __dsos__fprintf_buildid(&machine->kernel_dsos, fp, with_hits) + 2167 return __dsos__fprintf_buildid(&machine->kernel_dsos, fp, with_hits) +
2157 __dsos__fprintf_buildid(&machine->user_dsos, fp, with_hits); 2168 __dsos__fprintf_buildid(&machine->user_dsos, fp, with_hits);
2158 } 2169 }
2159 2170
2160 size_t machines__fprintf_dsos_buildid(struct rb_root *machines, 2171 size_t machines__fprintf_dsos_buildid(struct rb_root *machines,
2161 FILE *fp, bool with_hits) 2172 FILE *fp, bool with_hits)
2162 { 2173 {
2163 struct rb_node *nd; 2174 struct rb_node *nd;
2164 size_t ret = 0; 2175 size_t ret = 0;
2165 2176
2166 for (nd = rb_first(machines); nd; nd = rb_next(nd)) { 2177 for (nd = rb_first(machines); nd; nd = rb_next(nd)) {
2167 struct machine *pos = rb_entry(nd, struct machine, rb_node); 2178 struct machine *pos = rb_entry(nd, struct machine, rb_node);
2168 ret += machine__fprintf_dsos_buildid(pos, fp, with_hits); 2179 ret += machine__fprintf_dsos_buildid(pos, fp, with_hits);
2169 } 2180 }
2170 return ret; 2181 return ret;
2171 } 2182 }
2172 2183
2173 struct dso *dso__new_kernel(const char *name) 2184 struct dso *dso__new_kernel(const char *name)
2174 { 2185 {
2175 struct dso *dso = dso__new(name ?: "[kernel.kallsyms]"); 2186 struct dso *dso = dso__new(name ?: "[kernel.kallsyms]");
2176 2187
2177 if (dso != NULL) { 2188 if (dso != NULL) {
2178 dso__set_short_name(dso, "[kernel]"); 2189 dso__set_short_name(dso, "[kernel]");
2179 dso->kernel = DSO_TYPE_KERNEL; 2190 dso->kernel = DSO_TYPE_KERNEL;
2180 } 2191 }
2181 2192
2182 return dso; 2193 return dso;
2183 } 2194 }
2184 2195
2185 static struct dso *dso__new_guest_kernel(struct machine *machine, 2196 static struct dso *dso__new_guest_kernel(struct machine *machine,
2186 const char *name) 2197 const char *name)
2187 { 2198 {
2188 char bf[PATH_MAX]; 2199 char bf[PATH_MAX];
2189 struct dso *dso = dso__new(name ?: machine__mmap_name(machine, bf, 2200 struct dso *dso = dso__new(name ?: machine__mmap_name(machine, bf,
2190 sizeof(bf))); 2201 sizeof(bf)));
2191 if (dso != NULL) { 2202 if (dso != NULL) {
2192 dso__set_short_name(dso, "[guest.kernel]"); 2203 dso__set_short_name(dso, "[guest.kernel]");
2193 dso->kernel = DSO_TYPE_GUEST_KERNEL; 2204 dso->kernel = DSO_TYPE_GUEST_KERNEL;
2194 } 2205 }
2195 2206
2196 return dso; 2207 return dso;
2197 } 2208 }
2198 2209
2199 void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine) 2210 void dso__read_running_kernel_build_id(struct dso *dso, struct machine *machine)
2200 { 2211 {
2201 char path[PATH_MAX]; 2212 char path[PATH_MAX];
2202 2213
2203 if (machine__is_default_guest(machine)) 2214 if (machine__is_default_guest(machine))
2204 return; 2215 return;
2205 sprintf(path, "%s/sys/kernel/notes", machine->root_dir); 2216 sprintf(path, "%s/sys/kernel/notes", machine->root_dir);
2206 if (sysfs__read_build_id(path, dso->build_id, 2217 if (sysfs__read_build_id(path, dso->build_id,
2207 sizeof(dso->build_id)) == 0) 2218 sizeof(dso->build_id)) == 0)
2208 dso->has_build_id = true; 2219 dso->has_build_id = true;
2209 } 2220 }
2210 2221
2211 static struct dso *machine__create_kernel(struct machine *machine) 2222 static struct dso *machine__create_kernel(struct machine *machine)
2212 { 2223 {
2213 const char *vmlinux_name = NULL; 2224 const char *vmlinux_name = NULL;
2214 struct dso *kernel; 2225 struct dso *kernel;
2215 2226
2216 if (machine__is_host(machine)) { 2227 if (machine__is_host(machine)) {
2217 vmlinux_name = symbol_conf.vmlinux_name; 2228 vmlinux_name = symbol_conf.vmlinux_name;
2218 kernel = dso__new_kernel(vmlinux_name); 2229 kernel = dso__new_kernel(vmlinux_name);
2219 } else { 2230 } else {
2220 if (machine__is_default_guest(machine)) 2231 if (machine__is_default_guest(machine))
2221 vmlinux_name = symbol_conf.default_guest_vmlinux_name; 2232 vmlinux_name = symbol_conf.default_guest_vmlinux_name;
2222 kernel = dso__new_guest_kernel(machine, vmlinux_name); 2233 kernel = dso__new_guest_kernel(machine, vmlinux_name);
2223 } 2234 }
2224 2235
2225 if (kernel != NULL) { 2236 if (kernel != NULL) {
2226 dso__read_running_kernel_build_id(kernel, machine); 2237 dso__read_running_kernel_build_id(kernel, machine);
2227 dsos__add(&machine->kernel_dsos, kernel); 2238 dsos__add(&machine->kernel_dsos, kernel);
2228 } 2239 }
2229 return kernel; 2240 return kernel;
2230 } 2241 }
2231 2242
2232 struct process_args { 2243 struct process_args {
2233 u64 start; 2244 u64 start;
2234 }; 2245 };
2235 2246
2236 static int symbol__in_kernel(void *arg, const char *name, 2247 static int symbol__in_kernel(void *arg, const char *name,
2237 char type __used, u64 start, u64 end __used) 2248 char type __used, u64 start, u64 end __used)
2238 { 2249 {
2239 struct process_args *args = arg; 2250 struct process_args *args = arg;
2240 2251
2241 if (strchr(name, '[')) 2252 if (strchr(name, '['))
2242 return 0; 2253 return 0;
2243 2254
2244 args->start = start; 2255 args->start = start;
2245 return 1; 2256 return 1;
2246 } 2257 }
2247 2258
2248 /* Figure out the start address of kernel map from /proc/kallsyms */ 2259 /* Figure out the start address of kernel map from /proc/kallsyms */
2249 static u64 machine__get_kernel_start_addr(struct machine *machine) 2260 static u64 machine__get_kernel_start_addr(struct machine *machine)
2250 { 2261 {
2251 const char *filename; 2262 const char *filename;
2252 char path[PATH_MAX]; 2263 char path[PATH_MAX];
2253 struct process_args args; 2264 struct process_args args;
2254 2265
2255 if (machine__is_host(machine)) { 2266 if (machine__is_host(machine)) {
2256 filename = "/proc/kallsyms"; 2267 filename = "/proc/kallsyms";
2257 } else { 2268 } else {
2258 if (machine__is_default_guest(machine)) 2269 if (machine__is_default_guest(machine))
2259 filename = (char *)symbol_conf.default_guest_kallsyms; 2270 filename = (char *)symbol_conf.default_guest_kallsyms;
2260 else { 2271 else {
2261 sprintf(path, "%s/proc/kallsyms", machine->root_dir); 2272 sprintf(path, "%s/proc/kallsyms", machine->root_dir);
2262 filename = path; 2273 filename = path;
2263 } 2274 }
2264 } 2275 }
2265 2276
2266 if (symbol__restricted_filename(filename, "/proc/kallsyms")) 2277 if (symbol__restricted_filename(filename, "/proc/kallsyms"))
2267 return 0; 2278 return 0;
2268 2279
2269 if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0) 2280 if (kallsyms__parse(filename, &args, symbol__in_kernel) <= 0)
2270 return 0; 2281 return 0;
2271 2282
2272 return args.start; 2283 return args.start;
2273 } 2284 }
2274 2285
2275 int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel) 2286 int __machine__create_kernel_maps(struct machine *machine, struct dso *kernel)
2276 { 2287 {
2277 enum map_type type; 2288 enum map_type type;
2278 u64 start = machine__get_kernel_start_addr(machine); 2289 u64 start = machine__get_kernel_start_addr(machine);
2279 2290
2280 for (type = 0; type < MAP__NR_TYPES; ++type) { 2291 for (type = 0; type < MAP__NR_TYPES; ++type) {
2281 struct kmap *kmap; 2292 struct kmap *kmap;
2282 2293
2283 machine->vmlinux_maps[type] = map__new2(start, kernel, type); 2294 machine->vmlinux_maps[type] = map__new2(start, kernel, type);
2284 if (machine->vmlinux_maps[type] == NULL) 2295 if (machine->vmlinux_maps[type] == NULL)
2285 return -1; 2296 return -1;
2286 2297
2287 machine->vmlinux_maps[type]->map_ip = 2298 machine->vmlinux_maps[type]->map_ip =
2288 machine->vmlinux_maps[type]->unmap_ip = 2299 machine->vmlinux_maps[type]->unmap_ip =
2289 identity__map_ip; 2300 identity__map_ip;
2290 kmap = map__kmap(machine->vmlinux_maps[type]); 2301 kmap = map__kmap(machine->vmlinux_maps[type]);
2291 kmap->kmaps = &machine->kmaps; 2302 kmap->kmaps = &machine->kmaps;
2292 map_groups__insert(&machine->kmaps, 2303 map_groups__insert(&machine->kmaps,
2293 machine->vmlinux_maps[type]); 2304 machine->vmlinux_maps[type]);
2294 } 2305 }
2295 2306
2296 return 0; 2307 return 0;
2297 } 2308 }
2298 2309
2299 void machine__destroy_kernel_maps(struct machine *machine) 2310 void machine__destroy_kernel_maps(struct machine *machine)
2300 { 2311 {
2301 enum map_type type; 2312 enum map_type type;
2302 2313
2303 for (type = 0; type < MAP__NR_TYPES; ++type) { 2314 for (type = 0; type < MAP__NR_TYPES; ++type) {
2304 struct kmap *kmap; 2315 struct kmap *kmap;
2305 2316
2306 if (machine->vmlinux_maps[type] == NULL) 2317 if (machine->vmlinux_maps[type] == NULL)
2307 continue; 2318 continue;
2308 2319
2309 kmap = map__kmap(machine->vmlinux_maps[type]); 2320 kmap = map__kmap(machine->vmlinux_maps[type]);
2310 map_groups__remove(&machine->kmaps, 2321 map_groups__remove(&machine->kmaps,
2311 machine->vmlinux_maps[type]); 2322 machine->vmlinux_maps[type]);
2312 if (kmap->ref_reloc_sym) { 2323 if (kmap->ref_reloc_sym) {
2313 /* 2324 /*
2314 * ref_reloc_sym is shared among all maps, so free just 2325 * ref_reloc_sym is shared among all maps, so free just
2315 * on one of them. 2326 * on one of them.
2316 */ 2327 */
2317 if (type == MAP__FUNCTION) { 2328 if (type == MAP__FUNCTION) {
2318 free((char *)kmap->ref_reloc_sym->name); 2329 free((char *)kmap->ref_reloc_sym->name);
2319 kmap->ref_reloc_sym->name = NULL; 2330 kmap->ref_reloc_sym->name = NULL;
2320 free(kmap->ref_reloc_sym); 2331 free(kmap->ref_reloc_sym);
2321 } 2332 }
2322 kmap->ref_reloc_sym = NULL; 2333 kmap->ref_reloc_sym = NULL;
2323 } 2334 }
2324 2335
2325 map__delete(machine->vmlinux_maps[type]); 2336 map__delete(machine->vmlinux_maps[type]);
2326 machine->vmlinux_maps[type] = NULL; 2337 machine->vmlinux_maps[type] = NULL;
2327 } 2338 }
2328 } 2339 }
2329 2340
2330 int machine__create_kernel_maps(struct machine *machine) 2341 int machine__create_kernel_maps(struct machine *machine)
2331 { 2342 {
2332 struct dso *kernel = machine__create_kernel(machine); 2343 struct dso *kernel = machine__create_kernel(machine);
2333 2344
2334 if (kernel == NULL || 2345 if (kernel == NULL ||
2335 __machine__create_kernel_maps(machine, kernel) < 0) 2346 __machine__create_kernel_maps(machine, kernel) < 0)
2336 return -1; 2347 return -1;
2337 2348
2338 if (symbol_conf.use_modules && machine__create_modules(machine) < 0) 2349 if (symbol_conf.use_modules && machine__create_modules(machine) < 0)
2339 pr_debug("Problems creating module maps, continuing anyway...\n"); 2350 pr_debug("Problems creating module maps, continuing anyway...\n");
2340 /* 2351 /*
2341 * Now that we have all the maps created, just set the ->end of them: 2352 * Now that we have all the maps created, just set the ->end of them:
2342 */ 2353 */
2343 map_groups__fixup_end(&machine->kmaps); 2354 map_groups__fixup_end(&machine->kmaps);
2344 return 0; 2355 return 0;
2345 } 2356 }
2346 2357
2347 static void vmlinux_path__exit(void) 2358 static void vmlinux_path__exit(void)
2348 { 2359 {
2349 while (--vmlinux_path__nr_entries >= 0) { 2360 while (--vmlinux_path__nr_entries >= 0) {
2350 free(vmlinux_path[vmlinux_path__nr_entries]); 2361 free(vmlinux_path[vmlinux_path__nr_entries]);
2351 vmlinux_path[vmlinux_path__nr_entries] = NULL; 2362 vmlinux_path[vmlinux_path__nr_entries] = NULL;
2352 } 2363 }
2353 2364
2354 free(vmlinux_path); 2365 free(vmlinux_path);
2355 vmlinux_path = NULL; 2366 vmlinux_path = NULL;
2356 } 2367 }
2357 2368
2358 static int vmlinux_path__init(void) 2369 static int vmlinux_path__init(void)
2359 { 2370 {
2360 struct utsname uts; 2371 struct utsname uts;
2361 char bf[PATH_MAX]; 2372 char bf[PATH_MAX];
2362 2373
2363 vmlinux_path = malloc(sizeof(char *) * 5); 2374 vmlinux_path = malloc(sizeof(char *) * 5);
2364 if (vmlinux_path == NULL) 2375 if (vmlinux_path == NULL)
2365 return -1; 2376 return -1;
2366 2377
2367 vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux"); 2378 vmlinux_path[vmlinux_path__nr_entries] = strdup("vmlinux");
2368 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 2379 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2369 goto out_fail; 2380 goto out_fail;
2370 ++vmlinux_path__nr_entries; 2381 ++vmlinux_path__nr_entries;
2371 vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux"); 2382 vmlinux_path[vmlinux_path__nr_entries] = strdup("/boot/vmlinux");
2372 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 2383 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2373 goto out_fail; 2384 goto out_fail;
2374 ++vmlinux_path__nr_entries; 2385 ++vmlinux_path__nr_entries;
2375 2386
2376 /* only try running kernel version if no symfs was given */ 2387 /* only try running kernel version if no symfs was given */
2377 if (symbol_conf.symfs[0] != 0) 2388 if (symbol_conf.symfs[0] != 0)
2378 return 0; 2389 return 0;
2379 2390
2380 if (uname(&uts) < 0) 2391 if (uname(&uts) < 0)
2381 return -1; 2392 return -1;
2382 2393
2383 snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release); 2394 snprintf(bf, sizeof(bf), "/boot/vmlinux-%s", uts.release);
2384 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); 2395 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
2385 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 2396 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2386 goto out_fail; 2397 goto out_fail;
2387 ++vmlinux_path__nr_entries; 2398 ++vmlinux_path__nr_entries;
2388 snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release); 2399 snprintf(bf, sizeof(bf), "/lib/modules/%s/build/vmlinux", uts.release);
2389 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); 2400 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
2390 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 2401 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2391 goto out_fail; 2402 goto out_fail;
2392 ++vmlinux_path__nr_entries; 2403 ++vmlinux_path__nr_entries;
2393 snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux", 2404 snprintf(bf, sizeof(bf), "/usr/lib/debug/lib/modules/%s/vmlinux",
2394 uts.release); 2405 uts.release);
2395 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf); 2406 vmlinux_path[vmlinux_path__nr_entries] = strdup(bf);
2396 if (vmlinux_path[vmlinux_path__nr_entries] == NULL) 2407 if (vmlinux_path[vmlinux_path__nr_entries] == NULL)
2397 goto out_fail; 2408 goto out_fail;
2398 ++vmlinux_path__nr_entries; 2409 ++vmlinux_path__nr_entries;
2399 2410
2400 return 0; 2411 return 0;
2401 2412
2402 out_fail: 2413 out_fail:
2403 vmlinux_path__exit(); 2414 vmlinux_path__exit();
2404 return -1; 2415 return -1;
2405 } 2416 }
2406 2417
2407 size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp) 2418 size_t machine__fprintf_vmlinux_path(struct machine *machine, FILE *fp)
2408 { 2419 {
2409 int i; 2420 int i;
2410 size_t printed = 0; 2421 size_t printed = 0;
2411 struct dso *kdso = machine->vmlinux_maps[MAP__FUNCTION]->dso; 2422 struct dso *kdso = machine->vmlinux_maps[MAP__FUNCTION]->dso;
2412 2423
2413 if (kdso->has_build_id) { 2424 if (kdso->has_build_id) {
2414 char filename[PATH_MAX]; 2425 char filename[PATH_MAX];
2415 if (dso__build_id_filename(kdso, filename, sizeof(filename))) 2426 if (dso__build_id_filename(kdso, filename, sizeof(filename)))
2416 printed += fprintf(fp, "[0] %s\n", filename); 2427 printed += fprintf(fp, "[0] %s\n", filename);
2417 } 2428 }
2418 2429
2419 for (i = 0; i < vmlinux_path__nr_entries; ++i) 2430 for (i = 0; i < vmlinux_path__nr_entries; ++i)
2420 printed += fprintf(fp, "[%d] %s\n", 2431 printed += fprintf(fp, "[%d] %s\n",
2421 i + kdso->has_build_id, vmlinux_path[i]); 2432 i + kdso->has_build_id, vmlinux_path[i]);
2422 2433
2423 return printed; 2434 return printed;
2424 } 2435 }
2425 2436
2426 static int setup_list(struct strlist **list, const char *list_str, 2437 static int setup_list(struct strlist **list, const char *list_str,
2427 const char *list_name) 2438 const char *list_name)
2428 { 2439 {
2429 if (list_str == NULL) 2440 if (list_str == NULL)
2430 return 0; 2441 return 0;
2431 2442
2432 *list = strlist__new(true, list_str); 2443 *list = strlist__new(true, list_str);
2433 if (!*list) { 2444 if (!*list) {
2434 pr_err("problems parsing %s list\n", list_name); 2445 pr_err("problems parsing %s list\n", list_name);
2435 return -1; 2446 return -1;
2436 } 2447 }
2437 return 0; 2448 return 0;
2438 } 2449 }
2439 2450
2440 static bool symbol__read_kptr_restrict(void) 2451 static bool symbol__read_kptr_restrict(void)
2441 { 2452 {
2442 bool value = false; 2453 bool value = false;
2443 2454
2444 if (geteuid() != 0) { 2455 if (geteuid() != 0) {
2445 FILE *fp = fopen("/proc/sys/kernel/kptr_restrict", "r"); 2456 FILE *fp = fopen("/proc/sys/kernel/kptr_restrict", "r");
2446 if (fp != NULL) { 2457 if (fp != NULL) {
2447 char line[8]; 2458 char line[8];
2448 2459
2449 if (fgets(line, sizeof(line), fp) != NULL) 2460 if (fgets(line, sizeof(line), fp) != NULL)
2450 value = atoi(line) != 0; 2461 value = atoi(line) != 0;
2451 2462
2452 fclose(fp); 2463 fclose(fp);
2453 } 2464 }
2454 } 2465 }
2455 2466
2456 return value; 2467 return value;
2457 } 2468 }
2458 2469
2459 int symbol__init(void) 2470 int symbol__init(void)
2460 { 2471 {
2461 const char *symfs; 2472 const char *symfs;
2462 2473
2463 if (symbol_conf.initialized) 2474 if (symbol_conf.initialized)
2464 return 0; 2475 return 0;
2465 2476
2466 symbol_conf.priv_size = ALIGN(symbol_conf.priv_size, sizeof(u64)); 2477 symbol_conf.priv_size = ALIGN(symbol_conf.priv_size, sizeof(u64));
2467 2478
2468 elf_version(EV_CURRENT); 2479 elf_version(EV_CURRENT);
2469 if (symbol_conf.sort_by_name) 2480 if (symbol_conf.sort_by_name)
2470 symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) - 2481 symbol_conf.priv_size += (sizeof(struct symbol_name_rb_node) -
2471 sizeof(struct symbol)); 2482 sizeof(struct symbol));
2472 2483
2473 if (symbol_conf.try_vmlinux_path && vmlinux_path__init() < 0) 2484 if (symbol_conf.try_vmlinux_path && vmlinux_path__init() < 0)
2474 return -1; 2485 return -1;
2475 2486
2476 if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') { 2487 if (symbol_conf.field_sep && *symbol_conf.field_sep == '.') {
2477 pr_err("'.' is the only non valid --field-separator argument\n"); 2488 pr_err("'.' is the only non valid --field-separator argument\n");
2478 return -1; 2489 return -1;
2479 } 2490 }
2480 2491
2481 if (setup_list(&symbol_conf.dso_list, 2492 if (setup_list(&symbol_conf.dso_list,
2482 symbol_conf.dso_list_str, "dso") < 0) 2493 symbol_conf.dso_list_str, "dso") < 0)
2483 return -1; 2494 return -1;
2484 2495
2485 if (setup_list(&symbol_conf.comm_list, 2496 if (setup_list(&symbol_conf.comm_list,
2486 symbol_conf.comm_list_str, "comm") < 0) 2497 symbol_conf.comm_list_str, "comm") < 0)
2487 goto out_free_dso_list; 2498 goto out_free_dso_list;
2488 2499
2489 if (setup_list(&symbol_conf.sym_list, 2500 if (setup_list(&symbol_conf.sym_list,
2490 symbol_conf.sym_list_str, "symbol") < 0) 2501 symbol_conf.sym_list_str, "symbol") < 0)
2491 goto out_free_comm_list; 2502 goto out_free_comm_list;
2492 2503
2493 /* 2504 /*
2494 * A path to symbols of "/" is identical to "" 2505 * A path to symbols of "/" is identical to ""
2495 * reset here for simplicity. 2506 * reset here for simplicity.
2496 */ 2507 */
2497 symfs = realpath(symbol_conf.symfs, NULL); 2508 symfs = realpath(symbol_conf.symfs, NULL);
2498 if (symfs == NULL) 2509 if (symfs == NULL)
2499 symfs = symbol_conf.symfs; 2510 symfs = symbol_conf.symfs;
2500 if (strcmp(symfs, "/") == 0) 2511 if (strcmp(symfs, "/") == 0)
2501 symbol_conf.symfs = ""; 2512 symbol_conf.symfs = "";
2502 if (symfs != symbol_conf.symfs) 2513 if (symfs != symbol_conf.symfs)
2503 free((void *)symfs); 2514 free((void *)symfs);
2504 2515
2505 symbol_conf.kptr_restrict = symbol__read_kptr_restrict(); 2516 symbol_conf.kptr_restrict = symbol__read_kptr_restrict();
2506 2517
2507 symbol_conf.initialized = true; 2518 symbol_conf.initialized = true;
2508 return 0; 2519 return 0;
2509 2520
2510 out_free_dso_list: 2521 out_free_dso_list:
2511 strlist__delete(symbol_conf.dso_list); 2522 strlist__delete(symbol_conf.dso_list);
2512 out_free_comm_list: 2523 out_free_comm_list:
2513 strlist__delete(symbol_conf.comm_list); 2524 strlist__delete(symbol_conf.comm_list);
2514 return -1; 2525 return -1;
2515 } 2526 }
2516 2527
2517 void symbol__exit(void) 2528 void symbol__exit(void)
2518 { 2529 {
2519 if (!symbol_conf.initialized) 2530 if (!symbol_conf.initialized)
2520 return; 2531 return;
2521 strlist__delete(symbol_conf.sym_list); 2532 strlist__delete(symbol_conf.sym_list);
2522 strlist__delete(symbol_conf.dso_list); 2533 strlist__delete(symbol_conf.dso_list);
2523 strlist__delete(symbol_conf.comm_list); 2534 strlist__delete(symbol_conf.comm_list);
2524 vmlinux_path__exit(); 2535 vmlinux_path__exit();
2525 symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL; 2536 symbol_conf.sym_list = symbol_conf.dso_list = symbol_conf.comm_list = NULL;
2526 symbol_conf.initialized = false; 2537 symbol_conf.initialized = false;
2527 } 2538 }
2528 2539
2529 int machines__create_kernel_maps(struct rb_root *machines, pid_t pid) 2540 int machines__create_kernel_maps(struct rb_root *machines, pid_t pid)
2530 { 2541 {
2531 struct machine *machine = machines__findnew(machines, pid); 2542 struct machine *machine = machines__findnew(machines, pid);
2532 2543
2533 if (machine == NULL) 2544 if (machine == NULL)
2534 return -1; 2545 return -1;
2535 2546
2536 return machine__create_kernel_maps(machine); 2547 return machine__create_kernel_maps(machine);
2537 } 2548 }
2538 2549
2539 static int hex(char ch) 2550 static int hex(char ch)
2540 { 2551 {
2541 if ((ch >= '0') && (ch <= '9')) 2552 if ((ch >= '0') && (ch <= '9'))
2542 return ch - '0'; 2553 return ch - '0';
2543 if ((ch >= 'a') && (ch <= 'f')) 2554 if ((ch >= 'a') && (ch <= 'f'))
2544 return ch - 'a' + 10; 2555 return ch - 'a' + 10;
2545 if ((ch >= 'A') && (ch <= 'F')) 2556 if ((ch >= 'A') && (ch <= 'F'))
2546 return ch - 'A' + 10; 2557 return ch - 'A' + 10;
2547 return -1; 2558 return -1;
2548 } 2559 }
2549 2560
2550 /* 2561 /*
2551 * While we find nice hex chars, build a long_val. 2562 * While we find nice hex chars, build a long_val.
2552 * Return number of chars processed. 2563 * Return number of chars processed.
2553 */ 2564 */
2554 int hex2u64(const char *ptr, u64 *long_val) 2565 int hex2u64(const char *ptr, u64 *long_val)
2555 { 2566 {
2556 const char *p = ptr; 2567 const char *p = ptr;
2557 *long_val = 0; 2568 *long_val = 0;
2558 2569
2559 while (*p) { 2570 while (*p) {
2560 const int hex_val = hex(*p); 2571 const int hex_val = hex(*p);
2561 2572
2562 if (hex_val < 0) 2573 if (hex_val < 0)
2563 break; 2574 break;
2564 2575
2565 *long_val = (*long_val << 4) | hex_val; 2576 *long_val = (*long_val << 4) | hex_val;
2566 p++; 2577 p++;
2567 } 2578 }
2568 2579
2569 return p - ptr; 2580 return p - ptr;
2570 } 2581 }
2571 2582
2572 char *strxfrchar(char *s, char from, char to) 2583 char *strxfrchar(char *s, char from, char to)
2573 { 2584 {
2574 char *p = s; 2585 char *p = s;
2575 2586
2576 while ((p = strchr(p, from)) != NULL) 2587 while ((p = strchr(p, from)) != NULL)
2577 *p++ = to; 2588 *p++ = to;
2578 2589
2579 return s; 2590 return s;
2580 } 2591 }
2581 2592
2582 int machines__create_guest_kernel_maps(struct rb_root *machines) 2593 int machines__create_guest_kernel_maps(struct rb_root *machines)
2583 { 2594 {
2584 int ret = 0; 2595 int ret = 0;
2585 struct dirent **namelist = NULL; 2596 struct dirent **namelist = NULL;
2586 int i, items = 0; 2597 int i, items = 0;
2587 char path[PATH_MAX]; 2598 char path[PATH_MAX];
2588 pid_t pid; 2599 pid_t pid;
2589 2600
2590 if (symbol_conf.default_guest_vmlinux_name || 2601 if (symbol_conf.default_guest_vmlinux_name ||
2591 symbol_conf.default_guest_modules || 2602 symbol_conf.default_guest_modules ||
2592 symbol_conf.default_guest_kallsyms) { 2603 symbol_conf.default_guest_kallsyms) {
2593 machines__create_kernel_maps(machines, DEFAULT_GUEST_KERNEL_ID); 2604 machines__create_kernel_maps(machines, DEFAULT_GUEST_KERNEL_ID);
2594 } 2605 }
2595 2606
2596 if (symbol_conf.guestmount) { 2607 if (symbol_conf.guestmount) {
2597 items = scandir(symbol_conf.guestmount, &namelist, NULL, NULL); 2608 items = scandir(symbol_conf.guestmount, &namelist, NULL, NULL);
2598 if (items <= 0) 2609 if (items <= 0)
2599 return -ENOENT; 2610 return -ENOENT;
2600 for (i = 0; i < items; i++) { 2611 for (i = 0; i < items; i++) {
2601 if (!isdigit(namelist[i]->d_name[0])) { 2612 if (!isdigit(namelist[i]->d_name[0])) {
2602 /* Filter out . and .. */ 2613 /* Filter out . and .. */
2603 continue; 2614 continue;
2604 } 2615 }
2605 pid = atoi(namelist[i]->d_name); 2616 pid = atoi(namelist[i]->d_name);
2606 sprintf(path, "%s/%s/proc/kallsyms", 2617 sprintf(path, "%s/%s/proc/kallsyms",
2607 symbol_conf.guestmount, 2618 symbol_conf.guestmount,
2608 namelist[i]->d_name); 2619 namelist[i]->d_name);
2609 ret = access(path, R_OK); 2620 ret = access(path, R_OK);
2610 if (ret) { 2621 if (ret) {
2611 pr_debug("Can't access file %s\n", path); 2622 pr_debug("Can't access file %s\n", path);
2612 goto failure; 2623 goto failure;
2613 } 2624 }
2614 machines__create_kernel_maps(machines, pid); 2625 machines__create_kernel_maps(machines, pid);
2615 } 2626 }
2616 failure: 2627 failure:
2617 free(namelist); 2628 free(namelist);
2618 } 2629 }
2619 2630
2620 return ret; 2631 return ret;
2621 } 2632 }
2622 2633
2623 void machines__destroy_guest_kernel_maps(struct rb_root *machines) 2634 void machines__destroy_guest_kernel_maps(struct rb_root *machines)
2624 { 2635 {
2625 struct rb_node *next = rb_first(machines); 2636 struct rb_node *next = rb_first(machines);
2626 2637
2627 while (next) { 2638 while (next) {
2628 struct machine *pos = rb_entry(next, struct machine, rb_node); 2639 struct machine *pos = rb_entry(next, struct machine, rb_node);
2629 2640
2630 next = rb_next(&pos->rb_node); 2641 next = rb_next(&pos->rb_node);
2631 rb_erase(&pos->rb_node, machines); 2642 rb_erase(&pos->rb_node, machines);
2632 machine__delete(pos); 2643 machine__delete(pos);
2633 } 2644 }
2634 } 2645 }
2635 2646
2636 int machine__load_kallsyms(struct machine *machine, const char *filename, 2647 int machine__load_kallsyms(struct machine *machine, const char *filename,
2637 enum map_type type, symbol_filter_t filter) 2648 enum map_type type, symbol_filter_t filter)
2638 { 2649 {
2639 struct map *map = machine->vmlinux_maps[type]; 2650 struct map *map = machine->vmlinux_maps[type];
2640 int ret = dso__load_kallsyms(map->dso, filename, map, filter); 2651 int ret = dso__load_kallsyms(map->dso, filename, map, filter);
2641 2652
2642 if (ret > 0) { 2653 if (ret > 0) {
2643 dso__set_loaded(map->dso, type); 2654 dso__set_loaded(map->dso, type);
2644 /* 2655 /*
2645 * Since /proc/kallsyms will have multiple sessions for the 2656 * Since /proc/kallsyms will have multiple sessions for the
2646 * kernel, with modules between them, fixup the end of all 2657 * kernel, with modules between them, fixup the end of all
2647 * sections. 2658 * sections.
2648 */ 2659 */
2649 __map_groups__fixup_end(&machine->kmaps, type); 2660 __map_groups__fixup_end(&machine->kmaps, type);
2650 } 2661 }
2651 2662
2652 return ret; 2663 return ret;
2653 } 2664 }
2654 2665
2655 int machine__load_vmlinux_path(struct machine *machine, enum map_type type, 2666 int machine__load_vmlinux_path(struct machine *machine, enum map_type type,
2656 symbol_filter_t filter) 2667 symbol_filter_t filter)
2657 { 2668 {
2658 struct map *map = machine->vmlinux_maps[type]; 2669 struct map *map = machine->vmlinux_maps[type];
2659 int ret = dso__load_vmlinux_path(map->dso, map, filter); 2670 int ret = dso__load_vmlinux_path(map->dso, map, filter);
2660 2671
2661 if (ret > 0) { 2672 if (ret > 0) {
2662 dso__set_loaded(map->dso, type); 2673 dso__set_loaded(map->dso, type);
2663 map__reloc_vmlinux(map); 2674 map__reloc_vmlinux(map);
2664 } 2675 }
2665 2676
2666 return ret; 2677 return ret;
2667 } 2678 }
2668 2679