@@ -190,10 +190,12 @@ static void dev_map_free(struct bpf_map *map)
190
190
191
191
/* At this point bpf_prog->aux->refcnt == 0 and this map->refcnt == 0,
192
192
* so the programs (can be more than one that used this map) were
193
- * disconnected from events. Wait for outstanding critical sections in
194
- * these programs to complete. The rcu critical section only guarantees
195
- * no further reads against netdev_map. It does __not__ ensure pending
196
- * flush operations (if any) are complete.
193
+ * disconnected from events. The following synchronize_rcu() guarantees
194
+ * both rcu read critical sections complete and waits for
195
+ * preempt-disable regions (NAPI being the relevant context here) so we
196
+ * are certain there will be no further reads against the netdev_map and
197
+ * all flush operations are complete. Flush operations can only be done
198
+ * from NAPI context for this reason.
197
199
*/
198
200
199
201
spin_lock (& dev_map_lock );
@@ -503,12 +505,11 @@ static int dev_map_delete_elem(struct bpf_map *map, void *key)
503
505
return - EINVAL ;
504
506
505
507
/* Use call_rcu() here to ensure any rcu critical sections have
506
- * completed, but this does not guarantee a flush has happened
507
- * yet. Because driver side rcu_read_lock/unlock only protects the
508
- * running XDP program. However, for pending flush operations the
509
- * dev and ctx are stored in another per cpu map. And additionally,
510
- * the driver tear down ensures all soft irqs are complete before
511
- * removing the net device in the case of dev_put equals zero.
508
+ * completed as well as any flush operations because call_rcu
509
+ * will wait for preempt-disable region to complete, NAPI in this
510
+ * context. And additionally, the driver tear down ensures all
511
+ * soft irqs are complete before removing the net device in the
512
+ * case of dev_put equals zero.
512
513
*/
513
514
old_dev = xchg (& dtab -> netdev_map [k ], NULL );
514
515
if (old_dev )
0 commit comments