Skip to content

Commit 14e4b9f

Browse files
captain5050acmel
authored andcommitted
perf trace: Raw augmented syscalls fix libbpf 1.0+ compatibility
Don't use deprecated and now broken map style. Avoid use of tools/perf/include/bpf/bpf.h and use the more regular BPF headers. Committer notes: Add /usr/include to the include path so that bpf/bpf_helpers.h can be found, remove sys/socket.h, adding the sockaddr_storage definition, also remove stdbool.h, both were preventing building the augmented_raw_syscalls.c file with clang, revisit later. Testing it: Asking for syscalls that have string arguments: # perf trace -e ~acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.c,string --max-events 10 0.000 thermald/1144 openat(dfd: CWD, filename: "/sys/class/powercap/intel-rapl/intel-rapl:0/intel-rapl:0:2/energy_uj", flags: RDONLY) = 13 0.158 thermald/1144 openat(dfd: CWD, filename: "/sys/class/powercap/intel-rapl/intel-rapl:0/energy_uj", flags: RDONLY) = 13 0.215 thermald/1144 openat(dfd: CWD, filename: "/sys/class/thermal/thermal_zone3/temp", flags: RDONLY) = 13 16.448 cgroupify/36478 openat(dfd: 4, filename: ".", flags: RDONLY|CLOEXEC|DIRECTORY|NONBLOCK) = 5 16.468 cgroupify/36478 newfstatat(dfd: 5, filename: "", statbuf: 0x7fffca5b4130, flag: 4096) = 0 16.473 systemd-oomd/972 openat(dfd: CWD, filename: "/proc/meminfo", flags: RDONLY|CLOEXEC) = 12 16.499 systemd-oomd/972 newfstatat(dfd: 12, filename: "", statbuf: 0x7ffd2bc73cc0, flag: 4096) = 0 16.516 abrt-dump-jour/1370 openat(dfd: CWD, filename: "/var/log/journal/d6a97235307247e09f13f326fb607e3c/system.journal", flags: RDONLY|CLOEXEC|NONBLOCK) = 21 16.538 abrt-dump-jour/1370 newfstatat(dfd: 21, filename: "", statbuf: 0x7ffc651b8980, flag: 4096) = 0 16.540 abrt-dump-jour/1371 openat(dfd: CWD, filename: "/var/log/journal/d6a97235307247e09f13f326fb607e3c/system.journal", flags: RDONLY|CLOEXEC|NONBLOCK) = 21 # Networking syscalls: # perf trace -e ~acme/git/perf/tools/perf/examples/bpf/augmented_raw_syscalls.c,sendto*,connect* --max-events 10 0.000 isc-net-0005/1206 connect(fd: 512, uservaddr: { .family: INET, port: 53, addr: 23.211.132.65 }, addrlen: 16) = 0 0.070 isc-net-0002/1203 connect(fd: 515, uservaddr: { .family: INET6, port: 53, addr: 2600:1401:2::43 }, addrlen: 28) = -1 ENETUNREACH (Network is unreachable) 0.031 isc-net-0006/1207 connect(fd: 513, uservaddr: { .family: INET6, port: 53, addr: 2600:1401:2::43 }, addrlen: 28) = -1 ENETUNREACH (Network is unreachable) 0.079 isc-net-0006/1207 sendto(fd: 3, buff: 0x7f73a40611b0, len: 106, flags: NOSIGNAL, addr: { .family: UNSPEC }, addr_len: NULL) = 106 0.180 isc-net-0006/1207 connect(fd: 519, uservaddr: { .family: INET6, port: 53, addr: 2600:1401:1::43 }, addrlen: 28) = -1 ENETUNREACH (Network is unreachable) 0.211 isc-net-0006/1207 sendto(fd: 3, buff: 0x7f73a4061230, len: 106, flags: NOSIGNAL, addr: { .family: UNSPEC }, addr_len: NULL) = 106 0.298 isc-net-0006/1207 connect(fd: 515, uservaddr: { .family: INET, port: 53, addr: 96.7.49.67 }, addrlen: 16) = 0 0.109 isc-net-0004/1205 connect(fd: 518, uservaddr: { .family: INET6, port: 53, addr: 2600:1401:2::43 }, addrlen: 28) = -1 ENETUNREACH (Network is unreachable) 0.164 isc-net-0002/1203 sendto(fd: 3, buff: 0x7f73ac064300, len: 107, flags: NOSIGNAL, addr: { .family: UNSPEC }, addr_len: NULL) = 107 0.247 isc-net-0002/1203 connect(fd: 522, uservaddr: { .family: INET6, port: 53, addr: 2600:1401:1::43 }, addrlen: 28) = -1 ENETUNREACH (Network is unreachable) # Signed-off-by: Ian Rogers <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Leo Yan <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Stephane Eranian <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 92ea072 commit 14e4b9f

File tree

3 files changed

+89
-19
lines changed

3 files changed

+89
-19
lines changed

tools/perf/Makefile.config

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1239,7 +1239,8 @@ includedir = $(abspath $(prefix)/$(includedir_relative))
12391239
mandir = share/man
12401240
infodir = share/info
12411241
perfexecdir = libexec/perf-core
1242-
perf_include_dir = lib/perf/include
1242+
# FIXME: system's libbpf header directory, where we expect to find bpf/bpf_helpers.h, for instance
1243+
perf_include_dir = /usr/include
12431244
perf_examples_dir = lib/perf/examples
12441245
sharedir = $(prefix)/share
12451246
template_dir = share/perf-core/templates

tools/perf/examples/bpf/augmented_raw_syscalls.c

Lines changed: 86 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,21 @@
1414
* code that will combine entry/exit in a strace like way.
1515
*/
1616

17-
#include <unistd.h>
17+
#include <linux/bpf.h>
18+
#include <bpf/bpf_helpers.h>
1819
#include <linux/limits.h>
19-
#include <linux/socket.h>
20-
#include <pid_filter.h>
20+
21+
// FIXME: These should come from system headers
22+
typedef char bool;
23+
typedef int pid_t;
2124

2225
/* bpf-output associated map */
23-
bpf_map(__augmented_syscalls__, PERF_EVENT_ARRAY, int, u32, __NR_CPUS__);
26+
struct __augmented_syscalls__ {
27+
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
28+
__type(key, int);
29+
__type(value, __u32);
30+
__uint(max_entries, __NR_CPUS__);
31+
} __augmented_syscalls__ SEC(".maps");
2432

2533
/*
2634
* string_args_len: one per syscall arg, 0 means not a string or don't copy it,
@@ -29,24 +37,39 @@ bpf_map(__augmented_syscalls__, PERF_EVENT_ARRAY, int, u32, __NR_CPUS__);
2937
*/
3038
struct syscall {
3139
bool enabled;
32-
u16 string_args_len[6];
40+
__u16 string_args_len[6];
3341
};
3442

35-
bpf_map(syscalls, ARRAY, int, struct syscall, 512);
43+
struct syscalls {
44+
__uint(type, BPF_MAP_TYPE_ARRAY);
45+
__type(key, int);
46+
__type(value, struct syscall);
47+
__uint(max_entries, 512);
48+
} syscalls SEC(".maps");
3649

3750
/*
3851
* What to augment at entry?
3952
*
4053
* Pointer arg payloads (filenames, etc) passed from userspace to the kernel
4154
*/
42-
bpf_map(syscalls_sys_enter, PROG_ARRAY, u32, u32, 512);
55+
struct syscalls_sys_enter {
56+
__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
57+
__type(key, __u32);
58+
__type(value, __u32);
59+
__uint(max_entries, 512);
60+
} syscalls_sys_enter SEC(".maps");
4361

4462
/*
4563
* What to augment at exit?
4664
*
4765
* Pointer arg payloads returned from the kernel (struct stat, etc) to userspace.
4866
*/
49-
bpf_map(syscalls_sys_exit, PROG_ARRAY, u32, u32, 512);
67+
struct syscalls_sys_exit {
68+
__uint(type, BPF_MAP_TYPE_PROG_ARRAY);
69+
__type(key, __u32);
70+
__type(value, __u32);
71+
__uint(max_entries, 512);
72+
} syscalls_sys_exit SEC(".maps");
5073

5174
struct syscall_enter_args {
5275
unsigned long long common_tp_fields;
@@ -66,7 +89,38 @@ struct augmented_arg {
6689
char value[PATH_MAX];
6790
};
6891

69-
pid_filter(pids_filtered);
92+
struct pids_filtered {
93+
__uint(type, BPF_MAP_TYPE_HASH);
94+
__type(key, pid_t);
95+
__type(value, bool);
96+
__uint(max_entries, 64);
97+
} pids_filtered SEC(".maps");
98+
99+
/*
100+
* Desired design of maximum size and alignment (see RFC2553)
101+
*/
102+
#define SS_MAXSIZE 128 /* Implementation specific max size */
103+
104+
typedef unsigned short sa_family_t;
105+
106+
/*
107+
* FIXME: Should come from system headers
108+
*
109+
* The definition uses anonymous union and struct in order to control the
110+
* default alignment.
111+
*/
112+
struct sockaddr_storage {
113+
union {
114+
struct {
115+
sa_family_t ss_family; /* address family */
116+
/* Following field(s) are implementation specific */
117+
char __data[SS_MAXSIZE - sizeof(unsigned short)];
118+
/* space to achieve desired size, */
119+
/* _SS_MAXSIZE value minus size of ss_family */
120+
};
121+
void *__align; /* implementation specific desired alignment */
122+
};
123+
};
70124

71125
struct augmented_args_payload {
72126
struct syscall_enter_args args;
@@ -79,7 +133,12 @@ struct augmented_args_payload {
79133
};
80134

81135
// We need more tmp space than the BPF stack can give us
82-
bpf_map(augmented_args_tmp, PERCPU_ARRAY, int, struct augmented_args_payload, 1);
136+
struct augmented_args_tmp {
137+
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
138+
__type(key, int);
139+
__type(value, struct augmented_args_payload);
140+
__uint(max_entries, 1);
141+
} augmented_args_tmp SEC(".maps");
83142

84143
static inline struct augmented_args_payload *augmented_args_payload(void)
85144
{
@@ -90,14 +149,14 @@ static inline struct augmented_args_payload *augmented_args_payload(void)
90149
static inline int augmented__output(void *ctx, struct augmented_args_payload *args, int len)
91150
{
92151
/* If perf_event_output fails, return non-zero so that it gets recorded unaugmented */
93-
return perf_event_output(ctx, &__augmented_syscalls__, BPF_F_CURRENT_CPU, args, len);
152+
return bpf_perf_event_output(ctx, &__augmented_syscalls__, BPF_F_CURRENT_CPU, args, len);
94153
}
95154

96155
static inline
97156
unsigned int augmented_arg__read_str(struct augmented_arg *augmented_arg, const void *arg, unsigned int arg_len)
98157
{
99158
unsigned int augmented_len = sizeof(*augmented_arg);
100-
int string_len = probe_read_str(&augmented_arg->value, arg_len, arg);
159+
int string_len = bpf_probe_read_str(&augmented_arg->value, arg_len, arg);
101160

102161
augmented_arg->size = augmented_arg->err = 0;
103162
/*
@@ -146,7 +205,7 @@ int sys_enter_connect(struct syscall_enter_args *args)
146205
if (socklen > sizeof(augmented_args->saddr))
147206
socklen = sizeof(augmented_args->saddr);
148207

149-
probe_read(&augmented_args->saddr, socklen, sockaddr_arg);
208+
bpf_probe_read(&augmented_args->saddr, socklen, sockaddr_arg);
150209

151210
return augmented__output(args, augmented_args, len + socklen);
152211
}
@@ -165,7 +224,7 @@ int sys_enter_sendto(struct syscall_enter_args *args)
165224
if (socklen > sizeof(augmented_args->saddr))
166225
socklen = sizeof(augmented_args->saddr);
167226

168-
probe_read(&augmented_args->saddr, socklen, sockaddr_arg);
227+
bpf_probe_read(&augmented_args->saddr, socklen, sockaddr_arg);
169228

170229
return augmented__output(args, augmented_args, len + socklen);
171230
}
@@ -234,6 +293,16 @@ int sys_enter_renameat(struct syscall_enter_args *args)
234293
return augmented__output(args, augmented_args, len);
235294
}
236295

296+
static pid_t getpid(void)
297+
{
298+
return bpf_get_current_pid_tgid();
299+
}
300+
301+
static bool pid_filter__has(struct pids_filtered *pids, pid_t pid)
302+
{
303+
return bpf_map_lookup_elem(pids, &pid) != NULL;
304+
}
305+
237306
SEC("raw_syscalls:sys_enter")
238307
int sys_enter(struct syscall_enter_args *args)
239308
{
@@ -257,7 +326,7 @@ int sys_enter(struct syscall_enter_args *args)
257326
if (augmented_args == NULL)
258327
return 1;
259328

260-
probe_read(&augmented_args->args, sizeof(augmented_args->args), args);
329+
bpf_probe_read(&augmented_args->args, sizeof(augmented_args->args), args);
261330

262331
/*
263332
* Jump to syscall specific augmenter, even if the default one,
@@ -278,7 +347,7 @@ int sys_exit(struct syscall_exit_args *args)
278347
if (pid_filter__has(&pids_filtered, getpid()))
279348
return 0;
280349

281-
probe_read(&exit_args, sizeof(exit_args), args);
350+
bpf_probe_read(&exit_args, sizeof(exit_args), args);
282351
/*
283352
* Jump to syscall specific return augmenter, even if the default one,
284353
* "!raw_syscalls:unaugmented" that will just return 1 to return the
@@ -291,4 +360,4 @@ int sys_exit(struct syscall_exit_args *args)
291360
return 0;
292361
}
293362

294-
license(GPL);
363+
char _license[] SEC("license") = "GPL";

tools/perf/util/llvm-utils.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ int llvm__compile_bpf(const char *path, void **p_obj_buf,
495495

496496
snprintf(linux_version_code_str, sizeof(linux_version_code_str),
497497
"0x%x", kernel_version);
498-
if (asprintf(&perf_bpf_include_opts, "-I%s/bpf", perf_include_dir) < 0)
498+
if (asprintf(&perf_bpf_include_opts, "-I%s/", perf_include_dir) < 0)
499499
goto errout;
500500
force_set_env("NR_CPUS", nr_cpus_avail_str);
501501
force_set_env("LINUX_VERSION_CODE", linux_version_code_str);

0 commit comments

Comments
 (0)