Offering: HULK hulk inclusion category: bugfix bugzilla: https://atomgit.com/src-openeuler/kernel/issues/17960 -------------------------------- Fix kabi breakage for struct bpf_mem_alloc. Fixes: c4fd18e0bccb ("[Backport] bpf: Cancel special fields on map value recycle") Signed-off-by: Pu Lehui <pulehui@huawei.com> --- include/linux/bpf_mem_alloc.h | 2 -- kernel/bpf/memalloc.c | 24 +++++++++++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/include/linux/bpf_mem_alloc.h b/include/linux/bpf_mem_alloc.h index b902efccbf18..a72ca0d5c7e9 100644 --- a/include/linux/bpf_mem_alloc.h +++ b/include/linux/bpf_mem_alloc.h @@ -13,8 +13,6 @@ struct bpf_mem_alloc { struct bpf_mem_cache __percpu *cache; bool percpu; struct work_struct work; - void (*dtor_ctx_free)(void *ctx); - void *dtor_ctx; }; /* 'size != 0' is for bpf_mem_alloc which manages fixed-size objects. diff --git a/kernel/bpf/memalloc.c b/kernel/bpf/memalloc.c index 93b834de849f..e5f82c3845e1 100644 --- a/kernel/bpf/memalloc.c +++ b/kernel/bpf/memalloc.c @@ -103,6 +103,7 @@ struct bpf_mem_cache { bool draining; struct bpf_mem_cache *tgt; void (*dtor)(void *obj, void *ctx); + void (*dtor_ctx_free)(void *ctx); void *dtor_ctx; /* list of objects to be freed after RCU GP */ @@ -621,9 +622,23 @@ static void check_leaked_objs(struct bpf_mem_alloc *ma) static void free_mem_alloc_no_barrier(struct bpf_mem_alloc *ma) { + void (*dtor_ctx_free)(void *ctx) = NULL; + void *dtor_ctx = NULL; + + /* handle for KABI break */ + if (ma->cache) { + struct bpf_mem_cache *c = per_cpu_ptr(ma->cache, 0); + dtor_ctx_free = c->dtor_ctx_free; + dtor_ctx = c->dtor_ctx; + } else if (ma->caches) { + struct bpf_mem_caches *cc = per_cpu_ptr(ma->caches, 0); + dtor_ctx_free = cc->cache[0].dtor_ctx_free; + dtor_ctx = cc->cache[0].dtor_ctx; + } + /* We can free dtor ctx only once all callbacks are done using it. */ - if (ma->dtor_ctx_free) - ma->dtor_ctx_free(ma->dtor_ctx); + if (dtor_ctx_free) + dtor_ctx_free(dtor_ctx); check_leaked_objs(ma); free_percpu(ma->cache); free_percpu(ma->caches); @@ -957,14 +972,12 @@ void bpf_mem_alloc_set_dtor(struct bpf_mem_alloc *ma, void (*dtor)(void *obj, vo struct bpf_mem_cache *c; int cpu, i; - ma->dtor_ctx_free = dtor_ctx_free; - ma->dtor_ctx = ctx; - if (ma->cache) { for_each_possible_cpu(cpu) { c = per_cpu_ptr(ma->cache, cpu); c->dtor = dtor; c->dtor_ctx = ctx; + c->dtor_ctx_free = dtor_ctx_free; } } if (ma->caches) { @@ -974,6 +987,7 @@ void bpf_mem_alloc_set_dtor(struct bpf_mem_alloc *ma, void (*dtor)(void *obj, vo c = &cc->cache[i]; c->dtor = dtor; c->dtor_ctx = ctx; + c->dtor_ctx_free = dtor_ctx_free; } } } -- 2.34.1