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

Configure Feed

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

perf annotate: Calculate the max instruction name, align column to that

We were hardcoding '6' as the max instruction name, and we have lots
that are longer than that, see the diff from two 'P' printed TUI
annotations for a libc function that uses instructions with long names,
such as 'vpmovmskb' with its 9 chars:

--- __strcmp_avx2.annotation.before 2019-03-06 16:31:39.368020425 -0300
+++ __strcmp_avx2.annotation 2019-03-06 16:32:12.079450508 -0300
@@ -2,284 +2,284 @@
Event: cycles:ppp

Percent endbr64
- 0.10 mov %edi,%eax
+ 0.10 mov %edi,%eax
- xor %edx,%edx
+ xor %edx,%edx
- 3.54 vpxor %ymm7,%ymm7,%ymm7
+ 3.54 vpxor %ymm7,%ymm7,%ymm7
- or %esi,%eax
+ or %esi,%eax
- and $0xfff,%eax
+ and $0xfff,%eax
- cmp $0xf80,%eax
+ cmp $0xf80,%eax
- ↓ jg 370
+ ↓ jg 370
- 27.07 vmovdqu (%rdi),%ymm1
+ 27.07 vmovdqu (%rdi),%ymm1
- 7.97 vpcmpeqb (%rsi),%ymm1,%ymm0
+ 7.97 vpcmpeqb (%rsi),%ymm1,%ymm0
- 2.15 vpminub %ymm1,%ymm0,%ymm0
+ 2.15 vpminub %ymm1,%ymm0,%ymm0
- 4.09 vpcmpeqb %ymm7,%ymm0,%ymm0
+ 4.09 vpcmpeqb %ymm7,%ymm0,%ymm0
- 0.43 vpmovmskb %ymm0,%ecx
+ 0.43 vpmovmskb %ymm0,%ecx
- 1.53 test %ecx,%ecx
+ 1.53 test %ecx,%ecx
- ↓ je b0
+ ↓ je b0
- 5.26 tzcnt %ecx,%edx
+ 5.26 tzcnt %ecx,%edx
- 18.40 movzbl (%rdi,%rdx,1),%eax
+ 18.40 movzbl (%rdi,%rdx,1),%eax
- 7.09 movzbl (%rsi,%rdx,1),%edx
+ 7.09 movzbl (%rsi,%rdx,1),%edx
- 3.34 sub %edx,%eax
+ 3.34 sub %edx,%eax
2.37 vzeroupper
← retq
nop
- 50: tzcnt %ecx,%edx
+ 50: tzcnt %ecx,%edx
- movzbl 0x20(%rdi,%rdx,1),%eax
+ movzbl 0x20(%rdi,%rdx,1),%eax
- movzbl 0x20(%rsi,%rdx,1),%edx
+ movzbl 0x20(%rsi,%rdx,1),%edx
- sub %edx,%eax
+ sub %edx,%eax
vzeroupper
← retq
- data16 nopw %cs:0x0(%rax,%rax,1)
+ data16 nopw %cs:0x0(%rax,%rax,1)

Reported-by: Travis Downs <travis.downs@gmail.com>
LPU-Reference: CAOBGo4z1KfmWeOm6Et0cnX5Z6DWsG2PQbAvRn1MhVPJmXHrc5g@mail.gmail.com
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Link: https://lkml.kernel.org/n/tip-89wsdd9h9g6bvq52sgp6d0u4@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

+52 -33
+1 -1
tools/perf/arch/arm64/annotate/instructions.c
··· 58 58 } 59 59 60 60 static int mov__scnprintf(struct ins *ins, char *bf, size_t size, 61 - struct ins_operands *ops); 61 + struct ins_operands *ops, int max_ins_name); 62 62 63 63 static struct ins_ops arm64_mov_ops = { 64 64 .parse = arm64_mov__parse,
+1 -1
tools/perf/arch/s390/annotate/instructions.c
··· 46 46 } 47 47 48 48 static int call__scnprintf(struct ins *ins, char *bf, size_t size, 49 - struct ins_operands *ops); 49 + struct ins_operands *ops, int max_ins_name); 50 50 51 51 static struct ins_ops s390_call_ops = { 52 52 .parse = s390_call__parse,
+46 -28
tools/perf/util/annotate.c
··· 198 198 } 199 199 200 200 static int ins__raw_scnprintf(struct ins *ins, char *bf, size_t size, 201 - struct ins_operands *ops) 201 + struct ins_operands *ops, int max_ins_name) 202 202 { 203 - return scnprintf(bf, size, "%-6s %s", ins->name, ops->raw); 203 + return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->raw); 204 204 } 205 205 206 206 int ins__scnprintf(struct ins *ins, char *bf, size_t size, 207 - struct ins_operands *ops) 207 + struct ins_operands *ops, int max_ins_name) 208 208 { 209 209 if (ins->ops->scnprintf) 210 - return ins->ops->scnprintf(ins, bf, size, ops); 210 + return ins->ops->scnprintf(ins, bf, size, ops, max_ins_name); 211 211 212 - return ins__raw_scnprintf(ins, bf, size, ops); 212 + return ins__raw_scnprintf(ins, bf, size, ops, max_ins_name); 213 213 } 214 214 215 215 bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2) ··· 273 273 } 274 274 275 275 static int call__scnprintf(struct ins *ins, char *bf, size_t size, 276 - struct ins_operands *ops) 276 + struct ins_operands *ops, int max_ins_name) 277 277 { 278 278 if (ops->target.sym) 279 - return scnprintf(bf, size, "%-6s %s", ins->name, ops->target.sym->name); 279 + return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->target.sym->name); 280 280 281 281 if (ops->target.addr == 0) 282 - return ins__raw_scnprintf(ins, bf, size, ops); 282 + return ins__raw_scnprintf(ins, bf, size, ops, max_ins_name); 283 283 284 284 if (ops->target.name) 285 - return scnprintf(bf, size, "%-6s %s", ins->name, ops->target.name); 285 + return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->target.name); 286 286 287 - return scnprintf(bf, size, "%-6s *%" PRIx64, ins->name, ops->target.addr); 287 + return scnprintf(bf, size, "%-*s *%" PRIx64, max_ins_name, ins->name, ops->target.addr); 288 288 } 289 289 290 290 static struct ins_ops call_ops = { ··· 388 388 } 389 389 390 390 static int jump__scnprintf(struct ins *ins, char *bf, size_t size, 391 - struct ins_operands *ops) 391 + struct ins_operands *ops, int max_ins_name) 392 392 { 393 393 const char *c; 394 394 395 395 if (!ops->target.addr || ops->target.offset < 0) 396 - return ins__raw_scnprintf(ins, bf, size, ops); 396 + return ins__raw_scnprintf(ins, bf, size, ops, max_ins_name); 397 397 398 398 if (ops->target.outside && ops->target.sym != NULL) 399 - return scnprintf(bf, size, "%-6s %s", ins->name, ops->target.sym->name); 399 + return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, ops->target.sym->name); 400 400 401 401 c = strchr(ops->raw, ','); 402 402 c = validate_comma(c, ops); ··· 415 415 c++; 416 416 } 417 417 418 - return scnprintf(bf, size, "%-6s %.*s%" PRIx64, 418 + return scnprintf(bf, size, "%-*s %.*s%" PRIx64, max_ins_name, 419 419 ins->name, c ? c - ops->raw : 0, ops->raw, 420 420 ops->target.offset); 421 421 } ··· 483 483 } 484 484 485 485 static int lock__scnprintf(struct ins *ins, char *bf, size_t size, 486 - struct ins_operands *ops) 486 + struct ins_operands *ops, int max_ins_name) 487 487 { 488 488 int printed; 489 489 490 490 if (ops->locked.ins.ops == NULL) 491 - return ins__raw_scnprintf(ins, bf, size, ops); 491 + return ins__raw_scnprintf(ins, bf, size, ops, max_ins_name); 492 492 493 - printed = scnprintf(bf, size, "%-6s ", ins->name); 493 + printed = scnprintf(bf, size, "%-*s ", max_ins_name, ins->name); 494 494 return printed + ins__scnprintf(&ops->locked.ins, bf + printed, 495 - size - printed, ops->locked.ops); 495 + size - printed, ops->locked.ops, max_ins_name); 496 496 } 497 497 498 498 static void lock__delete(struct ins_operands *ops) ··· 564 564 } 565 565 566 566 static int mov__scnprintf(struct ins *ins, char *bf, size_t size, 567 - struct ins_operands *ops) 567 + struct ins_operands *ops, int max_ins_name) 568 568 { 569 - return scnprintf(bf, size, "%-6s %s,%s", ins->name, 569 + return scnprintf(bf, size, "%-*s %s,%s", max_ins_name, ins->name, 570 570 ops->source.name ?: ops->source.raw, 571 571 ops->target.name ?: ops->target.raw); 572 572 } ··· 604 604 } 605 605 606 606 static int dec__scnprintf(struct ins *ins, char *bf, size_t size, 607 - struct ins_operands *ops) 607 + struct ins_operands *ops, int max_ins_name) 608 608 { 609 - return scnprintf(bf, size, "%-6s %s", ins->name, 609 + return scnprintf(bf, size, "%-*s %s", max_ins_name, ins->name, 610 610 ops->target.name ?: ops->target.raw); 611 611 } 612 612 ··· 616 616 }; 617 617 618 618 static int nop__scnprintf(struct ins *ins __maybe_unused, char *bf, size_t size, 619 - struct ins_operands *ops __maybe_unused) 619 + struct ins_operands *ops __maybe_unused, int max_ins_name) 620 620 { 621 - return scnprintf(bf, size, "%-6s", "nop"); 621 + return scnprintf(bf, size, "%-*s", max_ins_name, "nop"); 622 622 } 623 623 624 624 static struct ins_ops nop_ops = { ··· 1232 1232 annotation_line__delete(&dl->al); 1233 1233 } 1234 1234 1235 - int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw) 1235 + int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw, int max_ins_name) 1236 1236 { 1237 1237 if (raw || !dl->ins.ops) 1238 - return scnprintf(bf, size, "%-6s %s", dl->ins.name, dl->ops.raw); 1238 + return scnprintf(bf, size, "%-*s %s", max_ins_name, dl->ins.name, dl->ops.raw); 1239 1239 1240 - return ins__scnprintf(&dl->ins, bf, size, &dl->ops); 1240 + return ins__scnprintf(&dl->ins, bf, size, &dl->ops, max_ins_name); 1241 1241 } 1242 1242 1243 1243 static void annotation_line__add(struct annotation_line *al, struct list_head *head) ··· 2414 2414 return 1; 2415 2415 } 2416 2416 2417 + static int annotation__max_ins_name(struct annotation *notes) 2418 + { 2419 + int max_name = 0, len; 2420 + struct annotation_line *al; 2421 + 2422 + list_for_each_entry(al, &notes->src->source, node) { 2423 + if (al->offset == -1) 2424 + continue; 2425 + 2426 + len = strlen(disasm_line(al)->ins.name); 2427 + if (max_name < len) 2428 + max_name = len; 2429 + } 2430 + 2431 + return max_name; 2432 + } 2433 + 2417 2434 void annotation__init_column_widths(struct annotation *notes, struct symbol *sym) 2418 2435 { 2419 2436 notes->widths.addr = notes->widths.target = 2420 2437 notes->widths.min_addr = hex_width(symbol__size(sym)); 2421 2438 notes->widths.max_addr = hex_width(sym->end); 2422 2439 notes->widths.jumps = width_jumps(notes->max_jump_sources); 2440 + notes->widths.max_ins_name = annotation__max_ins_name(notes); 2423 2441 } 2424 2442 2425 2443 void annotation__update_column_widths(struct annotation *notes) ··· 2601 2583 obj__printf(obj, " "); 2602 2584 } 2603 2585 2604 - disasm_line__scnprintf(dl, bf, size, !notes->options->use_offset); 2586 + disasm_line__scnprintf(dl, bf, size, !notes->options->use_offset, notes->widths.max_ins_name); 2605 2587 } 2606 2588 2607 2589 static void ipc_coverage_string(char *bf, int size, struct annotation *notes)
+4 -3
tools/perf/util/annotate.h
··· 59 59 void (*free)(struct ins_operands *ops); 60 60 int (*parse)(struct arch *arch, struct ins_operands *ops, struct map_symbol *ms); 61 61 int (*scnprintf)(struct ins *ins, char *bf, size_t size, 62 - struct ins_operands *ops); 62 + struct ins_operands *ops, int max_ins_name); 63 63 }; 64 64 65 65 bool ins__is_jump(const struct ins *ins); 66 66 bool ins__is_call(const struct ins *ins); 67 67 bool ins__is_ret(const struct ins *ins); 68 68 bool ins__is_lock(const struct ins *ins); 69 - int ins__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops); 69 + int ins__scnprintf(struct ins *ins, char *bf, size_t size, struct ins_operands *ops, int max_ins_name); 70 70 bool ins__is_fused(struct arch *arch, const char *ins1, const char *ins2); 71 71 72 72 #define ANNOTATION__IPC_WIDTH 6 ··· 219 219 struct perf_evsel *evsel, 220 220 bool show_freq); 221 221 222 - int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw); 222 + int disasm_line__scnprintf(struct disasm_line *dl, char *bf, size_t size, bool raw, int max_ins_name); 223 223 size_t disasm__fprintf(struct list_head *head, FILE *fp); 224 224 void symbol__calc_percent(struct symbol *sym, struct perf_evsel *evsel); 225 225 ··· 289 289 u8 target; 290 290 u8 min_addr; 291 291 u8 max_addr; 292 + u8 max_ins_name; 292 293 } widths; 293 294 bool have_cycles; 294 295 struct annotated_source *src;