Skip to content

Commit

Permalink
samples/bpf: Make samples more libbpf-centric
Browse files Browse the repository at this point in the history
Switch all of the sample code to use the function names from
tools/lib/bpf so that they're consistent with that, and to declare their
own log buffers. This allow the next commit to be purely devoted to
getting rid of the duplicate library in samples/bpf.

Committer notes:

Testing it:

On a fedora rawhide container, with clang/llvm 3.9, sharing the host
linux kernel git tree:

  # make O=/tmp/build/linux/ headers_install
  # make O=/tmp/build/linux -C samples/bpf/

Since I forgot to make it privileged, just tested it outside the
container, using what it generated:

  # uname -a
  Linux jouet 4.9.0-rc8+ #1 SMP Mon Dec 12 11:20:49 BRT 2016 x86_64 x86_64 x86_64 GNU/Linux
  # cd /var/lib/docker/devicemapper/mnt/c43e09a53ff56c86a07baf79847f00e2cc2a17a1e2220e1adbf8cbc62734feda/rootfs/tmp/build/linux/samples/bpf/
  # ls -la offwaketime
  -rwxr-xr-x. 1 root root 24200 Dec 15 12:19 offwaketime
  # file offwaketime
  offwaketime: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=c940d3f127d5e66cdd680e42d885cb0b64f8a0e4, not stripped
  # readelf -SW offwaketime_kern.o  | grep PROGBITS
  [ 2] .text             PROGBITS        0000000000000000 000040 000000 00  AX  0   0  4
  [ 3] kprobe/try_to_wake_up PROGBITS        0000000000000000 000040 0000d8 00  AX  0   0  8
  [ 5] tracepoint/sched/sched_switch PROGBITS        0000000000000000 000118 000318 00  AX  0   0  8
  [ 7] maps              PROGBITS        0000000000000000 000430 000050 00  WA  0   0  4
  [ 8] license           PROGBITS        0000000000000000 000480 000004 00  WA  0   0  1
  [ 9] version           PROGBITS        0000000000000000 000484 000004 00  WA  0   0  4
  # ./offwaketime | head -5
  swapper/1;start_secondary;cpu_startup_entry;schedule_preempt_disabled;schedule;__schedule;-;---;; 106
  CPU 0/KVM;entry_SYSCALL_64_fastpath;sys_ioctl;do_vfs_ioctl;kvm_vcpu_ioctl;kvm_arch_vcpu_ioctl_run;kvm_vcpu_block;schedule;__schedule;-;try_to_wake_up;swake_up_locked;swake_up;apic_timer_expired;apic_timer_fn;__hrtimer_run_queues;hrtimer_interrupt;local_apic_timer_interrupt;smp_apic_timer_interrupt;__irqentry_text_start;cpuidle_enter;call_cpuidle;cpu_startup_entry;start_secondary;;swapper/3 2
  Compositor;entry_SYSCALL_64_fastpath;sys_futex;do_futex;futex_wait;futex_wait_queue_me;schedule;__schedule;-;try_to_wake_up;futex_requeue;do_futex;sys_futex;entry_SYSCALL_64_fastpath;;SoftwareVsyncTh 5
  firefox;entry_SYSCALL_64_fastpath;sys_poll;do_sys_poll;poll_schedule_timeout;schedule_hrtimeout_range;schedule_hrtimeout_range_clock;schedule;__schedule;-;try_to_wake_up;pollwake;__wake_up_common;__wake_up_sync_key;pipe_write;__vfs_write;vfs_write;sys_write;entry_SYSCALL_64_fastpath;;Timer 13
  JS Helper;entry_SYSCALL_64_fastpath;sys_futex;do_futex;futex_wait;futex_wait_queue_me;schedule;__schedule;-;try_to_wake_up;do_futex;sys_futex;entry_SYSCALL_64_fastpath;;firefox 2
  #

Signed-off-by: Joe Stringer <[email protected]>
Tested-by: Arnaldo Carvalho de Melo <[email protected]>
Cc: Alexei Starovoitov <[email protected]>
Cc: Daniel Borkmann <[email protected]>
Cc: Wang Nan <[email protected]>
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
  • Loading branch information
joestringer authored and acmel committed Dec 15, 2016
1 parent a5580c7 commit d40fc18
Show file tree
Hide file tree
Showing 30 changed files with 133 additions and 109 deletions.
17 changes: 13 additions & 4 deletions samples/bpf/bpf_load.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,33 @@
#include <poll.h>
#include <ctype.h>
#include "libbpf.h"
#include "bpf_helpers.h"
#include "bpf_load.h"

#define DEBUGFS "/sys/kernel/debug/tracing/"

static char license[128];
static int kern_version;
static bool processed_sec[128];
char bpf_log_buf[BPF_LOG_BUF_SIZE];
int map_fd[MAX_MAPS];
int prog_fd[MAX_PROGS];
int event_fd[MAX_PROGS];
int prog_cnt;
int prog_array_fd = -1;

struct bpf_map_def {
unsigned int type;
unsigned int key_size;
unsigned int value_size;
unsigned int max_entries;
unsigned int map_flags;
};

static int populate_prog_array(const char *event, int prog_fd)
{
int ind = atoi(event), err;

err = bpf_update_elem(prog_array_fd, &ind, &prog_fd, BPF_ANY);
err = bpf_map_update_elem(prog_array_fd, &ind, &prog_fd, BPF_ANY);
if (err < 0) {
printf("failed to store prog_fd in prog_array\n");
return -1;
Expand Down Expand Up @@ -87,9 +95,10 @@ static int load_and_attach(const char *event, struct bpf_insn *prog, int size)
return -1;
}

fd = bpf_prog_load(prog_type, prog, size, license, kern_version);
fd = bpf_load_program(prog_type, prog, size, license, kern_version,
bpf_log_buf, BPF_LOG_BUF_SIZE);
if (fd < 0) {
printf("bpf_prog_load() err=%d\n%s", errno, bpf_log_buf);
printf("bpf_load_program() err=%d\n%s", errno, bpf_log_buf);
return -1;
}

Expand Down
3 changes: 3 additions & 0 deletions samples/bpf/bpf_load.h
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
#ifndef __BPF_LOAD_H
#define __BPF_LOAD_H

#include "libbpf.h"

#define MAX_MAPS 32
#define MAX_PROGS 32

extern int map_fd[MAX_MAPS];
extern int prog_fd[MAX_PROGS];
extern int event_fd[MAX_PROGS];
extern char bpf_log_buf[BPF_LOG_BUF_SIZE];
extern int prog_cnt;

/* parses elf file compiled by llvm .c->.o
Expand Down
9 changes: 5 additions & 4 deletions samples/bpf/fds_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,9 @@ static int bpf_prog_create(const char *object)
assert(!load_bpf_file((char *)object));
return prog_fd[0];
} else {
return bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER,
insns, sizeof(insns), "GPL", 0);
return bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER,
insns, sizeof(insns), "GPL", 0,
bpf_log_buf, BPF_LOG_BUF_SIZE);
}
}

Expand All @@ -83,12 +84,12 @@ static int bpf_do_map(const char *file, uint32_t flags, uint32_t key,
}

if ((flags & BPF_F_KEY_VAL) == BPF_F_KEY_VAL) {
ret = bpf_update_elem(fd, &key, &value, 0);
ret = bpf_map_update_elem(fd, &key, &value, 0);
printf("bpf: fd:%d u->(%u:%u) ret:(%d,%s)\n", fd, key, value,
ret, strerror(errno));
assert(ret == 0);
} else if (flags & BPF_F_KEY) {
ret = bpf_lookup_elem(fd, &key, &value);
ret = bpf_map_lookup_elem(fd, &key, &value);
printf("bpf: fd:%d l->(%u):%u ret:(%d,%s)\n", fd, key, value,
ret, strerror(errno));
assert(ret == 0);
Expand Down
2 changes: 1 addition & 1 deletion samples/bpf/lathist_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ static void get_data(int fd)
for (c = 0; c < MAX_CPU; c++) {
for (i = 0; i < MAX_ENTRIES; i++) {
key = c * MAX_ENTRIES + i;
bpf_lookup_elem(fd, &key, &value);
bpf_map_lookup_elem(fd, &key, &value);

cpu_hist[c].data[i] = value;
if (value > cpu_hist[c].max)
Expand Down
23 changes: 11 additions & 12 deletions samples/bpf/libbpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size,
return syscall(__NR_bpf, BPF_MAP_CREATE, &attr, sizeof(attr));
}

int bpf_update_elem(int fd, void *key, void *value, unsigned long long flags)
int bpf_map_update_elem(int fd, void *key, void *value, unsigned long long flags)
{
union bpf_attr attr = {
.map_fd = fd,
Expand All @@ -44,7 +44,7 @@ int bpf_update_elem(int fd, void *key, void *value, unsigned long long flags)
return syscall(__NR_bpf, BPF_MAP_UPDATE_ELEM, &attr, sizeof(attr));
}

int bpf_lookup_elem(int fd, void *key, void *value)
int bpf_map_lookup_elem(int fd, void *key, void *value)
{
union bpf_attr attr = {
.map_fd = fd,
Expand All @@ -55,7 +55,7 @@ int bpf_lookup_elem(int fd, void *key, void *value)
return syscall(__NR_bpf, BPF_MAP_LOOKUP_ELEM, &attr, sizeof(attr));
}

int bpf_delete_elem(int fd, void *key)
int bpf_map_delete_elem(int fd, void *key)
{
union bpf_attr attr = {
.map_fd = fd,
Expand All @@ -65,7 +65,7 @@ int bpf_delete_elem(int fd, void *key)
return syscall(__NR_bpf, BPF_MAP_DELETE_ELEM, &attr, sizeof(attr));
}

int bpf_get_next_key(int fd, void *key, void *next_key)
int bpf_map_get_next_key(int fd, void *key, void *next_key)
{
union bpf_attr attr = {
.map_fd = fd,
Expand All @@ -78,19 +78,18 @@ int bpf_get_next_key(int fd, void *key, void *next_key)

#define ROUND_UP(x, n) (((x) + (n) - 1u) & ~((n) - 1u))

char bpf_log_buf[LOG_BUF_SIZE];

int bpf_prog_load(enum bpf_prog_type prog_type,
const struct bpf_insn *insns, int prog_len,
const char *license, int kern_version)
int bpf_load_program(enum bpf_prog_type prog_type,
const struct bpf_insn *insns, int prog_len,
const char *license, int kern_version,
char *log_buf, size_t log_buf_sz)
{
union bpf_attr attr = {
.prog_type = prog_type,
.insns = ptr_to_u64((void *) insns),
.insn_cnt = prog_len / sizeof(struct bpf_insn),
.license = ptr_to_u64((void *) license),
.log_buf = ptr_to_u64(bpf_log_buf),
.log_size = LOG_BUF_SIZE,
.log_buf = ptr_to_u64(log_buf),
.log_size = log_buf_sz,
.log_level = 1,
};

Expand All @@ -99,7 +98,7 @@ int bpf_prog_load(enum bpf_prog_type prog_type,
*/
attr.kern_version = kern_version;

bpf_log_buf[0] = 0;
log_buf[0] = 0;

return syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
}
Expand Down
18 changes: 9 additions & 9 deletions samples/bpf/libbpf.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,23 @@ struct bpf_insn;

int bpf_create_map(enum bpf_map_type map_type, int key_size, int value_size,
int max_entries, int map_flags);
int bpf_update_elem(int fd, void *key, void *value, unsigned long long flags);
int bpf_lookup_elem(int fd, void *key, void *value);
int bpf_delete_elem(int fd, void *key);
int bpf_get_next_key(int fd, void *key, void *next_key);
int bpf_map_update_elem(int fd, void *key, void *value, unsigned long long flags);
int bpf_map_lookup_elem(int fd, void *key, void *value);
int bpf_map_delete_elem(int fd, void *key);
int bpf_map_get_next_key(int fd, void *key, void *next_key);

int bpf_prog_load(enum bpf_prog_type prog_type,
const struct bpf_insn *insns, int insn_len,
const char *license, int kern_version);
int bpf_load_program(enum bpf_prog_type prog_type,
const struct bpf_insn *insns, int insn_len,
const char *license, int kern_version,
char *log_buf, size_t log_buf_sz);

int bpf_prog_attach(int prog_fd, int attachable_fd, enum bpf_attach_type type);
int bpf_prog_detach(int attachable_fd, enum bpf_attach_type type);

int bpf_obj_pin(int fd, const char *pathname);
int bpf_obj_get(const char *pathname);

#define LOG_BUF_SIZE (256 * 1024)
extern char bpf_log_buf[LOG_BUF_SIZE];
#define BPF_LOG_BUF_SIZE (256 * 1024)

/* ALU ops on registers, bpf_add|sub|...: dst_reg += src_reg */

Expand Down
6 changes: 4 additions & 2 deletions samples/bpf/lwt_len_hist_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
#define MAX_INDEX 64
#define MAX_STARS 38

char bpf_log_buf[BPF_LOG_BUF_SIZE];

static void stars(char *str, long val, long max, int width)
{
int i;
Expand Down Expand Up @@ -41,13 +43,13 @@ int main(int argc, char **argv)
return -1;
}

while (bpf_get_next_key(map_fd, &key, &next_key) == 0) {
while (bpf_map_get_next_key(map_fd, &key, &next_key) == 0) {
if (next_key >= MAX_INDEX) {
fprintf(stderr, "Key %lu out of bounds\n", next_key);
continue;
}

bpf_lookup_elem(map_fd, &next_key, values);
bpf_map_lookup_elem(map_fd, &next_key, values);

sum = 0;
for (i = 0; i < nr_cpus; i++)
Expand Down
8 changes: 4 additions & 4 deletions samples/bpf/offwaketime_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,14 +49,14 @@ static void print_stack(struct key_t *key, __u64 count)
int i;

printf("%s;", key->target);
if (bpf_lookup_elem(map_fd[3], &key->tret, ip) != 0) {
if (bpf_map_lookup_elem(map_fd[3], &key->tret, ip) != 0) {
printf("---;");
} else {
for (i = PERF_MAX_STACK_DEPTH - 1; i >= 0; i--)
print_ksym(ip[i]);
}
printf("-;");
if (bpf_lookup_elem(map_fd[3], &key->wret, ip) != 0) {
if (bpf_map_lookup_elem(map_fd[3], &key->wret, ip) != 0) {
printf("---;");
} else {
for (i = 0; i < PERF_MAX_STACK_DEPTH; i++)
Expand All @@ -77,8 +77,8 @@ static void print_stacks(int fd)
struct key_t key = {}, next_key;
__u64 value;

while (bpf_get_next_key(fd, &key, &next_key) == 0) {
bpf_lookup_elem(fd, &next_key, &value);
while (bpf_map_get_next_key(fd, &key, &next_key) == 0) {
bpf_map_lookup_elem(fd, &next_key, &value);
print_stack(&next_key, value);
key = next_key;
}
Expand Down
4 changes: 2 additions & 2 deletions samples/bpf/sampleip_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,8 @@ static void print_ip_map(int fd)

/* fetch IPs and counts */
key = 0, i = 0;
while (bpf_get_next_key(fd, &key, &next_key) == 0) {
bpf_lookup_elem(fd, &next_key, &value);
while (bpf_map_get_next_key(fd, &key, &next_key) == 0) {
bpf_map_lookup_elem(fd, &next_key, &value);
counts[i].ip = next_key;
counts[i++].count = value;
key = next_key;
Expand Down
12 changes: 7 additions & 5 deletions samples/bpf/sock_example.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include <stddef.h>
#include "libbpf.h"

char bpf_log_buf[BPF_LOG_BUF_SIZE];

static int test_sock(void)
{
int sock = -1, map_fd, prog_fd, i, key;
Expand Down Expand Up @@ -55,8 +57,8 @@ static int test_sock(void)
BPF_EXIT_INSN(),
};

prog_fd = bpf_prog_load(BPF_PROG_TYPE_SOCKET_FILTER, prog, sizeof(prog),
"GPL", 0);
prog_fd = bpf_load_program(BPF_PROG_TYPE_SOCKET_FILTER, prog, sizeof(prog),
"GPL", 0, bpf_log_buf, BPF_LOG_BUF_SIZE);
if (prog_fd < 0) {
printf("failed to load prog '%s'\n", strerror(errno));
goto cleanup;
Expand All @@ -72,13 +74,13 @@ static int test_sock(void)

for (i = 0; i < 10; i++) {
key = IPPROTO_TCP;
assert(bpf_lookup_elem(map_fd, &key, &tcp_cnt) == 0);
assert(bpf_map_lookup_elem(map_fd, &key, &tcp_cnt) == 0);

key = IPPROTO_UDP;
assert(bpf_lookup_elem(map_fd, &key, &udp_cnt) == 0);
assert(bpf_map_lookup_elem(map_fd, &key, &udp_cnt) == 0);

key = IPPROTO_ICMP;
assert(bpf_lookup_elem(map_fd, &key, &icmp_cnt) == 0);
assert(bpf_map_lookup_elem(map_fd, &key, &icmp_cnt) == 0);

printf("TCP %lld UDP %lld ICMP %lld packets\n",
tcp_cnt, udp_cnt, icmp_cnt);
Expand Down
6 changes: 3 additions & 3 deletions samples/bpf/sockex1_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ int main(int ac, char **argv)
int key;

key = IPPROTO_TCP;
assert(bpf_lookup_elem(map_fd[0], &key, &tcp_cnt) == 0);
assert(bpf_map_lookup_elem(map_fd[0], &key, &tcp_cnt) == 0);

key = IPPROTO_UDP;
assert(bpf_lookup_elem(map_fd[0], &key, &udp_cnt) == 0);
assert(bpf_map_lookup_elem(map_fd[0], &key, &udp_cnt) == 0);

key = IPPROTO_ICMP;
assert(bpf_lookup_elem(map_fd[0], &key, &icmp_cnt) == 0);
assert(bpf_map_lookup_elem(map_fd[0], &key, &icmp_cnt) == 0);

printf("TCP %lld UDP %lld ICMP %lld bytes\n",
tcp_cnt, udp_cnt, icmp_cnt);
Expand Down
4 changes: 2 additions & 2 deletions samples/bpf/sockex2_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ int main(int ac, char **argv)
int key = 0, next_key;
struct pair value;

while (bpf_get_next_key(map_fd[0], &key, &next_key) == 0) {
bpf_lookup_elem(map_fd[0], &next_key, &value);
while (bpf_map_get_next_key(map_fd[0], &key, &next_key) == 0) {
bpf_map_lookup_elem(map_fd[0], &next_key, &value);
printf("ip %s bytes %lld packets %lld\n",
inet_ntoa((struct in_addr){htonl(next_key)}),
value.bytes, value.packets);
Expand Down
4 changes: 2 additions & 2 deletions samples/bpf/sockex3_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ int main(int argc, char **argv)

sleep(1);
printf("IP src.port -> dst.port bytes packets\n");
while (bpf_get_next_key(map_fd[2], &key, &next_key) == 0) {
bpf_lookup_elem(map_fd[2], &next_key, &value);
while (bpf_map_get_next_key(map_fd[2], &key, &next_key) == 0) {
bpf_map_lookup_elem(map_fd[2], &next_key, &value);
printf("%s.%05d -> %s.%05d %12lld %12lld\n",
inet_ntoa((struct in_addr){htonl(next_key.src)}),
next_key.port16[0],
Expand Down
8 changes: 4 additions & 4 deletions samples/bpf/spintest_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ int main(int ac, char **argv)
for (i = 0; i < 5; i++) {
key = 0;
printf("kprobing funcs:");
while (bpf_get_next_key(map_fd[0], &key, &next_key) == 0) {
bpf_lookup_elem(map_fd[0], &next_key, &value);
while (bpf_map_get_next_key(map_fd[0], &key, &next_key) == 0) {
bpf_map_lookup_elem(map_fd[0], &next_key, &value);
assert(next_key == value);
sym = ksym_search(value);
printf(" %s", sym->name);
Expand All @@ -41,8 +41,8 @@ int main(int ac, char **argv)
if (key)
printf("\n");
key = 0;
while (bpf_get_next_key(map_fd[0], &key, &next_key) == 0)
bpf_delete_elem(map_fd[0], &next_key);
while (bpf_map_get_next_key(map_fd[0], &key, &next_key) == 0)
bpf_map_delete_elem(map_fd[0], &next_key);
sleep(1);
}

Expand Down
4 changes: 2 additions & 2 deletions samples/bpf/tc_l2_redirect_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,9 @@ int main(int argc, char **argv)
}

/* bpf_tunnel_key.remote_ipv4 expects host byte orders */
ret = bpf_update_elem(array_fd, &array_key, &ifindex, 0);
ret = bpf_map_update_elem(array_fd, &array_key, &ifindex, 0);
if (ret) {
perror("bpf_update_elem");
perror("bpf_map_update_elem");
goto out;
}

Expand Down
4 changes: 2 additions & 2 deletions samples/bpf/test_cgrp2_array_pin.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,9 @@ int main(int argc, char **argv)
}
}

ret = bpf_update_elem(array_fd, &array_key, &cg2_fd, 0);
ret = bpf_map_update_elem(array_fd, &array_key, &cg2_fd, 0);
if (ret) {
perror("bpf_update_elem");
perror("bpf_map_update_elem");
goto out;
}

Expand Down
Loading

0 comments on commit d40fc18

Please sign in to comment.