155 lines
6.0 KiB
Diff
155 lines
6.0 KiB
Diff
|
Upstream-Status: Backport
|
||
|
|
||
|
From ca6d916a6f8f0f8abbb4c9b6a97dd1a1615bb124 Mon Sep 17 00:00:00 2001
|
||
|
From: Maynard Johnson <maynardj@us.ibm.com>
|
||
|
Date: Wed, 5 Dec 2012 10:16:35 -0600
|
||
|
Subject: [PATCH] Fix up configure to handle architectures that do not
|
||
|
implement perf_event_open
|
||
|
|
||
|
This patch fixes the following problems:
|
||
|
|
||
|
1) The configure script allows the user to pass a location to kernel
|
||
|
headers (via --with-kernel option) such that, even if the running
|
||
|
kernel does not have perf_events support, it may be possible to
|
||
|
build operf (e.g., in cross-compile environments). But the message
|
||
|
'This kernel does not have perf_events support; falling back to legacy
|
||
|
oprofile' was being displayed inappropriately in such cases. This
|
||
|
patch changes the configure script so that the "falling back to
|
||
|
legacy oprofile" message will only be displayed if we're running
|
||
|
on a kernel that does not have perf_events support AND the user
|
||
|
did not pass specify the "--with-kernel" option.
|
||
|
|
||
|
2) Some architectures don't even implement the perf_event_open syscall, so the
|
||
|
configure script must do more than checking kernel version and whether or not
|
||
|
perf_event.h is present in order to decide if perf_events is supported.
|
||
|
This patch provides that extra capability.
|
||
|
|
||
|
These problems were reported by Tony Jones <tonyj@suse.com>.
|
||
|
|
||
|
Signed-off-by: Maynard Johnson <maynardj@us.ibm.com>
|
||
|
---
|
||
|
configure.ac | 74 +++++++++++++++++++++++++++++-----------
|
||
|
utils/op_perf_events_checker.c | 6 ++--
|
||
|
2 files changed, 58 insertions(+), 22 deletions(-)
|
||
|
|
||
|
diff --git a/configure.ac b/configure.ac
|
||
|
--- a/configure.ac
|
||
|
+++ b/configure.ac
|
||
|
@@ -70,35 +70,70 @@ KERNELDIR=$withval)
|
||
|
|
||
|
|
||
|
dnl Check kernel version for perf_events supported
|
||
|
-AC_MSG_CHECKING([kernel version supports perf_events])
|
||
|
if test "$KERNELDIR" != ""; then
|
||
|
KINC="$KERNELDIR/include"
|
||
|
+ PERF_EVENT_FLAGS=" -I$KERNELDIR/include"
|
||
|
+ AC_SUBST(PERF_EVENT_FLAGS)
|
||
|
+ PERF_EVENT_H="$KERNELDIR/include/linux/perf_event.h"
|
||
|
+else
|
||
|
+ PERF_EVENT_H="/usr/include/linux/perf_event.h"
|
||
|
fi
|
||
|
-AX_KERNEL_VERSION(2, 6, 31, <=, kernel_has_perf_events_support="yes",
|
||
|
+
|
||
|
+PERF_EVENT_H_EXISTS="no"
|
||
|
+kernel_may_have_perf_events_support="no"
|
||
|
+AX_KERNEL_VERSION(2, 6, 31, <=, kernel_may_have_perf_events_support="yes",
|
||
|
kernel_has_perf_events_support="no")
|
||
|
|
||
|
-if test "$kernel_has_perf_events_support" = "no"; then
|
||
|
- AC_MSG_RESULT([This kernel does not have perf_events support; falling back to legacy oprofile])
|
||
|
+dnl The AX_KERNEL_VERSION macro may return kernel_may_have_perf_events_support="yes",
|
||
|
+dnl indicating a partial answer. Some architectures do not implement the Performance
|
||
|
+dnl Events Kernel Subsystem even with kernel versions > 2.6.31 -- i.e., not even
|
||
|
+dnl implementing the perf_event_open syscall to return ENOSYS. So the check below
|
||
|
+dnl will identify and handle such situations.
|
||
|
+
|
||
|
+if test "$kernel_may_have_perf_events_support" = "yes"; then
|
||
|
+ AC_CHECK_HEADER($PERF_EVENT_H,PERF_EVENT_H_EXISTS="yes")
|
||
|
+ AC_MSG_CHECKING([kernel supports perf_events])
|
||
|
+ if test "$PERF_EVENT_H_EXISTS" = "yes"; then
|
||
|
+ rm -f test-for-PERF_EVENT_OPEN
|
||
|
+ AC_LANG_CONFTEST(
|
||
|
+ [AC_LANG_PROGRAM([[#include <linux/perf_event.h>
|
||
|
+ #include <asm/unistd.h>
|
||
|
+ #include <sys/types.h>
|
||
|
+ #include <string.h>
|
||
|
+ ]],
|
||
|
+ [[struct perf_event_attr attr;
|
||
|
+ pid_t pid;
|
||
|
+ memset(&attr, 0, sizeof(attr));
|
||
|
+ attr.size = sizeof(attr);
|
||
|
+ attr.sample_type = PERF_SAMPLE_IP;
|
||
|
+ pid = getpid();
|
||
|
+ syscall(__NR_perf_event_open, &attr, pid, 0, -1, 0);
|
||
|
+ ]])
|
||
|
+ ])
|
||
|
+ $CC conftest.$ac_ext $CFLAGS $LDFLAGS $LIBS $PERF_EVENT_FLAGS -o test-for-PERF_EVENT_OPEN > /dev/null 2>&1
|
||
|
+ if test -f test-for-PERF_EVENT_OPEN; then
|
||
|
+ kernel_has_perf_events_support="yes"
|
||
|
+ AC_MSG_RESULT(yes)
|
||
|
+ else
|
||
|
+ AC_MSG_RESULT(no)
|
||
|
+ kernel_has_perf_events_support="no"
|
||
|
+ fi
|
||
|
+ else
|
||
|
+ AC_MSG_RESULT(unknown -- perf_event.h not found)
|
||
|
+ fi
|
||
|
else
|
||
|
- AC_MSG_RESULT([This kernel has perf_events support])
|
||
|
+ AC_MSG_RESULT(kernel supports perf_events... no)
|
||
|
+ kernel_has_perf_events_support="no"
|
||
|
+fi
|
||
|
+AM_CONDITIONAL(BUILD_FOR_PERF_EVENT, test "$kernel_has_perf_events_support" = "yes")
|
||
|
+
|
||
|
+if test "$kernel_has_perf_events_support" = "yes"; then
|
||
|
+ HAVE_PERF_EVENTS='1'
|
||
|
+else
|
||
|
+ HAVE_PERF_EVENTS='0'
|
||
|
+ AC_MSG_RESULT([No perf_events support available; falling back to legacy oprofile])
|
||
|
fi
|
||
|
|
||
|
-if test "$KERNELDIR" == ""; then
|
||
|
- PERF_EVENT_H="/usr/include/linux/perf_event.h"
|
||
|
-else
|
||
|
- PERF_EVENT_H="$KERNELDIR/include/linux/perf_event.h"
|
||
|
-fi
|
||
|
-AC_CHECK_HEADER($PERF_EVENT_H,PERF_EVENT_H_EXISTS="yes")
|
||
|
-AM_CONDITIONAL(BUILD_FOR_PERF_EVENT, test -n "$PERF_EVENT_H_EXISTS")
|
||
|
-if test "$PERF_EVENT_H_EXISTS" = "yes"; then
|
||
|
- HAVE_PERF_EVENTS='1'
|
||
|
- if test "$KERNELDIR" != ""; then
|
||
|
- PERF_EVENT_FLAGS=" -I$KERNELDIR/include"
|
||
|
- AC_SUBST(PERF_EVENT_FLAGS)
|
||
|
- fi
|
||
|
-else
|
||
|
- HAVE_PERF_EVENTS='0'
|
||
|
-fi
|
||
|
AC_DEFINE_UNQUOTED(HAVE_PERF_EVENTS, $HAVE_PERF_EVENTS, [Kernel support for perf_events exists])
|
||
|
AC_CANONICAL_HOST
|
||
|
if test "$HAVE_PERF_EVENTS" = "1"; then
|
||
|
@@ -414,7 +449,7 @@ elif test "`getent passwd oprofile 2>/de
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
-if test "$PERF_EVENT_H_EXISTS" != "yes" && test "$kernel_has_perf_events_support" = "yes"; then
|
||
|
+if test "$PERF_EVENT_H_EXISTS" != "yes" && test "$kernel_may_have_perf_events_support" = "yes"; then
|
||
|
echo "Warning: perf_event.h not found. Please install the kernel headers package if you"
|
||
|
echo " want non-root support built into OProfile."
|
||
|
fi
|
||
|
diff --git a/utils/op_perf_events_checker.c b/utils/op_perf_events_checker.c
|
||
|
--- a/utils/op_perf_events_checker.c
|
||
|
+++ b/utils/op_perf_events_checker.c
|
||
|
@@ -49,8 +49,10 @@ int main(int argc, char **argv)
|
||
|
}
|
||
|
|
||
|
#if HAVE_PERF_EVENTS
|
||
|
- /* If perf_events syscall is not implemented, the syscall below will fail
|
||
|
- * with ENOSYS (38). If implemented, but the processor type on which this
|
||
|
+ /* Even if the perf_event_open syscall is implemented, the architecture may still
|
||
|
+ * not provide a full implementation of the perf_events subsystem, in which case,
|
||
|
+ * the syscall below will fail with ENOSYS (38). If the perf_events subsystem is
|
||
|
+ * implemented for the architecture, but the processor type on which this
|
||
|
* program is running is not supported by perf_events, the syscall returns
|
||
|
* ENOENT (2).
|
||
|
*/
|