bpf: add a test case for helper bpf_perf_event_read_value
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>
This commit is contained in:
parent
908432ca84
commit
020a32d958
4 changed files with 43 additions and 2 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue