@@ -97,6 +97,8 @@ bpf_selem_alloc(struct bpf_local_storage_map *smap, void *owner,
9797 }
9898
9999 if (selem ) {
100+ RCU_INIT_POINTER (SDATA (selem )-> smap , smap );
101+
100102 if (value ) {
101103 /* No need to call check_and_init_map_value as memory is zero init */
102104 copy_map_value (& smap -> map , SDATA (selem )-> data , value );
@@ -227,9 +229,12 @@ static void bpf_selem_free_trace_rcu(struct rcu_head *rcu)
227229}
228230
229231void bpf_selem_free (struct bpf_local_storage_elem * selem ,
230- struct bpf_local_storage_map * smap ,
231232 bool reuse_now )
232233{
234+ struct bpf_local_storage_map * smap ;
235+
236+ smap = rcu_dereference_check (SDATA (selem )-> smap , bpf_rcu_lock_held ());
237+
233238 if (!smap -> bpf_ma ) {
234239 /* Only task storage has uptrs and task storage
235240 * has moved to bpf_mem_alloc. Meaning smap->bpf_ma == true
@@ -263,18 +268,15 @@ void bpf_selem_free(struct bpf_local_storage_elem *selem,
263268static void bpf_selem_free_list (struct hlist_head * list , bool reuse_now )
264269{
265270 struct bpf_local_storage_elem * selem ;
266- struct bpf_local_storage_map * smap ;
267271 struct hlist_node * n ;
268272
269273 /* The "_safe" iteration is needed.
270274 * The loop is not removing the selem from the list
271275 * but bpf_selem_free will use the selem->rcu_head
272276 * which is union-ized with the selem->free_node.
273277 */
274- hlist_for_each_entry_safe (selem , n , list , free_node ) {
275- smap = rcu_dereference_check (SDATA (selem )-> smap , bpf_rcu_lock_held ());
276- bpf_selem_free (selem , smap , reuse_now );
277- }
278+ hlist_for_each_entry_safe (selem , n , list , free_node )
279+ bpf_selem_free (selem , reuse_now );
278280}
279281
280282/* local_storage->lock must be held and selem->local_storage == local_storage.
@@ -432,7 +434,6 @@ void bpf_selem_link_map(struct bpf_local_storage_map *smap,
432434 unsigned long flags ;
433435
434436 raw_spin_lock_irqsave (& b -> lock , flags );
435- RCU_INIT_POINTER (SDATA (selem )-> smap , smap );
436437 hlist_add_head_rcu (& selem -> map_node , & b -> list );
437438 raw_spin_unlock_irqrestore (& b -> lock , flags );
438439}
@@ -586,7 +587,7 @@ bpf_local_storage_update(void *owner, struct bpf_local_storage_map *smap,
586587
587588 err = bpf_local_storage_alloc (owner , smap , selem , gfp_flags );
588589 if (err ) {
589- bpf_selem_free (selem , smap , true);
590+ bpf_selem_free (selem , true);
590591 mem_uncharge (smap , owner , smap -> elem_size );
591592 return ERR_PTR (err );
592593 }
@@ -662,7 +663,7 @@ bpf_local_storage_update(void *owner, struct bpf_local_storage_map *smap,
662663 bpf_selem_free_list (& old_selem_free_list , false);
663664 if (alloc_selem ) {
664665 mem_uncharge (smap , owner , smap -> elem_size );
665- bpf_selem_free (alloc_selem , smap , true);
666+ bpf_selem_free (alloc_selem , true);
666667 }
667668 return err ? ERR_PTR (err ) : SDATA (selem );
668669}
0 commit comments