@@ -2224,6 +2224,74 @@ static int lbr_callchain_add_kernel_ip(struct thread *thread,
2224
2224
return 0 ;
2225
2225
}
2226
2226
2227
+ static int lbr_callchain_add_lbr_ip (struct thread * thread ,
2228
+ struct callchain_cursor * cursor ,
2229
+ struct perf_sample * sample ,
2230
+ struct symbol * * parent ,
2231
+ struct addr_location * root_al ,
2232
+ u64 * branch_from ,
2233
+ bool callee )
2234
+ {
2235
+ struct branch_stack * lbr_stack = sample -> branch_stack ;
2236
+ struct branch_entry * entries = perf_sample__branch_entries (sample );
2237
+ u8 cpumode = PERF_RECORD_MISC_USER ;
2238
+ int lbr_nr = lbr_stack -> nr ;
2239
+ struct branch_flags * flags ;
2240
+ int err , i ;
2241
+ u64 ip ;
2242
+
2243
+ if (callee ) {
2244
+ /* Add LBR ip from first entries.to */
2245
+ ip = entries [0 ].to ;
2246
+ flags = & entries [0 ].flags ;
2247
+ * branch_from = entries [0 ].from ;
2248
+ err = add_callchain_ip (thread , cursor , parent ,
2249
+ root_al , & cpumode , ip ,
2250
+ true, flags , NULL ,
2251
+ * branch_from );
2252
+ if (err )
2253
+ return err ;
2254
+
2255
+ /* Add LBR ip from entries.from one by one. */
2256
+ for (i = 0 ; i < lbr_nr ; i ++ ) {
2257
+ ip = entries [i ].from ;
2258
+ flags = & entries [i ].flags ;
2259
+ err = add_callchain_ip (thread , cursor , parent ,
2260
+ root_al , & cpumode , ip ,
2261
+ true, flags , NULL ,
2262
+ * branch_from );
2263
+ if (err )
2264
+ return err ;
2265
+ }
2266
+ return 0 ;
2267
+ }
2268
+
2269
+ /* Add LBR ip from entries.from one by one. */
2270
+ for (i = lbr_nr - 1 ; i >= 0 ; i -- ) {
2271
+ ip = entries [i ].from ;
2272
+ flags = & entries [i ].flags ;
2273
+ err = add_callchain_ip (thread , cursor , parent ,
2274
+ root_al , & cpumode , ip ,
2275
+ true, flags , NULL ,
2276
+ * branch_from );
2277
+ if (err )
2278
+ return err ;
2279
+ }
2280
+
2281
+ /* Add LBR ip from first entries.to */
2282
+ ip = entries [0 ].to ;
2283
+ flags = & entries [0 ].flags ;
2284
+ * branch_from = entries [0 ].from ;
2285
+ err = add_callchain_ip (thread , cursor , parent ,
2286
+ root_al , & cpumode , ip ,
2287
+ true, flags , NULL ,
2288
+ * branch_from );
2289
+ if (err )
2290
+ return err ;
2291
+
2292
+ return 0 ;
2293
+ }
2294
+
2227
2295
/*
2228
2296
* Recolve LBR callstack chain sample
2229
2297
* Return:
@@ -2240,14 +2308,7 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
2240
2308
{
2241
2309
struct ip_callchain * chain = sample -> callchain ;
2242
2310
int chain_nr = min (max_stack , (int )chain -> nr ), i ;
2243
- u8 cpumode = PERF_RECORD_MISC_USER ;
2244
- u64 ip , branch_from = 0 ;
2245
- struct branch_stack * lbr_stack ;
2246
- struct branch_entry * entries ;
2247
- int lbr_nr , j , k ;
2248
- bool branch ;
2249
- struct branch_flags * flags ;
2250
- int mix_chain_nr ;
2311
+ u64 branch_from = 0 ;
2251
2312
int err ;
2252
2313
2253
2314
for (i = 0 ; i < chain_nr ; i ++ ) {
@@ -2259,21 +2320,6 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
2259
2320
if (i == chain_nr )
2260
2321
return 0 ;
2261
2322
2262
- lbr_stack = sample -> branch_stack ;
2263
- entries = perf_sample__branch_entries (sample );
2264
- lbr_nr = lbr_stack -> nr ;
2265
- /*
2266
- * LBR callstack can only get user call chain.
2267
- * The mix_chain_nr is kernel call chain
2268
- * number plus LBR user call chain number.
2269
- * i is kernel call chain number,
2270
- * 1 is PERF_CONTEXT_USER,
2271
- * lbr_nr + 1 is the user call chain number.
2272
- * For details, please refer to the comments
2273
- * in callchain__printf
2274
- */
2275
- mix_chain_nr = i + 1 + lbr_nr + 1 ;
2276
-
2277
2323
if (callchain_param .order == ORDER_CALLEE ) {
2278
2324
/* Add kernel ip */
2279
2325
err = lbr_callchain_add_kernel_ip (thread , cursor , sample ,
@@ -2282,57 +2328,14 @@ static int resolve_lbr_callchain_sample(struct thread *thread,
2282
2328
if (err )
2283
2329
goto error ;
2284
2330
2285
- /* Add LBR ip from first entries.to */
2286
- ip = entries [0 ].to ;
2287
- branch = true;
2288
- flags = & entries [0 ].flags ;
2289
- branch_from = entries [0 ].from ;
2290
- err = add_callchain_ip (thread , cursor , parent ,
2291
- root_al , & cpumode , ip ,
2292
- branch , flags , NULL ,
2293
- branch_from );
2331
+ err = lbr_callchain_add_lbr_ip (thread , cursor , sample , parent ,
2332
+ root_al , & branch_from , true);
2294
2333
if (err )
2295
2334
goto error ;
2296
2335
2297
- /* Add LBR ip from entries.from one by one. */
2298
- for (j = i + 2 ; j < mix_chain_nr ; j ++ ) {
2299
- k = j - i - 2 ;
2300
- ip = entries [k ].from ;
2301
- branch = true;
2302
- flags = & entries [k ].flags ;
2303
-
2304
- err = add_callchain_ip (thread , cursor , parent ,
2305
- root_al , & cpumode , ip ,
2306
- branch , flags , NULL ,
2307
- branch_from );
2308
- if (err )
2309
- goto error ;
2310
- }
2311
2336
} else {
2312
- /* Add LBR ip from entries.from one by one. */
2313
- for (j = 0 ; j < lbr_nr ; j ++ ) {
2314
- k = lbr_nr - j - 1 ;
2315
- ip = entries [k ].from ;
2316
- branch = true;
2317
- flags = & entries [k ].flags ;
2318
-
2319
- err = add_callchain_ip (thread , cursor , parent ,
2320
- root_al , & cpumode , ip ,
2321
- branch , flags , NULL ,
2322
- branch_from );
2323
- if (err )
2324
- goto error ;
2325
- }
2326
-
2327
- /* Add LBR ip from first entries.to */
2328
- ip = entries [0 ].to ;
2329
- branch = true;
2330
- flags = & entries [0 ].flags ;
2331
- branch_from = entries [0 ].from ;
2332
- err = add_callchain_ip (thread , cursor , parent ,
2333
- root_al , & cpumode , ip ,
2334
- branch , flags , NULL ,
2335
- branch_from );
2337
+ err = lbr_callchain_add_lbr_ip (thread , cursor , sample , parent ,
2338
+ root_al , & branch_from , false);
2336
2339
if (err )
2337
2340
goto error ;
2338
2341
0 commit comments