bpf: Simplify freeing logic in linfo and jited_linfo
authorMartin KaFai Lau <kafai@fb.com>
Thu, 25 Mar 2021 01:51:30 +0000 (18:51 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Sat, 27 Mar 2021 03:41:50 +0000 (20:41 -0700)
This patch simplifies the linfo freeing logic by combining
"bpf_prog_free_jited_linfo()" and "bpf_prog_free_unused_jited_linfo()"
into the new "bpf_prog_jit_attempt_done()".
It is a prep work for the kernel function call support.  In a later
patch, freeing the kernel function call descriptors will also
be done in the "bpf_prog_jit_attempt_done()".

"bpf_prog_free_linfo()" is removed since it is only called by
"__bpf_prog_put_noref()".  The kvfree() are directly called
instead.

It also takes this chance to s/kcalloc/kvcalloc/ for the jited_linfo
allocation.

Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/20210325015130.1544323-1-kafai@fb.com
include/linux/filter.h
kernel/bpf/core.c
kernel/bpf/syscall.c
kernel/bpf/verifier.c

index b2b85b2..0d9c710 100644 (file)
@@ -877,8 +877,7 @@ void bpf_prog_free_linfo(struct bpf_prog *prog);
 void bpf_prog_fill_jited_linfo(struct bpf_prog *prog,
                               const u32 *insn_to_jit_off);
 int bpf_prog_alloc_jited_linfo(struct bpf_prog *prog);
-void bpf_prog_free_jited_linfo(struct bpf_prog *prog);
-void bpf_prog_free_unused_jited_linfo(struct bpf_prog *prog);
+void bpf_prog_jit_attempt_done(struct bpf_prog *prog);
 
 struct bpf_prog *bpf_prog_alloc(unsigned int size, gfp_t gfp_extra_flags);
 struct bpf_prog *bpf_prog_alloc_no_stats(unsigned int size, gfp_t gfp_extra_flags);
index 75244ec..a35eb3d 100644 (file)
@@ -143,25 +143,22 @@ int bpf_prog_alloc_jited_linfo(struct bpf_prog *prog)
        if (!prog->aux->nr_linfo || !prog->jit_requested)
                return 0;
 
-       prog->aux->jited_linfo = kcalloc(prog->aux->nr_linfo,
-                                        sizeof(*prog->aux->jited_linfo),
-                                        GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
+       prog->aux->jited_linfo = kvcalloc(prog->aux->nr_linfo,
+                                         sizeof(*prog->aux->jited_linfo),
+                                         GFP_KERNEL_ACCOUNT | __GFP_NOWARN);
        if (!prog->aux->jited_linfo)
                return -ENOMEM;
 
        return 0;
 }
 
-void bpf_prog_free_jited_linfo(struct bpf_prog *prog)
+void bpf_prog_jit_attempt_done(struct bpf_prog *prog)
 {
-       kfree(prog->aux->jited_linfo);
-       prog->aux->jited_linfo = NULL;
-}
-
-void bpf_prog_free_unused_jited_linfo(struct bpf_prog *prog)
-{
-       if (prog->aux->jited_linfo && !prog->aux->jited_linfo[0])
-               bpf_prog_free_jited_linfo(prog);
+       if (prog->aux->jited_linfo &&
+           (!prog->jited || !prog->aux->jited_linfo[0])) {
+               kvfree(prog->aux->jited_linfo);
+               prog->aux->jited_linfo = NULL;
+       }
 }
 
 /* The jit engine is responsible to provide an array
@@ -217,12 +214,6 @@ void bpf_prog_fill_jited_linfo(struct bpf_prog *prog,
                        insn_to_jit_off[linfo[i].insn_off - insn_start - 1];
 }
 
-void bpf_prog_free_linfo(struct bpf_prog *prog)
-{
-       bpf_prog_free_jited_linfo(prog);
-       kvfree(prog->aux->linfo);
-}
-
 struct bpf_prog *bpf_prog_realloc(struct bpf_prog *fp_old, unsigned int size,
                                  gfp_t gfp_extra_flags)
 {
@@ -1866,15 +1857,13 @@ struct bpf_prog *bpf_prog_select_runtime(struct bpf_prog *fp, int *err)
                        return fp;
 
                fp = bpf_int_jit_compile(fp);
-               if (!fp->jited) {
-                       bpf_prog_free_jited_linfo(fp);
+               bpf_prog_jit_attempt_done(fp);
 #ifdef CONFIG_BPF_JIT_ALWAYS_ON
+               if (!fp->jited) {
                        *err = -ENOTSUPP;
                        return fp;
-#endif
-               } else {
-                       bpf_prog_free_unused_jited_linfo(fp);
                }
+#endif
        } else {
                *err = bpf_prog_offload_compile(fp);
                if (*err)
index 2505034..eaf85bf 100644 (file)
@@ -1694,7 +1694,8 @@ static void __bpf_prog_put_noref(struct bpf_prog *prog, bool deferred)
 {
        bpf_prog_kallsyms_del_all(prog);
        btf_put(prog->aux->btf);
-       bpf_prog_free_linfo(prog);
+       kvfree(prog->aux->jited_linfo);
+       kvfree(prog->aux->linfo);
        if (prog->aux->attach_btf)
                btf_put(prog->aux->attach_btf);
 
index 85f9f84..b7df3f0 100644 (file)
@@ -11741,7 +11741,7 @@ static int jit_subprogs(struct bpf_verifier_env *env)
        prog->bpf_func = func[0]->bpf_func;
        prog->aux->func = func;
        prog->aux->func_cnt = env->subprog_cnt;
-       bpf_prog_free_unused_jited_linfo(prog);
+       bpf_prog_jit_attempt_done(prog);
        return 0;
 out_free:
        for (i = 0; i < env->subprog_cnt; i++) {
@@ -11764,7 +11764,7 @@ out_undo_insn:
                insn->off = 0;
                insn->imm = env->insn_aux_data[i].call_imm;
        }
-       bpf_prog_free_jited_linfo(prog);
+       bpf_prog_jit_attempt_done(prog);
        return err;
 }