From: Dave Marchevsky Date: Tue, 11 Jan 2022 06:30:13 +0000 (-0500) Subject: Add perf_reader_consume X-Git-Tag: v0.24.0~5 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ad697c8f7da22f0dcecbc0f4d8f196a1fe709973;p=platform%2Fupstream%2Fbcc.git Add perf_reader_consume In order to read 'remainder' events from perf buffers w/ 'wakeup_events > 1', an API to force reading from a program's perf buffers regardless of whether their fds are in "ready to read" state is necessary. This commit introduces such an API, perf_reader_consume, modeled after libbpf's perf_buffer__consume. Future work will refactor bcc to use libbpf's perf buffer support as much as possible instead of duplicating functionality. For now, since #3801 was commited let's add this piece of missing functionality. --- diff --git a/src/cc/perf_reader.c b/src/cc/perf_reader.c index dedb11d2..4bcc5fed 100644 --- a/src/cc/perf_reader.c +++ b/src/cc/perf_reader.c @@ -237,6 +237,14 @@ int perf_reader_poll(int num_readers, struct perf_reader **readers, int timeout) return 0; } +int perf_reader_consume(int num_readers, struct perf_reader **readers) { + int i; + for (i = 0; i < num_readers; ++i) { + perf_reader_event_read(readers[i]); + } + return 0; +} + void perf_reader_set_fd(struct perf_reader *reader, int fd) { reader->fd = fd; } diff --git a/src/cc/perf_reader.h b/src/cc/perf_reader.h index dbe9cfb8..278b8850 100644 --- a/src/cc/perf_reader.h +++ b/src/cc/perf_reader.h @@ -32,6 +32,7 @@ void perf_reader_free(void *ptr); int perf_reader_mmap(struct perf_reader *reader); void perf_reader_event_read(struct perf_reader *reader); int perf_reader_poll(int num_readers, struct perf_reader **readers, int timeout); +int perf_reader_consume(int num_readers, struct perf_reader **readers); int perf_reader_fd(struct perf_reader *reader); void perf_reader_set_fd(struct perf_reader *reader, int fd); diff --git a/src/python/bcc/__init__.py b/src/python/bcc/__init__.py index 2ff5cf02..f1900a3f 100644 --- a/src/python/bcc/__init__.py +++ b/src/python/bcc/__init__.py @@ -1667,6 +1667,18 @@ class BPF(object): readers[i] = v lib.perf_reader_poll(len(readers), readers, timeout) + def perf_buffer_consume(self): + """perf_buffer_consume(self) + + Consume all open perf buffers, regardless of whether or not + they currently contain events data. Necessary to catch 'remainder' + events when wakeup_events > 1 is set in open_perf_buffer + """ + readers = (ct.c_void_p * len(self.perf_buffers))() + for i, v in enumerate(self.perf_buffers.values()): + readers[i] = v + lib.perf_reader_consume(len(readers), readers) + def kprobe_poll(self, timeout = -1): """kprobe_poll(self) diff --git a/src/python/bcc/libbcc.py b/src/python/bcc/libbcc.py index f9b83b3c..27076f48 100644 --- a/src/python/bcc/libbcc.py +++ b/src/python/bcc/libbcc.py @@ -147,6 +147,8 @@ lib.bpf_open_perf_event.restype = ct.c_int lib.bpf_open_perf_event.argtypes = [ct.c_uint, ct.c_ulonglong, ct.c_int, ct.c_int] lib.perf_reader_poll.restype = ct.c_int lib.perf_reader_poll.argtypes = [ct.c_int, ct.POINTER(ct.c_void_p), ct.c_int] +lib.perf_reader_consume.restype = ct.c_int +lib.perf_reader_consume.argtypes = [ct.c_int, ct.POINTER(ct.c_void_p)] lib.perf_reader_free.restype = None lib.perf_reader_free.argtypes = [ct.c_void_p] lib.perf_reader_fd.restype = int