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

perf annotate: Initial PowerPC support

Support the PowerPC architecture using the ins_ops association
method.

Committer notes:

Testing it with a perf.data file collected on a PowerPC machine and
cross-annotated on a x86_64 workstation, using the associated vmlinux
file:

$ perf report -i perf.data.f22vm.powerdev --vmlinux vmlinux.powerpc
.ktime_get vmlinux.powerpc
│ clrldi r9,r28,63
8.57 │ ┌──bne e0 <- TUI cursor positioned here
│54:│ lwsync
2.86 │ │ std r2,40(r1)
│ │ ld r9,144(r31)
│ │ ld r3,136(r31)
│ │ ld r30,184(r31)
│ │ ld r10,0(r9)
│ │ mtctr r10
│ │ ld r2,8(r9)
8.57 │ │→ bctrl
│ │ ld r2,40(r1)
│ │ ld r10,160(r31)
│ │ ld r5,152(r31)
│ │ lwz r7,168(r31)
│ │ ld r9,176(r31)
8.57 │ │ lwz r6,172(r31)
│ │ lwsync
2.86 │ │ lwz r8,128(r31)
│ │ cmpw cr7,r8,r28
2.86 │ │↑ bne 48
│ │ subf r10,r10,r3
│ │ mr r3,r29
│ │ and r10,r10,r5
2.86 │ │ mulld r10,r10,r7
│ │ add r9,r10,r9
│ │ srd r9,r9,r6
│ │ add r9,r9,r30
│ │ std r9,0(r29)
│ │ addi r1,r1,144
│ │ ld r0,16(r1)
│ │ ld r28,-32(r1)
│ │ ld r29,-24(r1)
│ │ ld r30,-16(r1)
│ │ mtlr r0
│ │ ld r31,-8(r1)
│ │← blr
5.71 │e0:└─→mr r1,r1
11.43 │ mr r2,r2
11.43 │ lwz r28,128(r31)
Press 'h' for help on key bindings

$ perf report -i perf.data.f22vm.powerdev --header-only
# ========
# captured on: Thu Nov 24 12:40:38 2016
# hostname : pdev-f22-qemu
# os release : 4.4.10-200.fc22.ppc64
# perf version : 4.9.rc1.g6298ce
# arch : ppc64
# nrcpus online : 48
# nrcpus avail : 48
# cpudesc : POWER7 (architected), altivec supported
# cpuid : 74,513
# total memory : 4158976 kB
# cmdline : /home/ravi/Workspace/linux/tools/perf/perf record -a
# event : name = cycles:ppp, , size = 112, { sample_period, sample_freq } = 4000, sample_type = IP|TID|TIME|CPU|PERIOD, disabled = 1, inherit = 1, mmap = 1, comm = 1, freq = 1, task = 1, precise_ip = 3, sample_id_all = 1, exclude_guest = 1, mmap2 = 1, comm_exec = 1
# HEADER_CPU_TOPOLOGY info available, use -I to display
# HEADER_NUMA_TOPOLOGY info available, use -I to display
# pmu mappings: cpu = 4, software = 1, tracepoint = 2, breakpoint = 5
# missing features: HEADER_TRACING_DATA HEADER_BRANCH_STACK HEADER_GROUP_DESC HEADER_AUXTRACE HEADER_STAT HEADER_CACHE
# ========
#
$

Signed-off-by: Ravi Bangoria <ravi.bangoria@linux.vnet.ibm.com>
Signed-off-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>
Tested-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: Kim Phillips <kim.phillips@arm.com>
Link: http://lkml.kernel.org/n/tip-tbjnp40ddoxxl474uvhwi6g4@git.kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

Ravi Bangoria and committed by
Arnaldo Carvalho de Melo
dbdebdc5 acc9bfb5

+63
+58
tools/perf/arch/powerpc/annotate/instructions.c
··· 1 + static struct ins_ops *powerpc__associate_instruction_ops(struct arch *arch, const char *name) 2 + { 3 + int i; 4 + struct ins_ops *ops; 5 + 6 + /* 7 + * - Interested only if instruction starts with 'b'. 8 + * - Few start with 'b', but aren't branch instructions. 9 + */ 10 + if (name[0] != 'b' || 11 + !strncmp(name, "bcd", 3) || 12 + !strncmp(name, "brinc", 5) || 13 + !strncmp(name, "bper", 4)) 14 + return NULL; 15 + 16 + ops = &jump_ops; 17 + 18 + i = strlen(name) - 1; 19 + if (i < 0) 20 + return NULL; 21 + 22 + /* ignore optional hints at the end of the instructions */ 23 + if (name[i] == '+' || name[i] == '-') 24 + i--; 25 + 26 + if (name[i] == 'l' || (name[i] == 'a' && name[i-1] == 'l')) { 27 + /* 28 + * if the instruction ends up with 'l' or 'la', then 29 + * those are considered 'calls' since they update LR. 30 + * ... except for 'bnl' which is branch if not less than 31 + * and the absolute form of the same. 32 + */ 33 + if (strcmp(name, "bnl") && strcmp(name, "bnl+") && 34 + strcmp(name, "bnl-") && strcmp(name, "bnla") && 35 + strcmp(name, "bnla+") && strcmp(name, "bnla-")) 36 + ops = &call_ops; 37 + } 38 + if (name[i] == 'r' && name[i-1] == 'l') 39 + /* 40 + * instructions ending with 'lr' are considered to be 41 + * return instructions 42 + */ 43 + ops = &ret_ops; 44 + 45 + arch__associate_ins_ops(arch, name, ops); 46 + return ops; 47 + } 48 + 49 + static int powerpc__annotate_init(struct arch *arch) 50 + { 51 + if (!arch->initialized) { 52 + arch->initialized = true; 53 + arch->associate_instruction_ops = powerpc__associate_instruction_ops; 54 + arch->objdump.comment_char = '#'; 55 + } 56 + 57 + return 0; 58 + }
+5
tools/perf/util/annotate.c
··· 106 106 107 107 #include "arch/arm/annotate/instructions.c" 108 108 #include "arch/x86/annotate/instructions.c" 109 + #include "arch/powerpc/annotate/instructions.c" 109 110 110 111 static struct arch architectures[] = { 111 112 { ··· 120 119 .objdump = { 121 120 .comment_char = '#', 122 121 }, 122 + }, 123 + { 124 + .name = "powerpc", 125 + .init = powerpc__annotate_init, 123 126 }, 124 127 }; 125 128