1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2020 Facebook
5 #include <bpf/bpf_helpers.h>
6 #include <bpf/bpf_tracing.h>
8 /* map of perf event fds, num_cpu * num_metric entries */
10 __uint(type
, BPF_MAP_TYPE_PERF_EVENT_ARRAY
);
11 __uint(key_size
, sizeof(u32
));
12 __uint(value_size
, sizeof(int));
13 } events
SEC(".maps");
15 /* readings at fentry */
17 __uint(type
, BPF_MAP_TYPE_PERCPU_ARRAY
);
18 __uint(key_size
, sizeof(u32
));
19 __uint(value_size
, sizeof(struct bpf_perf_event_value
));
20 } fentry_readings
SEC(".maps");
22 /* accumulated readings */
24 __uint(type
, BPF_MAP_TYPE_PERCPU_ARRAY
);
25 __uint(key_size
, sizeof(u32
));
26 __uint(value_size
, sizeof(struct bpf_perf_event_value
));
27 } accum_readings
SEC(".maps");
29 /* sample counts, one per cpu */
31 __uint(type
, BPF_MAP_TYPE_PERCPU_ARRAY
);
32 __uint(key_size
, sizeof(u32
));
33 __uint(value_size
, sizeof(u64
));
34 } counts
SEC(".maps");
36 const volatile __u32 num_cpu
= 1;
37 const volatile __u32 num_metric
= 1;
38 #define MAX_NUM_MATRICS 4
41 int BPF_PROG(fentry_XXX
)
43 struct bpf_perf_event_value
*ptrs
[MAX_NUM_MATRICS
];
44 u32 key
= bpf_get_smp_processor_id();
47 /* look up before reading, to reduce error */
48 for (i
= 0; i
< num_metric
&& i
< MAX_NUM_MATRICS
; i
++) {
51 ptrs
[i
] = bpf_map_lookup_elem(&fentry_readings
, &flag
);
56 for (i
= 0; i
< num_metric
&& i
< MAX_NUM_MATRICS
; i
++) {
57 struct bpf_perf_event_value reading
;
60 err
= bpf_perf_event_read_value(&events
, key
, &reading
,
72 fexit_update_maps(u32 id
, struct bpf_perf_event_value
*after
)
74 struct bpf_perf_event_value
*before
, diff
, *accum
;
76 before
= bpf_map_lookup_elem(&fentry_readings
, &id
);
77 /* only account samples with a valid fentry_reading */
78 if (before
&& before
->counter
) {
79 struct bpf_perf_event_value
*accum
;
81 diff
.counter
= after
->counter
- before
->counter
;
82 diff
.enabled
= after
->enabled
- before
->enabled
;
83 diff
.running
= after
->running
- before
->running
;
85 accum
= bpf_map_lookup_elem(&accum_readings
, &id
);
87 accum
->counter
+= diff
.counter
;
88 accum
->enabled
+= diff
.enabled
;
89 accum
->running
+= diff
.running
;
95 int BPF_PROG(fexit_XXX
)
97 struct bpf_perf_event_value readings
[MAX_NUM_MATRICS
];
98 u32 cpu
= bpf_get_smp_processor_id();
99 u32 i
, one
= 1, zero
= 0;
103 /* read all events before updating the maps, to reduce error */
104 for (i
= 0; i
< num_metric
&& i
< MAX_NUM_MATRICS
; i
++) {
105 err
= bpf_perf_event_read_value(&events
, cpu
+ i
* num_cpu
,
106 readings
+ i
, sizeof(*readings
));
110 count
= bpf_map_lookup_elem(&counts
, &zero
);
113 for (i
= 0; i
< num_metric
&& i
< MAX_NUM_MATRICS
; i
++)
114 fexit_update_maps(i
, &readings
[i
]);
119 char LICENSE
[] SEC("license") = "GPL";