Skip to content

Commit

Permalink
Merge branch 'convert-tests-to-libbpf'
Browse files Browse the repository at this point in the history
Andrii Nakryiko says:

====================
There were few more tests and samples that were using custom perf buffer setup
code from trace_helpers.h. This patch set gets rid of all the usages of those
and removes helpers themselves. Libbpf provides nicer, but equally powerful
set of APIs to work with perf ring buffers, so let's have all the samples use

v1->v2:
- make logging message one long line instead of two (Song).
====================

Signed-off-by: Alexei Starovoitov <ast@kernel.org>
  • Loading branch information
Alexei Starovoitov committed Jul 23, 2019
2 parents f2a3e4e + 47da6e4 commit 5e31d50
Show file tree
Hide file tree
Showing 7 changed files with 111 additions and 297 deletions.
43 changes: 14 additions & 29 deletions samples/bpf/trace_output_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
#include <libbpf.h>
#include "bpf_load.h"
#include "perf-sys.h"
#include "trace_helpers.h"

static int pmu_fd;

static __u64 time_get_ns(void)
{
Expand All @@ -31,12 +28,12 @@ static __u64 time_get_ns(void)
}

static __u64 start_time;
static __u64 cnt;

#define MAX_CNT 100000ll

static int print_bpf_output(void *data, int size)
static void print_bpf_output(void *ctx, int cpu, void *data, __u32 size)
{
static __u64 cnt;
struct {
__u64 pid;
__u64 cookie;
Expand All @@ -45,38 +42,22 @@ static int print_bpf_output(void *data, int size)
if (e->cookie != 0x12345678) {
printf("BUG pid %llx cookie %llx sized %d\n",
e->pid, e->cookie, size);
return LIBBPF_PERF_EVENT_ERROR;
return;
}

cnt++;

if (cnt == MAX_CNT) {
printf("recv %lld events per sec\n",
MAX_CNT * 1000000000ll / (time_get_ns() - start_time));
return LIBBPF_PERF_EVENT_DONE;
return;
}

return LIBBPF_PERF_EVENT_CONT;
}

static void test_bpf_perf_event(void)
{
struct perf_event_attr attr = {
.sample_type = PERF_SAMPLE_RAW,
.type = PERF_TYPE_SOFTWARE,
.config = PERF_COUNT_SW_BPF_OUTPUT,
};
int key = 0;

pmu_fd = sys_perf_event_open(&attr, -1/*pid*/, 0/*cpu*/, -1/*group_fd*/, 0);

assert(pmu_fd >= 0);
assert(bpf_map_update_elem(map_fd[0], &key, &pmu_fd, BPF_ANY) == 0);
ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0);
}

int main(int argc, char **argv)
{
struct perf_buffer_opts pb_opts = {};
struct perf_buffer *pb;
char filename[256];
FILE *f;
int ret;
Expand All @@ -88,16 +69,20 @@ int main(int argc, char **argv)
return 1;
}

test_bpf_perf_event();

if (perf_event_mmap(pmu_fd) < 0)
pb_opts.sample_cb = print_bpf_output;
pb = perf_buffer__new(map_fd[0], 8, &pb_opts);
ret = libbpf_get_error(pb);
if (ret) {
printf("failed to setup perf_buffer: %d\n", ret);
return 1;
}

f = popen("taskset 1 dd if=/dev/zero of=/dev/null", "r");
(void) f;

start_time = time_get_ns();
ret = perf_event_poller(pmu_fd, print_bpf_output);
while ((ret = perf_buffer__poll(pb, 1000)) >= 0 && cnt < MAX_CNT) {
}
kill(0, SIGINT);
return ret;
}
61 changes: 17 additions & 44 deletions samples/bpf/xdp_sample_pkts_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,13 @@
#include <linux/if_link.h>

#include "perf-sys.h"
#include "trace_helpers.h"

#define MAX_CPUS 128
static int pmu_fds[MAX_CPUS], if_idx;
static struct perf_event_mmap_page *headers[MAX_CPUS];
static int if_idx;
static char *if_name;
static __u32 xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST;
static __u32 prog_id;
static struct perf_buffer *pb = NULL;

static int do_attach(int idx, int fd, const char *name)
{
Expand Down Expand Up @@ -73,7 +72,7 @@ static int do_detach(int idx, const char *name)

#define SAMPLE_SIZE 64

static int print_bpf_output(void *data, int size)
static void print_bpf_output(void *ctx, int cpu, void *data, __u32 size)
{
struct {
__u16 cookie;
Expand All @@ -83,45 +82,20 @@ static int print_bpf_output(void *data, int size)
int i;

if (e->cookie != 0xdead) {
printf("BUG cookie %x sized %d\n",
e->cookie, size);
return LIBBPF_PERF_EVENT_ERROR;
printf("BUG cookie %x sized %d\n", e->cookie, size);
return;
}

printf("Pkt len: %-5d bytes. Ethernet hdr: ", e->pkt_len);
for (i = 0; i < 14 && i < e->pkt_len; i++)
printf("%02x ", e->pkt_data[i]);
printf("\n");

return LIBBPF_PERF_EVENT_CONT;
}

static void test_bpf_perf_event(int map_fd, int num)
{
struct perf_event_attr attr = {
.sample_type = PERF_SAMPLE_RAW,
.type = PERF_TYPE_SOFTWARE,
.config = PERF_COUNT_SW_BPF_OUTPUT,
.wakeup_events = 1, /* get an fd notification for every event */
};
int i;

for (i = 0; i < num; i++) {
int key = i;

pmu_fds[i] = sys_perf_event_open(&attr, -1/*pid*/, i/*cpu*/,
-1/*group_fd*/, 0);

assert(pmu_fds[i] >= 0);
assert(bpf_map_update_elem(map_fd, &key,
&pmu_fds[i], BPF_ANY) == 0);
ioctl(pmu_fds[i], PERF_EVENT_IOC_ENABLE, 0);
}
}

static void sig_handler(int signo)
{
do_detach(if_idx, if_name);
perf_buffer__free(pb);
exit(0);
}

Expand All @@ -140,13 +114,13 @@ int main(int argc, char **argv)
struct bpf_prog_load_attr prog_load_attr = {
.prog_type = BPF_PROG_TYPE_XDP,
};
struct perf_buffer_opts pb_opts = {};
const char *optstr = "F";
int prog_fd, map_fd, opt;
struct bpf_object *obj;
struct bpf_map *map;
char filename[256];
int ret, err, i;
int numcpus;
int ret, err;

while ((opt = getopt(argc, argv, optstr)) != -1) {
switch (opt) {
Expand All @@ -169,10 +143,6 @@ int main(int argc, char **argv)
return 1;
}

numcpus = get_nprocs();
if (numcpus > MAX_CPUS)
numcpus = MAX_CPUS;

snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]);
prog_load_attr.file = filename;

Expand Down Expand Up @@ -211,14 +181,17 @@ int main(int argc, char **argv)
return 1;
}

test_bpf_perf_event(map_fd, numcpus);
pb_opts.sample_cb = print_bpf_output;
pb = perf_buffer__new(map_fd, 8, &pb_opts);
err = libbpf_get_error(pb);
if (err) {
perror("perf_buffer setup failed");
return 1;
}

for (i = 0; i < numcpus; i++)
if (perf_event_mmap_header(pmu_fds[i], &headers[i]) < 0)
return 1;
while ((ret = perf_buffer__poll(pb, 1000)) >= 0) {
}

ret = perf_event_poller_multi(pmu_fds, headers, numcpus,
print_bpf_output);
kill(0, SIGINT);
return ret;
}
78 changes: 43 additions & 35 deletions tools/testing/selftests/bpf/prog_tests/get_stack_raw_tp.c
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
// SPDX-License-Identifier: GPL-2.0
#define _GNU_SOURCE
#include <pthread.h>
#include <sched.h>
#include <sys/socket.h>
#include <test_progs.h>

#define MAX_CNT_RAWTP 10ull
#define MAX_STACK_RAWTP 100

static int duration = 0;

struct get_stack_trace_t {
int pid;
int kern_stack_size;
Expand All @@ -13,7 +20,7 @@ struct get_stack_trace_t {
struct bpf_stack_build_id user_stack_buildid[MAX_STACK_RAWTP];
};

static int get_stack_print_output(void *data, int size)
static void get_stack_print_output(void *ctx, int cpu, void *data, __u32 size)
{
bool good_kern_stack = false, good_user_stack = false;
const char *nonjit_func = "___bpf_prog_run";
Expand Down Expand Up @@ -65,75 +72,76 @@ static int get_stack_print_output(void *data, int size)
if (e->user_stack_size > 0 && e->user_stack_buildid_size > 0)
good_user_stack = true;
}
if (!good_kern_stack || !good_user_stack)
return LIBBPF_PERF_EVENT_ERROR;

if (cnt == MAX_CNT_RAWTP)
return LIBBPF_PERF_EVENT_DONE;

return LIBBPF_PERF_EVENT_CONT;
if (!good_kern_stack)
CHECK(!good_kern_stack, "kern_stack", "corrupted kernel stack\n");
if (!good_user_stack)
CHECK(!good_user_stack, "user_stack", "corrupted user stack\n");
}

void test_get_stack_raw_tp(void)
{
const char *file = "./test_get_stack_rawtp.o";
int i, efd, err, prog_fd, pmu_fd, perfmap_fd;
struct perf_event_attr attr = {};
const char *prog_name = "raw_tracepoint/sys_enter";
int i, err, prog_fd, exp_cnt = MAX_CNT_RAWTP;
struct perf_buffer_opts pb_opts = {};
struct perf_buffer *pb = NULL;
struct bpf_link *link = NULL;
struct timespec tv = {0, 10};
__u32 key = 0, duration = 0;
struct bpf_program *prog;
struct bpf_object *obj;
struct bpf_map *map;
cpu_set_t cpu_set;

err = bpf_prog_load(file, BPF_PROG_TYPE_RAW_TRACEPOINT, &obj, &prog_fd);
if (CHECK(err, "prog_load raw tp", "err %d errno %d\n", err, errno))
return;

efd = bpf_raw_tracepoint_open("sys_enter", prog_fd);
if (CHECK(efd < 0, "raw_tp_open", "err %d errno %d\n", efd, errno))
prog = bpf_object__find_program_by_title(obj, prog_name);
if (CHECK(!prog, "find_probe", "prog '%s' not found\n", prog_name))
goto close_prog;

perfmap_fd = bpf_find_map(__func__, obj, "perfmap");
if (CHECK(perfmap_fd < 0, "bpf_find_map", "err %d errno %d\n",
perfmap_fd, errno))
map = bpf_object__find_map_by_name(obj, "perfmap");
if (CHECK(!map, "bpf_find_map", "not found\n"))
goto close_prog;

err = load_kallsyms();
if (CHECK(err < 0, "load_kallsyms", "err %d errno %d\n", err, errno))
goto close_prog;

attr.sample_type = PERF_SAMPLE_RAW;
attr.type = PERF_TYPE_SOFTWARE;
attr.config = PERF_COUNT_SW_BPF_OUTPUT;
pmu_fd = syscall(__NR_perf_event_open, &attr, getpid()/*pid*/, -1/*cpu*/,
-1/*group_fd*/, 0);
if (CHECK(pmu_fd < 0, "perf_event_open", "err %d errno %d\n", pmu_fd,
errno))
CPU_ZERO(&cpu_set);
CPU_SET(0, &cpu_set);
err = pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set);
if (CHECK(err, "set_affinity", "err %d, errno %d\n", err, errno))
goto close_prog;

err = bpf_map_update_elem(perfmap_fd, &key, &pmu_fd, BPF_ANY);
if (CHECK(err < 0, "bpf_map_update_elem", "err %d errno %d\n", err,
errno))
link = bpf_program__attach_raw_tracepoint(prog, "sys_enter");
if (CHECK(IS_ERR(link), "attach_raw_tp", "err %ld\n", PTR_ERR(link)))
goto close_prog;

err = ioctl(pmu_fd, PERF_EVENT_IOC_ENABLE, 0);
if (CHECK(err < 0, "ioctl PERF_EVENT_IOC_ENABLE", "err %d errno %d\n",
err, errno))
goto close_prog;

err = perf_event_mmap(pmu_fd);
if (CHECK(err < 0, "perf_event_mmap", "err %d errno %d\n", err, errno))
pb_opts.sample_cb = get_stack_print_output;
pb = perf_buffer__new(bpf_map__fd(map), 8, &pb_opts);
if (CHECK(IS_ERR(pb), "perf_buf__new", "err %ld\n", PTR_ERR(pb)))
goto close_prog;

/* trigger some syscall action */
for (i = 0; i < MAX_CNT_RAWTP; i++)
nanosleep(&tv, NULL);

err = perf_event_poller(pmu_fd, get_stack_print_output);
if (CHECK(err < 0, "perf_event_poller", "err %d errno %d\n", err, errno))
goto close_prog;
while (exp_cnt > 0) {
err = perf_buffer__poll(pb, 100);
if (err < 0 && CHECK(err < 0, "pb__poll", "err %d\n", err))
goto close_prog;
exp_cnt -= err;
}

goto close_prog_noerr;
close_prog:
error_cnt++;
close_prog_noerr:
if (!IS_ERR_OR_NULL(link))
bpf_link__destroy(link);
if (!IS_ERR_OR_NULL(pb))
perf_buffer__free(pb);
bpf_object__close(obj);
}
2 changes: 1 addition & 1 deletion tools/testing/selftests/bpf/progs/test_get_stack_rawtp.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ struct {
__type(value, raw_stack_trace_t);
} rawdata_map SEC(".maps");

SEC("tracepoint/raw_syscalls/sys_enter")
SEC("raw_tracepoint/sys_enter")
int bpf_prog1(void *ctx)
{
int max_len, max_buildid_len, usize, ksize, total_size;
Expand Down
Loading

0 comments on commit 5e31d50

Please sign in to comment.