All of lore.kernel.org
 help / color / mirror / Atom feed
* [net-next PATCH 0/3] Improve xdp_monitor samples/bpf
@ 2017-10-06  8:41 Jesper Dangaard Brouer
  2017-10-06  8:41 ` [net-next PATCH 1/3] samples/bpf: xdp_monitor first 8 bytes are not accessible by bpf Jesper Dangaard Brouer
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Jesper Dangaard Brouer @ 2017-10-06  8:41 UTC (permalink / raw)
  To: netdev, Andy Gospodarek
  Cc: Daniel Borkmann, Alexei Starovoitov, Jesper Dangaard Brouer

Here are some improvements to the xdp_monitor tool currently located
under samples/bpf/.  Once the tools library libbpf become more feature
complete, xdp_monitor should be converted to use it, and be moved into
tools/bpf/xdp/ or tools/xdp/.

---

Jesper Dangaard Brouer (3):
      samples/bpf: xdp_monitor first 8 bytes are not accessible by bpf
      samples/bpf: xdp_monitor also record xdp_exception tracepoint
      samples/bpf: xdp_monitor increase memory rlimit


 samples/bpf/xdp_monitor_kern.c |   60 +++++++++++++++-----
 samples/bpf/xdp_monitor_user.c |  119 +++++++++++++++++++++++++++++++---------
 2 files changed, 139 insertions(+), 40 deletions(-)

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [net-next PATCH 1/3] samples/bpf: xdp_monitor first 8 bytes are not accessible by bpf
  2017-10-06  8:41 [net-next PATCH 0/3] Improve xdp_monitor samples/bpf Jesper Dangaard Brouer
@ 2017-10-06  8:41 ` Jesper Dangaard Brouer
  2017-10-06 16:13   ` Alexei Starovoitov
  2017-10-06  8:41 ` [net-next PATCH 2/3] samples/bpf: xdp_monitor also record xdp_exception tracepoint Jesper Dangaard Brouer
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 6+ messages in thread
From: Jesper Dangaard Brouer @ 2017-10-06  8:41 UTC (permalink / raw)
  To: netdev, Andy Gospodarek
  Cc: Daniel Borkmann, Alexei Starovoitov, Jesper Dangaard Brouer

The first 8 bytes of the tracepoint context struct are not accessible
by the bpf code.  This is a choice that dates back to the original
inclusion of this code.

See explaination in:
 commit 98b5c2c65c29 ("perf, bpf: allow bpf programs attach to tracepoints")

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
 samples/bpf/xdp_monitor_kern.c |   22 +++++++++-------------
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/samples/bpf/xdp_monitor_kern.c b/samples/bpf/xdp_monitor_kern.c
index 74f3fd8ed729..cc7e19d2ad76 100644
--- a/samples/bpf/xdp_monitor_kern.c
+++ b/samples/bpf/xdp_monitor_kern.c
@@ -17,19 +17,15 @@ struct bpf_map_def SEC("maps") redirect_err_cnt = {
  * Code in:                kernel/include/trace/events/xdp.h
  */
 struct xdp_redirect_ctx {
-	unsigned short common_type;	//	offset:0;  size:2; signed:0;
-	unsigned char common_flags;	//	offset:2;  size:1; signed:0;
-	unsigned char common_preempt_count;//	offset:3;  size:1; signed:0;
-	int common_pid;			//	offset:4;  size:4; signed:1;
-
-	int prog_id;			//	offset:8;  size:4; signed:1;
-	u32 act;			//	offset:12  size:4; signed:0;
-	int ifindex;			//	offset:16  size:4; signed:1;
-	int err;			//	offset:20  size:4; signed:1;
-	int to_ifindex;			//	offset:24  size:4; signed:1;
-	u32 map_id;			//	offset:28  size:4; signed:0;
-	int map_index;			//	offset:32  size:4; signed:1;
-};					//	offset:36
+	u64 __pad;		// First 8 bytes are not accessible by bpf code
+	int prog_id;		//	offset:8;  size:4; signed:1;
+	u32 act;		//	offset:12  size:4; signed:0;
+	int ifindex;		//	offset:16  size:4; signed:1;
+	int err;		//	offset:20  size:4; signed:1;
+	int to_ifindex;		//	offset:24  size:4; signed:1;
+	u32 map_id;		//	offset:28  size:4; signed:0;
+	int map_index;		//	offset:32  size:4; signed:1;
+};				//	offset:36
 
 enum {
 	XDP_REDIRECT_SUCCESS = 0,

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [net-next PATCH 2/3] samples/bpf: xdp_monitor also record xdp_exception tracepoint
  2017-10-06  8:41 [net-next PATCH 0/3] Improve xdp_monitor samples/bpf Jesper Dangaard Brouer
  2017-10-06  8:41 ` [net-next PATCH 1/3] samples/bpf: xdp_monitor first 8 bytes are not accessible by bpf Jesper Dangaard Brouer
@ 2017-10-06  8:41 ` Jesper Dangaard Brouer
  2017-10-06  8:41 ` [net-next PATCH 3/3] samples/bpf: xdp_monitor increase memory rlimit Jesper Dangaard Brouer
  2017-10-06 17:10 ` [net-next PATCH 0/3] Improve xdp_monitor samples/bpf David Miller
  3 siblings, 0 replies; 6+ messages in thread
From: Jesper Dangaard Brouer @ 2017-10-06  8:41 UTC (permalink / raw)
  To: netdev, Andy Gospodarek
  Cc: Daniel Borkmann, Alexei Starovoitov, Jesper Dangaard Brouer

Also monitor the tracepoint xdp_exception.  This tracepoint is usually
invoked by the drivers.  Programs themselves can activate this by
returning XDP_ABORTED, which will drop the packet but also trigger the
tracepoint.  This is useful for distinguishing intentional (XDP_DROP)
vs. ebpf-program error cases that cased a drop (XDP_ABORTED).

Drivers also use this tracepoint for reporting on XDP actions that are
unknown to the specific driver.  This can help the user to detect if a
driver e.g. doesn't implement XDP_REDIRECT yet.

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
 samples/bpf/xdp_monitor_kern.c |   38 ++++++++++++++
 samples/bpf/xdp_monitor_user.c |  108 +++++++++++++++++++++++++++++++---------
 2 files changed, 121 insertions(+), 25 deletions(-)

diff --git a/samples/bpf/xdp_monitor_kern.c b/samples/bpf/xdp_monitor_kern.c
index cc7e19d2ad76..2fe2f761a0d0 100644
--- a/samples/bpf/xdp_monitor_kern.c
+++ b/samples/bpf/xdp_monitor_kern.c
@@ -13,6 +13,14 @@ struct bpf_map_def SEC("maps") redirect_err_cnt = {
 	/* TODO: have entries for all possible errno's */
 };
 
+#define XDP_UNKNOWN	XDP_REDIRECT + 1
+struct bpf_map_def SEC("maps") exception_cnt = {
+	.type		= BPF_MAP_TYPE_PERCPU_ARRAY,
+	.key_size	= sizeof(u32),
+	.value_size	= sizeof(u64),
+	.max_entries	= XDP_UNKNOWN + 1,
+};
+
 /* Tracepoint format: /sys/kernel/debug/tracing/events/xdp/xdp_redirect/format
  * Code in:                kernel/include/trace/events/xdp.h
  */
@@ -44,7 +52,7 @@ int xdp_redirect_collect_stat(struct xdp_redirect_ctx *ctx)
 
 	cnt  = bpf_map_lookup_elem(&redirect_err_cnt, &key);
 	if (!cnt)
-		return 0;
+		return 1;
 	*cnt += 1;
 
 	return 0; /* Indicate event was filtered (no further processing)*/
@@ -82,3 +90,31 @@ int trace_xdp_redirect_map(struct xdp_redirect_ctx *ctx)
 {
 	return xdp_redirect_collect_stat(ctx);
 }
+
+/* Tracepoint format: /sys/kernel/debug/tracing/events/xdp/xdp_exception/format
+ * Code in:                kernel/include/trace/events/xdp.h
+ */
+struct xdp_exception_ctx {
+	u64 __pad;	// First 8 bytes are not accessible by bpf code
+	int prog_id;	//	offset:8;  size:4; signed:1;
+	u32 act;	//	offset:12; size:4; signed:0;
+	int ifindex;	//	offset:16; size:4; signed:1;
+};
+
+SEC("tracepoint/xdp/xdp_exception")
+int trace_xdp_exception(struct xdp_exception_ctx *ctx)
+{
+	u64 *cnt;;
+	u32 key;
+
+	key = ctx->act;
+	if (key > XDP_REDIRECT)
+		key = XDP_UNKNOWN;
+
+	cnt = bpf_map_lookup_elem(&exception_cnt, &key);
+	if (!cnt)
+		return 1;
+	*cnt += 1;
+
+	return 0;
+}
diff --git a/samples/bpf/xdp_monitor_user.c b/samples/bpf/xdp_monitor_user.c
index c5ab8b776973..97c3456c11b2 100644
--- a/samples/bpf/xdp_monitor_user.c
+++ b/samples/bpf/xdp_monitor_user.c
@@ -89,6 +89,23 @@ static const char *err2str(int err)
 		return redir_names[err];
 	return NULL;
 }
+/* enum xdp_action */
+#define XDP_UNKNOWN	XDP_REDIRECT + 1
+#define XDP_ACTION_MAX (XDP_UNKNOWN + 1)
+static const char *xdp_action_names[XDP_ACTION_MAX] = {
+	[XDP_ABORTED]	= "XDP_ABORTED",
+	[XDP_DROP]	= "XDP_DROP",
+	[XDP_PASS]	= "XDP_PASS",
+	[XDP_TX]	= "XDP_TX",
+	[XDP_REDIRECT]	= "XDP_REDIRECT",
+	[XDP_UNKNOWN]	= "XDP_UNKNOWN",
+};
+static const char *action2str(int action)
+{
+	if (action < XDP_ACTION_MAX)
+		return xdp_action_names[action];
+	return NULL;
+}
 
 struct record {
 	__u64 counter;
@@ -97,6 +114,7 @@ struct record {
 
 struct stats_record {
 	struct record xdp_redir[REDIR_RES_MAX];
+	struct record xdp_exception[XDP_ACTION_MAX];
 };
 
 static void stats_print_headers(bool err_only)
@@ -104,39 +122,72 @@ static void stats_print_headers(bool err_only)
 	if (err_only)
 		printf("\n%s\n", __doc_err_only__);
 
-	printf("%-14s %-10s %-18s %-9s\n",
-	       "XDP_REDIRECT", "pps ", "pps-human-readable", "measure-period");
+	printf("%-14s %-11s %-10s %-18s %-9s\n",
+	       "ACTION", "result", "pps ", "pps-human-readable", "measure-period");
+}
+
+static double calc_period(struct record *r, struct record *p)
+{
+	double period_ = 0;
+	__u64 period = 0;
+
+	period = r->timestamp - p->timestamp;
+	if (period > 0)
+		period_ = ((double) period / NANOSEC_PER_SEC);
+
+	return period_;
+}
+
+static double calc_pps(struct record *r, struct record *p, double period)
+{
+	__u64 packets = 0;
+	double pps = 0;
+
+	if (period > 0) {
+		packets = r->counter - p->counter;
+		pps = packets / period;
+	}
+	return pps;
 }
 
 static void stats_print(struct stats_record *rec,
 			struct stats_record *prev,
 			bool err_only)
 {
+	double period = 0, pps = 0;
+	struct record *r, *p;
 	int i = 0;
 
+	char *fmt = "%-14s %-11s %-10.0f %'-18.0f %f\n";
+
+	/* tracepoint: xdp:xdp_redirect_* */
 	if (err_only)
 		i = REDIR_ERROR;
 
 	for (; i < REDIR_RES_MAX; i++) {
-		struct record *r = &rec->xdp_redir[i];
-		struct record *p = &prev->xdp_redir[i];
-		__u64 period  = 0;
-		__u64 packets = 0;
-		double pps = 0;
-		double period_ = 0;
+		r = &rec->xdp_redir[i];
+		p = &prev->xdp_redir[i];
 
 		if (p->timestamp) {
-			packets = r->counter - p->counter;
-			period  = r->timestamp - p->timestamp;
-			if (period > 0) {
-				period_ = ((double) period / NANOSEC_PER_SEC);
-				pps = packets / period_;
-			}
+			period = calc_period(r, p);
+			pps = calc_pps(r, p, period);
 		}
+		printf(fmt, "XDP_REDIRECT", err2str(i), pps, pps, period);
+	}
 
-		printf("%-14s %-10.0f %'-18.0f %f\n",
-		       err2str(i), pps, pps, period_);
+	/* tracepoint: xdp:xdp_exception */
+	for (i = 0; i < XDP_ACTION_MAX; i++) {
+		r = &rec->xdp_exception[i];
+		p = &prev->xdp_exception[i];
+		if (p->timestamp) {
+			period = calc_period(r, p);
+			pps = calc_pps(r, p, period);
+		}
+		if (pps > 0)
+			printf(fmt, action2str(i), "Exception",
+			       pps, pps, period);
 	}
+	printf("\n");
 }
 
 static __u64 get_key32_value64_percpu(int fd, __u32 key)
@@ -160,25 +211,33 @@ static __u64 get_key32_value64_percpu(int fd, __u32 key)
 	return sum;
 }
 
-static bool stats_collect(int fd, struct stats_record *rec)
+static bool stats_collect(struct stats_record *rec)
 {
+	int fd;
 	int i;
 
 	/* TODO: Detect if someone unloaded the perf event_fd's, as
 	 * this can happen by someone running perf-record -e
 	 */
 
+	fd = map_data[0].fd; /* map0: redirect_err_cnt */
 	for (i = 0; i < REDIR_RES_MAX; i++) {
 		rec->xdp_redir[i].timestamp = gettime();
 		rec->xdp_redir[i].counter = get_key32_value64_percpu(fd, i);
 	}
+
+	fd = map_data[1].fd; /* map1: exception_cnt */
+	for (i = 0; i < XDP_ACTION_MAX; i++) {
+		rec->xdp_exception[i].timestamp = gettime();
+		rec->xdp_exception[i].counter = get_key32_value64_percpu(fd, i);
+	}
+
 	return true;
 }
 
 static void stats_poll(int interval, bool err_only)
 {
 	struct stats_record rec, prev;
-	int map_fd;
 
 	memset(&rec, 0, sizeof(rec));
 
@@ -190,16 +249,17 @@ static void stats_poll(int interval, bool err_only)
 		printf("\n%s", __doc__);
 
 	/* TODO Need more advanced stats on error types */
-	if (verbose)
-		printf(" - Stats map: %s\n", map_data[0].name);
-	map_fd = map_data[0].fd;
-
-	stats_print_headers(err_only);
+	if (verbose) {
+		printf(" - Stats map0: %s\n", map_data[0].name);
+		printf(" - Stats map1: %s\n", map_data[1].name);
+		printf("\n");
+	}
 	fflush(stdout);
 
 	while (1) {
 		memcpy(&prev, &rec, sizeof(rec));
-		stats_collect(map_fd, &rec);
+		stats_collect(&rec);
+		stats_print_headers(err_only);
 		stats_print(&rec, &prev, err_only);
 		fflush(stdout);
 		sleep(interval);

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [net-next PATCH 3/3] samples/bpf: xdp_monitor increase memory rlimit
  2017-10-06  8:41 [net-next PATCH 0/3] Improve xdp_monitor samples/bpf Jesper Dangaard Brouer
  2017-10-06  8:41 ` [net-next PATCH 1/3] samples/bpf: xdp_monitor first 8 bytes are not accessible by bpf Jesper Dangaard Brouer
  2017-10-06  8:41 ` [net-next PATCH 2/3] samples/bpf: xdp_monitor also record xdp_exception tracepoint Jesper Dangaard Brouer
@ 2017-10-06  8:41 ` Jesper Dangaard Brouer
  2017-10-06 17:10 ` [net-next PATCH 0/3] Improve xdp_monitor samples/bpf David Miller
  3 siblings, 0 replies; 6+ messages in thread
From: Jesper Dangaard Brouer @ 2017-10-06  8:41 UTC (permalink / raw)
  To: netdev, Andy Gospodarek
  Cc: Daniel Borkmann, Alexei Starovoitov, Jesper Dangaard Brouer

Other concurrent running programs, like perf or the XDP program what
needed to be monitored, might take up part of the max locked memory
limit.  Thus, the xdp_monitor tool have to set the RLIMIT_MEMLOCK to
RLIM_INFINITY, as it cannot determine a more sane limit.

Using the man exit(3) specified EXIT_FAILURE return exit code, and
correct other users too.

Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>
---
 samples/bpf/xdp_monitor_user.c |   11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/samples/bpf/xdp_monitor_user.c b/samples/bpf/xdp_monitor_user.c
index 97c3456c11b2..eaba165b3549 100644
--- a/samples/bpf/xdp_monitor_user.c
+++ b/samples/bpf/xdp_monitor_user.c
@@ -20,6 +20,7 @@ static const char *__doc_err_only__=
 #include <unistd.h>
 #include <locale.h>
 
+#include <sys/resource.h>
 #include <getopt.h>
 #include <net/if.h>
 #include <time.h>
@@ -295,6 +296,7 @@ static void print_bpf_prog_info(void)
 
 int main(int argc, char **argv)
 {
+	struct rlimit r = {RLIM_INFINITY, RLIM_INFINITY};
 	int longindex = 0, opt;
 	int ret = EXIT_SUCCESS;
 	char bpf_obj_file[256];
@@ -325,13 +327,18 @@ int main(int argc, char **argv)
 		}
 	}
 
+	if (setrlimit(RLIMIT_MEMLOCK, &r)) {
+		perror("setrlimit(RLIMIT_MEMLOCK)");
+		return EXIT_FAILURE;
+	}
+
 	if (load_bpf_file(bpf_obj_file)) {
 		printf("ERROR - bpf_log_buf: %s", bpf_log_buf);
-		return 1;
+		return EXIT_FAILURE;
 	}
 	if (!prog_fd[0]) {
 		printf("ERROR - load_bpf_file: %s\n", strerror(errno));
-		return 1;
+		return EXIT_FAILURE;
 	}
 
 	if (debug) {

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [net-next PATCH 1/3] samples/bpf: xdp_monitor first 8 bytes are not accessible by bpf
  2017-10-06  8:41 ` [net-next PATCH 1/3] samples/bpf: xdp_monitor first 8 bytes are not accessible by bpf Jesper Dangaard Brouer
@ 2017-10-06 16:13   ` Alexei Starovoitov
  0 siblings, 0 replies; 6+ messages in thread
From: Alexei Starovoitov @ 2017-10-06 16:13 UTC (permalink / raw)
  To: Jesper Dangaard Brouer; +Cc: netdev, Andy Gospodarek, Daniel Borkmann

On Fri, Oct 06, 2017 at 10:41:41AM +0200, Jesper Dangaard Brouer wrote:
> The first 8 bytes of the tracepoint context struct are not accessible
> by the bpf code.  This is a choice that dates back to the original
> inclusion of this code.
> 
> See explaination in:
>  commit 98b5c2c65c29 ("perf, bpf: allow bpf programs attach to tracepoints")
> 
> Signed-off-by: Jesper Dangaard Brouer <brouer@redhat.com>

thank you for fixing it.
Acked-by: Alexei Starovoitov <ast@kernel.org>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [net-next PATCH 0/3] Improve xdp_monitor samples/bpf
  2017-10-06  8:41 [net-next PATCH 0/3] Improve xdp_monitor samples/bpf Jesper Dangaard Brouer
                   ` (2 preceding siblings ...)
  2017-10-06  8:41 ` [net-next PATCH 3/3] samples/bpf: xdp_monitor increase memory rlimit Jesper Dangaard Brouer
@ 2017-10-06 17:10 ` David Miller
  3 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2017-10-06 17:10 UTC (permalink / raw)
  To: brouer; +Cc: netdev, andy, borkmann, alexei.starovoitov

From: Jesper Dangaard Brouer <brouer@redhat.com>
Date: Fri, 06 Oct 2017 10:41:36 +0200

> Here are some improvements to the xdp_monitor tool currently located
> under samples/bpf/.  Once the tools library libbpf become more feature
> complete, xdp_monitor should be converted to use it, and be moved into
> tools/bpf/xdp/ or tools/xdp/.

Series applied.

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2017-10-06 17:10 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-06  8:41 [net-next PATCH 0/3] Improve xdp_monitor samples/bpf Jesper Dangaard Brouer
2017-10-06  8:41 ` [net-next PATCH 1/3] samples/bpf: xdp_monitor first 8 bytes are not accessible by bpf Jesper Dangaard Brouer
2017-10-06 16:13   ` Alexei Starovoitov
2017-10-06  8:41 ` [net-next PATCH 2/3] samples/bpf: xdp_monitor also record xdp_exception tracepoint Jesper Dangaard Brouer
2017-10-06  8:41 ` [net-next PATCH 3/3] samples/bpf: xdp_monitor increase memory rlimit Jesper Dangaard Brouer
2017-10-06 17:10 ` [net-next PATCH 0/3] Improve xdp_monitor samples/bpf David Miller

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.