diff options
author | Jakub Kicinski <jakub.kicinski@netronome.com> | 2018-05-10 13:24:40 -0400 |
---|---|---|
committer | Daniel Borkmann <daniel@iogearbox.net> | 2018-05-10 19:40:52 -0400 |
commit | d0cabbb021bee5c4b831a0235af9534ad07f8d3d (patch) | |
tree | 7843337206d80588110d9112d49836624b09be64 /tools/lib | |
parent | 5f9380572b4bb24f60cd492b17331db6ee34a516 (diff) |
tools: bpf: move the event reading loop to libbpf
There are two copies of event reading loop - in bpftool and
trace_helpers "library". Consolidate them and move the code
to libbpf. Return codes from trace_helpers are kept, but
renamed to include LIBBPF prefix.
Suggested-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'tools/lib')
-rw-r--r-- | tools/lib/bpf/Makefile | 2 | ||||
-rw-r--r-- | tools/lib/bpf/libbpf.c | 61 | ||||
-rw-r--r-- | tools/lib/bpf/libbpf.h | 13 |
3 files changed, 75 insertions, 1 deletions
diff --git a/tools/lib/bpf/Makefile b/tools/lib/bpf/Makefile index e6d5f8d1477f..f3fab4af4260 100644 --- a/tools/lib/bpf/Makefile +++ b/tools/lib/bpf/Makefile | |||
@@ -69,7 +69,7 @@ FEATURE_USER = .libbpf | |||
69 | FEATURE_TESTS = libelf libelf-getphdrnum libelf-mmap bpf | 69 | FEATURE_TESTS = libelf libelf-getphdrnum libelf-mmap bpf |
70 | FEATURE_DISPLAY = libelf bpf | 70 | FEATURE_DISPLAY = libelf bpf |
71 | 71 | ||
72 | INCLUDES = -I. -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(ARCH)/include/uapi -I$(srctree)/tools/include/uapi | 72 | INCLUDES = -I. -I$(srctree)/tools/include -I$(srctree)/tools/arch/$(ARCH)/include/uapi -I$(srctree)/tools/include/uapi -I$(srctree)/tools/perf |
73 | FEATURE_CHECK_CFLAGS-bpf = $(INCLUDES) | 73 | FEATURE_CHECK_CFLAGS-bpf = $(INCLUDES) |
74 | 74 | ||
75 | check_feat := 1 | 75 | check_feat := 1 |
diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c index 7bcdca13083a..ce96f1fe3f37 100644 --- a/tools/lib/bpf/libbpf.c +++ b/tools/lib/bpf/libbpf.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <unistd.h> | 31 | #include <unistd.h> |
32 | #include <fcntl.h> | 32 | #include <fcntl.h> |
33 | #include <errno.h> | 33 | #include <errno.h> |
34 | #include <perf-sys.h> | ||
34 | #include <asm/unistd.h> | 35 | #include <asm/unistd.h> |
35 | #include <linux/err.h> | 36 | #include <linux/err.h> |
36 | #include <linux/kernel.h> | 37 | #include <linux/kernel.h> |
@@ -2210,3 +2211,63 @@ int bpf_prog_load_xattr(const struct bpf_prog_load_attr *attr, | |||
2210 | *prog_fd = bpf_program__fd(first_prog); | 2211 | *prog_fd = bpf_program__fd(first_prog); |
2211 | return 0; | 2212 | return 0; |
2212 | } | 2213 | } |
2214 | |||
2215 | enum bpf_perf_event_ret | ||
2216 | bpf_perf_event_read_simple(void *mem, unsigned long size, | ||
2217 | unsigned long page_size, void **buf, size_t *buf_len, | ||
2218 | bpf_perf_event_print_t fn, void *priv) | ||
2219 | { | ||
2220 | volatile struct perf_event_mmap_page *header = mem; | ||
2221 | __u64 data_tail = header->data_tail; | ||
2222 | __u64 data_head = header->data_head; | ||
2223 | void *base, *begin, *end; | ||
2224 | int ret; | ||
2225 | |||
2226 | asm volatile("" ::: "memory"); /* in real code it should be smp_rmb() */ | ||
2227 | if (data_head == data_tail) | ||
2228 | return LIBBPF_PERF_EVENT_CONT; | ||
2229 | |||
2230 | base = ((char *)header) + page_size; | ||
2231 | |||
2232 | begin = base + data_tail % size; | ||
2233 | end = base + data_head % size; | ||
2234 | |||
2235 | while (begin != end) { | ||
2236 | struct perf_event_header *ehdr; | ||
2237 | |||
2238 | ehdr = begin; | ||
2239 | if (begin + ehdr->size > base + size) { | ||
2240 | long len = base + size - begin; | ||
2241 | |||
2242 | if (*buf_len < ehdr->size) { | ||
2243 | free(*buf); | ||
2244 | *buf = malloc(ehdr->size); | ||
2245 | if (!*buf) { | ||
2246 | ret = LIBBPF_PERF_EVENT_ERROR; | ||
2247 | break; | ||
2248 | } | ||
2249 | *buf_len = ehdr->size; | ||
2250 | } | ||
2251 | |||
2252 | memcpy(*buf, begin, len); | ||
2253 | memcpy(*buf + len, base, ehdr->size - len); | ||
2254 | ehdr = (void *)*buf; | ||
2255 | begin = base + ehdr->size - len; | ||
2256 | } else if (begin + ehdr->size == base + size) { | ||
2257 | begin = base; | ||
2258 | } else { | ||
2259 | begin += ehdr->size; | ||
2260 | } | ||
2261 | |||
2262 | ret = fn(ehdr, priv); | ||
2263 | if (ret != LIBBPF_PERF_EVENT_CONT) | ||
2264 | break; | ||
2265 | |||
2266 | data_tail += ehdr->size; | ||
2267 | } | ||
2268 | |||
2269 | __sync_synchronize(); /* smp_mb() */ | ||
2270 | header->data_tail = data_tail; | ||
2271 | |||
2272 | return ret; | ||
2273 | } | ||
diff --git a/tools/lib/bpf/libbpf.h b/tools/lib/bpf/libbpf.h index 197f9ce2248c..ce681097584e 100644 --- a/tools/lib/bpf/libbpf.h +++ b/tools/lib/bpf/libbpf.h | |||
@@ -267,4 +267,17 @@ int bpf_prog_load(const char *file, enum bpf_prog_type type, | |||
267 | struct bpf_object **pobj, int *prog_fd); | 267 | struct bpf_object **pobj, int *prog_fd); |
268 | 268 | ||
269 | int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags); | 269 | int bpf_set_link_xdp_fd(int ifindex, int fd, __u32 flags); |
270 | |||
271 | enum bpf_perf_event_ret { | ||
272 | LIBBPF_PERF_EVENT_DONE = 0, | ||
273 | LIBBPF_PERF_EVENT_ERROR = -1, | ||
274 | LIBBPF_PERF_EVENT_CONT = -2, | ||
275 | }; | ||
276 | |||
277 | typedef enum bpf_perf_event_ret (*bpf_perf_event_print_t)(void *event, | ||
278 | void *priv); | ||
279 | int bpf_perf_event_read_simple(void *mem, unsigned long size, | ||
280 | unsigned long page_size, | ||
281 | void **buf, size_t *buf_len, | ||
282 | bpf_perf_event_print_t fn, void *priv); | ||
270 | #endif | 283 | #endif |