Messages in this thread Patch in this message | | | From | Tom Zanussi <> | Subject | [RFC][PATCH 09/10] samples/bpf: Add readcounts-by-pid example | Date | Fri, 12 Feb 2016 10:11:27 -0600 |
| |
This is a simple demonstration of an eBPF program attached to static trace event ("event/subsys:event"). The count and pid values here are the values grabbed from the event hits and aggregated in a hash map.
Example output:
# ./readcounts-by-pid ^C pid 4143 comm uname count 832 hitcount 1 pid 2755 comm gdbus count 32 hitcount 2 pid 315 comm systemd-journal count 17408 hitcount 16 pid 2415 comm dbus-daemon count 8242 hitcount 5 pid 4164 comm gdbus count 288 hitcount 18 pid 4139 comm firefox count 384245 hitcount 61 pid 2660 comm gnome-shell count 42672 hitcount 117 pid 774 comm Xorg count 4621105 hitcount 1259 pid 2072 comm upowerd count 32 hitcount 2
Signed-off-by: Tom Zanussi <tom.zanussi@linux.intel.com> --- samples/bpf/Makefile | 4 +++ samples/bpf/readcounts-by-pid_kern.c | 57 +++++++++++++++++++++++++++++++ samples/bpf/readcounts-by-pid_user.c | 66 ++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 samples/bpf/readcounts-by-pid_kern.c create mode 100644 samples/bpf/readcounts-by-pid_user.c
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile index edd638b..d7af8d5 100644 --- a/samples/bpf/Makefile +++ b/samples/bpf/Makefile @@ -16,6 +16,7 @@ hostprogs-y += tracex5 hostprogs-y += tracex6 hostprogs-y += trace_output hostprogs-y += lathist +hostprogs-y += readcounts-by-pid test_verifier-objs := test_verifier.o libbpf.o test_maps-objs := test_maps.o libbpf.o @@ -32,6 +33,7 @@ tracex5-objs := bpf_load.o libbpf.o tracex5_user.o tracex6-objs := bpf_load.o libbpf.o tracex6_user.o trace_output-objs := bpf_load.o libbpf.o trace_output_user.o lathist-objs := bpf_load.o libbpf.o lathist_user.o +readcounts-by-pid-objs := bpf_load.o libbpf.o readcounts-by-pid_user.o # Tell kbuild to always build the programs always := $(hostprogs-y) @@ -47,6 +49,7 @@ always += tracex6_kern.o always += trace_output_kern.o always += tcbpf1_kern.o always += lathist_kern.o +always += readcounts-by-pid_kern.o HOSTCFLAGS += -I$(objtree)/usr/include @@ -63,6 +66,7 @@ HOSTLOADLIBES_tracex5 += -lelf HOSTLOADLIBES_tracex6 += -lelf HOSTLOADLIBES_trace_output += -lelf -lrt HOSTLOADLIBES_lathist += -lelf +HOSTLOADLIBES_readcounts-by-pid += -lelf # point this to your LLVM backend with bpf support LLC=$(srctree)/tools/bpf/llvm/bld/Debug+Asserts/bin/llc diff --git a/samples/bpf/readcounts-by-pid_kern.c b/samples/bpf/readcounts-by-pid_kern.c new file mode 100644 index 0000000..5967781 --- /dev/null +++ b/samples/bpf/readcounts-by-pid_kern.c @@ -0,0 +1,57 @@ +/* Copyright (c) 2016 Intel Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + */ + +#include <linux/version.h> +#include <uapi/linux/bpf.h> +#include "bpf_helpers.h" + +struct hist_key { + char comm[16]; + u64 pid; +}; + +struct hist_val { + u64 count; + u64 hitcount; +}; + +struct bpf_map_def SEC("maps") counts_map = { + .type = BPF_MAP_TYPE_HASH, + .key_size = sizeof(struct hist_key), + .value_size = sizeof(struct hist_val), + .max_entries = 1024, +}; + +SEC("event/syscalls:sys_enter_read") +int bpf_prog(void *ctx) +{ + struct hist_key key = {}; + struct hist_val init_val; + struct hist_val *val; + u64 count; + + char common_pid_field_name1[] = "common_pid"; + key.pid = bpf_trace_event_field_read(ctx, common_pid_field_name1); + + bpf_get_current_comm(&key.comm, sizeof(key.comm)); + + char count_field_name1[] = "count"; + count = bpf_trace_event_field_read(ctx, count_field_name1); + + val = bpf_map_lookup_elem(&counts_map, &key); + if (val) { + val->count += count; + val->hitcount += 1; + } else { + init_val.count = count; + init_val.hitcount = 1; + bpf_map_update_elem(&counts_map, &key, &init_val, BPF_ANY); + } + return 1; +} +char _license[] SEC("license") = "GPL"; +u32 _version SEC("version") = LINUX_VERSION_CODE; diff --git a/samples/bpf/readcounts-by-pid_user.c b/samples/bpf/readcounts-by-pid_user.c new file mode 100644 index 0000000..d08b867 --- /dev/null +++ b/samples/bpf/readcounts-by-pid_user.c @@ -0,0 +1,66 @@ +/* Copyright (c) 2016 Intel Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + */ + +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <signal.h> +#include <linux/bpf.h> +#include "libbpf.h" +#include "bpf_load.h" + +struct hist_key { + char comm[16]; + __u64 pid; +}; + +struct hist_val { + __u64 count; + __u64 hitcount; +}; + +static void print_hist(int fd) +{ + struct hist_key key = {}, next_key; + struct hist_val val; + + printf("\n"); + + while (bpf_get_next_key(fd, &key, &next_key) == 0) { + bpf_lookup_elem(fd, &next_key, &val); + printf("pid %8llu comm %-16s count %12llu hitcount %12llu\n", + next_key.pid, next_key.comm, val.count, val.hitcount); + key = next_key; + } +} + +static void int_exit(int sig) +{ + print_hist(map_fd[0]); + + exit(0); +} + +int main(int ac, char **argv) +{ + char filename[256]; + + snprintf(filename, sizeof(filename), "%s_kern.o", argv[0]); + + signal(SIGINT, int_exit); + + if (load_bpf_file(filename)) { + printf("%s", bpf_log_buf); + return 1; + } + + for (;;) { + sleep(60); + } + + return 0; +} -- 1.9.3
| |