Commit 6df4ea1f authored by Kumar Kartikeya Dwivedi's avatar Kumar Kartikeya Dwivedi Committed by Alexei Starovoitov

bpf: Support kptrs in percpu arraymap

Enable support for kptrs in percpu BPF arraymap by wiring up the freeing
of these kptrs from percpu map elements.
Signed-off-by: default avatarKumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20220904204145.3089-3-memxor@gmail.comSigned-off-by: default avatarAlexei Starovoitov <ast@kernel.org>
parent 44832519
...@@ -279,7 +279,8 @@ int bpf_percpu_array_copy(struct bpf_map *map, void *key, void *value) ...@@ -279,7 +279,8 @@ int bpf_percpu_array_copy(struct bpf_map *map, void *key, void *value)
rcu_read_lock(); rcu_read_lock();
pptr = array->pptrs[index & array->index_mask]; pptr = array->pptrs[index & array->index_mask];
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
bpf_long_memcpy(value + off, per_cpu_ptr(pptr, cpu), size); copy_map_value_long(map, value + off, per_cpu_ptr(pptr, cpu));
check_and_init_map_value(map, value + off);
off += size; off += size;
} }
rcu_read_unlock(); rcu_read_unlock();
...@@ -338,8 +339,9 @@ static int array_map_update_elem(struct bpf_map *map, void *key, void *value, ...@@ -338,8 +339,9 @@ static int array_map_update_elem(struct bpf_map *map, void *key, void *value,
return -EINVAL; return -EINVAL;
if (array->map.map_type == BPF_MAP_TYPE_PERCPU_ARRAY) { if (array->map.map_type == BPF_MAP_TYPE_PERCPU_ARRAY) {
memcpy(this_cpu_ptr(array->pptrs[index & array->index_mask]), val = this_cpu_ptr(array->pptrs[index & array->index_mask]);
value, map->value_size); copy_map_value(map, val, value);
check_and_free_fields(array, val);
} else { } else {
val = array->value + val = array->value +
(u64)array->elem_size * (index & array->index_mask); (u64)array->elem_size * (index & array->index_mask);
...@@ -383,7 +385,8 @@ int bpf_percpu_array_update(struct bpf_map *map, void *key, void *value, ...@@ -383,7 +385,8 @@ int bpf_percpu_array_update(struct bpf_map *map, void *key, void *value,
rcu_read_lock(); rcu_read_lock();
pptr = array->pptrs[index & array->index_mask]; pptr = array->pptrs[index & array->index_mask];
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
bpf_long_memcpy(per_cpu_ptr(pptr, cpu), value + off, size); copy_map_value_long(map, per_cpu_ptr(pptr, cpu), value + off);
check_and_free_fields(array, per_cpu_ptr(pptr, cpu));
off += size; off += size;
} }
rcu_read_unlock(); rcu_read_unlock();
...@@ -421,8 +424,20 @@ static void array_map_free(struct bpf_map *map) ...@@ -421,8 +424,20 @@ static void array_map_free(struct bpf_map *map)
int i; int i;
if (map_value_has_kptrs(map)) { if (map_value_has_kptrs(map)) {
for (i = 0; i < array->map.max_entries; i++) if (array->map.map_type == BPF_MAP_TYPE_PERCPU_ARRAY) {
bpf_map_free_kptrs(map, array_map_elem_ptr(array, i)); for (i = 0; i < array->map.max_entries; i++) {
void __percpu *pptr = array->pptrs[i & array->index_mask];
int cpu;
for_each_possible_cpu(cpu) {
bpf_map_free_kptrs(map, per_cpu_ptr(pptr, cpu));
cond_resched();
}
}
} else {
for (i = 0; i < array->map.max_entries; i++)
bpf_map_free_kptrs(map, array_map_elem_ptr(array, i));
}
bpf_map_free_kptr_off_tab(map); bpf_map_free_kptr_off_tab(map);
} }
...@@ -608,9 +623,9 @@ static int __bpf_array_map_seq_show(struct seq_file *seq, void *v) ...@@ -608,9 +623,9 @@ static int __bpf_array_map_seq_show(struct seq_file *seq, void *v)
pptr = v; pptr = v;
size = array->elem_size; size = array->elem_size;
for_each_possible_cpu(cpu) { for_each_possible_cpu(cpu) {
bpf_long_memcpy(info->percpu_value_buf + off, copy_map_value_long(map, info->percpu_value_buf + off,
per_cpu_ptr(pptr, cpu), per_cpu_ptr(pptr, cpu));
size); check_and_init_map_value(map, info->percpu_value_buf + off);
off += size; off += size;
} }
ctx.value = info->percpu_value_buf; ctx.value = info->percpu_value_buf;
......
...@@ -1049,7 +1049,8 @@ static int map_check_btf(struct bpf_map *map, const struct btf *btf, ...@@ -1049,7 +1049,8 @@ static int map_check_btf(struct bpf_map *map, const struct btf *btf,
} }
if (map->map_type != BPF_MAP_TYPE_HASH && if (map->map_type != BPF_MAP_TYPE_HASH &&
map->map_type != BPF_MAP_TYPE_LRU_HASH && map->map_type != BPF_MAP_TYPE_LRU_HASH &&
map->map_type != BPF_MAP_TYPE_ARRAY) { map->map_type != BPF_MAP_TYPE_ARRAY &&
map->map_type != BPF_MAP_TYPE_PERCPU_ARRAY) {
ret = -EOPNOTSUPP; ret = -EOPNOTSUPP;
goto free_map_tab; goto free_map_tab;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment