History

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.

Yafang Shao committed 3 years ago

Commit fa5e83d1 parent 835f1fc1 file · +24 −2Browse files

Unified · Split

kernel/bpf/devmap.c+24−2
@@ -819,8 +819,10 @@ static int dev_map_delete_elem(struct bpf_map *map, void *key) · 818 unmodified lines
819 return -EINVAL;819 return -EINVAL;
820 820
821 old_dev = unrcu_pointer(xchg(&dtab->netdev_map[k], NULL));821 old_dev = unrcu_pointer(xchg(&dtab->netdev_map[k], NULL));
822 if (old_dev)822 if (old_dev) {
823 call_rcu(&old_dev->rcu, __dev_map_entry_free);823 call_rcu(&old_dev->rcu, __dev_map_entry_free);
824 atomic_dec((atomic_t *)&dtab->items);
825 }
824 return 0;826 return 0;
825}827}
826 828
@@ -931,6 +933,8 @@ static int __dev_map_update_elem(struct net *net, struct bpf_map *map, · 104 unmodified lines
931 old_dev = unrcu_pointer(xchg(&dtab->netdev_map[i], RCU_INITIALIZER(dev)));933 old_dev = unrcu_pointer(xchg(&dtab->netdev_map[i], RCU_INITIALIZER(dev)));
932 if (old_dev)934 if (old_dev)
933 call_rcu(&old_dev->rcu, __dev_map_entry_free);935 call_rcu(&old_dev->rcu, __dev_map_entry_free);
936 else
937 atomic_inc((atomic_t *)&dtab->items);
934 938
935 return 0;939 return 0;
936}940}
@@ -1016,6 +1020,20 @@ static int dev_hash_map_redirect(struct bpf_map *map, u64 ifindex, u64 flags) · 79 unmodified lines
1016 __dev_map_hash_lookup_elem);1020 __dev_map_hash_lookup_elem);
1017}1021}
1018 1022
1023static u64 dev_map_mem_usage(const struct bpf_map *map)
1024{
1025 struct bpf_dtab *dtab = container_of(map, struct bpf_dtab, map);
1026 u64 usage = sizeof(struct bpf_dtab);
1027
1028 if (map->map_type == BPF_MAP_TYPE_DEVMAP_HASH)
1029 usage += (u64)dtab->n_buckets * sizeof(struct hlist_head);
1030 else
1031 usage += (u64)map->max_entries * sizeof(struct bpf_dtab_netdev *);
1032 usage += atomic_read((atomic_t *)&dtab->items) *
1033 (u64)sizeof(struct bpf_dtab_netdev);
1034 return usage;
1035}
1036
1019BTF_ID_LIST_SINGLE(dev_map_btf_ids, struct, bpf_dtab)1037BTF_ID_LIST_SINGLE(dev_map_btf_ids, struct, bpf_dtab)
1020const struct bpf_map_ops dev_map_ops = {1038const struct bpf_map_ops dev_map_ops = {
1021 .map_meta_equal = bpf_map_meta_equal,1039 .map_meta_equal = bpf_map_meta_equal,
@@ -1026,6 +1044,7 @@ const struct bpf_map_ops dev_map_ops = { · 4 unmodified lines
1026 .map_update_elem = dev_map_update_elem,1044 .map_update_elem = dev_map_update_elem,
1027 .map_delete_elem = dev_map_delete_elem,1045 .map_delete_elem = dev_map_delete_elem,
1028 .map_check_btf = map_check_no_btf,1046 .map_check_btf = map_check_no_btf,
1047 .map_mem_usage = dev_map_mem_usage,
1029 .map_btf_id = &dev_map_btf_ids[0],1048 .map_btf_id = &dev_map_btf_ids[0],
1030 .map_redirect = dev_map_redirect,1049 .map_redirect = dev_map_redirect,
1031};1050};
@@ -1039,6 +1058,7 @@ const struct bpf_map_ops dev_map_hash_ops = { · 7 unmodified lines
1039 .map_update_elem = dev_map_hash_update_elem,1058 .map_update_elem = dev_map_hash_update_elem,
1040 .map_delete_elem = dev_map_hash_delete_elem,1059 .map_delete_elem = dev_map_hash_delete_elem,
1041 .map_check_btf = map_check_no_btf,1060 .map_check_btf = map_check_no_btf,
1061 .map_mem_usage = dev_map_mem_usage,
1042 .map_btf_id = &dev_map_btf_ids[0],1062 .map_btf_id = &dev_map_btf_ids[0],
1043 .map_redirect = dev_hash_map_redirect,1063 .map_redirect = dev_hash_map_redirect,
1044};1064};
@@ -1109,9 +1129,11 @@ static int dev_map_notification(struct notifier_block *notifier, · 64 unmodified lines
1109 if (!dev || netdev != dev->dev)1129 if (!dev || netdev != dev->dev)
1110 continue;1130 continue;
1111 odev = unrcu_pointer(cmpxchg(&dtab->netdev_map[i], RCU_INITIALIZER(dev), NULL));1131 odev = unrcu_pointer(cmpxchg(&dtab->netdev_map[i], RCU_INITIALIZER(dev), NULL));
1112 if (dev == odev)1132 if (dev == odev) {
1113 call_rcu(&dev->rcu,1133 call_rcu(&dev->rcu,
1114 __dev_map_entry_free);1134 __dev_map_entry_free);
1135 atomic_dec((atomic_t *)&dtab->items);
1136 }
1115 }1137 }
1116 }1138 }
1117 rcu_read_unlock();1139 rcu_read_unlock();