From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751916AbcBLQMZ (ORCPT ); Fri, 12 Feb 2016 11:12:25 -0500 Received: from mga11.intel.com ([192.55.52.93]:61916 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751414AbcBLQMW (ORCPT ); Fri, 12 Feb 2016 11:12:22 -0500 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,436,1449561600"; d="scan'208";a="910816686" From: Tom Zanussi To: ast@plumgrid.com, rostedt@goodmis.org Cc: masami.hiramatsu.pt@hitachi.com, namhyung@kernel.org, peterz@infradead.org, linux-kernel@vger.kernel.org, Tom Zanussi Subject: [RFC][PATCH 09/10] samples/bpf: Add readcounts-by-pid example Date: Fri, 12 Feb 2016 10:11:27 -0600 Message-Id: <069d75bc6d81114d1c983d63ea495d9364ca6530.1455291671.git.tom.zanussi@linux.intel.com> X-Mailer: git-send-email 1.9.3 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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 +#include +#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 +#include +#include +#include +#include +#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