以下译自 en.wikipedia)
perf (有时亦称为 “Perf Events” 或 perf 工具,原始名称为 “Performance Counters for linux”, PCL),是一个 Linux 性能分析工具,从 Linux 内核版本 2.6.31 导入。用户空间控制工具名为 perf,在命令行使用,提供一系列子命令,适用于整个系统(包含用户空间、内核空间代码)的 profiling 数据统计(即性能剖析数据统计)。
perf 支持硬件性能计数器、tracepoints、软件性能计数器(如 hrtimer),和动态 probes (比如 kprobes 或uprobes)。IBM 在 2012 年将 perf 与 Oprofile 评为两个最常用的 linux performance counter profiling tools。
内核选项
1 | * General setup ---> |
体现在配置文件上的配置项:
ARM Cortex a9:
- CONFIG_HAVE_PERF_EVENTS=y
- CONFIG_PERF_USE_VMALLOC=y
- CONFIG_PERF_EVENTS=y
- CONFIG_DEBUG_PERF_USE_VMALLOC=y
- CONFIG_VM_EVENT_COUNTERS=y
- CONFIG_PROFILING=y
MIPS OCTEON II:
- CONFIG_CAVIUM_OCTEON_PERF=y
- CONFIG_HAVE_PERF_EVENTS=y
- CONFIG_PERF_USE_VMALLOC=y
- CONFIG_PERF_EVENTS=y
- CONFIG_DEBUG_PERF_USE_VMALLOC=y
- CONFIG_VM_EVENT_COUNTERS=y
- CONFIG_PROFILING=y
- CONFIG_HAVE_PERF_REGS=y
- CONFIG_HAVE_PERF_USER_STACK_DUMP=y
X86_64
ubuntu 16.04 上:
- 安装
linux-tools-generic
、linux-cloud-tools-generic
、perf-tools-unstable
- 如果 perf 工具支持的内核不是当前默认启机的内核,则启机后,通过 grub 菜单选择对应的内核后,perf 才能使用。
实测可用。
MIPS OCTEON II
截止 2016年8月24日,MIPS 平台的 perf 还不支持用户空间 callchain,即 perf 使用时无法识别用户空间的函数。
来自 arch/mips/kernel/perf_events.c:1
2
3
423 /*
24 * Leave userspace callchain empty for now. When we find a way to trace
25 * the user stack callchains, we will add it here.
26 */
实测不支持用户空间 callchains。
1 |
|
ARM Cortex a9
实测perf stat 时 counter 无计数,perf record 亦无数据,还不清楚问题在哪。
1 | ~ # perf stat ls |
以下为编译记录:
交叉编译记录参考,丫凡的博文《交叉编译 perf for arm》。
- 内核版本:3.10.18
- arm 交叉编译工具链:arm-cortex_a9-linux-gnueabi-gcc
- 依赖:zlib、elfutils
zlib
zlib 因公司的交叉编译环境已支持,不用重新编译,略过。
elfutils 交叉编译记录
- 版本,0.150,官方下载地址。
如果直接以 ./configure --host=arm-cotex_a9-linux-gnueabi --prefix=/home/sunnogo/workshop; make
,会编译不过,挂在:
1 | arm-cortex_a9-linux-gnueabi-gcc -std=gnu99 -Wall -Wshadow -Werror -Wunused -Wextra -Wformat=2 -fpic -fdollars-in-identifiers -I/home/sunnogo/workshop/rgosm-build/public/include -I/home/sunnogo/workshop/rgosm-build/prj_s6000e/images/header -D_LITTLE_ENDIAN -L/home/sunnogo/workshop/rgosm-build/prj_s6000e/images/lib -L/home/sunnogo/workshop/rgosm-build/prj_s6000e/images/rootfs/lib -o i386_gendis i386_gendis.o i386_lex.o i386_parse.o ../lib/libeu.a -lm |
- 配置
- aclocal
- autoheader
- autoconf
- automake –add-missing
- ./configure –host=arm-cotex_a9-linux-gnueabi –prefix=/home/sunnogo/workshop
1 | sunnogo@R04220:~/workshop/elfutils-0.150$ aclocal |
- 修改 Makefile
- 删除根目录 Makefile 中的 libcpu
- 删除 backends/Makefile 中的 libebl_i386.a and libebl_x86_64.a 相关内容 (这里把所有 i386 和 x86_64 字眼所在行全部注释)
- test 代码依赖 libz
patch 如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234diff -uNr elfutils-0.150/backends/Makefile elfutils-0.150.change_makefile/backends/Makefile
--- elfutils-0.150/backends/Makefile 2016-08-24 14:28:43.122364093 +0800
+++ elfutils-0.150.change_makefile/backends/Makefile 2016-08-24 10:44:13.750042768 +0800
arm_regs.$(OBJEXT) arm_corenote.$(OBJEXT) arm_auxv.$(OBJEXT) \
arm_attrs.$(OBJEXT) arm_retval.$(OBJEXT)
libebl_arm_pic_a_OBJECTS = $(am_libebl_arm_pic_a_OBJECTS)
-libebl_i386_pic_a_AR = $(AR) $(ARFLAGS)
-libebl_i386_pic_a_LIBADD =
-am__objects_3 = i386_init.$(OBJEXT) i386_symbol.$(OBJEXT) \
+#libebl_i386_pic_a_AR = $(AR) $(ARFLAGS)
+#libebl_i386_pic_a_LIBADD =
+#am__objects_3 = i386_init.$(OBJEXT) i386_symbol.$(OBJEXT) \
i386_corenote.$(OBJEXT) i386_cfi.$(OBJEXT) \
i386_retval.$(OBJEXT) i386_regs.$(OBJEXT) i386_auxv.$(OBJEXT) \
i386_syscall.$(OBJEXT)
-libebl_i386_pic_a_OBJECTS = $(am_libebl_i386_pic_a_OBJECTS)
+#libebl_i386_pic_a_OBJECTS = $(am_libebl_i386_pic_a_OBJECTS)
libebl_ia64_pic_a_AR = $(AR) $(ARFLAGS)
libebl_ia64_pic_a_LIBADD =
am__objects_4 = ia64_init.$(OBJEXT) ia64_symbol.$(OBJEXT) \
sparc_corenote.$(OBJEXT) sparc64_corenote.$(OBJEXT) \
sparc_auxv.$(OBJEXT)
libebl_sparc_pic_a_OBJECTS = $(am_libebl_sparc_pic_a_OBJECTS)
-libebl_x86_64_pic_a_AR = $(AR) $(ARFLAGS)
-libebl_x86_64_pic_a_LIBADD =
-am__objects_10 = x86_64_init.$(OBJEXT) x86_64_symbol.$(OBJEXT) \
+#libebl_x86_64_pic_a_AR = $(AR) $(ARFLAGS)
+#libebl_x86_64_pic_a_LIBADD =
+#am__objects_10 = x86_64_init.$(OBJEXT) x86_64_symbol.$(OBJEXT) \
x86_64_corenote.$(OBJEXT) x86_64_cfi.$(OBJEXT) \
x86_64_retval.$(OBJEXT) x86_64_regs.$(OBJEXT) \
i386_auxv.$(OBJEXT) x86_64_syscall.$(OBJEXT)
-libebl_x86_64_pic_a_OBJECTS = $(am_libebl_x86_64_pic_a_OBJECTS)
+#libebl_x86_64_pic_a_OBJECTS = $(am_libebl_x86_64_pic_a_OBJECTS)
AM_V_P = $(am__v_P_$(V))
am__v_P_ = $(am__v_P_$(AM_DEFAULT_VERBOSITY))
am__v_P_0 = false
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libebl_alpha_pic_a_SOURCES) $(libebl_arm_pic_a_SOURCES) \
- $(libebl_i386_pic_a_SOURCES) $(libebl_ia64_pic_a_SOURCES) \
+ $(libebl_ia64_pic_a_SOURCES) \
$(libebl_ppc64_pic_a_SOURCES) $(libebl_ppc_pic_a_SOURCES) \
$(libebl_s390_pic_a_SOURCES) $(libebl_sh_pic_a_SOURCES) \
- $(libebl_sparc_pic_a_SOURCES) $(libebl_x86_64_pic_a_SOURCES)
+ $(libebl_sparc_pic_a_SOURCES)
DIST_SOURCES = $(libebl_alpha_pic_a_SOURCES) \
- $(libebl_arm_pic_a_SOURCES) $(libebl_i386_pic_a_SOURCES) \
+ $(libebl_arm_pic_a_SOURCES) \
$(libebl_ia64_pic_a_SOURCES) $(libebl_ppc64_pic_a_SOURCES) \
$(libebl_ppc_pic_a_SOURCES) $(libebl_s390_pic_a_SOURCES) \
- $(libebl_sh_pic_a_SOURCES) $(libebl_sparc_pic_a_SOURCES) \
- $(libebl_x86_64_pic_a_SOURCES)
+ $(libebl_sh_pic_a_SOURCES) $(libebl_sparc_pic_a_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
MAINT = #
MAKEINFO = makeinfo
MKDIR_P = /bin/mkdir -p
-MODVERSION = Build on R04220 2016-08-24T14:28:41+0800
+MODVERSION = Build on R04220 2016-08-24T10:35:18+0800
MSGFMT = /usr/bin/msgfmt
MSGFMT_015 = /usr/bin/msgfmt
MSGMERGE = /usr/bin/msgmerge
CLEANFILES = *.gcno *.gcda $(foreach m,$(modules), libebl_$(m).map \
libebl_$(m).so $(am_libebl_$(m)_pic_a_OBJECTS))
textrel_check = if readelf -d $@ | fgrep -q TEXTREL; then exit 1; fi
-modules = i386 sh x86_64 ia64 alpha arm sparc ppc ppc64 s390
-libebl_pic = libebl_i386_pic.a libebl_sh_pic.a libebl_x86_64_pic.a \
+modules = sh ia64 alpha arm sparc ppc ppc64 s390
+libebl_pic = libebl_sh_pic.a \
libebl_ia64_pic.a libebl_alpha_pic.a libebl_arm_pic.a \
libebl_sparc_pic.a libebl_ppc_pic.a libebl_ppc64_pic.a \
libebl_s390_pic.a
#libelf = ../libelf/libelf.a
libdw = ../libdw/libdw.so
#libdw = ../libdw/libdw.a
-i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c i386_cfi.c \
+#i386_SRCS = i386_init.c i386_symbol.c i386_corenote.c i386_cfi.c \
i386_retval.c i386_regs.c i386_auxv.c i386_syscall.c
-cpu_i386 = ../libcpu/libcpu_i386.a
-libebl_i386_pic_a_SOURCES = $(i386_SRCS)
-am_libebl_i386_pic_a_OBJECTS = $(i386_SRCS:.c=.os)
+#cpu_i386 = ../libcpu/libcpu_i386.a
+#libebl_i386_pic_a_SOURCES = $(i386_SRCS)
+#am_libebl_i386_pic_a_OBJECTS = $(i386_SRCS:.c=.os)
sh_SRCS = sh_init.c sh_symbol.c sh_corenote.c sh_regs.c sh_retval.c
libebl_sh_pic_a_SOURCES = $(sh_SRCS)
am_libebl_sh_pic_a_OBJECTS = $(sh_SRCS:.c=.os)
-x86_64_SRCS = x86_64_init.c x86_64_symbol.c x86_64_corenote.c x86_64_cfi.c \
+#x86_64_SRCS = x86_64_init.c x86_64_symbol.c x86_64_corenote.c x86_64_cfi.c \
x86_64_retval.c x86_64_regs.c i386_auxv.c x86_64_syscall.c
-cpu_x86_64 = ../libcpu/libcpu_x86_64.a
-libebl_x86_64_pic_a_SOURCES = $(x86_64_SRCS)
-am_libebl_x86_64_pic_a_OBJECTS = $(x86_64_SRCS:.c=.os)
+#cpu_x86_64 = ../libcpu/libcpu_x86_64.a
+#libebl_x86_64_pic_a_SOURCES = $(x86_64_SRCS)
+#am_libebl_x86_64_pic_a_OBJECTS = $(x86_64_SRCS:.c=.os)
ia64_SRCS = ia64_init.c ia64_symbol.c ia64_regs.c ia64_retval.c
libebl_ia64_pic_a_SOURCES = $(ia64_SRCS)
am_libebl_ia64_pic_a_OBJECTS = $(ia64_SRCS:.c=.os)
$(AM_V_AR)$(libebl_arm_pic_a_AR) libebl_arm_pic.a $(libebl_arm_pic_a_OBJECTS) $(libebl_arm_pic_a_LIBADD)
$(AM_V_at)$(RANLIB) libebl_arm_pic.a
-libebl_i386_pic.a: $(libebl_i386_pic_a_OBJECTS) $(libebl_i386_pic_a_DEPENDENCIES) $(EXTRA_libebl_i386_pic_a_DEPENDENCIES)
- $(AM_V_at)-rm -f libebl_i386_pic.a
- $(AM_V_AR)$(libebl_i386_pic_a_AR) libebl_i386_pic.a $(libebl_i386_pic_a_OBJECTS) $(libebl_i386_pic_a_LIBADD)
- $(AM_V_at)$(RANLIB) libebl_i386_pic.a
+#libebl_i386_pic.a: $(libebl_i386_pic_a_OBJECTS) $(libebl_i386_pic_a_DEPENDENCIES) $(EXTRA_libebl_i386_pic_a_DEPENDENCIES)
+# $(AM_V_at)-rm -f libebl_i386_pic.a
+# $(AM_V_AR)$(libebl_i386_pic_a_AR) libebl_i386_pic.a $(libebl_i386_pic_a_OBJECTS) $(libebl_i386_pic_a_LIBADD)
+# $(AM_V_at)$(RANLIB) libebl_i386_pic.a
libebl_ia64_pic.a: $(libebl_ia64_pic_a_OBJECTS) $(libebl_ia64_pic_a_DEPENDENCIES) $(EXTRA_libebl_ia64_pic_a_DEPENDENCIES)
$(AM_V_at)-rm -f libebl_ia64_pic.a
$(AM_V_AR)$(libebl_sparc_pic_a_AR) libebl_sparc_pic.a $(libebl_sparc_pic_a_OBJECTS) $(libebl_sparc_pic_a_LIBADD)
$(AM_V_at)$(RANLIB) libebl_sparc_pic.a
-libebl_x86_64_pic.a: $(libebl_x86_64_pic_a_OBJECTS) $(libebl_x86_64_pic_a_DEPENDENCIES) $(EXTRA_libebl_x86_64_pic_a_DEPENDENCIES)
- $(AM_V_at)-rm -f libebl_x86_64_pic.a
- $(AM_V_AR)$(libebl_x86_64_pic_a_AR) libebl_x86_64_pic.a $(libebl_x86_64_pic_a_OBJECTS) $(libebl_x86_64_pic_a_LIBADD)
- $(AM_V_at)$(RANLIB) libebl_x86_64_pic.a
+#libebl_x86_64_pic.a: $(libebl_x86_64_pic_a_OBJECTS) $(libebl_x86_64_pic_a_DEPENDENCIES) $(EXTRA_libebl_x86_64_pic_a_DEPENDENCIES)
+# $(AM_V_at)-rm -f libebl_x86_64_pic.a
+# $(AM_V_AR)$(libebl_x86_64_pic_a_AR) libebl_x86_64_pic.a $(libebl_x86_64_pic_a_OBJECTS) $(libebl_x86_64_pic_a_LIBADD)
+# $(AM_V_at)$(RANLIB) libebl_x86_64_pic.a
mostlyclean-compile:
-rm -f *.$(OBJEXT)
include ./$(DEPDIR)/arm_regs.Po
include ./$(DEPDIR)/arm_retval.Po
include ./$(DEPDIR)/arm_symbol.Po
-include ./$(DEPDIR)/i386_auxv.Po
-include ./$(DEPDIR)/i386_cfi.Po
-include ./$(DEPDIR)/i386_corenote.Po
-include ./$(DEPDIR)/i386_init.Po
-include ./$(DEPDIR)/i386_regs.Po
-include ./$(DEPDIR)/i386_retval.Po
-include ./$(DEPDIR)/i386_symbol.Po
-include ./$(DEPDIR)/i386_syscall.Po
+#include ./$(DEPDIR)/i386_auxv.Po
+#include ./$(DEPDIR)/i386_cfi.Po
+#include ./$(DEPDIR)/i386_corenote.Po
+#include ./$(DEPDIR)/i386_init.Po
+#include ./$(DEPDIR)/i386_regs.Po
+#include ./$(DEPDIR)/i386_retval.Po
+#include ./$(DEPDIR)/i386_symbol.Po
+#include ./$(DEPDIR)/i386_syscall.Po
include ./$(DEPDIR)/ia64_init.Po
include ./$(DEPDIR)/ia64_regs.Po
include ./$(DEPDIR)/ia64_retval.Po
include ./$(DEPDIR)/sparc_regs.Po
include ./$(DEPDIR)/sparc_retval.Po
include ./$(DEPDIR)/sparc_symbol.Po
-include ./$(DEPDIR)/x86_64_cfi.Po
-include ./$(DEPDIR)/x86_64_corenote.Po
-include ./$(DEPDIR)/x86_64_init.Po
-include ./$(DEPDIR)/x86_64_regs.Po
-include ./$(DEPDIR)/x86_64_retval.Po
-include ./$(DEPDIR)/x86_64_symbol.Po
-include ./$(DEPDIR)/x86_64_syscall.Po
.c.o:
$(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-Wl,-z,defs -Wl,--as-needed $(libelf) $(libdw) $(libmudflap)
$(textrel_check)
-libebl_i386.so: $(cpu_i386)
-libebl_x86_64.so: $(cpu_x86_64)
+#libebl_i386.so: $(cpu_i386)
+#libebl_x86_64.so: $(cpu_x86_64)
install: install-am install-ebl-modules
install-ebl-modules:
diff -uNr elfutils-0.150/Makefile elfutils-0.150.change_makefile/Makefile
--- elfutils-0.150/Makefile 2016-08-24 14:28:43.006363730 +0800
+++ elfutils-0.150.change_makefile/Makefile 2016-08-24 10:35:45.771545207 +0800
pkginclude_HEADERS = version.h
# Add doc back when we have some real content.
-SUBDIRS = config m4 lib libelf libebl libdwfl libdw libcpu libasm backends \
+SUBDIRS = config m4 lib libelf libebl libdwfl libdw libasm backends \
src po tests
EXTRA_DIST = elfutils.spec GPG-KEY NOTES EXCEPTION
diff -uNr elfutils-0.150/src/Makefile elfutils-0.150.change_makefile/src/Makefile
--- elfutils-0.150/src/Makefile 2016-08-24 14:28:43.134364130 +0800
+++ elfutils-0.150.change_makefile/src/Makefile 2016-08-24 10:50:27.408937610 +0800
LEX_OUTPUT_ROOT = lex.yy
LIBEBL_SUBDIR = elfutils
LIBOBJS =
-LIBS =
+LIBS = -lz
LTLIBOBJS =
MAINT = #
MAKEINFO = makeinfo
MKDIR_P = /bin/mkdir -p
MODVERSION = Build on R04220 2016-08-24T10:35:18+0800
MSGFMT = /usr/bin/msgfmt
MSGFMT_015 = /usr/bin/msgfmt
MSGMERGE = /usr/bin/msgmerge
diff -uNr elfutils-0.150/tests/Makefile elfutils-0.150.change_makefile/tests/Makefile
--- elfutils-0.150/tests/Makefile 2016-08-24 14:28:43.158364205 +0800
+++ elfutils-0.150.change_makefile/tests/Makefile 2016-08-24 10:51:48.828696796 +0800
LEX_OUTPUT_ROOT = lex.yy
LIBEBL_SUBDIR = elfutils
LIBOBJS =
-LIBS =
+LIBS = -lz
LTLIBOBJS =
MAINT = #
MAKEINFO = makeinfo
MKDIR_P = /bin/mkdir -p
MODVERSION = Build on R04220 2016-08-24T14:28:41+0800
MSGFMT = /usr/bin/msgfmt
MSGFMT_015 = /usr/bin/msgfmt
MSGMERGE = /usr/bin/msgmerge
perf arm 交叉编译记录
- Makefile 添加外部库路径、外部头文件路径、依赖的库
patch 如下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29diff --git a/tools/perf/Makefile b/tools/perf/Makefile
index b0f164b..5e88839 100644
--- a/tools/perf/Makefile
+++ b/tools/perf/Makefile
@@ -30,11 +30,13 @@ include config/utilities.mak
# Define LDFLAGS=-static to build a static binary.
#
# Define EXTRA_CFLAGS=-m64 or EXTRA_CFLAGS=-m32 as appropriate for cross-builds.
-#
+EXTRA_CFLAGS=-I/home/sunnogo/workshop/rgosm-build/public/include -I/home/sunnogo/workshop/prj/images/header -D_LITTLE_ENDIAN -L/home/sunnogo/workshop/prj/images/lib -L/home/sunnogo/workshop/prj/images/rootfs/lib
+
# Define NO_DWARF if you do not want debug-info analysis feature at all.
#
# Define WERROR=0 to disable treating any warnings as errors.
-#
+WERROR=0
+
# Define NO_NEWT if you do not want TUI support. (deprecated)
#
# Define NO_SLANG if you do not want TUI support.
@@ -111,7 +113,7 @@ ifdef NO_NEWT
endif
CFLAGS = -fno-omit-frame-pointer -ggdb3 -funwind-tables -Wall -Wextra -std=gnu99 $(CFLAGS_WERROR) $(CFLAGS_OPTIMIZE) $(EXTRA_WARNINGS) $(EXTRA_CFLAGS) $(PARSER_DEBUG_CFLAGS)
-EXTLIBS = -lpthread -lrt -lelf -lm
+EXTLIBS = -lpthread -lrt -lelf -lm -lebl -lz -ldl
ALL_CFLAGS = $(CFLAGS) -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE
ALL_LDFLAGS = $(LDFLAGS)
STRIP ?= strip