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.
Unified · Split
| @@ -819,8 +819,10 @@ static int dev_map_delete_elem(struct bpf_map *map, void *key) · 818 unmodified lines | ||
| 819 | 819 | return -EINVAL; |
| 820 | 820 | |
| 821 | 821 | old_dev = unrcu_pointer(xchg(&dtab->netdev_map[k], NULL)); |
| 822 | − if (old_dev) | |
| 822 | + if (old_dev) { | |
| 823 | 823 | call_rcu(&old_dev->rcu, __dev_map_entry_free); |
| 824 | + atomic_dec((atomic_t *)&dtab->items); | |
| 825 | + } | |
| 824 | 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 | 933 | old_dev = unrcu_pointer(xchg(&dtab->netdev_map[i], RCU_INITIALIZER(dev))); |
| 932 | 934 | if (old_dev) |
| 933 | 935 | call_rcu(&old_dev->rcu, __dev_map_entry_free); |
| 936 | + else | |
| 937 | + atomic_inc((atomic_t *)&dtab->items); | |
| 934 | 938 | |
| 935 | 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 | 1020 | __dev_map_hash_lookup_elem); |
| 1017 | 1021 | } |
| 1018 | 1022 | |
| 1023 | +static 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 | + | |
| 1019 | 1037 | BTF_ID_LIST_SINGLE(dev_map_btf_ids, struct, bpf_dtab) |
| 1020 | 1038 | const struct bpf_map_ops dev_map_ops = { |
| 1021 | 1039 | .map_meta_equal = bpf_map_meta_equal, |
| @@ -1026,6 +1044,7 @@ const struct bpf_map_ops dev_map_ops = { · 4 unmodified lines | ||
| 1026 | 1044 | .map_update_elem = dev_map_update_elem, |
| 1027 | 1045 | .map_delete_elem = dev_map_delete_elem, |
| 1028 | 1046 | .map_check_btf = map_check_no_btf, |
| 1047 | + .map_mem_usage = dev_map_mem_usage, | |
| 1029 | 1048 | .map_btf_id = &dev_map_btf_ids[0], |
| 1030 | 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 | 1058 | .map_update_elem = dev_map_hash_update_elem, |
| 1040 | 1059 | .map_delete_elem = dev_map_hash_delete_elem, |
| 1041 | 1060 | .map_check_btf = map_check_no_btf, |
| 1061 | + .map_mem_usage = dev_map_mem_usage, | |
| 1042 | 1062 | .map_btf_id = &dev_map_btf_ids[0], |
| 1043 | 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 | 1129 | if (!dev || netdev != dev->dev) |
| 1110 | 1130 | continue; |
| 1111 | 1131 | odev = unrcu_pointer(cmpxchg(&dtab->netdev_map[i], RCU_INITIALIZER(dev), NULL)); |
| 1112 | − if (dev == odev) | |
| 1132 | + if (dev == odev) { | |
| 1113 | 1133 | call_rcu(&dev->rcu, |
| 1114 | 1134 | __dev_map_entry_free); |
| 1135 | + atomic_dec((atomic_t *)&dtab->items); | |
| 1136 | + } | |
| 1115 | 1137 | } |
| 1116 | 1138 | } |
| 1117 | 1139 | rcu_read_unlock(); |