bpf: add a test case for helper bpf_perf_event_read_value
authorYonghong Song <yhs@fb.com>
Thu, 5 Oct 2017 16:19:21 +0000 (09:19 -0700)
committerDavid S. Miller <davem@davemloft.net>
Sat, 7 Oct 2017 22:05:57 +0000 (23:05 +0100)
The bpf sample program tracex6 is enhanced to use the new
helper to read enabled/running time as well.

Signed-off-by: Yonghong Song <yhs@fb.com>
Acked-by: Alexei Starovoitov <ast@fb.com>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
samples/bpf/tracex6_kern.c
samples/bpf/tracex6_user.c
tools/include/uapi/linux/bpf.h
tools/testing/selftests/bpf/bpf_helpers.h

index e7d180305974e0e581790b3134ef6d012ec6adf0..46c557afac73a62cd8a4be0bd504afa53d946270 100644 (file)
@@ -15,6 +15,12 @@ struct bpf_map_def SEC("maps") values = {
        .value_size = sizeof(u64),
        .max_entries = 64,
 };
+struct bpf_map_def SEC("maps") values2 = {
+       .type = BPF_MAP_TYPE_HASH,
+       .key_size = sizeof(int),
+       .value_size = sizeof(struct bpf_perf_event_value),
+       .max_entries = 64,
+};
 
 SEC("kprobe/htab_map_get_next_key")
 int bpf_prog1(struct pt_regs *ctx)
@@ -37,5 +43,25 @@ int bpf_prog1(struct pt_regs *ctx)
        return 0;
 }
 
+SEC("kprobe/htab_map_lookup_elem")
+int bpf_prog2(struct pt_regs *ctx)
+{
+       u32 key = bpf_get_smp_processor_id();
+       struct bpf_perf_event_value *val, buf;
+       int error;
+
+       error = bpf_perf_event_read_value(&counters, key, &buf, sizeof(buf));
+       if (error)
+               return 0;
+
+       val = bpf_map_lookup_elem(&values2, &key);
+       if (val)
+               *val = buf;
+       else
+               bpf_map_update_elem(&values2, &key, &buf, BPF_NOEXIST);
+
+       return 0;
+}
+
 char _license[] SEC("license") = "GPL";
 u32 _version SEC("version") = LINUX_VERSION_CODE;
index a05a99a0752f4f053bc8e2f570166503a494fa3b..3341a96fc046ce91f6bf6a8581e3ac60a32f64fb 100644 (file)
@@ -22,6 +22,7 @@
 
 static void check_on_cpu(int cpu, struct perf_event_attr *attr)
 {
+       struct bpf_perf_event_value value2;
        int pmu_fd, error = 0;
        cpu_set_t set;
        __u64 value;
@@ -46,8 +47,18 @@ static void check_on_cpu(int cpu, struct perf_event_attr *attr)
                fprintf(stderr, "Value missing for CPU %d\n", cpu);
                error = 1;
                goto on_exit;
+       } else {
+               fprintf(stderr, "CPU %d: %llu\n", cpu, value);
+       }
+       /* The above bpf_map_lookup_elem should trigger the second kprobe */
+       if (bpf_map_lookup_elem(map_fd[2], &cpu, &value2)) {
+               fprintf(stderr, "Value2 missing for CPU %d\n", cpu);
+               error = 1;
+               goto on_exit;
+       } else {
+               fprintf(stderr, "CPU %d: counter: %llu, enabled: %llu, running: %llu\n", cpu,
+                       value2.counter, value2.enabled, value2.running);
        }
-       fprintf(stderr, "CPU %d: %llu\n", cpu, value);
 
 on_exit:
        assert(bpf_map_delete_elem(map_fd[0], &cpu) == 0 || error);
index cb2b9f95160aa5224eccc115d0cd5002241acb37..cdf6c4f50b0f1acb91e2b913e3b596078ba6a4d0 100644 (file)
@@ -697,7 +697,8 @@ union bpf_attr {
        FN(redirect_map),               \
        FN(sk_redirect_map),            \
        FN(sock_map_update),            \
-       FN(xdp_adjust_meta),
+       FN(xdp_adjust_meta),            \
+       FN(perf_event_read_value),
 
 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
  * function eBPF program intends to call
index a56053db26f54db94af0ee71bec7cc5a16c6d77e..c15ca83dbbd922e71d8ed4231e0d7a6b8dc6ed3a 100644 (file)
@@ -72,6 +72,9 @@ static int (*bpf_sk_redirect_map)(void *map, int key, int flags) =
 static int (*bpf_sock_map_update)(void *map, void *key, void *value,
                                  unsigned long long flags) =
        (void *) BPF_FUNC_sock_map_update;
+static int (*bpf_perf_event_read_value)(void *map, unsigned long long flags,
+                                       void *buf, unsigned int buf_size) =
+       (void *) BPF_FUNC_perf_event_read_value;
 
 
 /* llvm builtin functions that eBPF C program may use to