From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx0b-00082601.pphosted.com ([67.231.153.30]:56282 "EHLO mx0a-00082601.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751870AbeCVPnC (ORCPT ); Thu, 22 Mar 2018 11:43:02 -0400 Subject: Re: [PATCH v2 bpf-next 5/8] bpf: introduce BPF_RAW_TRACEPOINT To: Daniel Borkmann , References: <20180321185448.2806324-1-ast@fb.com> <20180321185448.2806324-6-ast@fb.com> <580e6dcd-7deb-9fe2-5e37-6ce9ad0593a4@iogearbox.net> CC: , , , , , From: Alexei Starovoitov Message-ID: <79700812-58e2-2534-081e-015db6630155@fb.com> Date: Thu, 22 Mar 2018 08:41:55 -0700 MIME-Version: 1.0 In-Reply-To: <580e6dcd-7deb-9fe2-5e37-6ce9ad0593a4@iogearbox.net> Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: 7bit Sender: netdev-owner@vger.kernel.org List-ID: On 3/22/18 2:43 AM, Daniel Borkmann wrote: > On 03/21/2018 07:54 PM, Alexei Starovoitov wrote: > [...] >> @@ -546,6 +556,53 @@ extern void ftrace_profile_free_filter(struct perf_event *event); >> void perf_trace_buf_update(void *record, u16 type); >> void *perf_trace_buf_alloc(int size, struct pt_regs **regs, int *rctxp); >> >> +void bpf_trace_run1(struct bpf_prog *prog, u64 arg1); >> +void bpf_trace_run2(struct bpf_prog *prog, u64 arg1, u64 arg2); >> +void bpf_trace_run3(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3); >> +void bpf_trace_run4(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4); >> +void bpf_trace_run5(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5); >> +void bpf_trace_run6(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6); >> +void bpf_trace_run7(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7); >> +void bpf_trace_run8(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, >> + u64 arg8); >> +void bpf_trace_run9(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, >> + u64 arg8, u64 arg9); >> +void bpf_trace_run10(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, >> + u64 arg8, u64 arg9, u64 arg10); >> +void bpf_trace_run11(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, >> + u64 arg8, u64 arg9, u64 arg10, u64 arg11); >> +void bpf_trace_run12(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, >> + u64 arg8, u64 arg9, u64 arg10, u64 arg11, u64 arg12); >> +void bpf_trace_run13(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, >> + u64 arg8, u64 arg9, u64 arg10, u64 arg11, u64 arg12, >> + u64 arg13); >> +void bpf_trace_run14(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, >> + u64 arg8, u64 arg9, u64 arg10, u64 arg11, u64 arg12, >> + u64 arg13, u64 arg14); >> +void bpf_trace_run15(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, >> + u64 arg8, u64 arg9, u64 arg10, u64 arg11, u64 arg12, >> + u64 arg13, u64 arg14, u64 arg15); >> +void bpf_trace_run16(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, >> + u64 arg8, u64 arg9, u64 arg10, u64 arg11, u64 arg12, >> + u64 arg13, u64 arg14, u64 arg15, u64 arg16); >> +void bpf_trace_run17(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, >> + u64 arg8, u64 arg9, u64 arg10, u64 arg11, u64 arg12, >> + u64 arg13, u64 arg14, u64 arg15, u64 arg16, u64 arg17); >> void perf_trace_run_bpf_submit(void *raw_data, int size, int rctx, >> struct trace_event_call *call, u64 count, >> struct pt_regs *regs, struct hlist_head *head, > [...] >> @@ -896,3 +976,206 @@ int perf_event_query_prog_array(struct perf_event *event, void __user *info) >> >> return ret; >> } >> + >> +static __always_inline >> +void __bpf_trace_run(struct bpf_prog *prog, u64 *args) >> +{ >> + rcu_read_lock(); >> + preempt_disable(); >> + (void) BPF_PROG_RUN(prog, args); >> + preempt_enable(); >> + rcu_read_unlock(); >> +} >> + >> +#define EVAL1(FN, X) FN(X) >> +#define EVAL2(FN, X, Y...) FN(X) EVAL1(FN, Y) >> +#define EVAL3(FN, X, Y...) FN(X) EVAL2(FN, Y) >> +#define EVAL4(FN, X, Y...) FN(X) EVAL3(FN, Y) >> +#define EVAL5(FN, X, Y...) FN(X) EVAL4(FN, Y) >> +#define EVAL6(FN, X, Y...) FN(X) EVAL5(FN, Y) >> + >> +#define COPY(X) args[X - 1] = arg##X; >> + >> +void bpf_trace_run1(struct bpf_prog *prog, u64 arg1) >> +{ >> + u64 args[1]; >> + >> + EVAL1(COPY, 1); >> + __bpf_trace_run(prog, args); >> +} >> +EXPORT_SYMBOL_GPL(bpf_trace_run1); >> +void bpf_trace_run2(struct bpf_prog *prog, u64 arg1, u64 arg2) >> +{ >> + u64 args[2]; >> + >> + EVAL2(COPY, 1, 2); >> + __bpf_trace_run(prog, args); >> +} >> +EXPORT_SYMBOL_GPL(bpf_trace_run2); >> +void bpf_trace_run3(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3) >> +{ >> + u64 args[3]; >> + >> + EVAL3(COPY, 1, 2, 3); >> + __bpf_trace_run(prog, args); >> +} >> +EXPORT_SYMBOL_GPL(bpf_trace_run3); >> +void bpf_trace_run4(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4) >> +{ >> + u64 args[4]; >> + >> + EVAL4(COPY, 1, 2, 3, 4); >> + __bpf_trace_run(prog, args); >> +} >> +EXPORT_SYMBOL_GPL(bpf_trace_run4); >> +void bpf_trace_run5(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5) >> +{ >> + u64 args[5]; >> + >> + EVAL5(COPY, 1, 2, 3, 4, 5); >> + __bpf_trace_run(prog, args); >> +} >> +EXPORT_SYMBOL_GPL(bpf_trace_run5); >> +void bpf_trace_run6(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6) >> +{ >> + u64 args[6]; >> + >> + EVAL6(COPY, 1, 2, 3, 4, 5, 6); >> + __bpf_trace_run(prog, args); >> +} >> +EXPORT_SYMBOL_GPL(bpf_trace_run6); >> +void bpf_trace_run7(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7) >> +{ >> + u64 args[7]; >> + >> + EVAL6(COPY, 1, 2, 3, 4, 5, 6); >> + EVAL1(COPY, 7); >> + __bpf_trace_run(prog, args); >> +} >> +EXPORT_SYMBOL_GPL(bpf_trace_run7); >> +void bpf_trace_run8(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, >> + u64 arg8) >> +{ >> + u64 args[8]; >> + >> + EVAL6(COPY, 1, 2, 3, 4, 5, 6); >> + EVAL2(COPY, 7, 8); >> + __bpf_trace_run(prog, args); >> +} >> +EXPORT_SYMBOL_GPL(bpf_trace_run8); >> +void bpf_trace_run9(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, >> + u64 arg8, u64 arg9) >> +{ >> + u64 args[9]; >> + >> + EVAL6(COPY, 1, 2, 3, 4, 5, 6); >> + EVAL3(COPY, 7, 8, 9); >> + __bpf_trace_run(prog, args); >> +} >> +EXPORT_SYMBOL_GPL(bpf_trace_run9); >> +void bpf_trace_run10(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, >> + u64 arg8, u64 arg9, u64 arg10) >> +{ >> + u64 args[10]; >> + >> + EVAL6(COPY, 1, 2, 3, 4, 5, 6); >> + EVAL4(COPY, 7, 8, 9, 10); >> + __bpf_trace_run(prog, args); >> +} >> +EXPORT_SYMBOL_GPL(bpf_trace_run10); >> +void bpf_trace_run11(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, >> + u64 arg8, u64 arg9, u64 arg10, u64 arg11) >> +{ >> + u64 args[11]; >> + >> + EVAL6(COPY, 1, 2, 3, 4, 5, 6); >> + EVAL5(COPY, 7, 8, 9, 10, 11); >> + __bpf_trace_run(prog, args); >> +} >> +EXPORT_SYMBOL_GPL(bpf_trace_run11); >> +void bpf_trace_run12(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, >> + u64 arg8, u64 arg9, u64 arg10, u64 arg11, u64 arg12) >> +{ >> + u64 args[12]; >> + >> + EVAL6(COPY, 1, 2, 3, 4, 5, 6); >> + EVAL6(COPY, 7, 8, 9, 10, 11, 12); >> + __bpf_trace_run(prog, args); >> +} >> +EXPORT_SYMBOL_GPL(bpf_trace_run12); >> +void bpf_trace_run17(struct bpf_prog *prog, u64 arg1, u64 arg2, >> + u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, >> + u64 arg8, u64 arg9, u64 arg10, u64 arg11, u64 arg12, >> + u64 arg13, u64 arg14, u64 arg15, u64 arg16, u64 arg17) >> +{ >> + u64 args[17]; >> + >> + EVAL6(COPY, 1, 2, 3, 4, 5, 6); >> + EVAL6(COPY, 7, 8, 9, 10, 11, 12); >> + EVAL5(COPY, 13, 14, 15, 16, 17); >> + __bpf_trace_run(prog, args); >> +} >> +EXPORT_SYMBOL_GPL(bpf_trace_run17); > > Would be nice if we could generate all these above via macro, e.g. when we define > a hard upper limit for max number of tracepoint args anyway, so this gets automatically > adjusted as well. Maybe some of the logic from BPF_CALL_*() macros could be borrowed > for this purpose. I've thought about it, but couldn't figure out how to do it. Suggestions are welcome. The preprocessor cannot expand a constant N into N statements. There gotta be something like: ... #define EVAL5(FN, X, Y...) FN(X) EVAL4(FN, Y) #define EVAL6(FN, X, Y...) FN(X) EVAL5(FN, Y) for whatever maximum we will pick. I picked 6 as a good compromise and used it twice in bpf_trace_run1x() Similar thing possible for u64 arg1, u64 arg2, ... but it will be harder to read. Looking forward what you can come up with.