On 8/6/19 4:42 PM, Daniel Xu wrote: > --- > tools/include/uapi/linux/perf_event.h | 23 ++++++++++ > .../selftests/bpf/prog_tests/attach_probe.c | 43 +++++++++++++++++++ Could you separate this into two patches? one patch for uapi update tools/include/uapi/linux/perf_event.h and the other for .../selftests/bpf/prog_tests/attach_probe.c The reason is to help libbpf mirror sync'ing. > 2 files changed, 66 insertions(+) > > diff --git a/tools/include/uapi/linux/perf_event.h b/tools/include/uapi/linux/perf_event.h > index 7198ddd0c6b1..4a5e18606baf 100644 > --- a/tools/include/uapi/linux/perf_event.h > +++ b/tools/include/uapi/linux/perf_event.h > @@ -447,6 +447,28 @@ struct perf_event_query_bpf { > __u32 ids[0]; > }; > > +/* > + * Structure used by below PERF_EVENT_IOC_QUERY_KPROE command > + * to query information about the kprobe attached to the perf > + * event. > + */ > +struct perf_event_query_kprobe { > + /* > + * Size of structure for forward/backward compatibility > + */ > + __u32 size; > + /* > + * Set by the kernel to indicate number of times this kprobe > + * was temporarily disabled > + */ > + __u64 nmissed; > + /* > + * Set by the kernel to indicate number of times this kprobe > + * was hit > + */ > + __u64 nhit; > +}; > + > /* > * Ioctls that can be done on a perf event fd: > */ > @@ -462,6 +484,7 @@ struct perf_event_query_bpf { > #define PERF_EVENT_IOC_PAUSE_OUTPUT _IOW('$', 9, __u32) > #define PERF_EVENT_IOC_QUERY_BPF _IOWR('$', 10, struct perf_event_query_bpf *) > #define PERF_EVENT_IOC_MODIFY_ATTRIBUTES _IOW('$', 11, struct perf_event_attr *) > +#define PERF_EVENT_IOC_QUERY_KPROBE _IOWR('$', 12, struct perf_event_query_kprobe *) > > enum perf_event_ioc_flags { > PERF_IOC_FLAG_GROUP = 1U << 0, > diff --git a/tools/testing/selftests/bpf/prog_tests/attach_probe.c b/tools/testing/selftests/bpf/prog_tests/attach_probe.c > index 5ecc267d98b0..5f118e9a1469 100644 > --- a/tools/testing/selftests/bpf/prog_tests/attach_probe.c > +++ b/tools/testing/selftests/bpf/prog_tests/attach_probe.c > @@ -38,9 +38,12 @@ void test_attach_probe(void) > struct bpf_link *kretprobe_link = NULL; > struct bpf_link *uprobe_link = NULL; > struct bpf_link *uretprobe_link = NULL; > + int kprobe_fd, kretprobe_fd; > int results_map_fd; > size_t uprobe_offset; > ssize_t base_addr; > + struct perf_event_query_kprobe kprobe_query; > + struct perf_event_query_kprobe kretprobe_query; Since you are adding new fields, could you try to maintain reverse Christmas coding style? > > base_addr = get_base_addr(); > if (CHECK(base_addr < 0, "get_base_addr", > @@ -116,6 +119,46 @@ void test_attach_probe(void) > /* trigger & validate kprobe && kretprobe */ > usleep(1); > > + kprobe_fd = bpf_link__get_perf_fd(kprobe_link); > + if (CHECK(kprobe_fd < 0, "kprobe_get_perf_fd", > + "failed to get perf fd from kprobe link\n")) > + goto cleanup; > + > + kretprobe_fd = bpf_link__get_perf_fd(kretprobe_link); > + if (CHECK(kprobe_fd < 0, "kprobe_get_perf_fd", typo: kprobe_fd => kretprobe_fd, kretprobe_get_perf_fd? > + "failed to get perf fd from kprobe link\n")) kretprobe link? > + goto cleanup; > + > + memset(&kprobe_query, 0, sizeof(kprobe_query)); > + kprobe_query.size = sizeof(kprobe_query); > + err = ioctl(kprobe_fd, PERF_EVENT_IOC_QUERY_KPROBE, &kprobe_query); > + if (CHECK(err, "get_kprobe_ioctl", > + "failed to issue kprobe query ioctl\n")) > + goto cleanup; > + if (CHECK(kprobe_query.nmissed > 0, "get_kprobe_ioctl", > + "read incorect nmissed from kprobe_ioctl: %llu\n", > + kprobe_query.nmissed)) > + goto cleanup; > + if (CHECK(kprobe_query.nhit <= 0, "get_kprobe_ioctl", nhit is __u64, it cannot be less than 0. > + "read incorect nhit from kprobe_ioctl: %llu\n", > + kprobe_query.nhit)) > + goto cleanup; > + > + memset(&kretprobe_query, 0, sizeof(kretprobe_query)); > + kretprobe_query.size = sizeof(kretprobe_query); > + err = ioctl(kretprobe_fd, PERF_EVENT_IOC_QUERY_KPROBE, &kretprobe_query); > + if (CHECK(err, "get_kretprobe_ioctl", > + "failed to issue kprobe query ioctl\n")) > + goto cleanup; > + if (CHECK(kretprobe_query.nmissed > 0, "get_kretprobe_ioctl", > + "read incorect nmissed from kretprobe_ioctl: %llu\n", > + kretprobe_query.nmissed)) > + goto cleanup; > + if (CHECK(kretprobe_query.nhit <= 0, "get_kretprobe_ioctl", <= 0 => == 0? > + "read incorect nhit from kretprobe_ioctl: %llu\n", > + kretprobe_query.nhit)) > + goto cleanup; > + > err = bpf_map_lookup_elem(results_map_fd, &kprobe_idx, &res); > if (CHECK(err, "get_kprobe_res", > "failed to get kprobe res: %d\n", err)) >