Skip to contentSkip to conversation

perf build: Fix installation directory for bpf

PATCH In review Thomas Richter 3 participants 3 messages Jul 31, 2018 – Aug 2, 2018 perf events

lore
Share & tools
lore
#0 lore raw

PATCH v2 1/1 perf build: Fix installation directory for bpf

Perf tool build and install is controlled via makefile. Make install creates directories and copies files. Among them are header files installed in /usr/lib/include/perf/bpf/.

However all listed examples are installing its header files in
/usr/lib/<tool-name>/...[/include]/header.h
and not in
/usr/lib/include/<tool-name>/.../header.h.

Background information:
Building the Fedora 28 glibc RPM on s390x and s390 fails on s390 (gcc -m31) as gcc is not able to find header-files like stdbool.h. In the glibc.spec file, you can see that glibc is configured with "--with-headers". In this case, first -nostdinc is added to the CFLAGS and then further include paths are added via -isystem. One of those paths should contain header files like stdbool.h.

In order to get this path, gcc is invoked with:
- on Fedora 28 (with 4.18 kernel):

  $ gcc -print-file-name=include
  /usr/lib/gcc/s390x-redhat-linux/8/include
  $ gcc -m31 -print-file-name=include
  /usr/lib/gcc/s390x-redhat-linux/8/../../../../lib/include
  => If perf is installed, this is: /usr/lib/include
  On my machine this directory is only containing the directory "perf".
  If perf is not installed gcc returns: /usr/lib/gcc/s390x-redhat-linux/8/\
						include

-on Ubuntu 18.04 (with 4.15 kernel):

  $ gcc  -print-file-name=include
  /usr/lib/gcc/s390x-linux-gnu/7/include
  $ gcc -m31 -print-file-name=include
  /usr/lib/gcc/s390x-linux-gnu/7/include
  => gcc returns the correct path even if perf is installed.

In each case, the introduction of the subdirectory /usr/lib/include leads to the regression that one can not build the glibc RPM for s390 anymore as gcc can not find headers like stdbool.h.

To remedy this install bpf.h to /usr/lib/perf/include/bpf/bpf.h

Output before using command ./perf test -Fv 40:

echo '...[bpf-program-source]...' | /usr/bin/clang ... \
		 -I/root/lib/include/perf/bpf ...
                             ^^^^^^^^^^^^
...
[root@p23lp27 perf]# ./perf test -F 40
40: BPF filter                                            :
40.1: Basic BPF filtering                                 : Ok
40.2: BPF pinning                                         : Ok
40.3: BPF prologue generation                             : Ok
40.4: BPF relocation checker                              : Ok

[root@p23lp27 perf]#

Output after using command ./perf test -Fv 40:

echo '...[bpf-program-source]...' | /usr/bin/clang ... \
		 -I/root/lib/perf/include/bpf ...
                             ^^^^^^^^^^^^
...
[root@p23lp27 perf]# ./perf test -F 40
40: BPF filter                                            :
40.1: Basic BPF filtering                                 : Ok
40.2: BPF pinning                                         : Ok
40.3: BPF prologue generation                             : Ok
40.4: BPF relocation checker                              : Ok

[root@p23lp27 perf]#

---
 tools/perf/Makefile.config | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/Makefile.config +2 -2
index f5a3b402589e..67b042738ed7 100644
@@ -905,8 +905,8 @@ bindir = $(abspath $(prefix)/$(bindir_relative))
 mandir = share/man
 infodir = share/info
 perfexecdir = libexec/perf-core
-perf_include_dir = lib/include/perf
-perf_examples_dir = lib/examples/perf
+perf_include_dir = lib/perf/include
+perf_examples_dir = lib/perf/examples
 sharedir = $(prefix)/share
 template_dir = share/perf-core/templates
 STRACE_GROUPS_DIR = share/perf-core/strace/groups
Signature · 1 line
2.17.0
#1 lore raw

Em Tue, Jul 31, 2018 at 09:32:54AM +0200, Thomas Richter escreveu:

Quoted 11 lines

Output after using command ./perf test -Fv 40:

echo '...[bpf-program-source]...' | /usr/bin/clang ... \
		 -I/root/lib/perf/include/bpf ...
                             ^^^^^^^^^^^^
...
[root@p23lp27 perf]# ./perf test -F 40
40: BPF filter                                            :
40.1: Basic BPF filtering                                 : Ok
40.2: BPF pinning                                         : Ok
40.3: BPF prologue generation                             : Ok
40.4: BPF relocation checker                              : Ok
Quoted 1 line

[root@p23lp27 perf]#

So, testing it:

[root@jouet perf]# cat tools/perf/examples/bpf/5sec.c // SPDX-License-Identifier: GPL-2.0
/*
Description:

. Disable strace like syscall tracing (--no-syscalls), or try tracing
just some (-e *sleep).

. Attach a filter function to a kernel function, returning when it should
be considered, i.e. appear on the output.

. Run it system wide, so that any sleep of >= 5 seconds and < than 6
seconds gets caught.

. Ask for callgraphs using DWARF info, so that userspace can be unwound

. While this is running, run something like "sleep 5s".

. If we decide to add tv_nsec as well, then it becomes:

int probe(hrtimer_nanosleep, rqtp->tv_sec rqtp->tv_nsec)(void *ctx, int err, long sec, long nsec)

I.e. add where it comes from (rqtp->tv_nsec) and where it will be accessible in the function body (nsec)

# perf trace --no-syscalls -e tools/perf/examples/bpf/5sec.c/call-graph=dwarf/
0.000 perf_bpf_probe:func:(ffffffff9811b5f0) tv_sec=5
hrtimer_nanosleep ([kernel.kallsyms]) __x64_sys_nanosleep ([kernel.kallsyms]) do_syscall_64 ([kernel.kallsyms]) entry_SYSCALL_64 ([kernel.kallsyms]) __GI___nanosleep (/usr/lib64/libc-2.26.so) rpl_nanosleep (/usr/bin/sleep) xnanosleep (/usr/bin/sleep) main (/usr/bin/sleep) __libc_start_main (/usr/lib64/libc-2.26.so) _start (/usr/bin/sleep)
^C#

Copyright (C) 2018 Red Hat, Inc., Arnaldo Carvalho de Melo <[email protected]>
*/

#include <bpf.h>

int probe(hrtimer_nanosleep, rqtp->tv_sec)(void *ctx, int err, long sec)

{
	return sec == 5;
}

license(GPL);
[root@jouet perf]# perf trace --no-syscalls -e tools/perf/examples/bpf/5sec.c

     0.000 perf_bpf_probe:hrtimer_nanosleep:(ffffffff9911efe0) tv_sec=5

3145.238 perf_bpf_probe:hrtimer_nanosleep:(ffffffff9911efe0) tv_sec=5
^C[root@jouet perf]#

After it works just the same, thanks, applying.

I need to get the above testing process hooked up in 'perf test', so that besides adding that -I/root/lib/perf/include/bpf we actually _try_ to include something from there from the /root/lib/perf/examples/bpf/ bpf example scripts.

- Arnaldo

#2 lore raw

[tip:perf/core] perf build: Fix installation directory for eBPF

In reply to Thomas Richter
perf build: Fix installation directory for eBPF
Commit-ID:  83868bf71d2eb7700b37f1ea188007f0125e4ee4
Gitweb:     https://git.kernel.org/tip/83868bf71d2eb7700b37f1ea188007f0125e4ee4
Author:     Thomas Richter <[email protected]>
AuthorDate: Tue, 31 Jul 2018 09:32:54 +0200
Committer:  Arnaldo Carvalho de Melo <[email protected]>
CommitDate: Tue, 31 Jul 2018 10:54:50 -0300

perf build: Fix installation directory for eBPF

The perf tool build and install is controlled via a Makefile. The 'install' rule creates directories and copies files. Among them are header files installed in /usr/lib/include/perf/bpf/.

However all listed examples are installing its header files in

/usr/lib/<tool-name>/...[/include]/header.h

and not in

/usr/lib/include/<tool-name>/.../header.h.

Background information:

Building the Fedora 28 glibc RPM on s390x and s390 fails on s390 (gcc -m31) as gcc is not able to find header-files like stdbool.h.

In the glibc.spec file, you can see that glibc is configured with "--with-headers". In this case, first -nostdinc is added to the CFLAGS and then further include paths are added via -isystem. One of those paths should contain header files like stdbool.h.

In order to get this path, gcc is invoked with:

- on Fedora 28 (with 4.18 kernel):

  $ gcc -print-file-name=include
  /usr/lib/gcc/s390x-redhat-linux/8/include
  $ gcc -m31 -print-file-name=include
  /usr/lib/gcc/s390x-redhat-linux/8/../../../../lib/include
  => If perf is installed, this is: /usr/lib/include
  On my machine this directory is only containing the directory "perf".
  If perf is not installed gcc returns: /usr/lib/gcc/s390x-redhat-linux/8/include

- on Ubuntu 18.04 (with 4.15 kernel):

  $ gcc  -print-file-name=include
  /usr/lib/gcc/s390x-linux-gnu/7/include
  $ gcc -m31 -print-file-name=include
  /usr/lib/gcc/s390x-linux-gnu/7/include
  => gcc returns the correct path even if perf is installed.

In each case, the introduction of the subdirectory /usr/lib/include leads to the regression that one can not build the glibc RPM for s390 anymore as gcc can not find headers like stdbool.h.

To remedy this install bpf.h to /usr/lib/perf/include/bpf/bpf.h

Output before using the command 'perf test -Fv 40':

  echo '...[bpf-program-source]...' | /usr/bin/clang ... \
		   -I/root/lib/include/perf/bpf ...
                               ^^^^^^^^^^^^
...
  [root@p23lp27 perf]# perf test -F 40
  40: BPF filter                                            :
  40.1: Basic BPF filtering                                 : Ok
  40.2: BPF pinning                                         : Ok
  40.3: BPF prologue generation                             : Ok
  40.4: BPF relocation checker                              : Ok

[root@p23lp27 perf]#

Output after using command 'perf test -Fv 40':

  echo '...[bpf-program-source]...' | /usr/bin/clang ... \
		 -I/root/lib/perf/include/bpf ...
                             ^^^^^^^^^^^^
...
  [root@p23lp27 perf]# perf test -F 40
  40: BPF filter                                            :
  40.1: Basic BPF filtering                                 : Ok
  40.2: BPF pinning                                         : Ok
  40.3: BPF prologue generation                             : Ok
  40.4: BPF relocation checker                              : Ok

[root@p23lp27 perf]#

Committer testing:

While the above 'perf test -F 40' (or 'perf test bpf') will allow us to see that the correct path is now added via -I, to actually test this we better try to use a bpf script that includes files in the changed directory.

We have the files that now reside in /root/lib/perf/examples/bpf/ to do just that:

  # tail -8 /root/lib/perf/examples/bpf/5sec.c
  #include <bpf.h>

int probe(hrtimer_nanosleep, rqtp->tv_sec)(void *ctx, int err, long sec)

  {
	  return sec == 5;

}

license(GPL);

  # perf trace -e *sleep -e /root/lib/perf/examples/bpf/5sec.c sleep 4
       0.333 (4000.086 ms): sleep/9248 nanosleep(rqtp: 0x7ffc155f3300) = 0
  # perf trace -e *sleep -e /root/lib/perf/examples/bpf/5sec.c sleep 5
       0.287 (         ): sleep/9659 nanosleep(rqtp: 0x7ffeafe38200) ...
       0.290 (         ): perf_bpf_probe:hrtimer_nanosleep:(ffffffff9911efe0) tv_sec=5
       0.287 (5000.059 ms): sleep/9659  ... [continued]: nanosleep()) = 0
  # perf trace -e *sleep -e /root/lib/perf/examples/bpf/5sec.c sleep 6
       0.247 (5999.951 ms): sleep/10068 nanosleep(rqtp: 0x7fff2086d900) = 0
  # perf trace -e *sleep -e /root/lib/perf/examples/bpf/5sec.c sleep 5.987
       0.293 (         ): sleep/10489 nanosleep(rqtp: 0x7ffdd4fc10e0) ...
       0.296 (         ): perf_bpf_probe:hrtimer_nanosleep:(ffffffff9911efe0) tv_sec=5
       0.293 (5986.912 ms): sleep/10489  ... [continued]: nanosleep()) = 0
  #
---
 tools/perf/Makefile.config | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/Makefile.config +2 -2
index d3318f99006c..f6d1a03c7523 100644
@@ -907,8 +907,8 @@ bindir = $(abspath $(prefix)/$(bindir_relative))
 mandir = share/man
 infodir = share/info
 perfexecdir = libexec/perf-core
-perf_include_dir = lib/include/perf
-perf_examples_dir = lib/examples/perf
+perf_include_dir = lib/perf/include
+perf_examples_dir = lib/perf/examples
 sharedir = $(prefix)/share
 template_dir = share/perf-core/templates
 STRACE_GROUPS_DIR = share/perf-core/strace/groups