On Fri, Oct 11, 2019 at 6:39 PM Alexei Starovoitov <ast@xxxxxx> wrote: > > On 10/11/19 12:02 PM, Andrii Nakryiko wrote: > > On Wed, Oct 9, 2019 at 9:15 PM Alexei Starovoitov <ast@xxxxxxxxxx> wrote: > >> > >> /* type of values returned from helper functions */ > >> @@ -235,11 +236,17 @@ struct bpf_func_proto { > >> bool gpl_only; > >> bool pkt_access; > >> enum bpf_return_type ret_type; > >> - enum bpf_arg_type arg1_type; > >> - enum bpf_arg_type arg2_type; > >> - enum bpf_arg_type arg3_type; > >> - enum bpf_arg_type arg4_type; > >> - enum bpf_arg_type arg5_type; > >> + union { > >> + struct { > >> + enum bpf_arg_type arg1_type; > >> + enum bpf_arg_type arg2_type; > >> + enum bpf_arg_type arg3_type; > >> + enum bpf_arg_type arg4_type; > >> + enum bpf_arg_type arg5_type; > >> + }; > >> + enum bpf_arg_type arg_type[5]; > >> + }; > >> + u32 *btf_id; /* BTF ids of arguments */ > > > > are you trying to save memory with this? otherwise not sure why it's > > not just `u32 btf_id[5]`? Even in that case it will save at most 12 > > bytes (and I haven't even check alignment padding and stuff). So > > doesn't seem worth it? > > Glad you asked :) > It cannot be "u32 btf_id[5];". > Guess why? /data/users/andriin/linux/kernel/bpf/verifier.c: In function ‘check_helper_call’: /data/users/andriin/linux/kernel/bpf/verifier.c:4097:19: error: assignment of read-only location ‘fn->btf_id[i]’ fn->btf_id[i] = btf_resolve_helper_id(&env->log, fn->func, 0); ^ That answers it :) Yeah, indirection w/ pointer is a clever hack :) > I think it's a cool trick. > I was happy when I finally figured out to solve it this way > after analyzing a bunch of ugly solutions. > > >> + * > >> + * The value to write, of *size*, is passed through eBPF stack and > >> + * pointed by *data*. > > > > typo? pointed __to__ by *data*? > > I'm not an grammar expert. That was a copy paste from existing comment. > > >> + * > >> + * *ctx* is a pointer to in-kernel sutrct sk_buff. randomly spotted "sutrct" here :) > >> + * > >> + * This helper is similar to **bpf_perf_event_output**\ () but > >> + * restricted to raw_tracepoint bpf programs. > > > > nit: with BTF type tracking enabled? > > sure. > > >> + for (i = 0; i < 5; i++) { > >> + if (fn->arg_type[i] == ARG_PTR_TO_BTF_ID) { > >> + if (!fn->btf_id[i]) > >> + fn->btf_id[i] = btf_resolve_helper_id(&env->log, fn->func, 0); > > > > bug: 0 -> i :) > > Nice catch. > Clearly I don't have a use case yet for 2nd arg being ptr_to_btf. This actually brings an interesting question. There are a bunch of helpers that track stuff like iphdr and so on. You could use that to test, except you can't, because their args are not marked as ARG_PTR_TO_BTF_ID. But marking it as such would break usual program types that don't track BTF. I wonder if it's possible to have some arrangement, that make the same helper be, sort of "BTF-enabled" for BTF-enabled type of programs (so far just raw tracepoint with attach_btf_id set), but for other programs where BTF types are not tracked it still allows normal semantics. Thoughts?