@@ -59,6 +59,9 @@ struct bpf_cpu_map_entry {
59
59
u32 cpu ; /* kthread CPU and map index */
60
60
int map_id ; /* Back reference to map */
61
61
62
+ /* Used to end ownership transfer transaction */
63
+ struct bpf_map * parent_map ;
64
+
62
65
/* XDP can run multiple RX-ring queues, need __percpu enqueue store */
63
66
struct xdp_bulk_queue __percpu * bulkq ;
64
67
@@ -428,6 +431,7 @@ __cpu_map_entry_alloc(struct bpf_map *map, struct bpf_cpumap_val *value,
428
431
rcpu -> cpu = cpu ;
429
432
rcpu -> map_id = map -> id ;
430
433
rcpu -> value .qsize = value -> qsize ;
434
+ rcpu -> parent_map = map ;
431
435
432
436
if (fd > 0 && __cpu_map_load_bpf_program (rcpu , map , fd ))
433
437
goto free_ptr_ring ;
@@ -640,6 +644,14 @@ static int cpu_map_get_next_key(struct bpf_map *map, void *key, void *next_key)
640
644
641
645
static long cpu_map_redirect (struct bpf_map * map , u64 index , u64 flags )
642
646
{
647
+ /*
648
+ * Redirection is a transfer of ownership of the bpf_cpu_map_entry
649
+ * During the transfer the bpf_cpu_map_entry is still in the map,
650
+ * so we need to prevent it from being freed.
651
+ * The bpf_map_inc() increments the refcnt of the map, so the
652
+ * bpf_cpu_map_entry will not be freed until the refcnt is decremented.
653
+ */
654
+ bpf_map_inc (map );
643
655
return __bpf_xdp_redirect_map (map , index , flags , 0 ,
644
656
__cpu_map_lookup_elem );
645
657
}
@@ -766,6 +778,16 @@ void __cpu_map_flush(struct list_head *flush_list)
766
778
list_for_each_entry_safe (bq , tmp , flush_list , flush_node ) {
767
779
bq_flush_to_queue (bq );
768
780
781
+ /*
782
+ * Flush operation is the last operation of ownership transfer
783
+ * transaction. Thus, we can safely clear the parent_map, decrement
784
+ * the refcnt of the map and free the bpf_cpu_map_entry if needed.
785
+ */
786
+ struct bpf_map * map = bq -> obj -> parent_map ;
787
+
788
+ if (map )
789
+ bpf_map_put (map );
790
+
769
791
/* If already running, costs spin_lock_irqsave + smb_mb */
770
792
wake_up_process (bq -> obj -> kthread );
771
793
}
0 commit comments