Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752487AbcDTSGe (ORCPT ); Wed, 20 Apr 2016 14:06:34 -0400 Received: from szxga01-in.huawei.com ([58.251.152.64]:50745 "EHLO szxga01-in.huawei.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750984AbcDTSC0 (ORCPT ); Wed, 20 Apr 2016 14:02:26 -0400 From: Wang Nan To: , , CC: , , Wang Nan , Arnaldo Carvalho de Melo , "Alexei Starovoitov" , Jiri Olsa , Li Zefan Subject: [RFC PATCH 00/13] perf tools: Support uBPF script Date: Wed, 20 Apr 2016 18:01:40 +0000 Message-ID: <1461175313-38310-1-git-send-email-wangnan0@huawei.com> X-Mailer: git-send-email 1.8.3.4 MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [10.107.193.248] X-CFilter-Loop: Reflected X-Mirapoint-Virus-RAPID-Raw: score=unknown(0), refid=str=0001.0A090204.5717C421.0033,ss=1,re=0.000,recu=0.000,reip=0.000,cl=1,cld=1,fgs=0, ip=0.0.0.0, so=2013-06-18 04:22:30, dmn=2013-03-21 17:37:32 X-Mirapoint-Loop-Id: 16c732c5b76ce1e785992836fb547483 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 6762 Lines: 211 This patch set allows to perf invoke some user space BPF scripts on some point. uBPF scripts and kernel BPF scripts reside in one BPF object. They communicate with each other with BPF maps. uBPF scripts can invoke helper functions provided by perf. At least following new features can be achieved based on uBPF support: 1) Report statistical result: Like DTrace, perf print statistical report before quit. No need to extract data using 'perf report'. Statistical method is controled by user. 2) Control perf's behavior: Dynamically adjust period of different events. Policy is defined by user. uBPF library is required before compile. It can be found from github: https://github.com/iovisor/ubpf.git Following is an example: Using BPF script attached at the bottom of this commit message, one can print histogram of write size before perf exit like this: # ~/perf record -a -e ./test_ubpf.c & [1] 16800 # dd if=/dev/zero of=/dev/null bs=512 count=5000 5000+0 records in 5000+0 records out 2560000 bytes (2.6 MB) copied, 0.00552838 s, 463 MB/s # dd if=/dev/zero of=/dev/null bs=2048 count=5000 5000+0 records in 5000+0 records out 10240000 bytes (10 MB) copied, 0.0188971 s, 542 MB/s # fg ^C <--- *Press Ctrl-c* 2^^0: 47 2^^1: 13 2^^2: 4 2^^3: 130 2^^4: 11 2^^5: 1051 2^^6: 486 2^^7: 4863 2^^8: 0 2^^9: 5003 2^^10: 4 2^^11: 5003 2^^12: 1 2^^13: 0 2^^14: 0 2^^15: 0 2^^16: 0 2^^17: 0 2^^18: 0 2^^19: 0 2^^20: 0 [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.788 MB perf.data ] Here is test_ubpf.c. /************ BEGIN ***************/ #include #define SEC(NAME) __attribute__((section(NAME), used)) struct bpf_map_def { unsigned int type; unsigned int key_size; unsigned int value_size; unsigned int max_entries; }; #define BPF_ANY 0 static void *(*map_lookup_elem)(struct bpf_map_def *, void *) = (void *)BPF_FUNC_map_lookup_elem; static inline unsigned int log2(unsigned int v) { unsigned int r; unsigned int shift; r = (v > 0xFFFF) << 4; v >>= r; shift = (v > 0xFF) << 3; v >>= shift; r |= shift; shift = (v > 0xF) << 2; v >>= shift; r |= shift; shift = (v > 0x3) << 1; v >>= shift; r |= shift; r |= (v >> 1); return r; } static inline unsigned int log2l(unsigned long v) { unsigned int hi = v >> 32; if (hi) return log2(hi) + 32; else return log2(v); } struct bpf_map_def SEC("maps") my_hist_map = { .type = BPF_MAP_TYPE_ARRAY, .key_size = sizeof(int), .value_size = sizeof(long), .max_entries = 21, }; SEC("sys_write=sys_write count") int sys_write(void *ctx, int err, long write_size) { long *value; int key = 0; if (err) return 0; key = log2l(write_size); if (key > 20) key = 20; value = map_lookup_elem(&my_hist_map, &key); if (!value) return 0; __sync_fetch_and_add(value, 1); return 0; } char _license[] SEC("license") = "GPL"; u32 _version SEC("version") = LINUX_VERSION_CODE; /* Following ugly magic numbers can be find from tools/perf/util/ubpf-helpers-list.h */ static int (*ubpf_memcmp)(void *s1, void *s2, unsigned int n) = (void *)1; static void (*ubpf_memcpy)(void *d, void *s, unsigned int size) = (void *)2; static int (*ubpf_strcmp)(void *s1, void *s2) = (void *)3; static int (*ubpf_printf)(char *fmt, ...) = (void *)4; static int (*ubpf_map_lookup_elem)(void *map_desc, void *key, void *value) = (void *)5; static int (*ubpf_map_update_elem)(void *map_desc, void *key, void *value, unsigned long long flags) = (void *)6; static int (*ubpf_map_get_next_key)(void *map_desc, void *key, void *value) = (void *)7; SEC("UBPF;perf_record_end") int perf_record_end(int samples) { int i, key; long value; char fmt[] = "2^^%d: %d\n"; for (i = 0; i < 21; i++) { ubpf_map_lookup_elem(&my_hist_map, &i, &value); ubpf_printf(fmt, i, value); } return 0; } /************** END ***************/ Cc: Wang Nan Cc: Arnaldo Carvalho de Melo Cc: Alexei Starovoitov Cc: Brendan Gregg Cc: Jiri Olsa Cc: Li Zefan Wang Nan (13): bpf tools: Add map related BPF helper tools: Add ubpf feature test bpf tools: Add ubpf include and makefile options bpf tools: Replace fd array to union array bpf tools: Save engine type in bpf_program bpf tools: Introduce ubpf_vm to program instance union bpf tools: Load ubpf program bpf tools: Add API for fetching ubpf_vm bpf tools: Register extern functions for ubpf programs perf tools: Register basic UBPF helpers perf bpf: Accept ubpf programs perf record: Add UBPF hooks at beginning and end of perf record perf tests: Add UBPF test case tools/build/Makefile.feature | 6 +- tools/build/feature/Makefile | 6 +- tools/build/feature/test-ubpf.c | 11 ++ tools/lib/bpf/Makefile | 16 +- tools/lib/bpf/bpf.c | 24 +++ tools/lib/bpf/bpf.h | 2 + tools/lib/bpf/libbpf.c | 281 ++++++++++++++++++++++++++++---- tools/lib/bpf/libbpf.h | 21 ++- tools/perf/Makefile.perf | 2 + tools/perf/builtin-record.c | 4 + tools/perf/config/Makefile | 7 + tools/perf/perf.c | 3 + tools/perf/tests/Build | 8 + tools/perf/tests/bpf-script-test-ubpf.c | 68 ++++++++ tools/perf/tests/bpf.c | 77 ++++++++- tools/perf/tests/llvm.c | 4 + tools/perf/tests/llvm.h | 2 + tools/perf/util/Build | 1 + tools/perf/util/bpf-loader.c | 22 +++ tools/perf/util/ubpf-helpers-list.h | 7 + tools/perf/util/ubpf-helpers.c | 66 ++++++++ tools/perf/util/ubpf-helpers.h | 21 +++ tools/perf/util/ubpf-hooks-list.h | 10 ++ tools/perf/util/ubpf-hooks.c | 81 +++++++++ tools/perf/util/ubpf-hooks.h | 35 ++++ 25 files changed, 745 insertions(+), 40 deletions(-) create mode 100644 tools/build/feature/test-ubpf.c create mode 100644 tools/perf/tests/bpf-script-test-ubpf.c create mode 100644 tools/perf/util/ubpf-helpers-list.h create mode 100644 tools/perf/util/ubpf-helpers.c create mode 100644 tools/perf/util/ubpf-helpers.h create mode 100644 tools/perf/util/ubpf-hooks-list.h create mode 100644 tools/perf/util/ubpf-hooks.c create mode 100644 tools/perf/util/ubpf-hooks.h -- 1.8.3.4