A no charge flag is also introduced for bpf prog, which is similar with the no charge flag introduced for bpf map. The usecase of it is the same too.
It is added in bpf_attr for BPF_PROG_LOAD command, and then set in bpf_prog_aux for the memory allocation which is not at the loading path. There're 4B holes after the member max_rdwr_access in struct bpf_prog_aux, so we can place the new member there.
Signed-off-by: Yafang Shao laoar.shao@gmail.com --- include/linux/bpf.h | 8 ++++++++ include/uapi/linux/bpf.h | 3 +++ kernel/bpf/syscall.c | 4 +++- tools/include/uapi/linux/bpf.h | 3 +++ 4 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index 90a542d5a411..69ff3e35b8f2 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -214,6 +214,13 @@ map_flags_no_charge(gfp_t flags, union bpf_attr *attr) return flags |= (attr->map_flags & BPF_F_NO_CHARGE) ? 0 : __GFP_ACCOUNT; }
+static inline gfp_t +prog_flags_no_charge(gfp_t flags, union bpf_attr *attr) +{ + return flags |= (attr->prog_flags & BPF_F_PROG_NO_CHARGE) ? + 0 : __GFP_ACCOUNT; +} + static inline gfp_t bpf_flags_no_charge(gfp_t flags, bool no_charge) { @@ -958,6 +965,7 @@ struct bpf_prog_aux { u32 ctx_arg_info_size; u32 max_rdonly_access; u32 max_rdwr_access; + bool no_charge; /* dont' charge memory to memcg */ struct btf *attach_btf; const struct bpf_ctx_arg_aux *ctx_arg_info; struct mutex dst_mutex; /* protects dst_* pointers below, *after* prog becomes visible */ diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index 93ee04fb8c62..3c98b1b77db6 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -1121,6 +1121,9 @@ enum { * fully support xdp frags. */ BPF_F_XDP_HAS_FRAGS = (1U << 5), + +/* Don't charge memory to memcg */ + BPF_F_PROG_NO_CHARGE = (1U << 6), };
/* link_create.kprobe_multi.flags used in LINK_CREATE command for diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index e84aeefa05f4..346f3df9fa1d 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -2230,7 +2230,8 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr) BPF_F_TEST_STATE_FREQ | BPF_F_SLEEPABLE | BPF_F_TEST_RND_HI32 | - BPF_F_XDP_HAS_FRAGS)) + BPF_F_XDP_HAS_FRAGS | + BPF_F_PROG_NO_CHARGE)) return -EINVAL;
if (!IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && @@ -2317,6 +2318,7 @@ static int bpf_prog_load(union bpf_attr *attr, bpfptr_t uattr) prog->aux->offload_requested = !!attr->prog_ifindex; prog->aux->sleepable = attr->prog_flags & BPF_F_SLEEPABLE; prog->aux->xdp_has_frags = attr->prog_flags & BPF_F_XDP_HAS_FRAGS; + prog->aux->no_charge = attr->prog_flags & BPF_F_PROG_NO_CHARGE;
err = security_bpf_prog_alloc(prog->aux); if (err) diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h index 71a4d8fdc880..89752e5c11c0 100644 --- a/tools/include/uapi/linux/bpf.h +++ b/tools/include/uapi/linux/bpf.h @@ -1121,6 +1121,9 @@ enum { * fully support xdp frags. */ BPF_F_XDP_HAS_FRAGS = (1U << 5), + +/* Don't charge memory to memcg */ + BPF_F_PROG_NO_CHARGE = (1U << 6), };
/* link_create.kprobe_multi.flags used in LINK_CREATE command for