Add a new map ops ->map_mem_usage to print the memory usage of a bpf map. ->map_mem_usage will get the map memory usage from the pointers which will be freed in ->map_free. So it is very similar to ->map_free except that it only get the underlaying memory size from the pointers rather than freeing them. We just need to keep the pointers used in ->map_mem_usage in sync with the pointers in ->map_free. This is a preparation for the followup change. Signed-off-by: Yafang Shao <laoar.shao@xxxxxxxxx> --- include/linux/bpf.h | 2 ++ kernel/bpf/syscall.c | 18 +++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/include/linux/bpf.h b/include/linux/bpf.h index e11db75..10eb8e9 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -160,6 +160,8 @@ struct bpf_map_ops { bpf_callback_t callback_fn, void *callback_ctx, u64 flags); + unsigned long (*map_mem_usage)(const struct bpf_map *map); + /* BTF id of struct allocated by map_alloc */ int *map_btf_id; diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c index 99417b3..df52853 100644 --- a/kernel/bpf/syscall.c +++ b/kernel/bpf/syscall.c @@ -758,16 +758,20 @@ static fmode_t map_get_sys_perms(struct bpf_map *map, struct fd f) } #ifdef CONFIG_PROC_FS -/* Provides an approximation of the map's memory footprint. - * Used only to provide a backward compatibility and display - * a reasonable "memlock" info. - */ -static unsigned long bpf_map_memory_footprint(const struct bpf_map *map) +/* Show the memory usage of a bpf map */ +static unsigned long bpf_map_memory_usage(const struct bpf_map *map) { unsigned long size; - size = round_up(map->key_size + bpf_map_value_size(map), 8); + /* ->map_mem_usage will get the map memory size from the pointers + * which will be freed in ->map_free. So it is very similar to + * ->map_free except that it only get the underlaying memory size + * from the pointers rather than freeing them. + */ + if (map->ops->map_mem_usage) + return map->ops->map_mem_usage(map); + size = round_up(map->key_size + bpf_map_value_size(map), 8); return round_up(map->max_entries * size, PAGE_SIZE); } @@ -799,7 +803,7 @@ static void bpf_map_show_fdinfo(struct seq_file *m, struct file *filp) map->max_entries, map->map_flags, (unsigned long long)map->map_extra, - bpf_map_memory_footprint(map), + bpf_map_memory_usage(map), map->id, READ_ONCE(map->frozen)); if (type) { -- 1.8.3.1