bpf.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH bpf-next v3 00/18] bpf: bpf memory usage
@ 2023-02-27 15:20 Yafang Shao
  2023-02-27 15:20 ` [PATCH bpf-next v3 01/18] bpf: add new map ops ->map_mem_usage Yafang Shao
                   ` (18 more replies)
  0 siblings, 19 replies; 26+ messages in thread
From: Yafang Shao @ 2023-02-27 15:20 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong
  Cc: bpf, Yafang Shao

Currently we can't get bpf memory usage reliably. bpftool now shows the
bpf memory footprint, which is difference with bpf memory usage. The
difference can be quite great in some cases, for example,

- non-preallocated bpf map
  The non-preallocated bpf map memory usage is dynamically changed. The
  allocated elements count can be from 0 to the max entries. But the
  memory footprint in bpftool only shows a fixed number.

- bpf metadata consumes more memory than bpf element
  In some corner cases, the bpf metadata can consumes a lot more memory
  than bpf element consumes. For example, it can happen when the element
  size is quite small.

- some maps don't have key, value or max_entries
  For example the key_size and value_size of ringbuf is 0, so its
  memlock is always 0.

We need a way to show the bpf memory usage especially there will be more
and more bpf programs running on the production environment and thus the
bpf memory usage is not trivial.

This patchset introduces a new map ops ->map_mem_usage to calculate the
memory usage. Note that we don't intend to make the memory usage 100%
accurate, while our goal is to make sure there is only a small difference
between what bpftool reports and the real memory. That small difference
can be ignored compared to the total usage.  That is enough to monitor
the bpf memory usage. For example, the user can rely on this value to
monitor the trend of bpf memory usage, compare the difference in bpf
memory usage between different bpf program versions, figure out which
maps consume large memory, and etc.

This patchset implements the bpf memory usage for all maps, and yet there's
still work to do. We don't want to introduce runtime overhead in the
element update and delete path, but we have to do it for some
non-preallocated maps,
- devmap, xskmap
  When we update or delete an element, it will allocate or free memory.
  In order to track this dynamic memory, we have to track the count in
  element update and delete path. 

- cpumap
  The element size of each cpumap element is not determinated. If we
  want to track the usage, we have to count the size of all elements in
  the element update and delete path. So I just put it aside currently.

- local_storage, bpf_local_storage
  When we attach or detach a cgroup, it will allocate or free memory. If
  we want to track the dynamic memory, we also need to do something in
  the update and delete path. So I just put it aside currently.

- offload map
  The element update and delete of offload map is via the netdev dev_ops,
  in which it may dynamically allocate or free memory, but this dynamic
  memory isn't counted in offload map memory usage currently.

The result of each map can be found in the individual patch.

Changes:
v2->v3: check callback at map creation time and avoid warning (Alexei)
        fix build error under CONFIG_BPF=n (lkp@intel.com)
v1->v2: calculate the memory usage within bpf (Alexei)
- [v1] bpf, mm: bpf memory usage
  https://lwn.net/Articles/921991/
- [RFC PATCH v2] mm, bpf: Add BPF into /proc/meminfo
  https://lwn.net/Articles/919848/
- [RFC PATCH v1] mm, bpf: Add BPF into /proc/meminfo
  https://lwn.net/Articles/917647/ 


Yafang Shao (18):
  bpf: add new map ops ->map_mem_usage
  bpf: lpm_trie memory usage
  bpf: hashtab memory usage
  bpf: arraymap memory usage
  bpf: stackmap memory usage
  bpf: reuseport_array memory usage
  bpf: ringbuf memory usage
  bpf: bloom_filter memory usage
  bpf: cpumap memory usage
  bpf: devmap memory usage
  bpf: queue_stack_maps memory usage
  bpf: bpf_struct_ops memory usage
  bpf: local_storage memory usage
  bpf, net: bpf_local_storage memory usage
  bpf, net: sock_map memory usage
  bpf, net: xskmap memory usage
  bpf: offload map memory usage
  bpf: enforce all maps having memory usage callback

 include/linux/bpf.h               |  8 ++++++++
 include/linux/bpf_local_storage.h |  1 +
 include/net/xdp_sock.h            |  1 +
 kernel/bpf/arraymap.c             | 28 +++++++++++++++++++++++++
 kernel/bpf/bloom_filter.c         | 12 +++++++++++
 kernel/bpf/bpf_cgrp_storage.c     |  1 +
 kernel/bpf/bpf_inode_storage.c    |  1 +
 kernel/bpf/bpf_local_storage.c    | 10 +++++++++
 kernel/bpf/bpf_struct_ops.c       | 16 +++++++++++++++
 kernel/bpf/bpf_task_storage.c     |  1 +
 kernel/bpf/cpumap.c               | 10 +++++++++
 kernel/bpf/devmap.c               | 26 +++++++++++++++++++++--
 kernel/bpf/hashtab.c              | 43 +++++++++++++++++++++++++++++++++++++++
 kernel/bpf/local_storage.c        |  7 +++++++
 kernel/bpf/lpm_trie.c             | 11 ++++++++++
 kernel/bpf/offload.c              |  6 ++++++
 kernel/bpf/queue_stack_maps.c     | 10 +++++++++
 kernel/bpf/reuseport_array.c      |  8 ++++++++
 kernel/bpf/ringbuf.c              | 19 +++++++++++++++++
 kernel/bpf/stackmap.c             | 14 +++++++++++++
 kernel/bpf/syscall.c              | 20 ++++++++----------
 net/core/bpf_sk_storage.c         |  1 +
 net/core/sock_map.c               | 20 ++++++++++++++++++
 net/xdp/xskmap.c                  | 13 ++++++++++++
 24 files changed, 273 insertions(+), 14 deletions(-)

-- 
1.8.3.1


^ permalink raw reply	[flat|nested] 26+ messages in thread

* [PATCH bpf-next v3 01/18] bpf: add new map ops ->map_mem_usage
  2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
@ 2023-02-27 15:20 ` Yafang Shao
  2023-02-27 15:20 ` [PATCH bpf-next v3 02/18] bpf: lpm_trie memory usage Yafang Shao
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Yafang Shao @ 2023-02-27 15:20 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong
  Cc: bpf, Yafang Shao

Add a new map ops ->map_mem_usage to print the memory usage of a
bpf map.

This is a preparation for the followup change.

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 include/linux/bpf.h  |  2 ++
 kernel/bpf/syscall.c | 15 +++++++--------
 2 files changed, 9 insertions(+), 8 deletions(-)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 520b238..bca0963 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -161,6 +161,8 @@ struct bpf_map_ops {
 				     bpf_callback_t callback_fn,
 				     void *callback_ctx, u64 flags);
 
+	u64 (*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 e3fcdc9..8333aa0 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -771,16 +771,15 @@ 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 u64 bpf_map_memory_usage(const struct bpf_map *map)
 {
 	unsigned long size;
 
-	size = round_up(map->key_size + bpf_map_value_size(map), 8);
+	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);
 }
 
@@ -803,7 +802,7 @@ static void bpf_map_show_fdinfo(struct seq_file *m, struct file *filp)
 		   "max_entries:\t%u\n"
 		   "map_flags:\t%#x\n"
 		   "map_extra:\t%#llx\n"
-		   "memlock:\t%lu\n"
+		   "memlock:\t%llu\n"
 		   "map_id:\t%u\n"
 		   "frozen:\t%u\n",
 		   map->map_type,
@@ -812,7 +811,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


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH bpf-next v3 02/18] bpf: lpm_trie memory usage
  2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
  2023-02-27 15:20 ` [PATCH bpf-next v3 01/18] bpf: add new map ops ->map_mem_usage Yafang Shao
@ 2023-02-27 15:20 ` Yafang Shao
  2023-03-01  2:59   ` Hou Tao
  2023-02-27 15:20 ` [PATCH bpf-next v3 03/18] bpf: hashtab " Yafang Shao
                   ` (16 subsequent siblings)
  18 siblings, 1 reply; 26+ messages in thread
From: Yafang Shao @ 2023-02-27 15:20 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong
  Cc: bpf, Yafang Shao

trie_mem_usage() is introduced to calculate the lpm_trie memory usage.
Some small memory allocations are ignored. The inner node is also
ignored.

The result as follows,

- before
10: lpm_trie  flags 0x1
        key 8B  value 8B  max_entries 65536  memlock 1048576B

- after
10: lpm_trie  flags 0x1
        key 8B  value 8B  max_entries 65536  memlock 2291536B

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 kernel/bpf/lpm_trie.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c
index d833496..e0ca08e 100644
--- a/kernel/bpf/lpm_trie.c
+++ b/kernel/bpf/lpm_trie.c
@@ -720,6 +720,16 @@ static int trie_check_btf(const struct bpf_map *map,
 	       -EINVAL : 0;
 }
 
+static u64 trie_mem_usage(const struct bpf_map *map)
+{
+	struct lpm_trie *trie = container_of(map, struct lpm_trie, map);
+	u64 elem_size;
+
+	elem_size = sizeof(struct lpm_trie_node) + trie->data_size +
+			    trie->map.value_size;
+	return elem_size * trie->n_entries;
+}
+
 BTF_ID_LIST_SINGLE(trie_map_btf_ids, struct, lpm_trie)
 const struct bpf_map_ops trie_map_ops = {
 	.map_meta_equal = bpf_map_meta_equal,
@@ -733,5 +743,6 @@ static int trie_check_btf(const struct bpf_map *map,
 	.map_update_batch = generic_map_update_batch,
 	.map_delete_batch = generic_map_delete_batch,
 	.map_check_btf = trie_check_btf,
+	.map_mem_usage = trie_mem_usage,
 	.map_btf_id = &trie_map_btf_ids[0],
 };
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH bpf-next v3 03/18] bpf: hashtab memory usage
  2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
  2023-02-27 15:20 ` [PATCH bpf-next v3 01/18] bpf: add new map ops ->map_mem_usage Yafang Shao
  2023-02-27 15:20 ` [PATCH bpf-next v3 02/18] bpf: lpm_trie memory usage Yafang Shao
@ 2023-02-27 15:20 ` Yafang Shao
  2023-03-01  2:59   ` Hou Tao
  2023-02-27 15:20 ` [PATCH bpf-next v3 04/18] bpf: arraymap " Yafang Shao
                   ` (15 subsequent siblings)
  18 siblings, 1 reply; 26+ messages in thread
From: Yafang Shao @ 2023-02-27 15:20 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong
  Cc: bpf, Yafang Shao

htab_map_mem_usage() is introduced to calculate hashmap memory usage. In
this helper, some small memory allocations are ignore, as their size is
quite small compared with the total size. The inner_map_meta in
hash_of_map is also ignored.

The result for hashtab as follows,

- before this change
1: hash  name count_map  flags 0x1  <<<< no prealloc, fully set
        key 16B  value 24B  max_entries 1048576  memlock 41943040B
2: hash  name count_map  flags 0x1  <<<< no prealloc, none set
        key 16B  value 24B  max_entries 1048576  memlock 41943040B
3: hash  name count_map  flags 0x0  <<<< prealloc
        key 16B  value 24B  max_entries 1048576  memlock 41943040B

The memlock is always a fixed size whatever it is preallocated or
not, and whatever the count of allocated elements is.

- after this change
1: hash  name count_map  flags 0x1    <<<< non prealloc, fully set
        key 16B  value 24B  max_entries 1048576  memlock 117441536B
2: hash  name count_map  flags 0x1    <<<< non prealloc, non set
        key 16B  value 24B  max_entries 1048576  memlock 16778240B
3: hash  name count_map  flags 0x0    <<<< prealloc
        key 16B  value 24B  max_entries 1048576  memlock 109056000B

The memlock now is hashtab actually allocated.

The result for percpu hash map as follows,
- before this change
4: percpu_hash  name count_map  flags 0x0       <<<< prealloc
        key 16B  value 24B  max_entries 1048576  memlock 822083584B
5: percpu_hash  name count_map  flags 0x1       <<<< no prealloc
        key 16B  value 24B  max_entries 1048576  memlock 822083584B

- after this change
4: percpu_hash  name count_map  flags 0x0
        key 16B  value 24B  max_entries 1048576  memlock 897582080B
5: percpu_hash  name count_map  flags 0x1
        key 16B  value 24B  max_entries 1048576  memlock 922748736B

At worst, the difference can be 10x, for example,
- before this change
6: hash  name count_map  flags 0x0
        key 4B  value 4B  max_entries 1048576  memlock 8388608B

- after this change
6: hash  name count_map  flags 0x0
        key 4B  value 4B  max_entries 1048576  memlock 83889408B

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 kernel/bpf/hashtab.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 43 insertions(+)

diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index 5dfcb5a..6913b92 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -2175,6 +2175,44 @@ static int bpf_for_each_hash_elem(struct bpf_map *map, bpf_callback_t callback_f
 	return num_elems;
 }
 
+static u64 htab_map_mem_usage(const struct bpf_map *map)
+{
+	struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
+	u32 value_size = round_up(htab->map.value_size, 8);
+	bool prealloc = htab_is_prealloc(htab);
+	bool percpu = htab_is_percpu(htab);
+	bool lru = htab_is_lru(htab);
+	u64 num_entries;
+	u64 usage = sizeof(struct bpf_htab);
+
+	usage += sizeof(struct bucket) * htab->n_buckets;
+	usage += sizeof(int) * num_possible_cpus() * HASHTAB_MAP_LOCK_COUNT;
+	if (prealloc) {
+		num_entries = map->max_entries;
+		if (htab_has_extra_elems(htab))
+			num_entries += num_possible_cpus();
+
+		usage += htab->elem_size * num_entries;
+
+		if (percpu)
+			usage += value_size * num_possible_cpus() * num_entries;
+		else if (!lru)
+			usage += sizeof(struct htab_elem *) * num_possible_cpus();
+	} else {
+#define LLIST_NODE_SZ sizeof(struct llist_node)
+
+		num_entries = htab->use_percpu_counter ?
+					  percpu_counter_sum(&htab->pcount) :
+					  atomic_read(&htab->count);
+		usage += (htab->elem_size + LLIST_NODE_SZ) * num_entries;
+		if (percpu) {
+			usage += (LLIST_NODE_SZ + sizeof(void *)) * num_entries;
+			usage += value_size * num_possible_cpus() * num_entries;
+		}
+	}
+	return usage;
+}
+
 BTF_ID_LIST_SINGLE(htab_map_btf_ids, struct, bpf_htab)
 const struct bpf_map_ops htab_map_ops = {
 	.map_meta_equal = bpf_map_meta_equal,
@@ -2191,6 +2229,7 @@ static int bpf_for_each_hash_elem(struct bpf_map *map, bpf_callback_t callback_f
 	.map_seq_show_elem = htab_map_seq_show_elem,
 	.map_set_for_each_callback_args = map_set_for_each_callback_args,
 	.map_for_each_callback = bpf_for_each_hash_elem,
+	.map_mem_usage = htab_map_mem_usage,
 	BATCH_OPS(htab),
 	.map_btf_id = &htab_map_btf_ids[0],
 	.iter_seq_info = &iter_seq_info,
@@ -2212,6 +2251,7 @@ static int bpf_for_each_hash_elem(struct bpf_map *map, bpf_callback_t callback_f
 	.map_seq_show_elem = htab_map_seq_show_elem,
 	.map_set_for_each_callback_args = map_set_for_each_callback_args,
 	.map_for_each_callback = bpf_for_each_hash_elem,
+	.map_mem_usage = htab_map_mem_usage,
 	BATCH_OPS(htab_lru),
 	.map_btf_id = &htab_map_btf_ids[0],
 	.iter_seq_info = &iter_seq_info,
@@ -2363,6 +2403,7 @@ static void htab_percpu_map_seq_show_elem(struct bpf_map *map, void *key,
 	.map_seq_show_elem = htab_percpu_map_seq_show_elem,
 	.map_set_for_each_callback_args = map_set_for_each_callback_args,
 	.map_for_each_callback = bpf_for_each_hash_elem,
+	.map_mem_usage = htab_map_mem_usage,
 	BATCH_OPS(htab_percpu),
 	.map_btf_id = &htab_map_btf_ids[0],
 	.iter_seq_info = &iter_seq_info,
@@ -2382,6 +2423,7 @@ static void htab_percpu_map_seq_show_elem(struct bpf_map *map, void *key,
 	.map_seq_show_elem = htab_percpu_map_seq_show_elem,
 	.map_set_for_each_callback_args = map_set_for_each_callback_args,
 	.map_for_each_callback = bpf_for_each_hash_elem,
+	.map_mem_usage = htab_map_mem_usage,
 	BATCH_OPS(htab_lru_percpu),
 	.map_btf_id = &htab_map_btf_ids[0],
 	.iter_seq_info = &iter_seq_info,
@@ -2519,6 +2561,7 @@ static void htab_of_map_free(struct bpf_map *map)
 	.map_fd_sys_lookup_elem = bpf_map_fd_sys_lookup_elem,
 	.map_gen_lookup = htab_of_map_gen_lookup,
 	.map_check_btf = map_check_no_btf,
+	.map_mem_usage = htab_map_mem_usage,
 	BATCH_OPS(htab),
 	.map_btf_id = &htab_map_btf_ids[0],
 };
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH bpf-next v3 04/18] bpf: arraymap memory usage
  2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
                   ` (2 preceding siblings ...)
  2023-02-27 15:20 ` [PATCH bpf-next v3 03/18] bpf: hashtab " Yafang Shao
@ 2023-02-27 15:20 ` Yafang Shao
  2023-02-27 15:20 ` [PATCH bpf-next v3 05/18] bpf: stackmap " Yafang Shao
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Yafang Shao @ 2023-02-27 15:20 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong
  Cc: bpf, Yafang Shao

Introduce array_map_mem_usage() to calculate arraymap memory usage. In
this helper, some small memory allocations are ignored, like the
allocation of struct bpf_array_aux in prog_array. The inner_map_meta in
array_of_map is also ignored.

The result as follows,

- before
11: array  name count_map  flags 0x0
        key 4B  value 4B  max_entries 65536  memlock 524288B
12: percpu_array  name count_map  flags 0x0
        key 4B  value 4B  max_entries 65536  memlock 8912896B
13: perf_event_array  name count_map  flags 0x0
        key 4B  value 4B  max_entries 65536  memlock 524288B
14: prog_array  name count_map  flags 0x0
        key 4B  value 4B  max_entries 65536  memlock 524288B
15: cgroup_array  name count_map  flags 0x0
        key 4B  value 4B  max_entries 65536  memlock 524288B

- after
11: array  name count_map  flags 0x0
        key 4B  value 4B  max_entries 65536  memlock 524608B
12: percpu_array  name count_map  flags 0x0
        key 4B  value 4B  max_entries 65536  memlock 17301824B
13: perf_event_array  name count_map  flags 0x0
        key 4B  value 4B  max_entries 65536  memlock 524608B
14: prog_array  name count_map  flags 0x0
        key 4B  value 4B  max_entries 65536  memlock 524608B
15: cgroup_array  name count_map  flags 0x0
        key 4B  value 4B  max_entries 65536  memlock 524608B

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 kernel/bpf/arraymap.c | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
index 4847069..1588c79 100644
--- a/kernel/bpf/arraymap.c
+++ b/kernel/bpf/arraymap.c
@@ -721,6 +721,28 @@ static int bpf_for_each_array_elem(struct bpf_map *map, bpf_callback_t callback_
 	return num_elems;
 }
 
+static u64 array_map_mem_usage(const struct bpf_map *map)
+{
+	struct bpf_array *array = container_of(map, struct bpf_array, map);
+	bool percpu = map->map_type == BPF_MAP_TYPE_PERCPU_ARRAY;
+	u32 elem_size = array->elem_size;
+	u64 entries = map->max_entries;
+	u64 usage = sizeof(*array);
+
+	if (percpu) {
+		usage += entries * sizeof(void *);
+		usage += entries * elem_size * num_possible_cpus();
+	} else {
+		if (map->map_flags & BPF_F_MMAPABLE) {
+			usage = PAGE_ALIGN(usage);
+			usage += PAGE_ALIGN(entries * elem_size);
+		} else {
+			usage += entries * elem_size;
+		}
+	}
+	return usage;
+}
+
 BTF_ID_LIST_SINGLE(array_map_btf_ids, struct, bpf_array)
 const struct bpf_map_ops array_map_ops = {
 	.map_meta_equal = array_map_meta_equal,
@@ -742,6 +764,7 @@ static int bpf_for_each_array_elem(struct bpf_map *map, bpf_callback_t callback_
 	.map_update_batch = generic_map_update_batch,
 	.map_set_for_each_callback_args = map_set_for_each_callback_args,
 	.map_for_each_callback = bpf_for_each_array_elem,
+	.map_mem_usage = array_map_mem_usage,
 	.map_btf_id = &array_map_btf_ids[0],
 	.iter_seq_info = &iter_seq_info,
 };
@@ -762,6 +785,7 @@ static int bpf_for_each_array_elem(struct bpf_map *map, bpf_callback_t callback_
 	.map_update_batch = generic_map_update_batch,
 	.map_set_for_each_callback_args = map_set_for_each_callback_args,
 	.map_for_each_callback = bpf_for_each_array_elem,
+	.map_mem_usage = array_map_mem_usage,
 	.map_btf_id = &array_map_btf_ids[0],
 	.iter_seq_info = &iter_seq_info,
 };
@@ -1156,6 +1180,7 @@ static void prog_array_map_free(struct bpf_map *map)
 	.map_fd_sys_lookup_elem = prog_fd_array_sys_lookup_elem,
 	.map_release_uref = prog_array_map_clear,
 	.map_seq_show_elem = prog_array_map_seq_show_elem,
+	.map_mem_usage = array_map_mem_usage,
 	.map_btf_id = &array_map_btf_ids[0],
 };
 
@@ -1257,6 +1282,7 @@ static void perf_event_fd_array_map_free(struct bpf_map *map)
 	.map_fd_put_ptr = perf_event_fd_array_put_ptr,
 	.map_release = perf_event_fd_array_release,
 	.map_check_btf = map_check_no_btf,
+	.map_mem_usage = array_map_mem_usage,
 	.map_btf_id = &array_map_btf_ids[0],
 };
 
@@ -1291,6 +1317,7 @@ static void cgroup_fd_array_free(struct bpf_map *map)
 	.map_fd_get_ptr = cgroup_fd_array_get_ptr,
 	.map_fd_put_ptr = cgroup_fd_array_put_ptr,
 	.map_check_btf = map_check_no_btf,
+	.map_mem_usage = array_map_mem_usage,
 	.map_btf_id = &array_map_btf_ids[0],
 };
 #endif
@@ -1379,5 +1406,6 @@ static int array_of_map_gen_lookup(struct bpf_map *map,
 	.map_lookup_batch = generic_map_lookup_batch,
 	.map_update_batch = generic_map_update_batch,
 	.map_check_btf = map_check_no_btf,
+	.map_mem_usage = array_map_mem_usage,
 	.map_btf_id = &array_map_btf_ids[0],
 };
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH bpf-next v3 05/18] bpf: stackmap memory usage
  2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
                   ` (3 preceding siblings ...)
  2023-02-27 15:20 ` [PATCH bpf-next v3 04/18] bpf: arraymap " Yafang Shao
@ 2023-02-27 15:20 ` Yafang Shao
  2023-02-27 15:20 ` [PATCH bpf-next v3 06/18] bpf: reuseport_array " Yafang Shao
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Yafang Shao @ 2023-02-27 15:20 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong
  Cc: bpf, Yafang Shao

A new helper is introduced to get stackmap memory usage. Some small
memory allocations are ignored as their memory size is quite small
compared to the totol usage.

The result as follows,
- before
16: stack_trace  name count_map  flags 0x0
        key 4B  value 8B  max_entries 65536  memlock 1048576B

- after
16: stack_trace  name count_map  flags 0x0
        key 4B  value 8B  max_entries 65536  memlock 2097472B

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 kernel/bpf/stackmap.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c
index aecea74..0f1d8dc 100644
--- a/kernel/bpf/stackmap.c
+++ b/kernel/bpf/stackmap.c
@@ -654,6 +654,19 @@ static void stack_map_free(struct bpf_map *map)
 	put_callchain_buffers();
 }
 
+static u64 stack_map_mem_usage(const struct bpf_map *map)
+{
+	struct bpf_stack_map *smap = container_of(map, struct bpf_stack_map, map);
+	u64 value_size = map->value_size;
+	u64 n_buckets = smap->n_buckets;
+	u64 enties = map->max_entries;
+	u64 usage = sizeof(*smap);
+
+	usage += n_buckets * sizeof(struct stack_map_bucket *);
+	usage += enties * (sizeof(struct stack_map_bucket) + value_size);
+	return usage;
+}
+
 BTF_ID_LIST_SINGLE(stack_trace_map_btf_ids, struct, bpf_stack_map)
 const struct bpf_map_ops stack_trace_map_ops = {
 	.map_meta_equal = bpf_map_meta_equal,
@@ -664,5 +677,6 @@ static void stack_map_free(struct bpf_map *map)
 	.map_update_elem = stack_map_update_elem,
 	.map_delete_elem = stack_map_delete_elem,
 	.map_check_btf = map_check_no_btf,
+	.map_mem_usage = stack_map_mem_usage,
 	.map_btf_id = &stack_trace_map_btf_ids[0],
 };
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH bpf-next v3 06/18] bpf: reuseport_array memory usage
  2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
                   ` (4 preceding siblings ...)
  2023-02-27 15:20 ` [PATCH bpf-next v3 05/18] bpf: stackmap " Yafang Shao
@ 2023-02-27 15:20 ` Yafang Shao
  2023-02-27 15:20 ` [PATCH bpf-next v3 07/18] bpf: ringbuf " Yafang Shao
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Yafang Shao @ 2023-02-27 15:20 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong
  Cc: bpf, Yafang Shao

A new helper is introduced to calculate reuseport_array memory usage.

The result as follows,
- before
14: reuseport_sockarray  name count_map  flags 0x0
        key 4B  value 8B  max_entries 65536  memlock 1048576B

- after
14: reuseport_sockarray  name count_map  flags 0x0
        key 4B  value 8B  max_entries 65536  memlock 524544B

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 kernel/bpf/reuseport_array.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/kernel/bpf/reuseport_array.c b/kernel/bpf/reuseport_array.c
index 82c6161..71cb72f 100644
--- a/kernel/bpf/reuseport_array.c
+++ b/kernel/bpf/reuseport_array.c
@@ -335,6 +335,13 @@ static int reuseport_array_get_next_key(struct bpf_map *map, void *key,
 	return 0;
 }
 
+static u64 reuseport_array_mem_usage(const struct bpf_map *map)
+{
+	struct reuseport_array *array;
+
+	return struct_size(array, ptrs, map->max_entries);
+}
+
 BTF_ID_LIST_SINGLE(reuseport_array_map_btf_ids, struct, reuseport_array)
 const struct bpf_map_ops reuseport_array_ops = {
 	.map_meta_equal = bpf_map_meta_equal,
@@ -344,5 +351,6 @@ static int reuseport_array_get_next_key(struct bpf_map *map, void *key,
 	.map_lookup_elem = reuseport_array_lookup_elem,
 	.map_get_next_key = reuseport_array_get_next_key,
 	.map_delete_elem = reuseport_array_delete_elem,
+	.map_mem_usage = reuseport_array_mem_usage,
 	.map_btf_id = &reuseport_array_map_btf_ids[0],
 };
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH bpf-next v3 07/18] bpf: ringbuf memory usage
  2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
                   ` (5 preceding siblings ...)
  2023-02-27 15:20 ` [PATCH bpf-next v3 06/18] bpf: reuseport_array " Yafang Shao
@ 2023-02-27 15:20 ` Yafang Shao
  2023-02-27 17:21   ` Andrii Nakryiko
  2023-02-27 15:20 ` [PATCH bpf-next v3 08/18] bpf: bloom_filter " Yafang Shao
                   ` (11 subsequent siblings)
  18 siblings, 1 reply; 26+ messages in thread
From: Yafang Shao @ 2023-02-27 15:20 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong
  Cc: bpf, Yafang Shao

A new helper ringbuf_map_mem_usage() is introduced to calculate ringbuf
memory usage.

The result as follows,
- before
15: ringbuf  name count_map  flags 0x0
        key 0B  value 0B  max_entries 65536  memlock 0B

- after
15: ringbuf  name count_map  flags 0x0
        key 0B  value 0B  max_entries 65536  memlock 78424B

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 kernel/bpf/ringbuf.c | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

diff --git a/kernel/bpf/ringbuf.c b/kernel/bpf/ringbuf.c
index 80f4b4d..2bbf6e2 100644
--- a/kernel/bpf/ringbuf.c
+++ b/kernel/bpf/ringbuf.c
@@ -336,6 +336,23 @@ static __poll_t ringbuf_map_poll_user(struct bpf_map *map, struct file *filp,
 	return 0;
 }
 
+static u64 ringbuf_map_mem_usage(const struct bpf_map *map)
+{
+	struct bpf_ringbuf_map *rb_map;
+	struct bpf_ringbuf *rb;
+	int nr_data_pages;
+	int nr_meta_pages;
+	u64 usage = sizeof(struct bpf_ringbuf_map);
+
+	rb_map = container_of(map, struct bpf_ringbuf_map, map);
+	rb = rb_map->rb;
+	usage += (u64)rb->nr_pages << PAGE_SHIFT;
+	nr_meta_pages = RINGBUF_PGOFF + RINGBUF_POS_PAGES;
+	nr_data_pages = map->max_entries >> PAGE_SHIFT;
+	usage += (nr_meta_pages + 2 * nr_data_pages) * sizeof(struct page *);
+	return usage;
+}
+
 BTF_ID_LIST_SINGLE(ringbuf_map_btf_ids, struct, bpf_ringbuf_map)
 const struct bpf_map_ops ringbuf_map_ops = {
 	.map_meta_equal = bpf_map_meta_equal,
@@ -347,6 +364,7 @@ static __poll_t ringbuf_map_poll_user(struct bpf_map *map, struct file *filp,
 	.map_update_elem = ringbuf_map_update_elem,
 	.map_delete_elem = ringbuf_map_delete_elem,
 	.map_get_next_key = ringbuf_map_get_next_key,
+	.map_mem_usage = ringbuf_map_mem_usage,
 	.map_btf_id = &ringbuf_map_btf_ids[0],
 };
 
@@ -361,6 +379,7 @@ static __poll_t ringbuf_map_poll_user(struct bpf_map *map, struct file *filp,
 	.map_update_elem = ringbuf_map_update_elem,
 	.map_delete_elem = ringbuf_map_delete_elem,
 	.map_get_next_key = ringbuf_map_get_next_key,
+	.map_mem_usage = ringbuf_map_mem_usage,
 	.map_btf_id = &user_ringbuf_map_btf_ids[0],
 };
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH bpf-next v3 08/18] bpf: bloom_filter memory usage
  2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
                   ` (6 preceding siblings ...)
  2023-02-27 15:20 ` [PATCH bpf-next v3 07/18] bpf: ringbuf " Yafang Shao
@ 2023-02-27 15:20 ` Yafang Shao
  2023-02-27 15:20 ` [PATCH bpf-next v3 09/18] bpf: cpumap " Yafang Shao
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Yafang Shao @ 2023-02-27 15:20 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong
  Cc: bpf, Yafang Shao

Introduce a new helper to calculate the bloom_filter memory usage.

The result as follows,
- before
16: bloom_filter  flags 0x0
        key 0B  value 8B  max_entries 65536  memlock 524288B

- after
16: bloom_filter  flags 0x0
        key 0B  value 8B  max_entries 65536  memlock 65856B

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 kernel/bpf/bloom_filter.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/kernel/bpf/bloom_filter.c b/kernel/bpf/bloom_filter.c
index 48ee750..6350c5d 100644
--- a/kernel/bpf/bloom_filter.c
+++ b/kernel/bpf/bloom_filter.c
@@ -193,6 +193,17 @@ static int bloom_map_check_btf(const struct bpf_map *map,
 	return btf_type_is_void(key_type) ? 0 : -EINVAL;
 }
 
+static u64 bloom_map_mem_usage(const struct bpf_map *map)
+{
+	struct bpf_bloom_filter *bloom;
+	u64 bitset_bytes;
+
+	bloom = container_of(map, struct bpf_bloom_filter, map);
+	bitset_bytes = BITS_TO_BYTES((u64)bloom->bitset_mask + 1);
+	bitset_bytes = roundup(bitset_bytes, sizeof(unsigned long));
+	return sizeof(*bloom) + bitset_bytes;
+}
+
 BTF_ID_LIST_SINGLE(bpf_bloom_map_btf_ids, struct, bpf_bloom_filter)
 const struct bpf_map_ops bloom_filter_map_ops = {
 	.map_meta_equal = bpf_map_meta_equal,
@@ -206,5 +217,6 @@ static int bloom_map_check_btf(const struct bpf_map *map,
 	.map_update_elem = bloom_map_update_elem,
 	.map_delete_elem = bloom_map_delete_elem,
 	.map_check_btf = bloom_map_check_btf,
+	.map_mem_usage = bloom_map_mem_usage,
 	.map_btf_id = &bpf_bloom_map_btf_ids[0],
 };
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH bpf-next v3 09/18] bpf: cpumap memory usage
  2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
                   ` (7 preceding siblings ...)
  2023-02-27 15:20 ` [PATCH bpf-next v3 08/18] bpf: bloom_filter " Yafang Shao
@ 2023-02-27 15:20 ` Yafang Shao
  2023-02-27 15:20 ` [PATCH bpf-next v3 10/18] bpf: devmap " Yafang Shao
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Yafang Shao @ 2023-02-27 15:20 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong
  Cc: bpf, Yafang Shao

A new helper is introduced to calculate cpumap memory usage. The size of
cpu_entries can be dynamically changed when we update or delete a cpumap
element, but this patch doesn't include the memory size of cpu_entry
yet. We can dynamically calculate the memory usage when we alloc or free
a cpu_entry, but it will take extra runtime overhead, so let just put it
aside currently. Note that the size of different cpu_entry may be
different as well.

The result as follows,
- before
48: cpumap  name count_map  flags 0x4
        key 4B  value 4B  max_entries 64  memlock 4096B

- after
48: cpumap  name count_map  flags 0x4
        key 4B  value 4B  max_entries 64  memlock 832B

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 kernel/bpf/cpumap.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/kernel/bpf/cpumap.c b/kernel/bpf/cpumap.c
index d2110c1..871809e 100644
--- a/kernel/bpf/cpumap.c
+++ b/kernel/bpf/cpumap.c
@@ -673,6 +673,15 @@ static int cpu_map_redirect(struct bpf_map *map, u64 index, u64 flags)
 				      __cpu_map_lookup_elem);
 }
 
+static u64 cpu_map_mem_usage(const struct bpf_map *map)
+{
+	u64 usage = sizeof(struct bpf_cpu_map);
+
+	/* Currently the dynamically allocated elements are not counted */
+	usage += (u64)map->max_entries * sizeof(struct bpf_cpu_map_entry *);
+	return usage;
+}
+
 BTF_ID_LIST_SINGLE(cpu_map_btf_ids, struct, bpf_cpu_map)
 const struct bpf_map_ops cpu_map_ops = {
 	.map_meta_equal		= bpf_map_meta_equal,
@@ -683,6 +692,7 @@ static int cpu_map_redirect(struct bpf_map *map, u64 index, u64 flags)
 	.map_lookup_elem	= cpu_map_lookup_elem,
 	.map_get_next_key	= cpu_map_get_next_key,
 	.map_check_btf		= map_check_no_btf,
+	.map_mem_usage		= cpu_map_mem_usage,
 	.map_btf_id		= &cpu_map_btf_ids[0],
 	.map_redirect		= cpu_map_redirect,
 };
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH bpf-next v3 10/18] bpf: devmap memory usage
  2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
                   ` (8 preceding siblings ...)
  2023-02-27 15:20 ` [PATCH bpf-next v3 09/18] bpf: cpumap " Yafang Shao
@ 2023-02-27 15:20 ` Yafang Shao
  2023-02-27 15:20 ` [PATCH bpf-next v3 11/18] bpf: queue_stack_maps " Yafang Shao
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Yafang Shao @ 2023-02-27 15:20 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong
  Cc: bpf, Yafang Shao

A new helper is introduced to calculate the memory usage of devmap and
devmap_hash. The number of dynamically allocated elements are recored
for devmap_hash already, but not for devmap. To track the memory size of
dynamically allocated elements, this patch also count the numbers for
devmap.

The result as follows,
- before
40: devmap  name count_map  flags 0x80
        key 4B  value 4B  max_entries 65536  memlock 524288B
41: devmap_hash  name count_map  flags 0x80
        key 4B  value 4B  max_entries 65536  memlock 524288B

- after
40: devmap  name count_map  flags 0x80  <<<< no elements
        key 4B  value 4B  max_entries 65536  memlock 524608B
41: devmap_hash  name count_map  flags 0x80 <<<< no elements
        key 4B  value 4B  max_entries 65536  memlock 524608B

Note that the number of buckets is same with max_entries for devmap_hash
in this case.

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 kernel/bpf/devmap.c | 26 ++++++++++++++++++++++++--
 1 file changed, 24 insertions(+), 2 deletions(-)

diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
index 2675fef..19b036a 100644
--- a/kernel/bpf/devmap.c
+++ b/kernel/bpf/devmap.c
@@ -819,8 +819,10 @@ static int dev_map_delete_elem(struct bpf_map *map, void *key)
 		return -EINVAL;
 
 	old_dev = unrcu_pointer(xchg(&dtab->netdev_map[k], NULL));
-	if (old_dev)
+	if (old_dev) {
 		call_rcu(&old_dev->rcu, __dev_map_entry_free);
+		atomic_dec((atomic_t *)&dtab->items);
+	}
 	return 0;
 }
 
@@ -931,6 +933,8 @@ static int __dev_map_update_elem(struct net *net, struct bpf_map *map,
 	old_dev = unrcu_pointer(xchg(&dtab->netdev_map[i], RCU_INITIALIZER(dev)));
 	if (old_dev)
 		call_rcu(&old_dev->rcu, __dev_map_entry_free);
+	else
+		atomic_inc((atomic_t *)&dtab->items);
 
 	return 0;
 }
@@ -1016,6 +1020,20 @@ static int dev_hash_map_redirect(struct bpf_map *map, u64 ifindex, u64 flags)
 				      __dev_map_hash_lookup_elem);
 }
 
+static u64 dev_map_mem_usage(const struct bpf_map *map)
+{
+	struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
+	u64 usage = sizeof(struct bpf_dtab);
+
+	if (map->map_type == BPF_MAP_TYPE_DEVMAP_HASH)
+		usage += (u64)dtab->n_buckets * sizeof(struct hlist_head);
+	else
+		usage += (u64)map->max_entries * sizeof(struct bpf_dtab_netdev *);
+	usage += atomic_read((atomic_t *)&dtab->items) *
+			 (u64)sizeof(struct bpf_dtab_netdev);
+	return usage;
+}
+
 BTF_ID_LIST_SINGLE(dev_map_btf_ids, struct, bpf_dtab)
 const struct bpf_map_ops dev_map_ops = {
 	.map_meta_equal = bpf_map_meta_equal,
@@ -1026,6 +1044,7 @@ static int dev_hash_map_redirect(struct bpf_map *map, u64 ifindex, u64 flags)
 	.map_update_elem = dev_map_update_elem,
 	.map_delete_elem = dev_map_delete_elem,
 	.map_check_btf = map_check_no_btf,
+	.map_mem_usage = dev_map_mem_usage,
 	.map_btf_id = &dev_map_btf_ids[0],
 	.map_redirect = dev_map_redirect,
 };
@@ -1039,6 +1058,7 @@ static int dev_hash_map_redirect(struct bpf_map *map, u64 ifindex, u64 flags)
 	.map_update_elem = dev_map_hash_update_elem,
 	.map_delete_elem = dev_map_hash_delete_elem,
 	.map_check_btf = map_check_no_btf,
+	.map_mem_usage = dev_map_mem_usage,
 	.map_btf_id = &dev_map_btf_ids[0],
 	.map_redirect = dev_hash_map_redirect,
 };
@@ -1109,9 +1129,11 @@ static int dev_map_notification(struct notifier_block *notifier,
 				if (!dev || netdev != dev->dev)
 					continue;
 				odev = unrcu_pointer(cmpxchg(&dtab->netdev_map[i], RCU_INITIALIZER(dev), NULL));
-				if (dev == odev)
+				if (dev == odev) {
 					call_rcu(&dev->rcu,
 						 __dev_map_entry_free);
+					atomic_dec((atomic_t *)&dtab->items);
+				}
 			}
 		}
 		rcu_read_unlock();
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH bpf-next v3 11/18] bpf: queue_stack_maps memory usage
  2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
                   ` (9 preceding siblings ...)
  2023-02-27 15:20 ` [PATCH bpf-next v3 10/18] bpf: devmap " Yafang Shao
@ 2023-02-27 15:20 ` Yafang Shao
  2023-02-27 15:20 ` [PATCH bpf-next v3 12/18] bpf: bpf_struct_ops " Yafang Shao
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Yafang Shao @ 2023-02-27 15:20 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong
  Cc: bpf, Yafang Shao

A new helper is introduced to calculate queue_stack_maps memory usage.

The result as follows,

- before
20: queue  name count_map  flags 0x0
        key 0B  value 4B  max_entries 65536  memlock 266240B
21: stack  name count_map  flags 0x0
        key 0B  value 4B  max_entries 65536  memlock 266240B

- after
20: queue  name count_map  flags 0x0
        key 0B  value 4B  max_entries 65536  memlock 524288B
21: stack  name count_map  flags 0x0
        key 0B  value 4B  max_entries 65536  memlock 524288B

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 kernel/bpf/queue_stack_maps.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/kernel/bpf/queue_stack_maps.c b/kernel/bpf/queue_stack_maps.c
index 8a5e060..63ecbbc 100644
--- a/kernel/bpf/queue_stack_maps.c
+++ b/kernel/bpf/queue_stack_maps.c
@@ -246,6 +246,14 @@ static int queue_stack_map_get_next_key(struct bpf_map *map, void *key,
 	return -EINVAL;
 }
 
+static u64 queue_stack_map_mem_usage(const struct bpf_map *map)
+{
+	u64 usage = sizeof(struct bpf_queue_stack);
+
+	usage += ((u64)map->max_entries + 1) * map->value_size;
+	return usage;
+}
+
 BTF_ID_LIST_SINGLE(queue_map_btf_ids, struct, bpf_queue_stack)
 const struct bpf_map_ops queue_map_ops = {
 	.map_meta_equal = bpf_map_meta_equal,
@@ -259,6 +267,7 @@ static int queue_stack_map_get_next_key(struct bpf_map *map, void *key,
 	.map_pop_elem = queue_map_pop_elem,
 	.map_peek_elem = queue_map_peek_elem,
 	.map_get_next_key = queue_stack_map_get_next_key,
+	.map_mem_usage = queue_stack_map_mem_usage,
 	.map_btf_id = &queue_map_btf_ids[0],
 };
 
@@ -274,5 +283,6 @@ static int queue_stack_map_get_next_key(struct bpf_map *map, void *key,
 	.map_pop_elem = stack_map_pop_elem,
 	.map_peek_elem = stack_map_peek_elem,
 	.map_get_next_key = queue_stack_map_get_next_key,
+	.map_mem_usage = queue_stack_map_mem_usage,
 	.map_btf_id = &queue_map_btf_ids[0],
 };
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH bpf-next v3 12/18] bpf: bpf_struct_ops memory usage
  2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
                   ` (10 preceding siblings ...)
  2023-02-27 15:20 ` [PATCH bpf-next v3 11/18] bpf: queue_stack_maps " Yafang Shao
@ 2023-02-27 15:20 ` Yafang Shao
  2023-02-27 15:20 ` [PATCH bpf-next v3 13/18] bpf: local_storage " Yafang Shao
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Yafang Shao @ 2023-02-27 15:20 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong
  Cc: bpf, Yafang Shao

A new helper is introduced to calculate bpf_struct_ops memory usage.

The result as follows,

- before
1: struct_ops  name count_map  flags 0x0
        key 4B  value 256B  max_entries 1  memlock 4096B
        btf_id 73

- after
1: struct_ops  name count_map  flags 0x0
        key 4B  value 256B  max_entries 1  memlock 5016B
        btf_id 73

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 kernel/bpf/bpf_struct_ops.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/kernel/bpf/bpf_struct_ops.c b/kernel/bpf/bpf_struct_ops.c
index ece9870..38903fb 100644
--- a/kernel/bpf/bpf_struct_ops.c
+++ b/kernel/bpf/bpf_struct_ops.c
@@ -641,6 +641,21 @@ static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
 	return map;
 }
 
+static u64 bpf_struct_ops_map_mem_usage(const struct bpf_map *map)
+{
+	struct bpf_struct_ops_map *st_map = (struct bpf_struct_ops_map *)map;
+	const struct bpf_struct_ops *st_ops = st_map->st_ops;
+	const struct btf_type *vt = st_ops->value_type;
+	u64 usage;
+
+	usage = sizeof(*st_map) +
+			vt->size - sizeof(struct bpf_struct_ops_value);
+	usage += vt->size;
+	usage += btf_type_vlen(vt) * sizeof(struct bpf_links *);
+	usage += PAGE_SIZE;
+	return usage;
+}
+
 BTF_ID_LIST_SINGLE(bpf_struct_ops_map_btf_ids, struct, bpf_struct_ops_map)
 const struct bpf_map_ops bpf_struct_ops_map_ops = {
 	.map_alloc_check = bpf_struct_ops_map_alloc_check,
@@ -651,6 +666,7 @@ static struct bpf_map *bpf_struct_ops_map_alloc(union bpf_attr *attr)
 	.map_delete_elem = bpf_struct_ops_map_delete_elem,
 	.map_update_elem = bpf_struct_ops_map_update_elem,
 	.map_seq_show_elem = bpf_struct_ops_map_seq_show_elem,
+	.map_mem_usage = bpf_struct_ops_map_mem_usage,
 	.map_btf_id = &bpf_struct_ops_map_btf_ids[0],
 };
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH bpf-next v3 13/18] bpf: local_storage memory usage
  2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
                   ` (11 preceding siblings ...)
  2023-02-27 15:20 ` [PATCH bpf-next v3 12/18] bpf: bpf_struct_ops " Yafang Shao
@ 2023-02-27 15:20 ` Yafang Shao
  2023-02-27 15:20 ` [PATCH bpf-next v3 14/18] bpf, net: bpf_local_storage " Yafang Shao
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Yafang Shao @ 2023-02-27 15:20 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong
  Cc: bpf, Yafang Shao

A new helper is introduced to calculate local_storage map memory usage.
Currently the dynamically allocated elements are not counted, since it
will take runtime overhead in the element update or delete path. So
let's put it aside currently, and implement it in the future if the user
really needs it.

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 kernel/bpf/local_storage.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
index e90d9f6..a993560 100644
--- a/kernel/bpf/local_storage.c
+++ b/kernel/bpf/local_storage.c
@@ -446,6 +446,12 @@ static void cgroup_storage_seq_show_elem(struct bpf_map *map, void *key,
 	rcu_read_unlock();
 }
 
+static u64 cgroup_storage_map_usage(const struct bpf_map *map)
+{
+	/* Currently the dynamically allocated elements are not counted. */
+	return sizeof(struct bpf_cgroup_storage_map);
+}
+
 BTF_ID_LIST_SINGLE(cgroup_storage_map_btf_ids, struct,
 		   bpf_cgroup_storage_map)
 const struct bpf_map_ops cgroup_storage_map_ops = {
@@ -457,6 +463,7 @@ static void cgroup_storage_seq_show_elem(struct bpf_map *map, void *key,
 	.map_delete_elem = cgroup_storage_delete_elem,
 	.map_check_btf = cgroup_storage_check_btf,
 	.map_seq_show_elem = cgroup_storage_seq_show_elem,
+	.map_mem_usage = cgroup_storage_map_usage,
 	.map_btf_id = &cgroup_storage_map_btf_ids[0],
 };
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH bpf-next v3 14/18] bpf, net: bpf_local_storage memory usage
  2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
                   ` (12 preceding siblings ...)
  2023-02-27 15:20 ` [PATCH bpf-next v3 13/18] bpf: local_storage " Yafang Shao
@ 2023-02-27 15:20 ` Yafang Shao
  2023-02-27 15:20 ` [PATCH bpf-next v3 15/18] bpf, net: sock_map " Yafang Shao
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Yafang Shao @ 2023-02-27 15:20 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong
  Cc: bpf, Yafang Shao

A new helper is introduced into bpf_local_storage map to calculate the
memory usage. This helper is also used by other maps like
bpf_cgrp_storage, bpf_inode_storage, bpf_task_storage and etc.

Note that currently the dynamically allocated storage elements are not
counted in the usage, since it will take extra runtime overhead in the
elements update or delete path. So let's put it aside now, and implement
it in the future when someone really need it.

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 include/linux/bpf_local_storage.h |  1 +
 kernel/bpf/bpf_cgrp_storage.c     |  1 +
 kernel/bpf/bpf_inode_storage.c    |  1 +
 kernel/bpf/bpf_local_storage.c    | 10 ++++++++++
 kernel/bpf/bpf_task_storage.c     |  1 +
 net/core/bpf_sk_storage.c         |  1 +
 6 files changed, 15 insertions(+)

diff --git a/include/linux/bpf_local_storage.h b/include/linux/bpf_local_storage.h
index 6d37a40..d934248 100644
--- a/include/linux/bpf_local_storage.h
+++ b/include/linux/bpf_local_storage.h
@@ -164,5 +164,6 @@ struct bpf_local_storage_data *
 			 void *value, u64 map_flags, gfp_t gfp_flags);
 
 void bpf_local_storage_free_rcu(struct rcu_head *rcu);
+u64 bpf_local_storage_map_mem_usage(const struct bpf_map *map);
 
 #endif /* _BPF_LOCAL_STORAGE_H */
diff --git a/kernel/bpf/bpf_cgrp_storage.c b/kernel/bpf/bpf_cgrp_storage.c
index 6cdf6d9..9ae07ae 100644
--- a/kernel/bpf/bpf_cgrp_storage.c
+++ b/kernel/bpf/bpf_cgrp_storage.c
@@ -221,6 +221,7 @@ static void cgroup_storage_map_free(struct bpf_map *map)
 	.map_update_elem = bpf_cgrp_storage_update_elem,
 	.map_delete_elem = bpf_cgrp_storage_delete_elem,
 	.map_check_btf = bpf_local_storage_map_check_btf,
+	.map_mem_usage = bpf_local_storage_map_mem_usage,
 	.map_btf_id = &bpf_local_storage_map_btf_id[0],
 	.map_owner_storage_ptr = cgroup_storage_ptr,
 };
diff --git a/kernel/bpf/bpf_inode_storage.c b/kernel/bpf/bpf_inode_storage.c
index 05f4c66..43e2619c 100644
--- a/kernel/bpf/bpf_inode_storage.c
+++ b/kernel/bpf/bpf_inode_storage.c
@@ -223,6 +223,7 @@ static void inode_storage_map_free(struct bpf_map *map)
 	.map_update_elem = bpf_fd_inode_storage_update_elem,
 	.map_delete_elem = bpf_fd_inode_storage_delete_elem,
 	.map_check_btf = bpf_local_storage_map_check_btf,
+	.map_mem_usage = bpf_local_storage_map_mem_usage,
 	.map_btf_id = &bpf_local_storage_map_btf_id[0],
 	.map_owner_storage_ptr = inode_storage_ptr,
 };
diff --git a/kernel/bpf/bpf_local_storage.c b/kernel/bpf/bpf_local_storage.c
index 58da17a..0d4d108 100644
--- a/kernel/bpf/bpf_local_storage.c
+++ b/kernel/bpf/bpf_local_storage.c
@@ -646,6 +646,16 @@ bool bpf_local_storage_unlink_nolock(struct bpf_local_storage *local_storage)
 	return free_storage;
 }
 
+u64 bpf_local_storage_map_mem_usage(const struct bpf_map *map)
+{
+	struct bpf_local_storage_map *smap = (struct bpf_local_storage_map *)map;
+	u64 usage = sizeof(*smap);
+
+	/* The dynamically callocated selems are not counted currently. */
+	usage += sizeof(*smap->buckets) * (1ULL << smap->bucket_log);
+	return usage;
+}
+
 struct bpf_map *
 bpf_local_storage_map_alloc(union bpf_attr *attr,
 			    struct bpf_local_storage_cache *cache)
diff --git a/kernel/bpf/bpf_task_storage.c b/kernel/bpf/bpf_task_storage.c
index 1e48605..20f9422 100644
--- a/kernel/bpf/bpf_task_storage.c
+++ b/kernel/bpf/bpf_task_storage.c
@@ -335,6 +335,7 @@ static void task_storage_map_free(struct bpf_map *map)
 	.map_update_elem = bpf_pid_task_storage_update_elem,
 	.map_delete_elem = bpf_pid_task_storage_delete_elem,
 	.map_check_btf = bpf_local_storage_map_check_btf,
+	.map_mem_usage = bpf_local_storage_map_mem_usage,
 	.map_btf_id = &bpf_local_storage_map_btf_id[0],
 	.map_owner_storage_ptr = task_storage_ptr,
 };
diff --git a/net/core/bpf_sk_storage.c b/net/core/bpf_sk_storage.c
index bb378c3..7a36353 100644
--- a/net/core/bpf_sk_storage.c
+++ b/net/core/bpf_sk_storage.c
@@ -324,6 +324,7 @@ static void bpf_sk_storage_uncharge(struct bpf_local_storage_map *smap,
 	.map_local_storage_charge = bpf_sk_storage_charge,
 	.map_local_storage_uncharge = bpf_sk_storage_uncharge,
 	.map_owner_storage_ptr = bpf_sk_storage_ptr,
+	.map_mem_usage = bpf_local_storage_map_mem_usage,
 };
 
 const struct bpf_func_proto bpf_sk_storage_get_proto = {
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH bpf-next v3 15/18] bpf, net: sock_map memory usage
  2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
                   ` (13 preceding siblings ...)
  2023-02-27 15:20 ` [PATCH bpf-next v3 14/18] bpf, net: bpf_local_storage " Yafang Shao
@ 2023-02-27 15:20 ` Yafang Shao
  2023-02-27 15:20 ` [PATCH bpf-next v3 16/18] bpf, net: xskmap " Yafang Shao
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Yafang Shao @ 2023-02-27 15:20 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong
  Cc: bpf, Yafang Shao

sockmap and sockhash don't have something in common in allocation, so let's
introduce different helpers to calculate their memory usage.

The reuslt as follows,

- before
28: sockmap  name count_map  flags 0x0
        key 4B  value 4B  max_entries 65536  memlock 524288B
29: sockhash  name count_map  flags 0x0
        key 4B  value 4B  max_entries 65536  memlock 524288B

- after
28: sockmap  name count_map  flags 0x0
        key 4B  value 4B  max_entries 65536  memlock 524608B
29: sockhash  name count_map  flags 0x0  <<<< no updated elements
        key 4B  value 4B  max_entries 65536  memlock 1048896B

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 net/core/sock_map.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/net/core/sock_map.c b/net/core/sock_map.c
index a68a729..9b854e2 100644
--- a/net/core/sock_map.c
+++ b/net/core/sock_map.c
@@ -797,6 +797,14 @@ static void sock_map_fini_seq_private(void *priv_data)
 	bpf_map_put_with_uref(info->map);
 }
 
+static u64 sock_map_mem_usage(const struct bpf_map *map)
+{
+	u64 usage = sizeof(struct bpf_stab);
+
+	usage += (u64)map->max_entries * sizeof(struct sock *);
+	return usage;
+}
+
 static const struct bpf_iter_seq_info sock_map_iter_seq_info = {
 	.seq_ops		= &sock_map_seq_ops,
 	.init_seq_private	= sock_map_init_seq_private,
@@ -816,6 +824,7 @@ static void sock_map_fini_seq_private(void *priv_data)
 	.map_lookup_elem	= sock_map_lookup,
 	.map_release_uref	= sock_map_release_progs,
 	.map_check_btf		= map_check_no_btf,
+	.map_mem_usage		= sock_map_mem_usage,
 	.map_btf_id		= &sock_map_btf_ids[0],
 	.iter_seq_info		= &sock_map_iter_seq_info,
 };
@@ -1397,6 +1406,16 @@ static void sock_hash_fini_seq_private(void *priv_data)
 	bpf_map_put_with_uref(info->map);
 }
 
+static u64 sock_hash_mem_usage(const struct bpf_map *map)
+{
+	struct bpf_shtab *htab = container_of(map, struct bpf_shtab, map);
+	u64 usage = sizeof(*htab);
+
+	usage += htab->buckets_num * sizeof(struct bpf_shtab_bucket);
+	usage += atomic_read(&htab->count) * (u64)htab->elem_size;
+	return usage;
+}
+
 static const struct bpf_iter_seq_info sock_hash_iter_seq_info = {
 	.seq_ops		= &sock_hash_seq_ops,
 	.init_seq_private	= sock_hash_init_seq_private,
@@ -1416,6 +1435,7 @@ static void sock_hash_fini_seq_private(void *priv_data)
 	.map_lookup_elem_sys_only = sock_hash_lookup_sys,
 	.map_release_uref	= sock_hash_release_progs,
 	.map_check_btf		= map_check_no_btf,
+	.map_mem_usage		= sock_hash_mem_usage,
 	.map_btf_id		= &sock_hash_map_btf_ids[0],
 	.iter_seq_info		= &sock_hash_iter_seq_info,
 };
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH bpf-next v3 16/18] bpf, net: xskmap memory usage
  2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
                   ` (14 preceding siblings ...)
  2023-02-27 15:20 ` [PATCH bpf-next v3 15/18] bpf, net: sock_map " Yafang Shao
@ 2023-02-27 15:20 ` Yafang Shao
  2023-02-27 15:20 ` [PATCH bpf-next v3 17/18] bpf: offload map " Yafang Shao
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 26+ messages in thread
From: Yafang Shao @ 2023-02-27 15:20 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong
  Cc: bpf, Yafang Shao

A new helper is introduced to calculate xskmap memory usage.

The xfsmap memory usage can be dynamically changed when we add or remove
a xsk_map_node. Hence we need to track the count of xsk_map_node to get
its memory usage.

The result as follows,
- before
10: xskmap  name count_map  flags 0x0
        key 4B  value 4B  max_entries 65536  memlock 524288B

- after
10: xskmap  name count_map  flags 0x0 <<< no elements case
        key 4B  value 4B  max_entries 65536  memlock 524608B

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 include/net/xdp_sock.h |  1 +
 net/xdp/xskmap.c       | 13 +++++++++++++
 2 files changed, 14 insertions(+)

diff --git a/include/net/xdp_sock.h b/include/net/xdp_sock.h
index 3057e1a..e96a115 100644
--- a/include/net/xdp_sock.h
+++ b/include/net/xdp_sock.h
@@ -38,6 +38,7 @@ struct xdp_umem {
 struct xsk_map {
 	struct bpf_map map;
 	spinlock_t lock; /* Synchronize map updates */
+	atomic_t count;
 	struct xdp_sock __rcu *xsk_map[];
 };
 
diff --git a/net/xdp/xskmap.c b/net/xdp/xskmap.c
index 771d0fa..0c38d71 100644
--- a/net/xdp/xskmap.c
+++ b/net/xdp/xskmap.c
@@ -24,6 +24,7 @@ static struct xsk_map_node *xsk_map_node_alloc(struct xsk_map *map,
 		return ERR_PTR(-ENOMEM);
 
 	bpf_map_inc(&map->map);
+	atomic_inc(&map->count);
 
 	node->map = map;
 	node->map_entry = map_entry;
@@ -32,8 +33,11 @@ static struct xsk_map_node *xsk_map_node_alloc(struct xsk_map *map,
 
 static void xsk_map_node_free(struct xsk_map_node *node)
 {
+	struct xsk_map *map = node->map;
+
 	bpf_map_put(&node->map->map);
 	kfree(node);
+	atomic_dec(&map->count);
 }
 
 static void xsk_map_sock_add(struct xdp_sock *xs, struct xsk_map_node *node)
@@ -85,6 +89,14 @@ static struct bpf_map *xsk_map_alloc(union bpf_attr *attr)
 	return &m->map;
 }
 
+static u64 xsk_map_mem_usage(const struct bpf_map *map)
+{
+	struct xsk_map *m = container_of(map, struct xsk_map, map);
+
+	return struct_size(m, xsk_map, map->max_entries) +
+		   (u64)atomic_read(&m->count) * sizeof(struct xsk_map_node);
+}
+
 static void xsk_map_free(struct bpf_map *map)
 {
 	struct xsk_map *m = container_of(map, struct xsk_map, map);
@@ -267,6 +279,7 @@ static bool xsk_map_meta_equal(const struct bpf_map *meta0,
 	.map_update_elem = xsk_map_update_elem,
 	.map_delete_elem = xsk_map_delete_elem,
 	.map_check_btf = map_check_no_btf,
+	.map_mem_usage = xsk_map_mem_usage,
 	.map_btf_id = &xsk_map_btf_ids[0],
 	.map_redirect = xsk_map_redirect,
 };
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH bpf-next v3 17/18] bpf: offload map memory usage
  2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
                   ` (15 preceding siblings ...)
  2023-02-27 15:20 ` [PATCH bpf-next v3 16/18] bpf, net: xskmap " Yafang Shao
@ 2023-02-27 15:20 ` Yafang Shao
  2023-02-27 15:20 ` [PATCH bpf-next v3 18/18] bpf: enforce all maps having memory usage callback Yafang Shao
  2023-02-27 22:37 ` [PATCH bpf-next v3 00/18] bpf: bpf memory usage Daniel Borkmann
  18 siblings, 0 replies; 26+ messages in thread
From: Yafang Shao @ 2023-02-27 15:20 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong
  Cc: bpf, Yafang Shao

A new helper is introduced to calculate offload map memory usage. But
currently the memory dynamically allocated in netdev dev_ops, like
nsim_map_update_elem, is not counted. Let's just put it aside now.

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 include/linux/bpf.h  | 6 ++++++
 kernel/bpf/offload.c | 6 ++++++
 kernel/bpf/syscall.c | 1 +
 3 files changed, 13 insertions(+)

diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index bca0963..341e8df 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -2568,6 +2568,7 @@ static inline bool bpf_map_is_offloaded(struct bpf_map *map)
 
 struct bpf_map *bpf_map_offload_map_alloc(union bpf_attr *attr);
 void bpf_map_offload_map_free(struct bpf_map *map);
+u64 bpf_map_offload_map_mem_usage(const struct bpf_map *map);
 int bpf_prog_test_run_syscall(struct bpf_prog *prog,
 			      const union bpf_attr *kattr,
 			      union bpf_attr __user *uattr);
@@ -2639,6 +2640,11 @@ static inline void bpf_map_offload_map_free(struct bpf_map *map)
 {
 }
 
+static inline u64 bpf_map_offload_map_mem_usage(const struct bpf_map *map)
+{
+	return 0;
+}
+
 static inline int bpf_prog_test_run_syscall(struct bpf_prog *prog,
 					    const union bpf_attr *kattr,
 					    union bpf_attr __user *uattr)
diff --git a/kernel/bpf/offload.c b/kernel/bpf/offload.c
index 0c85e06..d9c9f45 100644
--- a/kernel/bpf/offload.c
+++ b/kernel/bpf/offload.c
@@ -563,6 +563,12 @@ void bpf_map_offload_map_free(struct bpf_map *map)
 	bpf_map_area_free(offmap);
 }
 
+u64 bpf_map_offload_map_mem_usage(const struct bpf_map *map)
+{
+	/* The memory dynamically allocated in netdev dev_ops is not counted */
+	return sizeof(struct bpf_offloaded_map);
+}
+
 int bpf_map_offload_lookup_elem(struct bpf_map *map, void *key, void *value)
 {
 	struct bpf_offloaded_map *offmap = map_to_offmap(map);
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 8333aa0..e12b03e 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -105,6 +105,7 @@ int bpf_check_uarg_tail_zero(bpfptr_t uaddr,
 	.map_alloc = bpf_map_offload_map_alloc,
 	.map_free = bpf_map_offload_map_free,
 	.map_check_btf = map_check_no_btf,
+	.map_mem_usage = bpf_map_offload_map_mem_usage,
 };
 
 static struct bpf_map *find_and_alloc_map(union bpf_attr *attr)
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* [PATCH bpf-next v3 18/18] bpf: enforce all maps having memory usage callback
  2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
                   ` (16 preceding siblings ...)
  2023-02-27 15:20 ` [PATCH bpf-next v3 17/18] bpf: offload map " Yafang Shao
@ 2023-02-27 15:20 ` Yafang Shao
  2023-02-27 22:37 ` [PATCH bpf-next v3 00/18] bpf: bpf memory usage Daniel Borkmann
  18 siblings, 0 replies; 26+ messages in thread
From: Yafang Shao @ 2023-02-27 15:20 UTC (permalink / raw)
  To: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong
  Cc: bpf, Yafang Shao

We have implemented memory usage callback for all maps, and we enforce
any newly added map having a callback as well. We will check the
callback at map creation time. If a map doesn't have the callback, it
will return EINVAL.

Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
 kernel/bpf/syscall.c | 10 +++-------
 1 file changed, 3 insertions(+), 7 deletions(-)

diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index e12b03e..cbe7ff3 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -129,6 +129,8 @@ static struct bpf_map *find_and_alloc_map(union bpf_attr *attr)
 	}
 	if (attr->map_ifindex)
 		ops = &bpf_map_offload_ops;
+	if (!ops->map_mem_usage)
+		return ERR_PTR(-EINVAL);
 	map = ops->map_alloc(attr);
 	if (IS_ERR(map))
 		return map;
@@ -775,13 +777,7 @@ static fmode_t map_get_sys_perms(struct bpf_map *map, struct fd f)
 /* Show the memory usage of a bpf map */
 static u64 bpf_map_memory_usage(const struct bpf_map *map)
 {
-	unsigned long size;
-
-	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);
+	return map->ops->map_mem_usage(map);
 }
 
 static void bpf_map_show_fdinfo(struct seq_file *m, struct file *filp)
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 26+ messages in thread

* Re: [PATCH bpf-next v3 07/18] bpf: ringbuf memory usage
  2023-02-27 15:20 ` [PATCH bpf-next v3 07/18] bpf: ringbuf " Yafang Shao
@ 2023-02-27 17:21   ` Andrii Nakryiko
  2023-02-28  2:55     ` Yafang Shao
  0 siblings, 1 reply; 26+ messages in thread
From: Andrii Nakryiko @ 2023-02-27 17:21 UTC (permalink / raw)
  To: Yafang Shao
  Cc: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong, bpf

On Mon, Feb 27, 2023 at 7:21 AM Yafang Shao <laoar.shao@gmail.com> wrote:
>
> A new helper ringbuf_map_mem_usage() is introduced to calculate ringbuf
> memory usage.
>
> The result as follows,
> - before
> 15: ringbuf  name count_map  flags 0x0
>         key 0B  value 0B  max_entries 65536  memlock 0B
>
> - after
> 15: ringbuf  name count_map  flags 0x0
>         key 0B  value 0B  max_entries 65536  memlock 78424B
>
> Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> ---
>  kernel/bpf/ringbuf.c | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
>
> diff --git a/kernel/bpf/ringbuf.c b/kernel/bpf/ringbuf.c
> index 80f4b4d..2bbf6e2 100644
> --- a/kernel/bpf/ringbuf.c
> +++ b/kernel/bpf/ringbuf.c
> @@ -336,6 +336,23 @@ static __poll_t ringbuf_map_poll_user(struct bpf_map *map, struct file *filp,
>         return 0;
>  }
>
> +static u64 ringbuf_map_mem_usage(const struct bpf_map *map)
> +{
> +       struct bpf_ringbuf_map *rb_map;
> +       struct bpf_ringbuf *rb;
> +       int nr_data_pages;
> +       int nr_meta_pages;
> +       u64 usage = sizeof(struct bpf_ringbuf_map);
> +
> +       rb_map = container_of(map, struct bpf_ringbuf_map, map);
> +       rb = rb_map->rb;

nit: rb_map seems unnecessary, I'd just go straight to rb

rb = container_of(map, struct bpf_ringbuf_map, map)->rb;

> +       usage += (u64)rb->nr_pages << PAGE_SHIFT;
> +       nr_meta_pages = RINGBUF_PGOFF + RINGBUF_POS_PAGES;

it would be cleaner to extract this into a constant
RINGBUF_NR_META_PAGES and use it in ringbuf_map_mem_usage and
bpf_ringbuf_area_alloc to keep them in sync

But other than that, looks good:

Acked-by: Andrii Nakryiko <andrii@kernel.org>

> +       nr_data_pages = map->max_entries >> PAGE_SHIFT;
> +       usage += (nr_meta_pages + 2 * nr_data_pages) * sizeof(struct page *);
> +       return usage;
> +}
> +
>  BTF_ID_LIST_SINGLE(ringbuf_map_btf_ids, struct, bpf_ringbuf_map)
>  const struct bpf_map_ops ringbuf_map_ops = {
>         .map_meta_equal = bpf_map_meta_equal,
> @@ -347,6 +364,7 @@ static __poll_t ringbuf_map_poll_user(struct bpf_map *map, struct file *filp,
>         .map_update_elem = ringbuf_map_update_elem,
>         .map_delete_elem = ringbuf_map_delete_elem,
>         .map_get_next_key = ringbuf_map_get_next_key,
> +       .map_mem_usage = ringbuf_map_mem_usage,
>         .map_btf_id = &ringbuf_map_btf_ids[0],
>  };
>
> @@ -361,6 +379,7 @@ static __poll_t ringbuf_map_poll_user(struct bpf_map *map, struct file *filp,
>         .map_update_elem = ringbuf_map_update_elem,
>         .map_delete_elem = ringbuf_map_delete_elem,
>         .map_get_next_key = ringbuf_map_get_next_key,
> +       .map_mem_usage = ringbuf_map_mem_usage,
>         .map_btf_id = &user_ringbuf_map_btf_ids[0],
>  };
>
> --
> 1.8.3.1
>

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH bpf-next v3 00/18] bpf: bpf memory usage
  2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
                   ` (17 preceding siblings ...)
  2023-02-27 15:20 ` [PATCH bpf-next v3 18/18] bpf: enforce all maps having memory usage callback Yafang Shao
@ 2023-02-27 22:37 ` Daniel Borkmann
  2023-02-28  2:53   ` Yafang Shao
  18 siblings, 1 reply; 26+ messages in thread
From: Daniel Borkmann @ 2023-02-27 22:37 UTC (permalink / raw)
  To: Yafang Shao, ast, andrii, kafai, songliubraving, yhs,
	john.fastabend, kpsingh, sdf, haoluo, jolsa, horenc,
	xiyou.wangcong
  Cc: bpf

On 2/27/23 4:20 PM, Yafang Shao wrote:
> Currently we can't get bpf memory usage reliably. bpftool now shows the
> bpf memory footprint, which is difference with bpf memory usage. The
> difference can be quite great in some cases, for example,
> 
> - non-preallocated bpf map
>    The non-preallocated bpf map memory usage is dynamically changed. The
>    allocated elements count can be from 0 to the max entries. But the
>    memory footprint in bpftool only shows a fixed number.
> 
> - bpf metadata consumes more memory than bpf element
>    In some corner cases, the bpf metadata can consumes a lot more memory
>    than bpf element consumes. For example, it can happen when the element
>    size is quite small.
> 
> - some maps don't have key, value or max_entries
>    For example the key_size and value_size of ringbuf is 0, so its
>    memlock is always 0.
> 
> We need a way to show the bpf memory usage especially there will be more
> and more bpf programs running on the production environment and thus the
> bpf memory usage is not trivial.
> 
> This patchset introduces a new map ops ->map_mem_usage to calculate the
> memory usage. Note that we don't intend to make the memory usage 100%
> accurate, while our goal is to make sure there is only a small difference
> between what bpftool reports and the real memory. That small difference
> can be ignored compared to the total usage.  That is enough to monitor
> the bpf memory usage. For example, the user can rely on this value to
> monitor the trend of bpf memory usage, compare the difference in bpf
> memory usage between different bpf program versions, figure out which
> maps consume large memory, and etc.

Now that there is the cgroup.memory=nobpf, this is now rebuilding the memory
accounting as a band aid that you would otherwise get for free via memcg.. :/
Can't you instead move the selectable memcg forward? Tejun and others have
brought up the resource domain concept, have you looked into it?

Thanks,
Daniel

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH bpf-next v3 00/18] bpf: bpf memory usage
  2023-02-27 22:37 ` [PATCH bpf-next v3 00/18] bpf: bpf memory usage Daniel Borkmann
@ 2023-02-28  2:53   ` Yafang Shao
  0 siblings, 0 replies; 26+ messages in thread
From: Yafang Shao @ 2023-02-28  2:53 UTC (permalink / raw)
  To: Daniel Borkmann
  Cc: ast, andrii, kafai, songliubraving, yhs, john.fastabend, kpsingh,
	sdf, haoluo, jolsa, horenc, xiyou.wangcong, bpf

On Tue, Feb 28, 2023 at 6:37 AM Daniel Borkmann <daniel@iogearbox.net> wrote:
>
> On 2/27/23 4:20 PM, Yafang Shao wrote:
> > Currently we can't get bpf memory usage reliably. bpftool now shows the
> > bpf memory footprint, which is difference with bpf memory usage. The
> > difference can be quite great in some cases, for example,
> >
> > - non-preallocated bpf map
> >    The non-preallocated bpf map memory usage is dynamically changed. The
> >    allocated elements count can be from 0 to the max entries. But the
> >    memory footprint in bpftool only shows a fixed number.
> >
> > - bpf metadata consumes more memory than bpf element
> >    In some corner cases, the bpf metadata can consumes a lot more memory
> >    than bpf element consumes. For example, it can happen when the element
> >    size is quite small.
> >
> > - some maps don't have key, value or max_entries
> >    For example the key_size and value_size of ringbuf is 0, so its
> >    memlock is always 0.
> >
> > We need a way to show the bpf memory usage especially there will be more
> > and more bpf programs running on the production environment and thus the
> > bpf memory usage is not trivial.
> >
> > This patchset introduces a new map ops ->map_mem_usage to calculate the
> > memory usage. Note that we don't intend to make the memory usage 100%
> > accurate, while our goal is to make sure there is only a small difference
> > between what bpftool reports and the real memory. That small difference
> > can be ignored compared to the total usage.  That is enough to monitor
> > the bpf memory usage. For example, the user can rely on this value to
> > monitor the trend of bpf memory usage, compare the difference in bpf
> > memory usage between different bpf program versions, figure out which
> > maps consume large memory, and etc.
>
> Now that there is the cgroup.memory=nobpf, this is now rebuilding the memory
> accounting as a band aid that you would otherwise get for free via memcg.. :/

No, we can't get it for free via memcg, because there's no such a
"bpf" item in memory.stat, but only "kmem", "sock" and "vmalloc" in
memory.stat. With these three items we still can't figure out the bpf
memory usage, because the bpf memory usage may be far less than kmem,
for example, the dentry may consume lots of kmem.
Furthermore,  we still can't get the memory usage of each individual
map with memcg, but we can get it with bpftool. As Alexei explained in
another thread [1], "bpftool map show | awk" can show all cases.

I have tried to add the bpf item into memory.stat earlier[2], but it
seems we'd better add "memcg_id" or "memcg_path" into
bpftool-{map,prog}-show[3] instead.

[1]. https://lore.kernel.org/bpf/CAADnVQJGF5Xthpn7D2DgHHvZz8+dnuz2xMi6yoSziuauXO7ncA@mail.gmail.com/
[2]. https://lore.kernel.org/bpf/20220921170002.29557-1-laoar.shao@gmail.com/
[3]. https://lore.kernel.org/bpf/CALOAHbCY4fGyAN6q3dd+hULs3hRJcYgvMR7M5wg1yb3vPiK=mw@mail.gmail.com/


> Can't you instead move the selectable memcg forward? Tejun and others have
> brought up the resource domain concept, have you looked into it?
>

I will take a look at the resource domain concept and try to move
selectable memory forward again, but it doesn't conflict with this
series.

-- 
Regards
Yafang

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH bpf-next v3 07/18] bpf: ringbuf memory usage
  2023-02-27 17:21   ` Andrii Nakryiko
@ 2023-02-28  2:55     ` Yafang Shao
  0 siblings, 0 replies; 26+ messages in thread
From: Yafang Shao @ 2023-02-28  2:55 UTC (permalink / raw)
  To: Andrii Nakryiko
  Cc: ast, daniel, andrii, kafai, songliubraving, yhs, john.fastabend,
	kpsingh, sdf, haoluo, jolsa, horenc, xiyou.wangcong, bpf

On Tue, Feb 28, 2023 at 1:22 AM Andrii Nakryiko
<andrii.nakryiko@gmail.com> wrote:
>
> On Mon, Feb 27, 2023 at 7:21 AM Yafang Shao <laoar.shao@gmail.com> wrote:
> >
> > A new helper ringbuf_map_mem_usage() is introduced to calculate ringbuf
> > memory usage.
> >
> > The result as follows,
> > - before
> > 15: ringbuf  name count_map  flags 0x0
> >         key 0B  value 0B  max_entries 65536  memlock 0B
> >
> > - after
> > 15: ringbuf  name count_map  flags 0x0
> >         key 0B  value 0B  max_entries 65536  memlock 78424B
> >
> > Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> > ---
> >  kernel/bpf/ringbuf.c | 19 +++++++++++++++++++
> >  1 file changed, 19 insertions(+)
> >
> > diff --git a/kernel/bpf/ringbuf.c b/kernel/bpf/ringbuf.c
> > index 80f4b4d..2bbf6e2 100644
> > --- a/kernel/bpf/ringbuf.c
> > +++ b/kernel/bpf/ringbuf.c
> > @@ -336,6 +336,23 @@ static __poll_t ringbuf_map_poll_user(struct bpf_map *map, struct file *filp,
> >         return 0;
> >  }
> >
> > +static u64 ringbuf_map_mem_usage(const struct bpf_map *map)
> > +{
> > +       struct bpf_ringbuf_map *rb_map;
> > +       struct bpf_ringbuf *rb;
> > +       int nr_data_pages;
> > +       int nr_meta_pages;
> > +       u64 usage = sizeof(struct bpf_ringbuf_map);
> > +
> > +       rb_map = container_of(map, struct bpf_ringbuf_map, map);
> > +       rb = rb_map->rb;
>
> nit: rb_map seems unnecessary, I'd just go straight to rb
>
> rb = container_of(map, struct bpf_ringbuf_map, map)->rb;

Thanks for the suggestion. I will do it.

>
> > +       usage += (u64)rb->nr_pages << PAGE_SHIFT;
> > +       nr_meta_pages = RINGBUF_PGOFF + RINGBUF_POS_PAGES;
>
> it would be cleaner to extract this into a constant
> RINGBUF_NR_META_PAGES and use it in ringbuf_map_mem_usage and
> bpf_ringbuf_area_alloc to keep them in sync
>

Will do it.

> But other than that, looks good:
>
> Acked-by: Andrii Nakryiko <andrii@kernel.org>

Thanks for the review.


-- 
Regards
Yafang

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH bpf-next v3 02/18] bpf: lpm_trie memory usage
  2023-02-27 15:20 ` [PATCH bpf-next v3 02/18] bpf: lpm_trie memory usage Yafang Shao
@ 2023-03-01  2:59   ` Hou Tao
  2023-03-03 10:38     ` Yafang Shao
  0 siblings, 1 reply; 26+ messages in thread
From: Hou Tao @ 2023-03-01  2:59 UTC (permalink / raw)
  To: laoar.shao
  Cc: andrii, ast, bpf, daniel, haoluo, horenc, john.fastabend, jolsa,
	kafai, kpsingh, sdf, songliubraving, xiyou.wangcong, yhs

From: Hou Tao <houtao1@huawei.com>

Hi,

> trie_mem_usage() is introduced to calculate the lpm_trie memory usage.
> Some small memory allocations are ignored. The inner node is also
> ignored.
> 
> The result as follows,
> 
> - before
> 10: lpm_trie  flags 0x1
>         key 8B  value 8B  max_entries 65536  memlock 1048576B
> 
> - after
> 10: lpm_trie  flags 0x1
>         key 8B  value 8B  max_entries 65536  memlock 2291536B
> 
> Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> ---
>  kernel/bpf/lpm_trie.c | 11 +++++++++++
>  1 file changed, 11 insertions(+)
> 
> diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c
> index d833496..e0ca08e 100644
> --- a/kernel/bpf/lpm_trie.c
> +++ b/kernel/bpf/lpm_trie.c
> @@ -720,6 +720,16 @@ static int trie_check_btf(const struct bpf_map *map,
>  	       -EINVAL : 0;
>  }
>  
> +static u64 trie_mem_usage(const struct bpf_map *map)
> +{
> +	struct lpm_trie *trie = container_of(map, struct lpm_trie, map);
> +	u64 elem_size;
> +
> +	elem_size = sizeof(struct lpm_trie_node) + trie->data_size +
> +			    trie->map.value_size;
> +	return elem_size * trie->n_entries;
Need to use READ_ONCE(trie->n_entries) because all updates of n_entries are protected by trie->lock and here it is a lockless read.

> +}
> +
>  BTF_ID_LIST_SINGLE(trie_map_btf_ids, struct, lpm_trie)
>  const struct bpf_map_ops trie_map_ops = {
>  	.map_meta_equal = bpf_map_meta_equal,
> @@ -733,5 +743,6 @@ static int trie_check_btf(const struct bpf_map *map,
>  	.map_update_batch = generic_map_update_batch,
>  	.map_delete_batch = generic_map_delete_batch,
>  	.map_check_btf = trie_check_btf,
> +	.map_mem_usage = trie_mem_usage,
>  	.map_btf_id = &trie_map_btf_ids[0],
>  };
> -- 
> 1.8.3.1
> 


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH bpf-next v3 03/18] bpf: hashtab memory usage
  2023-02-27 15:20 ` [PATCH bpf-next v3 03/18] bpf: hashtab " Yafang Shao
@ 2023-03-01  2:59   ` Hou Tao
  0 siblings, 0 replies; 26+ messages in thread
From: Hou Tao @ 2023-03-01  2:59 UTC (permalink / raw)
  To: laoar.shao
  Cc: andrii, ast, bpf, daniel, haoluo, horenc, john.fastabend, jolsa,
	kafai, kpsingh, sdf, songliubraving, xiyou.wangcong, yhs

From: Hou Tao <houtao1@huawei.com>

> htab_map_mem_usage() is introduced to calculate hashmap memory usage. In
> this helper, some small memory allocations are ignore, as their size is
> quite small compared with the total size. The inner_map_meta in
> hash_of_map is also ignored.
> 
> The result for hashtab as follows,
> 
> - before this change
> 1: hash  name count_map  flags 0x1  <<<< no prealloc, fully set
>         key 16B  value 24B  max_entries 1048576  memlock 41943040B
> 2: hash  name count_map  flags 0x1  <<<< no prealloc, none set
>         key 16B  value 24B  max_entries 1048576  memlock 41943040B
> 3: hash  name count_map  flags 0x0  <<<< prealloc
>         key 16B  value 24B  max_entries 1048576  memlock 41943040B
> 
> The memlock is always a fixed size whatever it is preallocated or
> not, and whatever the count of allocated elements is.
> 
> - after this change
> 1: hash  name count_map  flags 0x1    <<<< non prealloc, fully set
>         key 16B  value 24B  max_entries 1048576  memlock 117441536B
> 2: hash  name count_map  flags 0x1    <<<< non prealloc, non set
>         key 16B  value 24B  max_entries 1048576  memlock 16778240B
> 3: hash  name count_map  flags 0x0    <<<< prealloc
>         key 16B  value 24B  max_entries 1048576  memlock 109056000B
> 
> The memlock now is hashtab actually allocated.
> 
> The result for percpu hash map as follows,
> - before this change
> 4: percpu_hash  name count_map  flags 0x0       <<<< prealloc
>         key 16B  value 24B  max_entries 1048576  memlock 822083584B
> 5: percpu_hash  name count_map  flags 0x1       <<<< no prealloc
>         key 16B  value 24B  max_entries 1048576  memlock 822083584B
> 
> - after this change
> 4: percpu_hash  name count_map  flags 0x0
>         key 16B  value 24B  max_entries 1048576  memlock 897582080B
> 5: percpu_hash  name count_map  flags 0x1
>         key 16B  value 24B  max_entries 1048576  memlock 922748736B
> 
> At worst, the difference can be 10x, for example,
> - before this change
> 6: hash  name count_map  flags 0x0
>         key 4B  value 4B  max_entries 1048576  memlock 8388608B
> 
> - after this change
> 6: hash  name count_map  flags 0x0
>         key 4B  value 4B  max_entries 1048576  memlock 83889408B
> 
> Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> 
Acked-by: Hou Tao <houtao1@huawei.com>


^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: [PATCH bpf-next v3 02/18] bpf: lpm_trie memory usage
  2023-03-01  2:59   ` Hou Tao
@ 2023-03-03 10:38     ` Yafang Shao
  0 siblings, 0 replies; 26+ messages in thread
From: Yafang Shao @ 2023-03-03 10:38 UTC (permalink / raw)
  To: Hou Tao
  Cc: andrii, ast, bpf, daniel, haoluo, horenc, john.fastabend, jolsa,
	kafai, kpsingh, sdf, songliubraving, xiyou.wangcong, yhs

On Wed, Mar 1, 2023 at 10:31 AM Hou Tao <houtao@huaweicloud.com> wrote:
>
> From: Hou Tao <houtao1@huawei.com>
>
> Hi,
>
> > trie_mem_usage() is introduced to calculate the lpm_trie memory usage.
> > Some small memory allocations are ignored. The inner node is also
> > ignored.
> >
> > The result as follows,
> >
> > - before
> > 10: lpm_trie  flags 0x1
> >         key 8B  value 8B  max_entries 65536  memlock 1048576B
> >
> > - after
> > 10: lpm_trie  flags 0x1
> >         key 8B  value 8B  max_entries 65536  memlock 2291536B
> >
> > Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
> > ---
> >  kernel/bpf/lpm_trie.c | 11 +++++++++++
> >  1 file changed, 11 insertions(+)
> >
> > diff --git a/kernel/bpf/lpm_trie.c b/kernel/bpf/lpm_trie.c
> > index d833496..e0ca08e 100644
> > --- a/kernel/bpf/lpm_trie.c
> > +++ b/kernel/bpf/lpm_trie.c
> > @@ -720,6 +720,16 @@ static int trie_check_btf(const struct bpf_map *map,
> >              -EINVAL : 0;
> >  }
> >
> > +static u64 trie_mem_usage(const struct bpf_map *map)
> > +{
> > +     struct lpm_trie *trie = container_of(map, struct lpm_trie, map);
> > +     u64 elem_size;
> > +
> > +     elem_size = sizeof(struct lpm_trie_node) + trie->data_size +
> > +                         trie->map.value_size;
> > +     return elem_size * trie->n_entries;
> Need to use READ_ONCE(trie->n_entries) because all updates of n_entries are protected by trie->lock and here it is a lockless read.

Indeed. Will change it in the next version.
Thanks for your review.

-- 
Regards
Yafang

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2023-03-03 10:38 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-27 15:20 [PATCH bpf-next v3 00/18] bpf: bpf memory usage Yafang Shao
2023-02-27 15:20 ` [PATCH bpf-next v3 01/18] bpf: add new map ops ->map_mem_usage Yafang Shao
2023-02-27 15:20 ` [PATCH bpf-next v3 02/18] bpf: lpm_trie memory usage Yafang Shao
2023-03-01  2:59   ` Hou Tao
2023-03-03 10:38     ` Yafang Shao
2023-02-27 15:20 ` [PATCH bpf-next v3 03/18] bpf: hashtab " Yafang Shao
2023-03-01  2:59   ` Hou Tao
2023-02-27 15:20 ` [PATCH bpf-next v3 04/18] bpf: arraymap " Yafang Shao
2023-02-27 15:20 ` [PATCH bpf-next v3 05/18] bpf: stackmap " Yafang Shao
2023-02-27 15:20 ` [PATCH bpf-next v3 06/18] bpf: reuseport_array " Yafang Shao
2023-02-27 15:20 ` [PATCH bpf-next v3 07/18] bpf: ringbuf " Yafang Shao
2023-02-27 17:21   ` Andrii Nakryiko
2023-02-28  2:55     ` Yafang Shao
2023-02-27 15:20 ` [PATCH bpf-next v3 08/18] bpf: bloom_filter " Yafang Shao
2023-02-27 15:20 ` [PATCH bpf-next v3 09/18] bpf: cpumap " Yafang Shao
2023-02-27 15:20 ` [PATCH bpf-next v3 10/18] bpf: devmap " Yafang Shao
2023-02-27 15:20 ` [PATCH bpf-next v3 11/18] bpf: queue_stack_maps " Yafang Shao
2023-02-27 15:20 ` [PATCH bpf-next v3 12/18] bpf: bpf_struct_ops " Yafang Shao
2023-02-27 15:20 ` [PATCH bpf-next v3 13/18] bpf: local_storage " Yafang Shao
2023-02-27 15:20 ` [PATCH bpf-next v3 14/18] bpf, net: bpf_local_storage " Yafang Shao
2023-02-27 15:20 ` [PATCH bpf-next v3 15/18] bpf, net: sock_map " Yafang Shao
2023-02-27 15:20 ` [PATCH bpf-next v3 16/18] bpf, net: xskmap " Yafang Shao
2023-02-27 15:20 ` [PATCH bpf-next v3 17/18] bpf: offload map " Yafang Shao
2023-02-27 15:20 ` [PATCH bpf-next v3 18/18] bpf: enforce all maps having memory usage callback Yafang Shao
2023-02-27 22:37 ` [PATCH bpf-next v3 00/18] bpf: bpf memory usage Daniel Borkmann
2023-02-28  2:53   ` Yafang Shao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).