selftests/bpf: Add BPF_PROG, BPF_KPROBE, and BPF_KRETPROBE macros
Streamline BPF_TRACE_x macro by moving out return type and section attribute
definition out of macro itself. That makes those function look in source code
similar to other BPF programs. Additionally, simplify its usage by determining
number of arguments automatically (so just single BPF_TRACE vs a family of
BPF_TRACE_1, BPF_TRACE_2, etc). Also, allow more natural function argument
syntax without commas inbetween argument type and name.
Given this helper is useful not only for tracing tp_btf/fenty/fexit programs,
but could be used for LSM programs and others following the same pattern,
rename BPF_TRACE macro into more generic BPF_PROG. Existing BPF_TRACE_x
usages in selftests are converted to new BPF_PROG macro.
Following the same pattern, define BPF_KPROBE and BPF_KRETPROBE macros for
nicer usage of kprobe/kretprobe arguments, respectively. BPF_KRETPROBE, adopts
same convention used by fexit programs, that last defined argument is probed
function's return result.
v4->v5:
- fix test_overhead test (__set_task_comm is void) (Alexei);
v3->v4:
- rebased and fixed one more BPF_TRACE_x occurence (Alexei);
v2->v3:
- rename to shorter and as generic BPF_PROG (Alexei);
v1->v2:
- verified GCC handles pragmas as expected;
- added descriptions to macros;
- converted new STRUCT_OPS selftest to BPF_HANDLER (worked as expected);
- added original context as 'ctx' parameter, for cases where it has to be
passed into BPF helpers. This might cause an accidental naming collision,
unfortunately, but at least it's easy to work around. Fortunately, this
situation produces quite legible compilation error:
progs/bpf_dctcp.c:46:6: error: redefinition of 'ctx' with a different type: 'int' vs 'unsigned long long *'
int ctx = 123;
^
progs/bpf_dctcp.c:42:6: note: previous definition is here
void BPF_HANDLER(dctcp_init, struct sock *sk)
^
./bpf_trace_helpers.h:58:32: note: expanded from macro 'BPF_HANDLER'
____##name(unsigned long long *ctx, ##args)
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Link: https://lore.kernel.org/bpf/20200110211634.1614739-1-andriin@fb.com
2020-01-10 21:16:34 +00:00
|
|
|
/* SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) */
|
2019-11-23 20:25:04 +00:00
|
|
|
#ifndef __BPF_TRACE_HELPERS_H
|
|
|
|
#define __BPF_TRACE_HELPERS_H
|
|
|
|
|
2020-01-20 13:06:45 +00:00
|
|
|
#include <bpf/bpf_helpers.h>
|
selftests/bpf: Add BPF_PROG, BPF_KPROBE, and BPF_KRETPROBE macros
Streamline BPF_TRACE_x macro by moving out return type and section attribute
definition out of macro itself. That makes those function look in source code
similar to other BPF programs. Additionally, simplify its usage by determining
number of arguments automatically (so just single BPF_TRACE vs a family of
BPF_TRACE_1, BPF_TRACE_2, etc). Also, allow more natural function argument
syntax without commas inbetween argument type and name.
Given this helper is useful not only for tracing tp_btf/fenty/fexit programs,
but could be used for LSM programs and others following the same pattern,
rename BPF_TRACE macro into more generic BPF_PROG. Existing BPF_TRACE_x
usages in selftests are converted to new BPF_PROG macro.
Following the same pattern, define BPF_KPROBE and BPF_KRETPROBE macros for
nicer usage of kprobe/kretprobe arguments, respectively. BPF_KRETPROBE, adopts
same convention used by fexit programs, that last defined argument is probed
function's return result.
v4->v5:
- fix test_overhead test (__set_task_comm is void) (Alexei);
v3->v4:
- rebased and fixed one more BPF_TRACE_x occurence (Alexei);
v2->v3:
- rename to shorter and as generic BPF_PROG (Alexei);
v1->v2:
- verified GCC handles pragmas as expected;
- added descriptions to macros;
- converted new STRUCT_OPS selftest to BPF_HANDLER (worked as expected);
- added original context as 'ctx' parameter, for cases where it has to be
passed into BPF helpers. This might cause an accidental naming collision,
unfortunately, but at least it's easy to work around. Fortunately, this
situation produces quite legible compilation error:
progs/bpf_dctcp.c:46:6: error: redefinition of 'ctx' with a different type: 'int' vs 'unsigned long long *'
int ctx = 123;
^
progs/bpf_dctcp.c:42:6: note: previous definition is here
void BPF_HANDLER(dctcp_init, struct sock *sk)
^
./bpf_trace_helpers.h:58:32: note: expanded from macro 'BPF_HANDLER'
____##name(unsigned long long *ctx, ##args)
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Link: https://lore.kernel.org/bpf/20200110211634.1614739-1-andriin@fb.com
2020-01-10 21:16:34 +00:00
|
|
|
|
|
|
|
#define ___bpf_concat(a, b) a ## b
|
|
|
|
#define ___bpf_apply(fn, n) ___bpf_concat(fn, n)
|
|
|
|
#define ___bpf_nth(_, _1, _2, _3, _4, _5, _6, _7, _8, _9, _a, _b, _c, N, ...) N
|
|
|
|
#define ___bpf_narg(...) \
|
|
|
|
___bpf_nth(_, ##__VA_ARGS__, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
|
|
|
|
#define ___bpf_empty(...) \
|
|
|
|
___bpf_nth(_, ##__VA_ARGS__, N, N, N, N, N, N, N, N, N, N, 0)
|
|
|
|
|
|
|
|
#define ___bpf_ctx_cast0() ctx
|
|
|
|
#define ___bpf_ctx_cast1(x) ___bpf_ctx_cast0(), (void *)ctx[0]
|
|
|
|
#define ___bpf_ctx_cast2(x, args...) ___bpf_ctx_cast1(args), (void *)ctx[1]
|
|
|
|
#define ___bpf_ctx_cast3(x, args...) ___bpf_ctx_cast2(args), (void *)ctx[2]
|
|
|
|
#define ___bpf_ctx_cast4(x, args...) ___bpf_ctx_cast3(args), (void *)ctx[3]
|
|
|
|
#define ___bpf_ctx_cast5(x, args...) ___bpf_ctx_cast4(args), (void *)ctx[4]
|
|
|
|
#define ___bpf_ctx_cast6(x, args...) ___bpf_ctx_cast5(args), (void *)ctx[5]
|
|
|
|
#define ___bpf_ctx_cast7(x, args...) ___bpf_ctx_cast6(args), (void *)ctx[6]
|
|
|
|
#define ___bpf_ctx_cast8(x, args...) ___bpf_ctx_cast7(args), (void *)ctx[7]
|
|
|
|
#define ___bpf_ctx_cast9(x, args...) ___bpf_ctx_cast8(args), (void *)ctx[8]
|
|
|
|
#define ___bpf_ctx_cast10(x, args...) ___bpf_ctx_cast9(args), (void *)ctx[9]
|
|
|
|
#define ___bpf_ctx_cast11(x, args...) ___bpf_ctx_cast10(args), (void *)ctx[10]
|
|
|
|
#define ___bpf_ctx_cast12(x, args...) ___bpf_ctx_cast11(args), (void *)ctx[11]
|
|
|
|
#define ___bpf_ctx_cast(args...) \
|
|
|
|
___bpf_apply(___bpf_ctx_cast, ___bpf_narg(args))(args)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* BPF_PROG is a convenience wrapper for generic tp_btf/fentry/fexit and
|
|
|
|
* similar kinds of BPF programs, that accept input arguments as a single
|
|
|
|
* pointer to untyped u64 array, where each u64 can actually be a typed
|
|
|
|
* pointer or integer of different size. Instead of requring user to write
|
|
|
|
* manual casts and work with array elements by index, BPF_PROG macro
|
|
|
|
* allows user to declare a list of named and typed input arguments in the
|
|
|
|
* same syntax as for normal C function. All the casting is hidden and
|
|
|
|
* performed transparently, while user code can just assume working with
|
|
|
|
* function arguments of specified type and name.
|
|
|
|
*
|
|
|
|
* Original raw context argument is preserved as well as 'ctx' argument.
|
|
|
|
* This is useful when using BPF helpers that expect original context
|
|
|
|
* as one of the parameters (e.g., for bpf_perf_event_output()).
|
2019-11-23 20:25:04 +00:00
|
|
|
*/
|
selftests/bpf: Add BPF_PROG, BPF_KPROBE, and BPF_KRETPROBE macros
Streamline BPF_TRACE_x macro by moving out return type and section attribute
definition out of macro itself. That makes those function look in source code
similar to other BPF programs. Additionally, simplify its usage by determining
number of arguments automatically (so just single BPF_TRACE vs a family of
BPF_TRACE_1, BPF_TRACE_2, etc). Also, allow more natural function argument
syntax without commas inbetween argument type and name.
Given this helper is useful not only for tracing tp_btf/fenty/fexit programs,
but could be used for LSM programs and others following the same pattern,
rename BPF_TRACE macro into more generic BPF_PROG. Existing BPF_TRACE_x
usages in selftests are converted to new BPF_PROG macro.
Following the same pattern, define BPF_KPROBE and BPF_KRETPROBE macros for
nicer usage of kprobe/kretprobe arguments, respectively. BPF_KRETPROBE, adopts
same convention used by fexit programs, that last defined argument is probed
function's return result.
v4->v5:
- fix test_overhead test (__set_task_comm is void) (Alexei);
v3->v4:
- rebased and fixed one more BPF_TRACE_x occurence (Alexei);
v2->v3:
- rename to shorter and as generic BPF_PROG (Alexei);
v1->v2:
- verified GCC handles pragmas as expected;
- added descriptions to macros;
- converted new STRUCT_OPS selftest to BPF_HANDLER (worked as expected);
- added original context as 'ctx' parameter, for cases where it has to be
passed into BPF helpers. This might cause an accidental naming collision,
unfortunately, but at least it's easy to work around. Fortunately, this
situation produces quite legible compilation error:
progs/bpf_dctcp.c:46:6: error: redefinition of 'ctx' with a different type: 'int' vs 'unsigned long long *'
int ctx = 123;
^
progs/bpf_dctcp.c:42:6: note: previous definition is here
void BPF_HANDLER(dctcp_init, struct sock *sk)
^
./bpf_trace_helpers.h:58:32: note: expanded from macro 'BPF_HANDLER'
____##name(unsigned long long *ctx, ##args)
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Link: https://lore.kernel.org/bpf/20200110211634.1614739-1-andriin@fb.com
2020-01-10 21:16:34 +00:00
|
|
|
#define BPF_PROG(name, args...) \
|
|
|
|
name(unsigned long long *ctx); \
|
|
|
|
static __always_inline typeof(name(0)) \
|
|
|
|
____##name(unsigned long long *ctx, ##args); \
|
|
|
|
typeof(name(0)) name(unsigned long long *ctx) \
|
|
|
|
{ \
|
|
|
|
_Pragma("GCC diagnostic push") \
|
|
|
|
_Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \
|
|
|
|
return ____##name(___bpf_ctx_cast(args)); \
|
|
|
|
_Pragma("GCC diagnostic pop") \
|
|
|
|
} \
|
|
|
|
static __always_inline typeof(name(0)) \
|
|
|
|
____##name(unsigned long long *ctx, ##args)
|
|
|
|
|
|
|
|
struct pt_regs;
|
|
|
|
|
|
|
|
#define ___bpf_kprobe_args0() ctx
|
|
|
|
#define ___bpf_kprobe_args1(x) \
|
|
|
|
___bpf_kprobe_args0(), (void *)PT_REGS_PARM1(ctx)
|
|
|
|
#define ___bpf_kprobe_args2(x, args...) \
|
|
|
|
___bpf_kprobe_args1(args), (void *)PT_REGS_PARM2(ctx)
|
|
|
|
#define ___bpf_kprobe_args3(x, args...) \
|
|
|
|
___bpf_kprobe_args2(args), (void *)PT_REGS_PARM3(ctx)
|
|
|
|
#define ___bpf_kprobe_args4(x, args...) \
|
|
|
|
___bpf_kprobe_args3(args), (void *)PT_REGS_PARM4(ctx)
|
|
|
|
#define ___bpf_kprobe_args5(x, args...) \
|
|
|
|
___bpf_kprobe_args4(args), (void *)PT_REGS_PARM5(ctx)
|
|
|
|
#define ___bpf_kprobe_args(args...) \
|
|
|
|
___bpf_apply(___bpf_kprobe_args, ___bpf_narg(args))(args)
|
2019-11-23 20:25:04 +00:00
|
|
|
|
selftests/bpf: Add BPF_PROG, BPF_KPROBE, and BPF_KRETPROBE macros
Streamline BPF_TRACE_x macro by moving out return type and section attribute
definition out of macro itself. That makes those function look in source code
similar to other BPF programs. Additionally, simplify its usage by determining
number of arguments automatically (so just single BPF_TRACE vs a family of
BPF_TRACE_1, BPF_TRACE_2, etc). Also, allow more natural function argument
syntax without commas inbetween argument type and name.
Given this helper is useful not only for tracing tp_btf/fenty/fexit programs,
but could be used for LSM programs and others following the same pattern,
rename BPF_TRACE macro into more generic BPF_PROG. Existing BPF_TRACE_x
usages in selftests are converted to new BPF_PROG macro.
Following the same pattern, define BPF_KPROBE and BPF_KRETPROBE macros for
nicer usage of kprobe/kretprobe arguments, respectively. BPF_KRETPROBE, adopts
same convention used by fexit programs, that last defined argument is probed
function's return result.
v4->v5:
- fix test_overhead test (__set_task_comm is void) (Alexei);
v3->v4:
- rebased and fixed one more BPF_TRACE_x occurence (Alexei);
v2->v3:
- rename to shorter and as generic BPF_PROG (Alexei);
v1->v2:
- verified GCC handles pragmas as expected;
- added descriptions to macros;
- converted new STRUCT_OPS selftest to BPF_HANDLER (worked as expected);
- added original context as 'ctx' parameter, for cases where it has to be
passed into BPF helpers. This might cause an accidental naming collision,
unfortunately, but at least it's easy to work around. Fortunately, this
situation produces quite legible compilation error:
progs/bpf_dctcp.c:46:6: error: redefinition of 'ctx' with a different type: 'int' vs 'unsigned long long *'
int ctx = 123;
^
progs/bpf_dctcp.c:42:6: note: previous definition is here
void BPF_HANDLER(dctcp_init, struct sock *sk)
^
./bpf_trace_helpers.h:58:32: note: expanded from macro 'BPF_HANDLER'
____##name(unsigned long long *ctx, ##args)
Signed-off-by: Andrii Nakryiko <andriin@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Martin KaFai Lau <kafai@fb.com>
Link: https://lore.kernel.org/bpf/20200110211634.1614739-1-andriin@fb.com
2020-01-10 21:16:34 +00:00
|
|
|
/*
|
|
|
|
* BPF_KPROBE serves the same purpose for kprobes as BPF_PROG for
|
|
|
|
* tp_btf/fentry/fexit BPF programs. It hides the underlying platform-specific
|
|
|
|
* low-level way of getting kprobe input arguments from struct pt_regs, and
|
|
|
|
* provides a familiar typed and named function arguments syntax and
|
|
|
|
* semantics of accessing kprobe input paremeters.
|
|
|
|
*
|
|
|
|
* Original struct pt_regs* context is preserved as 'ctx' argument. This might
|
|
|
|
* be necessary when using BPF helpers like bpf_perf_event_output().
|
|
|
|
*/
|
|
|
|
#define BPF_KPROBE(name, args...) \
|
|
|
|
name(struct pt_regs *ctx); \
|
|
|
|
static __always_inline typeof(name(0)) ____##name(struct pt_regs *ctx, ##args);\
|
|
|
|
typeof(name(0)) name(struct pt_regs *ctx) \
|
|
|
|
{ \
|
|
|
|
_Pragma("GCC diagnostic push") \
|
|
|
|
_Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \
|
|
|
|
return ____##name(___bpf_kprobe_args(args)); \
|
|
|
|
_Pragma("GCC diagnostic pop") \
|
|
|
|
} \
|
|
|
|
static __always_inline typeof(name(0)) ____##name(struct pt_regs *ctx, ##args)
|
|
|
|
|
|
|
|
#define ___bpf_kretprobe_args0() ctx
|
|
|
|
#define ___bpf_kretprobe_argsN(x, args...) \
|
|
|
|
___bpf_kprobe_args(args), (void *)PT_REGS_RET(ctx)
|
|
|
|
#define ___bpf_kretprobe_args(args...) \
|
|
|
|
___bpf_apply(___bpf_kretprobe_args, ___bpf_empty(args))(args)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* BPF_KRETPROBE is similar to BPF_KPROBE, except, in addition to listing all
|
|
|
|
* input kprobe arguments, one last extra argument has to be specified, which
|
|
|
|
* captures kprobe return value.
|
|
|
|
*/
|
|
|
|
#define BPF_KRETPROBE(name, args...) \
|
|
|
|
name(struct pt_regs *ctx); \
|
|
|
|
static __always_inline typeof(name(0)) ____##name(struct pt_regs *ctx, ##args);\
|
|
|
|
typeof(name(0)) name(struct pt_regs *ctx) \
|
|
|
|
{ \
|
|
|
|
_Pragma("GCC diagnostic push") \
|
|
|
|
_Pragma("GCC diagnostic ignored \"-Wint-conversion\"") \
|
|
|
|
return ____##name(___bpf_kretprobe_args(args)); \
|
|
|
|
_Pragma("GCC diagnostic pop") \
|
|
|
|
} \
|
|
|
|
static __always_inline typeof(name(0)) ____##name(struct pt_regs *ctx, ##args)
|
2019-11-23 20:25:04 +00:00
|
|
|
#endif
|