diff options
author | Anay Wadhera <awadhera@berkeley.edu> | 2021-05-20 22:00:28 -0700 |
---|---|---|
committer | Michael Bestas <mkbestas@lineageos.org> | 2022-04-19 00:49:51 +0300 |
commit | 4c60d1c4fe45588f4d15c3887b6c94993f7b4b9c (patch) | |
tree | 8afba0d7ca6d8465d33bf03f445c4e6ad389eff9 /kernel | |
parent | d692db0fad2ff92fec4e091181b994461fc9d4f1 (diff) |
Revert "bpf: fix clearing on persistent program array maps"
This reverts commit c9da161c6517ba12154059d3b965c2cbaf16f90f.
Signed-off-by: Chatur27 <jasonbright2709@gmail.com>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/bpf/inode.c | 6 | ||||
-rw-r--r-- | kernel/bpf/syscall.c | 36 | ||||
-rw-r--r-- | kernel/bpf/verifier.c | 3 |
3 files changed, 16 insertions, 29 deletions
diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c index 5a8a797d50b7..be6d726e31c9 100644 --- a/kernel/bpf/inode.c +++ b/kernel/bpf/inode.c @@ -34,7 +34,7 @@ static void *bpf_any_get(void *raw, enum bpf_type type) atomic_inc(&((struct bpf_prog *)raw)->aux->refcnt); break; case BPF_TYPE_MAP: - bpf_map_inc(raw, true); + atomic_inc(&((struct bpf_map *)raw)->refcnt); break; default: WARN_ON_ONCE(1); @@ -51,7 +51,7 @@ static void bpf_any_put(void *raw, enum bpf_type type) bpf_prog_put(raw); break; case BPF_TYPE_MAP: - bpf_map_put_with_uref(raw); + bpf_map_put(raw); break; default: WARN_ON_ONCE(1); @@ -64,7 +64,7 @@ static void *bpf_fd_probe_obj(u32 ufd, enum bpf_type *type) void *raw; *type = BPF_TYPE_MAP; - raw = bpf_map_get_with_uref(ufd); + raw = bpf_map_get(ufd); if (IS_ERR(raw)) { *type = BPF_TYPE_PROG; raw = bpf_prog_get(ufd); diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 72a2272e370f..14bc36a91d5d 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -82,14 +82,6 @@ static void bpf_map_free_deferred(struct work_struct *work) map->ops->map_free(map); } -static void bpf_map_put_uref(struct bpf_map *map) -{ - if (atomic_dec_and_test(&map->usercnt)) { - if (map->map_type == BPF_MAP_TYPE_PROG_ARRAY) - bpf_fd_array_map_clear(map); - } -} - /* decrement map refcnt and schedule it for freeing via workqueue * (unrelying map implementation ops->map_free() might sleep) */ @@ -101,15 +93,17 @@ void bpf_map_put(struct bpf_map *map) } } -void bpf_map_put_with_uref(struct bpf_map *map) -{ - bpf_map_put_uref(map); - bpf_map_put(map); -} - static int bpf_map_release(struct inode *inode, struct file *filp) { - bpf_map_put_with_uref(filp->private_data); + struct bpf_map *map = filp->private_data; + + if (map->map_type == BPF_MAP_TYPE_PROG_ARRAY) + /* prog_array stores refcnt-ed bpf_prog pointers + * release them all when user space closes prog_array_fd + */ + bpf_fd_array_map_clear(map); + + bpf_map_put(map); return 0; } @@ -148,7 +142,6 @@ static int map_create(union bpf_attr *attr) return PTR_ERR(map); atomic_set(&map->refcnt, 1); - atomic_set(&map->usercnt, 1); err = bpf_map_charge_memlock(map); if (err) @@ -183,14 +176,7 @@ struct bpf_map *__bpf_map_get(struct fd f) return f.file->private_data; } -void bpf_map_inc(struct bpf_map *map, bool uref) -{ - atomic_inc(&map->refcnt); - if (uref) - atomic_inc(&map->usercnt); -} - -struct bpf_map *bpf_map_get_with_uref(u32 ufd) +struct bpf_map *bpf_map_get(u32 ufd) { struct fd f = fdget(ufd); struct bpf_map *map; @@ -199,7 +185,7 @@ struct bpf_map *bpf_map_get_with_uref(u32 ufd) if (IS_ERR(map)) return map; - bpf_map_inc(map, true); + atomic_inc(&map->refcnt); fdput(f); return map; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index a7945d10b378..c6073056badf 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -2021,7 +2021,8 @@ static int replace_map_fd_with_map_ptr(struct verifier_env *env) * will be used by the valid program until it's unloaded * and all maps are released in free_bpf_prog_info() */ - bpf_map_inc(map, false); + atomic_inc(&map->refcnt); + fdput(f); next_insn: insn++; |