1 Upstream-Status: Backport
3 From ca6d916a6f8f0f8abbb4c9b6a97dd1a1615bb124 Mon Sep 17 00:00:00 2001
4 From: Maynard Johnson <maynardj@us.ibm.com>
5 Date: Wed, 5 Dec 2012 10:16:35 -0600
6 Subject: [PATCH] Fix up configure to handle architectures that do not
7 implement perf_event_open
9 This patch fixes the following problems:
11 1) The configure script allows the user to pass a location to kernel
12 headers (via --with-kernel option) such that, even if the running
13 kernel does not have perf_events support, it may be possible to
14 build operf (e.g., in cross-compile environments). But the message
15 'This kernel does not have perf_events support; falling back to legacy
16 oprofile' was being displayed inappropriately in such cases. This
17 patch changes the configure script so that the "falling back to
18 legacy oprofile" message will only be displayed if we're running
19 on a kernel that does not have perf_events support AND the user
20 did not pass specify the "--with-kernel" option.
22 2) Some architectures don't even implement the perf_event_open syscall, so the
23 configure script must do more than checking kernel version and whether or not
24 perf_event.h is present in order to decide if perf_events is supported.
25 This patch provides that extra capability.
27 These problems were reported by Tony Jones <tonyj@suse.com>.
29 Signed-off-by: Maynard Johnson <maynardj@us.ibm.com>
31 configure.ac | 74 +++++++++++++++++++++++++++++-----------
32 utils/op_perf_events_checker.c | 6 ++--
33 2 files changed, 58 insertions(+), 22 deletions(-)
35 diff --git a/configure.ac b/configure.ac
36 index 5c3d13d..89336ee 100644
39 @@ -70,34 +70,66 @@ KERNELDIR=$withval)
42 dnl Check kernel version for perf_events supported
43 -AC_MSG_CHECKING([kernel version supports perf_events])
44 if test "$KERNELDIR" != ""; then
45 KINC="$KERNELDIR/include"
47 -AX_KERNEL_VERSION(2, 6, 31, <=, kernel_has_perf_events_support="yes",
48 -kernel_has_perf_events_support="no")
50 -if test "$kernel_has_perf_events_support" = "no"; then
51 - AC_MSG_RESULT([This kernel does not have perf_events support; falling back to legacy oprofile])
52 + PERF_EVENT_FLAGS=" -I$KERNELDIR/include"
53 + AC_SUBST(PERF_EVENT_FLAGS)
54 + PERF_EVENT_H="$KERNELDIR/include/linux/perf_event.h"
56 - AC_MSG_RESULT([This kernel has perf_events support])
57 + PERF_EVENT_H="/usr/include/linux/perf_event.h"
60 -if test "$KERNELDIR" == ""; then
61 - PERF_EVENT_H="/usr/include/linux/perf_event.h"
62 +PERF_EVENT_H_EXISTS="no"
63 +kernel_may_have_perf_events_support="no"
64 +AX_KERNEL_VERSION(2, 6, 31, <=, kernel_may_have_perf_events_support="yes",
65 +kernel_has_perf_events_support="no")
67 +dnl The AX_KERNEL_VERSION macro may return kernel_may_have_perf_events_support="yes",
68 +dnl indicating a partial answer. Some architectures do not implement the Performance
69 +dnl Events Kernel Subsystem even with kernel versions > 2.6.31 -- i.e., not even
70 +dnl implementing the perf_event_open syscall to return ENOSYS. So the check below
71 +dnl will identify and handle such situations.
73 +if test "$kernel_may_have_perf_events_support" = "yes"; then
74 + AC_CHECK_HEADER($PERF_EVENT_H,PERF_EVENT_H_EXISTS="yes")
75 + AC_MSG_CHECKING([kernel supports perf_events])
76 + if test "$PERF_EVENT_H_EXISTS" = "yes"; then
77 + rm -f test-for-PERF_EVENT_OPEN
79 + [AC_LANG_PROGRAM([[#include <linux/perf_event.h>
80 + #include <asm/unistd.h>
81 + #include <sys/types.h>
84 + [[struct perf_event_attr attr;
86 + memset(&attr, 0, sizeof(attr));
87 + attr.size = sizeof(attr);
88 + attr.sample_type = PERF_SAMPLE_IP;
90 + syscall(__NR_perf_event_open, &attr, pid, 0, -1, 0);
93 + $CC conftest.$ac_ext $CFLAGS $LDFLAGS $LIBS $PERF_EVENT_FLAGS -o test-for-PERF_EVENT_OPEN > /dev/null 2>&1
94 + if test -f test-for-PERF_EVENT_OPEN; then
95 + kernel_has_perf_events_support="yes"
99 + kernel_has_perf_events_support="no"
102 + AC_MSG_RESULT(unknown -- perf_event.h not found)
105 - PERF_EVENT_H="$KERNELDIR/include/linux/perf_event.h"
106 + AC_MSG_RESULT(kernel supports perf_events... no)
107 + kernel_has_perf_events_support="no"
109 -AC_CHECK_HEADER($PERF_EVENT_H,PERF_EVENT_H_EXISTS="yes")
110 -AM_CONDITIONAL(BUILD_FOR_PERF_EVENT, test -n "$PERF_EVENT_H_EXISTS")
111 -if test "$PERF_EVENT_H_EXISTS" = "yes"; then
112 - HAVE_PERF_EVENTS='1'
114 - if test "$KERNELDIR" != ""; then
115 - PERF_EVENT_FLAGS=" -I$KERNELDIR/include"
116 - AC_SUBST(PERF_EVENT_FLAGS)
118 +AM_CONDITIONAL(BUILD_FOR_PERF_EVENT, test "$kernel_has_perf_events_support" = "yes")
120 +if test "$kernel_has_perf_events_support" = "yes"; then
121 + HAVE_PERF_EVENTS='1'
122 AC_MSG_CHECKING([whether PERF_RECORD_MISC_GUEST_KERNEL is defined in perf_event.h])
123 rm -f test-for-PERF_GUEST
125 @@ -117,7 +149,9 @@ if test "$PERF_EVENT_H_EXISTS" = "yes"; then
126 rm -f test-for-PERF_GUEST*
129 + AC_MSG_RESULT([No perf_events support available; falling back to legacy oprofile])
132 AC_DEFINE_UNQUOTED(HAVE_PERF_EVENTS, $HAVE_PERF_EVENTS, [Kernel support for perf_events exists])
134 if test "$HAVE_PERF_EVENTS" = "1"; then
135 @@ -433,7 +467,7 @@ elif test "`getent passwd oprofile 2>/dev/null`" == "" || \
139 -if test "$PERF_EVENT_H_EXISTS" != "yes" && test "$kernel_has_perf_events_support" = "yes"; then
140 +if test "$PERF_EVENT_H_EXISTS" != "yes" && test "$kernel_may_have_perf_events_support" = "yes"; then
141 echo "Warning: perf_event.h not found. Either install the kernel headers package or"
142 echo "use the --with-kernel option if you want the non-root, single application"
143 echo "profiling support provided by operf."
144 diff --git a/utils/op_perf_events_checker.c b/utils/op_perf_events_checker.c
145 index 519cafa..74a410e 100644
146 --- a/utils/op_perf_events_checker.c
147 +++ b/utils/op_perf_events_checker.c
148 @@ -49,8 +49,10 @@ int main(int argc, char **argv)
152 - /* If perf_events syscall is not implemented, the syscall below will fail
153 - * with ENOSYS (38). If implemented, but the processor type on which this
154 + /* Even if the perf_event_open syscall is implemented, the architecture may still
155 + * not provide a full implementation of the perf_events subsystem, in which case,
156 + * the syscall below will fail with ENOSYS (38). If the perf_events subsystem is
157 + * implemented for the architecture, but the processor type on which this
158 * program is running is not supported by perf_events, the syscall returns