Hi folks, I'm the author of bpftop, a top-like monitor for bpf programs. A user reported that for the libxdp framework, only the xdp dispatcher is getting bfp stats: https://github.com/Netflix/bpftop/issues/15 The dispatcher created by libxdp declares a few global dummy functions to act as the targets where BPF_PROG_TYPE_EXT programs can be hooked via the freplace mechanism. The missing BPF_PROG_TYPE_EXT stats result from how bpf-to-bpf freplace works. The reference to the extension program is only kept in trampoline->extension_prog, making the bpf_prog in bpf_prog_run() unaware that its bpf_func was swapped. Consequently, stats are incremented only for the target program, and not the extension program. I believe users expect that stats for both target and extension programs to be incremented. In the case of libxdp, the dispatcher's stats should represent an aggregate of all programs, with each program also maintaining its independent stats. First of all, is there any objection to this proposed behavior? I thought of a few ways to accomplish this via a patch and I wanted to get some guidance on which is the correct/preferred approach: 1. Add a new `extension_prog` pointer in the bpf_prog or bpf_prog_aux structs. Then, set and clear the pointer in the same place where we set/clear trampoline->extension_prog during bpf-to-bpf attach. Finally, when we increment stats for the target prog, we check for the presence of the extension prog and increment its stats. 2. Similar to 1, but we store a pointer to the extension prog's `bpf_prog_stats` in bpf_prog. 3. Wrap the extension program's bpf_func within another function dedicated to updating stats, and utilize the address of this wrapper function in bpf_arch_text_poke. This approach is the least clear to me, and I'm uncertain about its feasibility. 4. A bigger refactor that would enable this new behavior. Thanks! - Jose