mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-12-28 10:15:32 -05:00
bpf: devmap memory usage
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>
Link: https://lore.kernel.org/r/20230305124615.12358-11-laoar.shao@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
committed by
Alexei Starovoitov
parent
835f1fca95
commit
fa5e83df17
@@ -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 @@ const struct bpf_map_ops dev_map_ops = {
|
||||
.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 @@ const struct bpf_map_ops dev_map_hash_ops = {
|
||||
.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();
|
||||
|
||||
Reference in New Issue
Block a user