History

bpf: Reshuffle some parts of bpf/offload.c

To avoid adding forward declarations in the main patch, shuffle some code around. No functional changes.

Stanislav Fomichev committed 3 years ago

Commit 89bbc531 parent f1fc43d1 file · +117 −105Browse files

Unified · Split

kernel/bpf/offload.c+117−105
@@ -74,6 +74,121 @@ bpf_offload_find_netdev(struct net_device *netdev) · 73 unmodified lines
74 return rhashtable_lookup_fast(&offdevs, &netdev, offdevs_params);74 return rhashtable_lookup_fast(&offdevs, &netdev, offdevs_params);
75}75}
76 76
77static int __bpf_offload_dev_netdev_register(struct bpf_offload_dev *offdev,
78 struct net_device *netdev)
79{
80 struct bpf_offload_netdev *ondev;
81 int err;
82
83 ondev = kzalloc(sizeof(*ondev), GFP_KERNEL);
84 if (!ondev)
85 return -ENOMEM;
86
87 ondev->netdev = netdev;
88 ondev->offdev = offdev;
89 INIT_LIST_HEAD(&ondev->progs);
90 INIT_LIST_HEAD(&ondev->maps);
91
92 down_write(&bpf_devs_lock);
93 err = rhashtable_insert_fast(&offdevs, &ondev->l, offdevs_params);
94 if (err) {
95 netdev_warn(netdev, "failed to register for BPF offload\n");
96 goto err_unlock_free;
97 }
98
99 list_add(&ondev->offdev_netdevs, &offdev->netdevs);
100 up_write(&bpf_devs_lock);
101 return 0;
102
103err_unlock_free:
104 up_write(&bpf_devs_lock);
105 kfree(ondev);
106 return err;
107}
108
109static void __bpf_prog_offload_destroy(struct bpf_prog *prog)
110{
111 struct bpf_prog_offload *offload = prog->aux->offload;
112
113 if (offload->dev_state)
114 offload->offdev->ops->destroy(prog);
115
116 /* Make sure BPF_PROG_GET_NEXT_ID can't find this dead program */
117 bpf_prog_free_id(prog, true);
118
119 list_del_init(&offload->offloads);
120 kfree(offload);
121 prog->aux->offload = NULL;
122}
123
124static int bpf_map_offload_ndo(struct bpf_offloaded_map *offmap,
125 enum bpf_netdev_command cmd)
126{
127 struct netdev_bpf data = {};
128 struct net_device *netdev;
129
130 ASSERT_RTNL();
131
132 data.command = cmd;
133 data.offmap = offmap;
134 /* Caller must make sure netdev is valid */
135 netdev = offmap->netdev;
136
137 return netdev->netdev_ops->ndo_bpf(netdev, &data);
138}
139
140static void __bpf_map_offload_destroy(struct bpf_offloaded_map *offmap)
141{
142 WARN_ON(bpf_map_offload_ndo(offmap, BPF_OFFLOAD_MAP_FREE));
143 /* Make sure BPF_MAP_GET_NEXT_ID can't find this dead map */
144 bpf_map_free_id(&offmap->map, true);
145 list_del_init(&offmap->offloads);
146 offmap->netdev = NULL;
147}
148
149static void __bpf_offload_dev_netdev_unregister(struct bpf_offload_dev *offdev,
150 struct net_device *netdev)
151{
152 struct bpf_offload_netdev *ondev, *altdev;
153 struct bpf_offloaded_map *offmap, *mtmp;
154 struct bpf_prog_offload *offload, *ptmp;
155
156 ASSERT_RTNL();
157
158 down_write(&bpf_devs_lock);
159 ondev = rhashtable_lookup_fast(&offdevs, &netdev, offdevs_params);
160 if (WARN_ON(!ondev))
161 goto unlock;
162
163 WARN_ON(rhashtable_remove_fast(&offdevs, &ondev->l, offdevs_params));
164 list_del(&ondev->offdev_netdevs);
165
166 /* Try to move the objects to another netdev of the device */
167 altdev = list_first_entry_or_null(&offdev->netdevs,
168 struct bpf_offload_netdev,
169 offdev_netdevs);
170 if (altdev) {
171 list_for_each_entry(offload, &ondev->progs, offloads)
172 offload->netdev = altdev->netdev;
173 list_splice_init(&ondev->progs, &altdev->progs);
174
175 list_for_each_entry(offmap, &ondev->maps, offloads)
176 offmap->netdev = altdev->netdev;
177 list_splice_init(&ondev->maps, &altdev->maps);
178 } else {
179 list_for_each_entry_safe(offload, ptmp, &ondev->progs, offloads)
180 __bpf_prog_offload_destroy(offload->prog);
181 list_for_each_entry_safe(offmap, mtmp, &ondev->maps, offloads)
182 __bpf_map_offload_destroy(offmap);
183 }
184
185 WARN_ON(!list_empty(&ondev->progs));
186 WARN_ON(!list_empty(&ondev->maps));
187 kfree(ondev);
188unlock:
189 up_write(&bpf_devs_lock);
190}
191
77int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr)192int bpf_prog_offload_init(struct bpf_prog *prog, union bpf_attr *attr)
78{193{
79 struct bpf_offload_netdev *ondev;194 struct bpf_offload_netdev *ondev;
@@ -206,21 +321,6 @@ bpf_prog_offload_remove_insns(struct bpf_verifier_env *env, u32 off, u32 cnt) · 126 unmodified lines
206 up_read(&bpf_devs_lock);321 up_read(&bpf_devs_lock);
207}322}
208 323
209static void __bpf_prog_offload_destroy(struct bpf_prog *prog)
210{
211 struct bpf_prog_offload *offload = prog->aux->offload;
212
213 if (offload->dev_state)
214 offload->offdev->ops->destroy(prog);
215
216 /* Make sure BPF_PROG_GET_NEXT_ID can't find this dead program */
217 bpf_prog_free_id(prog, true);
218
219 list_del_init(&offload->offloads);
220 kfree(offload);
221 prog->aux->offload = NULL;
222}
223
224void bpf_prog_offload_destroy(struct bpf_prog *prog)324void bpf_prog_offload_destroy(struct bpf_prog *prog)
225{325{
226 down_write(&bpf_devs_lock);326 down_write(&bpf_devs_lock);
@@ -340,22 +440,6 @@ int bpf_prog_offload_info_fill(struct bpf_prog_info *info, · 113 unmodified lines
340const struct bpf_prog_ops bpf_offload_prog_ops = {440const struct bpf_prog_ops bpf_offload_prog_ops = {
341};441};
342 442
343static int bpf_map_offload_ndo(struct bpf_offloaded_map *offmap,
344 enum bpf_netdev_command cmd)
345{
346 struct netdev_bpf data = {};
347 struct net_device *netdev;
348
349 ASSERT_RTNL();
350
351 data.command = cmd;
352 data.offmap = offmap;
353 /* Caller must make sure netdev is valid */
354 netdev = offmap->netdev;
355
356 return netdev->netdev_ops->ndo_bpf(netdev, &data);
357}
358
359struct bpf_map *bpf_map_offload_map_alloc(union bpf_attr *attr)443struct bpf_map *bpf_map_offload_map_alloc(union bpf_attr *attr)
360{444{
361 struct net *net = current->nsproxy->net_ns;445 struct net *net = current->nsproxy->net_ns;
@@ -405,15 +489,6 @@ err_unlock: · 43 unmodified lines
405 return ERR_PTR(err);489 return ERR_PTR(err);
406}490}
407 491
408static void __bpf_map_offload_destroy(struct bpf_offloaded_map *offmap)
409{
410 WARN_ON(bpf_map_offload_ndo(offmap, BPF_OFFLOAD_MAP_FREE));
411 /* Make sure BPF_MAP_GET_NEXT_ID can't find this dead map */
412 bpf_map_free_id(&offmap->map, true);
413 list_del_init(&offmap->offloads);
414 offmap->netdev = NULL;
415}
416
417void bpf_map_offload_map_free(struct bpf_map *map)492void bpf_map_offload_map_free(struct bpf_map *map)
418{493{
419 struct bpf_offloaded_map *offmap = map_to_offmap(map);494 struct bpf_offloaded_map *offmap = map_to_offmap(map);
@@ -592,77 +667,14 @@ bool bpf_offload_prog_map_match(struct bpf_prog *prog, struct bpf_map *map) · 172 unmodified lines
592int bpf_offload_dev_netdev_register(struct bpf_offload_dev *offdev,667int bpf_offload_dev_netdev_register(struct bpf_offload_dev *offdev,
593 struct net_device *netdev)668 struct net_device *netdev)
594{669{
595 struct bpf_offload_netdev *ondev;670 return __bpf_offload_dev_netdev_register(offdev, netdev);
596 int err;
597
598 ondev = kzalloc(sizeof(*ondev), GFP_KERNEL);
599 if (!ondev)
600 return -ENOMEM;
601
602 ondev->netdev = netdev;
603 ondev->offdev = offdev;
604 INIT_LIST_HEAD(&ondev->progs);
605 INIT_LIST_HEAD(&ondev->maps);
606
607 down_write(&bpf_devs_lock);
608 err = rhashtable_insert_fast(&offdevs, &ondev->l, offdevs_params);
609 if (err) {
610 netdev_warn(netdev, "failed to register for BPF offload\n");
611 goto err_unlock_free;
612 }
613
614 list_add(&ondev->offdev_netdevs, &offdev->netdevs);
615 up_write(&bpf_devs_lock);
616 return 0;
617
618err_unlock_free:
619 up_write(&bpf_devs_lock);
620 kfree(ondev);
621 return err;
622}671}
623EXPORT_SYMBOL_GPL(bpf_offload_dev_netdev_register);672EXPORT_SYMBOL_GPL(bpf_offload_dev_netdev_register);
624 673
625void bpf_offload_dev_netdev_unregister(struct bpf_offload_dev *offdev,674void bpf_offload_dev_netdev_unregister(struct bpf_offload_dev *offdev,
626 struct net_device *netdev)675 struct net_device *netdev)
627{676{
628 struct bpf_offload_netdev *ondev, *altdev;677 __bpf_offload_dev_netdev_unregister(offdev, netdev);
629 struct bpf_offloaded_map *offmap, *mtmp;
630 struct bpf_prog_offload *offload, *ptmp;
631
632 ASSERT_RTNL();
633
634 down_write(&bpf_devs_lock);
635 ondev = rhashtable_lookup_fast(&offdevs, &netdev, offdevs_params);
636 if (WARN_ON(!ondev))
637 goto unlock;
638
639 WARN_ON(rhashtable_remove_fast(&offdevs, &ondev->l, offdevs_params));
640 list_del(&ondev->offdev_netdevs);
641
642 /* Try to move the objects to another netdev of the device */
643 altdev = list_first_entry_or_null(&offdev->netdevs,
644 struct bpf_offload_netdev,
645 offdev_netdevs);
646 if (altdev) {
647 list_for_each_entry(offload, &ondev->progs, offloads)
648 offload->netdev = altdev->netdev;
649 list_splice_init(&ondev->progs, &altdev->progs);
650
651 list_for_each_entry(offmap, &ondev->maps, offloads)
652 offmap->netdev = altdev->netdev;
653 list_splice_init(&ondev->maps, &altdev->maps);
654 } else {
655 list_for_each_entry_safe(offload, ptmp, &ondev->progs, offloads)
656 __bpf_prog_offload_destroy(offload->prog);
657 list_for_each_entry_safe(offmap, mtmp, &ondev->maps, offloads)
658 __bpf_map_offload_destroy(offmap);
659 }
660
661 WARN_ON(!list_empty(&ondev->progs));
662 WARN_ON(!list_empty(&ondev->maps));
663 kfree(ondev);
664unlock:
665 up_write(&bpf_devs_lock);
666}678}
667EXPORT_SYMBOL_GPL(bpf_offload_dev_netdev_unregister);679EXPORT_SYMBOL_GPL(bpf_offload_dev_netdev_unregister);
668 680

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t