]> code.ossystems Code Review - openembedded-core.git/blob
5e6d5de35518550b7d3475745e02546c6edc5553
[openembedded-core.git] /
1 Upstream-Status: Backport
2
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
8
9 This patch fixes the following problems:
10
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.
21
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.
26
27 These problems were reported by Tony Jones <tonyj@suse.com>.
28
29 Signed-off-by:  Maynard Johnson <maynardj@us.ibm.com>
30 ---
31  configure.ac                   |   74 +++++++++++++++++++++++++++++-----------
32  utils/op_perf_events_checker.c |    6 ++--
33  2 files changed, 58 insertions(+), 22 deletions(-)
34
35 diff --git a/configure.ac b/configure.ac
36 index 5c3d13d..89336ee 100644
37 --- a/configure.ac
38 +++ b/configure.ac
39 @@ -70,34 +70,66 @@ KERNELDIR=$withval)
40  
41  
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"
46 -fi
47 -AX_KERNEL_VERSION(2, 6, 31, <=, kernel_has_perf_events_support="yes",
48 -kernel_has_perf_events_support="no")
49 -
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"
55  else
56 -       AC_MSG_RESULT([This kernel has perf_events support])
57 +       PERF_EVENT_H="/usr/include/linux/perf_event.h"
58  fi
59  
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")
66 +
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.
72 +
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
78 +               AC_LANG_CONFTEST(
79 +                       [AC_LANG_PROGRAM([[#include <linux/perf_event.h>
80 +                               #include <asm/unistd.h>
81 +                               #include <sys/types.h>
82 +                               #include <string.h>
83 +                       ]],
84 +                       [[struct perf_event_attr attr;
85 +                               pid_t pid;
86 +                               memset(&attr, 0, sizeof(attr));
87 +                               attr.size = sizeof(attr);
88 +                               attr.sample_type = PERF_SAMPLE_IP;
89 +                               pid = getpid();
90 +                               syscall(__NR_perf_event_open, &attr, pid, 0, -1, 0);
91 +                               ]])
92 +               ])
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"
96 +                       AC_MSG_RESULT(yes)
97 +               else
98 +                       AC_MSG_RESULT(no)
99 +                       kernel_has_perf_events_support="no"
100 +               fi
101 +       else
102 +               AC_MSG_RESULT(unknown -- perf_event.h not found)
103 +       fi
104  else
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"
108  fi
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'
113  
114 -       if test "$KERNELDIR" != ""; then
115 -               PERF_EVENT_FLAGS=" -I$KERNELDIR/include"
116 -               AC_SUBST(PERF_EVENT_FLAGS)
117 -       fi
118 +AM_CONDITIONAL(BUILD_FOR_PERF_EVENT, test "$kernel_has_perf_events_support" = "yes")
119  
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
124         AC_LANG_CONFTEST(
125 @@ -117,7 +149,9 @@ if test "$PERF_EVENT_H_EXISTS" = "yes"; then
126         rm -f test-for-PERF_GUEST*
127  else
128         HAVE_PERF_EVENTS='0'
129 +       AC_MSG_RESULT([No perf_events support available; falling back to legacy oprofile])
130  fi
131 +
132  AC_DEFINE_UNQUOTED(HAVE_PERF_EVENTS, $HAVE_PERF_EVENTS, [Kernel support for perf_events exists])
133  
134  if test "$HAVE_PERF_EVENTS" = "1"; then
135 @@ -433,7 +467,7 @@ elif test "`getent passwd oprofile 2>/dev/null`" == "" || \
136         fi
137  fi
138  
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)
149         }
150  
151  #if HAVE_PERF_EVENTS
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
159          * ENOENT (2).
160          */
161 -- 
162 1.7.9.7
163