1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
2 // Copyright (c) 2020 Facebook
4 #include <bpf/bpf_helpers.h>
5 #include <bpf/bpf_tracing.h>
7 /* map of perf event fds, num_cpu * num_metric entries */
9 __uint(type
, BPF_MAP_TYPE_PERF_EVENT_ARRAY
);
10 __uint(key_size
, sizeof(u32
));
11 __uint(value_size
, sizeof(int));
12 } events
SEC(".maps");
14 /* readings at fentry */
16 __uint(type
, BPF_MAP_TYPE_PERCPU_ARRAY
);
17 __uint(key_size
, sizeof(u32
));
18 __uint(value_size
, sizeof(struct bpf_perf_event_value
));
19 } fentry_readings
SEC(".maps");
21 /* accumulated readings */
23 __uint(type
, BPF_MAP_TYPE_PERCPU_ARRAY
);
24 __uint(key_size
, sizeof(u32
));
25 __uint(value_size
, sizeof(struct bpf_perf_event_value
));
26 } accum_readings
SEC(".maps");
28 /* sample counts, one per cpu */
30 __uint(type
, BPF_MAP_TYPE_PERCPU_ARRAY
);
31 __uint(key_size
, sizeof(u32
));
32 __uint(value_size
, sizeof(u64
));
33 } counts
SEC(".maps");
35 const volatile __u32 num_cpu
= 1;
36 const volatile __u32 num_metric
= 1;
37 #define MAX_NUM_MATRICS 4
40 int BPF_PROG(fentry_XXX
)
42 struct bpf_perf_event_value
*ptrs
[MAX_NUM_MATRICS
];
43 u32 key
= bpf_get_smp_processor_id();
46 /* look up before reading, to reduce error */
47 for (i
= 0; i
< num_metric
&& i
< MAX_NUM_MATRICS
; i
++) {
50 ptrs
[i
] = bpf_map_lookup_elem(&fentry_readings
, &flag
);
55 for (i
= 0; i
< num_metric
&& i
< MAX_NUM_MATRICS
; i
++) {
56 struct bpf_perf_event_value reading
;
59 err
= bpf_perf_event_read_value(&events
, key
, &reading
,
71 fexit_update_maps(u32 id
, struct bpf_perf_event_value
*after
)
73 struct bpf_perf_event_value
*before
, diff
;
75 before
= bpf_map_lookup_elem(&fentry_readings
, &id
);
76 /* only account samples with a valid fentry_reading */
77 if (before
&& before
->counter
) {
78 struct bpf_perf_event_value
*accum
;
80 diff
.counter
= after
->counter
- before
->counter
;
81 diff
.enabled
= after
->enabled
- before
->enabled
;
82 diff
.running
= after
->running
- before
->running
;
84 accum
= bpf_map_lookup_elem(&accum_readings
, &id
);
86 accum
->counter
+= diff
.counter
;
87 accum
->enabled
+= diff
.enabled
;
88 accum
->running
+= diff
.running
;
94 int BPF_PROG(fexit_XXX
)
96 struct bpf_perf_event_value readings
[MAX_NUM_MATRICS
];
97 u32 cpu
= bpf_get_smp_processor_id();
102 /* read all events before updating the maps, to reduce error */
103 for (i
= 0; i
< num_metric
&& i
< MAX_NUM_MATRICS
; i
++) {
104 err
= bpf_perf_event_read_value(&events
, cpu
+ i
* num_cpu
,
105 readings
+ i
, sizeof(*readings
));
109 count
= bpf_map_lookup_elem(&counts
, &zero
);
112 for (i
= 0; i
< num_metric
&& i
< MAX_NUM_MATRICS
; i
++)
113 fexit_update_maps(i
, &readings
[i
]);
118 char LICENSE
[] SEC("license") = "Dual BSD/GPL";