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: Set instruction name to be used with insn-stat when using raw instruction

Since the "ins.name" is not set while using raw instruction,
'perf annotate' with insn-stat gives wrong data:

Result from "./perf annotate --data-type --insn-stat":

Annotate Instruction stats
total 615, ok 419 (68.1%), bad 196 (31.9%)

Name : Good Bad
-----------------------------------------------------------
: 419 196

This patch sets "dl->ins.name" in arch specific function
"check_ppc_insn" while initialising "struct disasm_line".

Also update "ins_find" function to pass "struct disasm_line" as a
parameter so as to set its name field in arch specific call.

With the patch changes:

Annotate Instruction stats
total 609, ok 446 (73.2%), bad 163 (26.8%)

Name/opcode : Good Bad
-----------------------------------------------------------
58 : 323 80
32 : 49 43
34 : 33 11
OP_31_XOP_LDX : 8 20
40 : 23 0
OP_31_XOP_LWARX : 5 1
OP_31_XOP_LWZX : 2 3
OP_31_XOP_LDARX : 3 0
33 : 0 2
OP_31_XOP_LBZX : 0 1
OP_31_XOP_LWAX : 0 1
OP_31_XOP_LHZX : 0 1

Reviewed-by: Kajol Jain <kjain@linux.ibm.com>
Reviewed-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Athira Rajeev <atrajeev@linux.vnet.ibm.com>
Tested-by: Kajol Jain <kjain@linux.ibm.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Akanksha J N <akanksha@linux.ibm.com>
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
Cc: Disha Goel <disgoel@linux.vnet.ibm.com>
Cc: Hari Bathini <hbathini@linux.ibm.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Segher Boessenkool <segher@kernel.crashing.org>
Link: https://lore.kernel.org/lkml/20240718084358.72242-16-atrajeev@linux.vnet.ibm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Athira Rajeev and committed by
Arnaldo Carvalho de Melo
2c9db747 c5d60de1

+24 -12
+15 -3
tools/perf/arch/powerpc/annotate/instructions.c
··· 189 189 return (val1->value - val2->value); 190 190 } 191 191 192 - static struct ins_ops *check_ppc_insn(u32 raw_insn) 192 + static struct ins_ops *check_ppc_insn(struct disasm_line *dl) 193 193 { 194 + int raw_insn = dl->raw.raw_insn; 194 195 int opcode = PPC_OP(raw_insn); 195 196 int mem_insn_31 = PPC_21_30(raw_insn); 196 197 struct insn_offset *ret; ··· 199 198 "OP_31_INSN", 200 199 mem_insn_31 201 200 }; 201 + char name_insn[32]; 202 202 203 203 /* 204 204 * Instructions with opcode 32 to 63 are memory 205 205 * instructions in powerpc 206 206 */ 207 207 if ((opcode & 0x20)) { 208 + /* 209 + * Set name in case of raw instruction to 210 + * opcode to be used in insn-stat 211 + */ 212 + if (!strlen(dl->ins.name)) { 213 + sprintf(name_insn, "%d", opcode); 214 + dl->ins.name = strdup(name_insn); 215 + } 208 216 return &load_store_ops; 209 217 } else if (opcode == 31) { 210 218 /* Check for memory instructions with opcode 31 */ 211 219 ret = bsearch(&mem_insns_31_opcode, ins_array, ARRAY_SIZE(ins_array), sizeof(ins_array[0]), cmp_offset); 212 - if (ret != NULL) 220 + if (ret) { 221 + if (!strlen(dl->ins.name)) 222 + dl->ins.name = strdup(ret->name); 213 223 return &load_store_ops; 214 - else { 224 + } else { 215 225 mem_insns_31_opcode.value = PPC_22_30(raw_insn); 216 226 ret = bsearch(&mem_insns_31_opcode, arithmetic_ins_op_31, ARRAY_SIZE(arithmetic_ins_op_31), 217 227 sizeof(arithmetic_ins_op_31[0]), cmp_offset);
+2 -2
tools/perf/builtin-annotate.c
··· 396 396 printf("total %d, ok %d (%.1f%%), bad %d (%.1f%%)\n\n", total, 397 397 total_good, 100.0 * total_good / (total ?: 1), 398 398 total_bad, 100.0 * total_bad / (total ?: 1)); 399 - printf(" %-10s: %5s %5s\n", "Name", "Good", "Bad"); 399 + printf(" %-20s: %5s %5s\n", "Name/opcode", "Good", "Bad"); 400 400 printf("-----------------------------------------------------------\n"); 401 401 list_for_each_entry(istat, head, list) 402 - printf(" %-10s: %5d %5d\n", istat->name, istat->good, istat->bad); 402 + printf(" %-20s: %5d %5d\n", istat->name, istat->good, istat->bad); 403 403 printf("\n"); 404 404 } 405 405
+1 -1
tools/perf/util/annotate.c
··· 2229 2229 return NULL; 2230 2230 2231 2231 istat->name = strdup(name); 2232 - if (istat->name == NULL) { 2232 + if ((istat->name == NULL) || (!strlen(istat->name))) { 2233 2233 free(istat); 2234 2234 return NULL; 2235 2235 }
+5 -5
tools/perf/util/disasm.c
··· 857 857 qsort(arch->instructions, nmemb, sizeof(struct ins), ins__cmp); 858 858 } 859 859 860 - static struct ins_ops *__ins__find(struct arch *arch, const char *name, u32 raw_insn) 860 + static struct ins_ops *__ins__find(struct arch *arch, const char *name, struct disasm_line *dl) 861 861 { 862 862 struct ins *ins; 863 863 const int nmemb = arch->nr_instructions; ··· 869 869 */ 870 870 struct ins_ops *ops; 871 871 872 - ops = check_ppc_insn(raw_insn); 872 + ops = check_ppc_insn(dl); 873 873 if (ops) 874 874 return ops; 875 875 } ··· 903 903 return ins ? ins->ops : NULL; 904 904 } 905 905 906 - struct ins_ops *ins__find(struct arch *arch, const char *name, u32 raw_insn) 906 + struct ins_ops *ins__find(struct arch *arch, const char *name, struct disasm_line *dl) 907 907 { 908 - struct ins_ops *ops = __ins__find(arch, name, raw_insn); 908 + struct ins_ops *ops = __ins__find(arch, name, dl); 909 909 910 910 if (!ops && arch->associate_instruction_ops) 911 911 ops = arch->associate_instruction_ops(arch, name); ··· 915 915 916 916 static void disasm_line__init_ins(struct disasm_line *dl, struct arch *arch, struct map_symbol *ms) 917 917 { 918 - dl->ins.ops = ins__find(arch, dl->ins.name, dl->raw.raw_insn); 918 + dl->ins.ops = ins__find(arch, dl->ins.name, dl); 919 919 920 920 if (!dl->ins.ops) 921 921 return;
+1 -1
tools/perf/util/disasm.h
··· 105 105 struct arch *arch__find(const char *name); 106 106 bool arch__is(struct arch *arch, const char *name); 107 107 108 - struct ins_ops *ins__find(struct arch *arch, const char *name, u32 raw_insn); 108 + struct ins_ops *ins__find(struct arch *arch, const char *name, struct disasm_line *dl); 109 109 int ins__scnprintf(struct ins *ins, char *bf, size_t size, 110 110 struct ins_operands *ops, int max_ins_name); 111 111