summaryrefslogtreecommitdiffstats
path: root/kernel/bpf/verifier.c
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2021-03-10 01:06:34 +0100
committerDaniel Borkmann <daniel@iogearbox.net>2021-03-10 01:07:21 +0100
commit32f91529e2bdbe0d92edb3ced41dfba4beffa84a (patch)
tree2e6ca2aa0d6d1ac694002dd4aff11915473d4118 /kernel/bpf/verifier.c
parent11d39cfeecfc9d92a5faa2a55c228e796478e0cb (diff)
parentee75aef23afe6e88497151c127c13ed69f41aaa2 (diff)
downloadlinux-32f91529e2bdbe0d92edb3ced41dfba4beffa84a.tar.bz2
Merge branch 'bpf-xdp-redirect'
Björn Töpel says: ==================== This two patch series contain two optimizations for the bpf_redirect_map() helper and the xdp_do_redirect() function. The bpf_redirect_map() optimization is about avoiding the map lookup dispatching. Instead of having a switch-statement and selecting the correct lookup function, we let bpf_redirect_map() be a map operation, where each map has its own bpf_redirect_map() implementation. This way the run-time lookup is avoided. The xdp_do_redirect() patch restructures the code, so that the map pointer indirection can be avoided. Performance-wise I got 4% improvement for XSKMAP (sample:xdpsock/rx-drop), and 8% (sample:xdp_redirect_map) on my machine. v5->v6: Removed REDIR enum, and instead use map_id and map_type. (Daniel) Applied Daniel's fixups on patch 1. (Daniel) v4->v5: Renamed map operation to map_redirect. (Daniel) v3->v4: Made bpf_redirect_map() a map operation. (Daniel) v2->v3: Fix build when CONFIG_NET is not set. (lkp) v1->v2: Removed warning when CONFIG_BPF_SYSCALL was not set. (lkp) Cleaned up case-clause in xdp_do_generic_redirect_map(). (Toke) Re-added comment. (Toke) rfc->v1: Use map_id, and remove bpf_clear_redirect_map(). (Toke) Get rid of the macro and use __always_inline. (Jesper) ==================== Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'kernel/bpf/verifier.c')
-rw-r--r--kernel/bpf/verifier.c13
1 files changed, 11 insertions, 2 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 9fe90ce52a65..97eb0b2435b8 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -5582,7 +5582,8 @@ record_func_map(struct bpf_verifier_env *env, struct bpf_call_arg_meta *meta,
func_id != BPF_FUNC_map_push_elem &&
func_id != BPF_FUNC_map_pop_elem &&
func_id != BPF_FUNC_map_peek_elem &&
- func_id != BPF_FUNC_for_each_map_elem)
+ func_id != BPF_FUNC_for_each_map_elem &&
+ func_id != BPF_FUNC_redirect_map)
return 0;
if (map == NULL) {
@@ -12017,7 +12018,8 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
insn->imm == BPF_FUNC_map_delete_elem ||
insn->imm == BPF_FUNC_map_push_elem ||
insn->imm == BPF_FUNC_map_pop_elem ||
- insn->imm == BPF_FUNC_map_peek_elem)) {
+ insn->imm == BPF_FUNC_map_peek_elem ||
+ insn->imm == BPF_FUNC_redirect_map)) {
aux = &env->insn_aux_data[i + delta];
if (bpf_map_ptr_poisoned(aux))
goto patch_call_imm;
@@ -12059,6 +12061,9 @@ static int do_misc_fixups(struct bpf_verifier_env *env)
(int (*)(struct bpf_map *map, void *value))NULL));
BUILD_BUG_ON(!__same_type(ops->map_peek_elem,
(int (*)(struct bpf_map *map, void *value))NULL));
+ BUILD_BUG_ON(!__same_type(ops->map_redirect,
+ (int (*)(struct bpf_map *map, u32 ifindex, u64 flags))NULL));
+
patch_map_ops_generic:
switch (insn->imm) {
case BPF_FUNC_map_lookup_elem:
@@ -12085,6 +12090,10 @@ patch_map_ops_generic:
insn->imm = BPF_CAST_CALL(ops->map_peek_elem) -
__bpf_call_base;
continue;
+ case BPF_FUNC_redirect_map:
+ insn->imm = BPF_CAST_CALL(ops->map_redirect) -
+ __bpf_call_base;
+ continue;
}
goto patch_call_imm;