summaryrefslogtreecommitdiffstats
path: root/kernel/bpf/devmap.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/bpf/devmap.c')
-rw-r--r--kernel/bpf/devmap.c33
1 files changed, 32 insertions, 1 deletions
diff --git a/kernel/bpf/devmap.c b/kernel/bpf/devmap.c
index d27f3b60ff6d..3867864cdc2f 100644
--- a/kernel/bpf/devmap.c
+++ b/kernel/bpf/devmap.c
@@ -128,7 +128,7 @@ static int dev_map_init_map(struct bpf_dtab *dtab, union bpf_attr *attr)
128 128
129 if (!dtab->n_buckets) /* Overflow check */ 129 if (!dtab->n_buckets) /* Overflow check */
130 return -EINVAL; 130 return -EINVAL;
131 cost += sizeof(struct hlist_head) * dtab->n_buckets; 131 cost += (u64) sizeof(struct hlist_head) * dtab->n_buckets;
132 } 132 }
133 133
134 /* if map size is larger than memlock limit, reject it */ 134 /* if map size is larger than memlock limit, reject it */
@@ -719,6 +719,32 @@ const struct bpf_map_ops dev_map_hash_ops = {
719 .map_check_btf = map_check_no_btf, 719 .map_check_btf = map_check_no_btf,
720}; 720};
721 721
722static void dev_map_hash_remove_netdev(struct bpf_dtab *dtab,
723 struct net_device *netdev)
724{
725 unsigned long flags;
726 u32 i;
727
728 spin_lock_irqsave(&dtab->index_lock, flags);
729 for (i = 0; i < dtab->n_buckets; i++) {
730 struct bpf_dtab_netdev *dev;
731 struct hlist_head *head;
732 struct hlist_node *next;
733
734 head = dev_map_index_hash(dtab, i);
735
736 hlist_for_each_entry_safe(dev, next, head, index_hlist) {
737 if (netdev != dev->dev)
738 continue;
739
740 dtab->items--;
741 hlist_del_rcu(&dev->index_hlist);
742 call_rcu(&dev->rcu, __dev_map_entry_free);
743 }
744 }
745 spin_unlock_irqrestore(&dtab->index_lock, flags);
746}
747
722static int dev_map_notification(struct notifier_block *notifier, 748static int dev_map_notification(struct notifier_block *notifier,
723 ulong event, void *ptr) 749 ulong event, void *ptr)
724{ 750{
@@ -735,6 +761,11 @@ static int dev_map_notification(struct notifier_block *notifier,
735 */ 761 */
736 rcu_read_lock(); 762 rcu_read_lock();
737 list_for_each_entry_rcu(dtab, &dev_map_list, list) { 763 list_for_each_entry_rcu(dtab, &dev_map_list, list) {
764 if (dtab->map.map_type == BPF_MAP_TYPE_DEVMAP_HASH) {
765 dev_map_hash_remove_netdev(dtab, netdev);
766 continue;
767 }
768
738 for (i = 0; i < dtab->map.max_entries; i++) { 769 for (i = 0; i < dtab->map.max_entries; i++) {
739 struct bpf_dtab_netdev *dev, *odev; 770 struct bpf_dtab_netdev *dev, *odev;
740 771