Commit e3687510 authored by Jakub Kicinski's avatar Jakub Kicinski Committed by Daniel Borkmann

tools: bpftool: use PERF_SAMPLE_TIME instead of reading the clock

Ask the kernel to include sample time in each even instead of
reading the clock.  This is also more accurate because our
clock reading was done when user space would dump the buffer,
not when sample was produced.
Suggested-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
Signed-off-by: default avatarJakub Kicinski <jakub.kicinski@netronome.com>
Reviewed-by: default avatarQuentin Monnet <quentin.monnet@netronome.com>
Signed-off-by: default avatarDaniel Borkmann <daniel@iogearbox.net>
parent cb9c28ef
...@@ -39,6 +39,7 @@ struct event_ring_info { ...@@ -39,6 +39,7 @@ struct event_ring_info {
struct perf_event_sample { struct perf_event_sample {
struct perf_event_header header; struct perf_event_header header;
u64 time;
__u32 size; __u32 size;
unsigned char data[]; unsigned char data[];
}; };
...@@ -57,17 +58,9 @@ print_bpf_output(struct event_ring_info *ring, struct perf_event_sample *e) ...@@ -57,17 +58,9 @@ print_bpf_output(struct event_ring_info *ring, struct perf_event_sample *e)
__u64 id; __u64 id;
__u64 lost; __u64 lost;
} *lost = (void *)e; } *lost = (void *)e;
struct timespec ts;
if (clock_gettime(CLOCK_MONOTONIC, &ts)) {
perror("Can't read clock for timestamp");
return;
}
if (json_output) { if (json_output) {
jsonw_start_object(json_wtr); jsonw_start_object(json_wtr);
jsonw_name(json_wtr, "timestamp");
jsonw_uint(json_wtr, ts.tv_sec * 1000000000ull + ts.tv_nsec);
jsonw_name(json_wtr, "type"); jsonw_name(json_wtr, "type");
jsonw_uint(json_wtr, e->header.type); jsonw_uint(json_wtr, e->header.type);
jsonw_name(json_wtr, "cpu"); jsonw_name(json_wtr, "cpu");
...@@ -75,6 +68,8 @@ print_bpf_output(struct event_ring_info *ring, struct perf_event_sample *e) ...@@ -75,6 +68,8 @@ print_bpf_output(struct event_ring_info *ring, struct perf_event_sample *e)
jsonw_name(json_wtr, "index"); jsonw_name(json_wtr, "index");
jsonw_uint(json_wtr, ring->key); jsonw_uint(json_wtr, ring->key);
if (e->header.type == PERF_RECORD_SAMPLE) { if (e->header.type == PERF_RECORD_SAMPLE) {
jsonw_name(json_wtr, "timestamp");
jsonw_uint(json_wtr, e->time);
jsonw_name(json_wtr, "data"); jsonw_name(json_wtr, "data");
print_data_json(e->data, e->size); print_data_json(e->data, e->size);
} else if (e->header.type == PERF_RECORD_LOST) { } else if (e->header.type == PERF_RECORD_LOST) {
...@@ -89,8 +84,8 @@ print_bpf_output(struct event_ring_info *ring, struct perf_event_sample *e) ...@@ -89,8 +84,8 @@ print_bpf_output(struct event_ring_info *ring, struct perf_event_sample *e)
jsonw_end_object(json_wtr); jsonw_end_object(json_wtr);
} else { } else {
if (e->header.type == PERF_RECORD_SAMPLE) { if (e->header.type == PERF_RECORD_SAMPLE) {
printf("== @%ld.%ld CPU: %d index: %d =====\n", printf("== @%lld.%09lld CPU: %d index: %d =====\n",
(long)ts.tv_sec, ts.tv_nsec, e->time / 1000000000ULL, e->time % 1000000000ULL,
ring->cpu, ring->key); ring->cpu, ring->key);
fprint_hex(stdout, e->data, e->size, " "); fprint_hex(stdout, e->data, e->size, " ");
printf("\n"); printf("\n");
...@@ -185,7 +180,7 @@ static void perf_event_unmap(void *mem) ...@@ -185,7 +180,7 @@ static void perf_event_unmap(void *mem)
static int bpf_perf_event_open(int map_fd, int key, int cpu) static int bpf_perf_event_open(int map_fd, int key, int cpu)
{ {
struct perf_event_attr attr = { struct perf_event_attr attr = {
.sample_type = PERF_SAMPLE_RAW, .sample_type = PERF_SAMPLE_RAW | PERF_SAMPLE_TIME,
.type = PERF_TYPE_SOFTWARE, .type = PERF_TYPE_SOFTWARE,
.config = PERF_COUNT_SW_BPF_OUTPUT, .config = PERF_COUNT_SW_BPF_OUTPUT,
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment