diff mbox series

[bpf-next,v2,1/2] trace_helpers.c: Add helpers to poll multiple perf FDs for events

Message ID 152813003609.3465.618891361534945522.stgit@alrua-kau
State Changes Requested, archived
Delegated to: BPF Maintainers
Headers show
Series [bpf-next,v2,1/2] trace_helpers.c: Add helpers to poll multiple perf FDs for events | expand

Commit Message

Toke Høiland-Jørgensen June 4, 2018, 4:33 p.m. UTC
This adds two new helper functions to trace_helpers that supports polling
multiple perf file descriptors for events. These are used to the XDP
perf_event_output example, which needs to work with one perf fd per CPU.

Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
---
 tools/testing/selftests/bpf/trace_helpers.c |   47 ++++++++++++++++++++++++++-
 tools/testing/selftests/bpf/trace_helpers.h |    4 ++
 2 files changed, 49 insertions(+), 2 deletions(-)

Comments

Jakub Kicinski June 4, 2018, 10:26 p.m. UTC | #1
On Mon, 04 Jun 2018 18:33:56 +0200, Toke Høiland-Jørgensen wrote:
> This adds two new helper functions to trace_helpers that supports polling
> multiple perf file descriptors for events. These are used to the XDP
> perf_event_output example, which needs to work with one perf fd per CPU.
> 
> Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>

Did you take a look at tools/bpf/bpftool/map_perf_ring.c ?

I think the ability to poll multiple FDs could be generally useful and
therefore better add it to libbpf.c than
tools/testing/selftests/bpf/trace_helpers.c?  I'm not 100% sure myself...
Daniel Borkmann June 4, 2018, 11:42 p.m. UTC | #2
On 06/05/2018 12:26 AM, Jakub Kicinski wrote:
> On Mon, 04 Jun 2018 18:33:56 +0200, Toke Høiland-Jørgensen wrote:
>> This adds two new helper functions to trace_helpers that supports polling
>> multiple perf file descriptors for events. These are used to the XDP
>> perf_event_output example, which needs to work with one perf fd per CPU.
>>
>> Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
> 
> Did you take a look at tools/bpf/bpftool/map_perf_ring.c ?
> 
> I think the ability to poll multiple FDs could be generally useful and
> therefore better add it to libbpf.c than
> tools/testing/selftests/bpf/trace_helpers.c?  I'm not 100% sure myself...

I think for it to land in libbpf this code needs to be more generalized
as it is right now and allowing for more flexibility like pinning RB
processing threads to CPUs, poll handling, etc.
Toke Høiland-Jørgensen June 5, 2018, 9:22 a.m. UTC | #3
Daniel Borkmann <daniel@iogearbox.net> writes:

> On 06/05/2018 12:26 AM, Jakub Kicinski wrote:
>> On Mon, 04 Jun 2018 18:33:56 +0200, Toke Høiland-Jørgensen wrote:
>>> This adds two new helper functions to trace_helpers that supports polling
>>> multiple perf file descriptors for events. These are used to the XDP
>>> perf_event_output example, which needs to work with one perf fd per CPU.
>>>
>>> Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
>> 
>> Did you take a look at tools/bpf/bpftool/map_perf_ring.c ?
>> 
>> I think the ability to poll multiple FDs could be generally useful and
>> therefore better add it to libbpf.c than
>> tools/testing/selftests/bpf/trace_helpers.c?  I'm not 100% sure myself...
>
> I think for it to land in libbpf this code needs to be more generalized
> as it is right now and allowing for more flexibility like pinning RB
> processing threads to CPUs, poll handling, etc.

Hmm, so how about we leave it in trace_helpers.c for now? I don't
necessarily mind working on an addition to libbpf at some point, but
don't have time to do so short term...
Daniel Borkmann June 5, 2018, 9:27 a.m. UTC | #4
On 06/05/2018 11:22 AM, Toke Høiland-Jørgensen wrote:
> Daniel Borkmann <daniel@iogearbox.net> writes:
>> On 06/05/2018 12:26 AM, Jakub Kicinski wrote:
>>> On Mon, 04 Jun 2018 18:33:56 +0200, Toke Høiland-Jørgensen wrote:
>>>> This adds two new helper functions to trace_helpers that supports polling
>>>> multiple perf file descriptors for events. These are used to the XDP
>>>> perf_event_output example, which needs to work with one perf fd per CPU.
>>>>
>>>> Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
>>>
>>> Did you take a look at tools/bpf/bpftool/map_perf_ring.c ?
>>>
>>> I think the ability to poll multiple FDs could be generally useful and
>>> therefore better add it to libbpf.c than
>>> tools/testing/selftests/bpf/trace_helpers.c?  I'm not 100% sure myself...
>>
>> I think for it to land in libbpf this code needs to be more generalized
>> as it is right now and allowing for more flexibility like pinning RB
>> processing threads to CPUs, poll handling, etc.
> 
> Hmm, so how about we leave it in trace_helpers.c for now? I don't
> necessarily mind working on an addition to libbpf at some point, but
> don't have time to do so short term...

That's okay with me as well.
diff mbox series

Patch

diff --git a/tools/testing/selftests/bpf/trace_helpers.c b/tools/testing/selftests/bpf/trace_helpers.c
index 3868dcb63420..1e62d89f34cf 100644
--- a/tools/testing/selftests/bpf/trace_helpers.c
+++ b/tools/testing/selftests/bpf/trace_helpers.c
@@ -88,7 +88,7 @@  static int page_size;
 static int page_cnt = 8;
 static struct perf_event_mmap_page *header;
 
-int perf_event_mmap(int fd)
+int perf_event_mmap_header(int fd, struct perf_event_mmap_page **header)
 {
 	void *base;
 	int mmap_size;
@@ -102,10 +102,15 @@  int perf_event_mmap(int fd)
 		return -1;
 	}
 
-	header = base;
+	*header = base;
 	return 0;
 }
 
+int perf_event_mmap(int fd)
+{
+	return perf_event_mmap_header(fd, &header);
+}
+
 static int perf_event_poll(int fd)
 {
 	struct pollfd pfd = { .fd = fd, .events = POLLIN };
@@ -163,3 +168,41 @@  int perf_event_poller(int fd, perf_event_print_fn output_fn)
 
 	return ret;
 }
+
+int perf_event_poller_multi(int *fds, struct perf_event_mmap_page **headers,
+			    int num_fds, perf_event_print_fn output_fn)
+{
+	enum bpf_perf_event_ret ret;
+	struct pollfd *pfds;
+	void *buf = NULL;
+	size_t len = 0;
+	int i;
+
+	pfds = malloc(sizeof(*pfds) * num_fds);
+	if (!pfds)
+		return -1;
+
+	memset(pfds, 0, sizeof(*pfds) * num_fds);
+	for (i = 0; i < num_fds; i++) {
+		pfds[i].fd = fds[i];
+		pfds[i].events = POLLIN;
+	}
+
+	for (;;) {
+		poll(pfds, num_fds, 1000);
+		for (i = 0; i < num_fds; i++) {
+			if (pfds[i].revents) {
+				ret = bpf_perf_event_read_simple(headers[i], page_cnt * page_size,
+								page_size, &buf, &len,
+								bpf_perf_event_print,
+								output_fn);
+				if (ret != LIBBPF_PERF_EVENT_CONT)
+					break;
+			}
+		}
+	}
+	free(buf);
+	free(pfds);
+
+	return ret;
+}
diff --git a/tools/testing/selftests/bpf/trace_helpers.h b/tools/testing/selftests/bpf/trace_helpers.h
index 3b4bcf7f5084..18924f23db1b 100644
--- a/tools/testing/selftests/bpf/trace_helpers.h
+++ b/tools/testing/selftests/bpf/trace_helpers.h
@@ -3,6 +3,7 @@ 
 #define __TRACE_HELPER_H
 
 #include <libbpf.h>
+#include <linux/perf_event.h>
 
 struct ksym {
 	long addr;
@@ -16,6 +17,9 @@  long ksym_get_addr(const char *name);
 typedef enum bpf_perf_event_ret (*perf_event_print_fn)(void *data, int size);
 
 int perf_event_mmap(int fd);
+int perf_event_mmap_header(int fd, struct perf_event_mmap_page **header);
 /* return LIBBPF_PERF_EVENT_DONE or LIBBPF_PERF_EVENT_ERROR */
 int perf_event_poller(int fd, perf_event_print_fn output_fn);
+int perf_event_poller_multi(int *fds, struct perf_event_mmap_page **headers,
+			    int num_fds, perf_event_print_fn output_fn);
 #endif