Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
[linux-2.6-microblaze.git] / samples / bpf / xdp_monitor_kern.c
index 2fe2f76..211db8d 100644 (file)
@@ -1,6 +1,7 @@
-/* XDP monitor tool, based on tracepoints
+/* SPDX-License-Identifier: GPL-2.0
+ *  Copyright(c) 2017-2018 Jesper Dangaard Brouer, Red Hat Inc.
  *
- *  Copyright(c) 2017 Jesper Dangaard Brouer, Red Hat Inc.
+ * XDP monitor tool, based on tracepoints
  */
 #include <uapi/linux/bpf.h>
 #include "bpf_helpers.h"
@@ -104,7 +105,7 @@ struct xdp_exception_ctx {
 SEC("tracepoint/xdp/xdp_exception")
 int trace_xdp_exception(struct xdp_exception_ctx *ctx)
 {
-       u64 *cnt;;
+       u64 *cnt;
        u32 key;
 
        key = ctx->act;
@@ -118,3 +119,92 @@ int trace_xdp_exception(struct xdp_exception_ctx *ctx)
 
        return 0;
 }
+
+/* Common stats data record shared with _user.c */
+struct datarec {
+       u64 processed;
+       u64 dropped;
+       u64 info;
+};
+#define MAX_CPUS 64
+
+struct bpf_map_def SEC("maps") cpumap_enqueue_cnt = {
+       .type           = BPF_MAP_TYPE_PERCPU_ARRAY,
+       .key_size       = sizeof(u32),
+       .value_size     = sizeof(struct datarec),
+       .max_entries    = MAX_CPUS,
+};
+
+struct bpf_map_def SEC("maps") cpumap_kthread_cnt = {
+       .type           = BPF_MAP_TYPE_PERCPU_ARRAY,
+       .key_size       = sizeof(u32),
+       .value_size     = sizeof(struct datarec),
+       .max_entries    = 1,
+};
+
+/* Tracepoint: /sys/kernel/debug/tracing/events/xdp/xdp_cpumap_enqueue/format
+ * Code in:         kernel/include/trace/events/xdp.h
+ */
+struct cpumap_enqueue_ctx {
+       u64 __pad;              // First 8 bytes are not accessible by bpf code
+       int map_id;             //      offset:8;  size:4; signed:1;
+       u32 act;                //      offset:12; size:4; signed:0;
+       int cpu;                //      offset:16; size:4; signed:1;
+       unsigned int drops;     //      offset:20; size:4; signed:0;
+       unsigned int processed; //      offset:24; size:4; signed:0;
+       int to_cpu;             //      offset:28; size:4; signed:1;
+};
+
+SEC("tracepoint/xdp/xdp_cpumap_enqueue")
+int trace_xdp_cpumap_enqueue(struct cpumap_enqueue_ctx *ctx)
+{
+       u32 to_cpu = ctx->to_cpu;
+       struct datarec *rec;
+
+       if (to_cpu >= MAX_CPUS)
+               return 1;
+
+       rec = bpf_map_lookup_elem(&cpumap_enqueue_cnt, &to_cpu);
+       if (!rec)
+               return 0;
+       rec->processed += ctx->processed;
+       rec->dropped   += ctx->drops;
+
+       /* Record bulk events, then userspace can calc average bulk size */
+       if (ctx->processed > 0)
+               rec->info += 1;
+
+       return 0;
+}
+
+/* Tracepoint: /sys/kernel/debug/tracing/events/xdp/xdp_cpumap_kthread/format
+ * Code in:         kernel/include/trace/events/xdp.h
+ */
+struct cpumap_kthread_ctx {
+       u64 __pad;              // First 8 bytes are not accessible by bpf code
+       int map_id;             //      offset:8;  size:4; signed:1;
+       u32 act;                //      offset:12; size:4; signed:0;
+       int cpu;                //      offset:16; size:4; signed:1;
+       unsigned int drops;     //      offset:20; size:4; signed:0;
+       unsigned int processed; //      offset:24; size:4; signed:0;
+       int sched;              //      offset:28; size:4; signed:1;
+};
+
+SEC("tracepoint/xdp/xdp_cpumap_kthread")
+int trace_xdp_cpumap_kthread(struct cpumap_kthread_ctx *ctx)
+{
+       struct datarec *rec;
+       u32 key = 0;
+
+       rec = bpf_map_lookup_elem(&cpumap_kthread_cnt, &key);
+       if (!rec)
+               return 0;
+       rec->processed += ctx->processed;
+       rec->dropped   += ctx->drops;
+
+       /* Count times kthread yielded CPU via schedule call */
+       if (ctx->sched)
+               rec->info++;
+
+       return 0;
+}