On Fri, Dec 8, 2023 at 12:56 PM Peter Zijlstra <peterz@xxxxxxxxxxxxx> wrote: > > On Fri, Dec 08, 2023 at 12:45:51PM -0800, Alexei Starovoitov wrote: > > > I mean we don't need to store a pointer to a func in stubs. > > Can it be, roughly: > > > > extern void bpf_tcp_ca_cong_avoid(struct sock *sk, u32 ack, u32 acked); > > KCFI_MACRO(hash_of_cong_avoid, bpf_tcp_ca_cong_avoid); > > u32 __array_of_kcfi_hash[] = {hash_of_cong_avoid, hash_of_set_state,...}; > > .bpf_ops_stubs = __array_of_kcfi_hash, > > But then how do I index this array? The bpf_ops_stubs thing having the > same layout at the target struct made it easy and we could use 'moff' > for both. > > That also remains working if someone adds a member to the struct or > moves some members around. I was thinking to just moff/2 assuming u32 array will have the same order, but I missed the fact that init() and release() in tcp_congestion_ops come after some variables. And you're right it's more fragile when things change in tcp_congestion_ops. Storing u32 hash as (void *) into function pointers is just ugly. Let's go with your initial approach.