@@ -80,17 +80,9 @@ bpf_selem_alloc(struct bpf_local_storage_map *smap, void *owner,
8080 if (mem_charge (smap , owner , smap -> elem_size ))
8181 return NULL ;
8282
83- if (smap -> bpf_ma ) {
84- selem = bpf_mem_cache_alloc_flags (& smap -> selem_ma , gfp_flags );
85- if (selem )
86- /* Keep the original bpf_map_kzalloc behavior
87- * before started using the bpf_mem_cache_alloc.
88- *
89- * No need to use zero_map_value. The bpf_selem_free()
90- * only does bpf_mem_cache_free when there is
91- * no other bpf prog is using the selem.
92- */
93- memset (SDATA (selem )-> data , 0 , smap -> map .value_size );
83+ if (smap -> use_kmalloc_nolock ) {
84+ selem = bpf_map_kmalloc_nolock (& smap -> map , smap -> elem_size ,
85+ __GFP_ZERO , NUMA_NO_NODE );
9486 } else {
9587 selem = bpf_map_kzalloc (& smap -> map , smap -> elem_size ,
9688 gfp_flags | __GFP_NOWARN );
@@ -113,7 +105,7 @@ bpf_selem_alloc(struct bpf_local_storage_map *smap, void *owner,
113105 return NULL ;
114106}
115107
116- /* rcu tasks trace callback for bpf_ma == false */
108+ /* rcu tasks trace callback for use_kmalloc_nolock == false */
117109static void __bpf_local_storage_free_trace_rcu (struct rcu_head * rcu )
118110{
119111 struct bpf_local_storage * local_storage ;
@@ -128,12 +120,23 @@ static void __bpf_local_storage_free_trace_rcu(struct rcu_head *rcu)
128120 kfree_rcu (local_storage , rcu );
129121}
130122
123+ /* Handle use_kmalloc_nolock == false */
124+ static void __bpf_local_storage_free (struct bpf_local_storage * local_storage ,
125+ bool vanilla_rcu )
126+ {
127+ if (vanilla_rcu )
128+ kfree_rcu (local_storage , rcu );
129+ else
130+ call_rcu_tasks_trace (& local_storage -> rcu ,
131+ __bpf_local_storage_free_trace_rcu );
132+ }
133+
131134static void bpf_local_storage_free_rcu (struct rcu_head * rcu )
132135{
133136 struct bpf_local_storage * local_storage ;
134137
135138 local_storage = container_of (rcu , struct bpf_local_storage , rcu );
136- bpf_mem_cache_raw_free (local_storage );
139+ kfree_nolock (local_storage );
137140}
138141
139142static void bpf_local_storage_free_trace_rcu (struct rcu_head * rcu )
@@ -144,46 +147,27 @@ static void bpf_local_storage_free_trace_rcu(struct rcu_head *rcu)
144147 call_rcu (rcu , bpf_local_storage_free_rcu );
145148}
146149
147- /* Handle bpf_ma == false */
148- static void __bpf_local_storage_free (struct bpf_local_storage * local_storage ,
149- bool vanilla_rcu )
150- {
151- if (vanilla_rcu )
152- kfree_rcu (local_storage , rcu );
153- else
154- call_rcu_tasks_trace (& local_storage -> rcu ,
155- __bpf_local_storage_free_trace_rcu );
156- }
157-
158150static void bpf_local_storage_free (struct bpf_local_storage * local_storage ,
159- struct bpf_local_storage_map * smap ,
160151 bool reuse_now )
161152{
162153 if (!local_storage )
163154 return ;
164155
165- if (!local_storage -> bpf_ma ) {
156+ if (!local_storage -> use_kmalloc_nolock ) {
166157 __bpf_local_storage_free (local_storage , reuse_now );
167158 return ;
168159 }
169160
170- if (!reuse_now ) {
171- call_rcu_tasks_trace (& local_storage -> rcu ,
172- bpf_local_storage_free_trace_rcu );
161+ if (reuse_now ) {
162+ call_rcu (& local_storage -> rcu , bpf_local_storage_free_rcu );
173163 return ;
174164 }
175165
176- if (smap )
177- bpf_mem_cache_free (& smap -> storage_ma , local_storage );
178- else
179- /* smap could be NULL if the selem that triggered
180- * this 'local_storage' creation had been long gone.
181- * In this case, directly do call_rcu().
182- */
183- call_rcu (& local_storage -> rcu , bpf_local_storage_free_rcu );
166+ call_rcu_tasks_trace (& local_storage -> rcu ,
167+ bpf_local_storage_free_trace_rcu );
184168}
185169
186- /* rcu tasks trace callback for bpf_ma == false */
170+ /* rcu tasks trace callback for use_kmalloc_nolock == false */
187171static void __bpf_selem_free_trace_rcu (struct rcu_head * rcu )
188172{
189173 struct bpf_local_storage_elem * selem ;
@@ -195,7 +179,7 @@ static void __bpf_selem_free_trace_rcu(struct rcu_head *rcu)
195179 kfree_rcu (selem , rcu );
196180}
197181
198- /* Handle bpf_ma == false */
182+ /* Handle use_kmalloc_nolock == false */
199183static void __bpf_selem_free (struct bpf_local_storage_elem * selem ,
200184 bool vanilla_rcu )
201185{
@@ -217,7 +201,7 @@ static void bpf_selem_free_rcu(struct rcu_head *rcu)
217201 migrate_disable ();
218202 bpf_obj_free_fields (smap -> map .record , SDATA (selem )-> data );
219203 migrate_enable ();
220- bpf_mem_cache_raw_free (selem );
204+ kfree_nolock (selem );
221205}
222206
223207static void bpf_selem_free_trace_rcu (struct rcu_head * rcu )
@@ -235,30 +219,23 @@ void bpf_selem_free(struct bpf_local_storage_elem *selem,
235219
236220 smap = rcu_dereference_check (SDATA (selem )-> smap , bpf_rcu_lock_held ());
237221
238- if (!smap -> bpf_ma ) {
239- /* Only task storage has uptrs and task storage
240- * has moved to bpf_mem_alloc. Meaning smap->bpf_ma == true
241- * for task storage, so this bpf_obj_free_fields() won't unpin
242- * any uptr .
222+ if (!smap -> use_kmalloc_nolock ) {
223+ /*
224+ * No uptr will be unpin even when reuse_now == false since uptr
225+ * is only supported in task local storage, where
226+ * smap->use_kmalloc_nolock == true .
243227 */
244228 bpf_obj_free_fields (smap -> map .record , SDATA (selem )-> data );
245229 __bpf_selem_free (selem , reuse_now );
246230 return ;
247231 }
248232
249233 if (reuse_now ) {
250- /* reuse_now == true only happens when the storage owner
251- * (e.g. task_struct) is being destructed or the map itself
252- * is being destructed (ie map_free). In both cases,
253- * no bpf prog can have a hold on the selem. It is
254- * safe to unpin the uptrs and free the selem now.
255- */
256- bpf_obj_free_fields (smap -> map .record , SDATA (selem )-> data );
257- /* Instead of using the vanilla call_rcu(),
258- * bpf_mem_cache_free will be able to reuse selem
259- * immediately.
234+ /*
235+ * While it is okay to call bpf_obj_free_fields() that unpins uptr when
236+ * reuse_now == true, keep it in bpf_selem_free_rcu() for simplicity.
260237 */
261- bpf_mem_cache_free ( & smap -> selem_ma , selem );
238+ call_rcu ( & selem -> rcu , bpf_selem_free_rcu );
262239 return ;
263240 }
264241
@@ -339,7 +316,6 @@ static bool bpf_selem_unlink_storage_nolock(struct bpf_local_storage *local_stor
339316static void bpf_selem_unlink_storage (struct bpf_local_storage_elem * selem ,
340317 bool reuse_now )
341318{
342- struct bpf_local_storage_map * storage_smap ;
343319 struct bpf_local_storage * local_storage ;
344320 bool free_local_storage = false;
345321 HLIST_HEAD (selem_free_list );
@@ -351,8 +327,6 @@ static void bpf_selem_unlink_storage(struct bpf_local_storage_elem *selem,
351327
352328 local_storage = rcu_dereference_check (selem -> local_storage ,
353329 bpf_rcu_lock_held ());
354- storage_smap = rcu_dereference_check (local_storage -> smap ,
355- bpf_rcu_lock_held ());
356330
357331 raw_spin_lock_irqsave (& local_storage -> lock , flags );
358332 if (likely (selem_linked_to_storage (selem )))
@@ -363,7 +337,7 @@ static void bpf_selem_unlink_storage(struct bpf_local_storage_elem *selem,
363337 bpf_selem_free_list (& selem_free_list , reuse_now );
364338
365339 if (free_local_storage )
366- bpf_local_storage_free (local_storage , storage_smap , reuse_now );
340+ bpf_local_storage_free (local_storage , reuse_now );
367341}
368342
369343void bpf_selem_link_storage_nolock (struct bpf_local_storage * local_storage ,
@@ -456,8 +430,9 @@ int bpf_local_storage_alloc(void *owner,
456430 if (err )
457431 return err ;
458432
459- if (smap -> bpf_ma )
460- storage = bpf_mem_cache_alloc_flags (& smap -> storage_ma , gfp_flags );
433+ if (smap -> use_kmalloc_nolock )
434+ storage = bpf_map_kmalloc_nolock (& smap -> map , sizeof (* storage ),
435+ __GFP_ZERO , NUMA_NO_NODE );
461436 else
462437 storage = bpf_map_kzalloc (& smap -> map , sizeof (* storage ),
463438 gfp_flags | __GFP_NOWARN );
@@ -470,7 +445,7 @@ int bpf_local_storage_alloc(void *owner,
470445 INIT_HLIST_HEAD (& storage -> list );
471446 raw_spin_lock_init (& storage -> lock );
472447 storage -> owner = owner ;
473- storage -> bpf_ma = smap -> bpf_ma ;
448+ storage -> use_kmalloc_nolock = smap -> use_kmalloc_nolock ;
474449
475450 bpf_selem_link_storage_nolock (storage , first_selem );
476451 bpf_selem_link_map (smap , first_selem );
@@ -492,22 +467,12 @@ int bpf_local_storage_alloc(void *owner,
492467 bpf_selem_unlink_map (first_selem );
493468 err = - EAGAIN ;
494469 goto uncharge ;
495-
496- /* Note that even first_selem was linked to smap's
497- * bucket->list, first_selem can be freed immediately
498- * (instead of kfree_rcu) because
499- * bpf_local_storage_map_free() does a
500- * synchronize_rcu_mult (waiting for both sleepable and
501- * normal programs) before walking the bucket->list.
502- * Hence, no one is accessing selem from the
503- * bucket->list under rcu_read_lock().
504- */
505470 }
506471
507472 return 0 ;
508473
509474uncharge :
510- bpf_local_storage_free (storage , smap , true);
475+ bpf_local_storage_free (storage , true);
511476 mem_uncharge (smap , owner , sizeof (* storage ));
512477 return err ;
513478}
@@ -694,15 +659,12 @@ int bpf_local_storage_map_check_btf(const struct bpf_map *map,
694659
695660void bpf_local_storage_destroy (struct bpf_local_storage * local_storage )
696661{
697- struct bpf_local_storage_map * storage_smap ;
698662 struct bpf_local_storage_elem * selem ;
699663 bool free_storage = false;
700664 HLIST_HEAD (free_selem_list );
701665 struct hlist_node * n ;
702666 unsigned long flags ;
703667
704- storage_smap = rcu_dereference_check (local_storage -> smap , bpf_rcu_lock_held ());
705-
706668 /* Neither the bpf_prog nor the bpf_map's syscall
707669 * could be modifying the local_storage->list now.
708670 * Thus, no elem can be added to or deleted from the
@@ -732,7 +694,7 @@ void bpf_local_storage_destroy(struct bpf_local_storage *local_storage)
732694 bpf_selem_free_list (& free_selem_list , true);
733695
734696 if (free_storage )
735- bpf_local_storage_free (local_storage , storage_smap , true);
697+ bpf_local_storage_free (local_storage , true);
736698}
737699
738700u64 bpf_local_storage_map_mem_usage (const struct bpf_map * map )
@@ -745,20 +707,10 @@ u64 bpf_local_storage_map_mem_usage(const struct bpf_map *map)
745707 return usage ;
746708}
747709
748- /* When bpf_ma == true, the bpf_mem_alloc is used to allocate and free memory.
749- * A deadlock free allocator is useful for storage that the bpf prog can easily
750- * get a hold of the owner PTR_TO_BTF_ID in any context. eg. bpf_get_current_task_btf.
751- * The task and cgroup storage fall into this case. The bpf_mem_alloc reuses
752- * memory immediately. To be reuse-immediate safe, the owner destruction
753- * code path needs to go through a rcu grace period before calling
754- * bpf_local_storage_destroy().
755- *
756- * When bpf_ma == false, the kmalloc and kfree are used.
757- */
758710struct bpf_map *
759711bpf_local_storage_map_alloc (union bpf_attr * attr ,
760712 struct bpf_local_storage_cache * cache ,
761- bool bpf_ma )
713+ bool use_kmalloc_nolock )
762714{
763715 struct bpf_local_storage_map * smap ;
764716 unsigned int i ;
@@ -792,20 +744,9 @@ bpf_local_storage_map_alloc(union bpf_attr *attr,
792744
793745 /* In PREEMPT_RT, kmalloc(GFP_ATOMIC) is still not safe in non
794746 * preemptible context. Thus, enforce all storages to use
795- * bpf_mem_alloc when CONFIG_PREEMPT_RT is enabled.
747+ * kmalloc_nolock() when CONFIG_PREEMPT_RT is enabled.
796748 */
797- smap -> bpf_ma = IS_ENABLED (CONFIG_PREEMPT_RT ) ? true : bpf_ma ;
798- if (smap -> bpf_ma ) {
799- err = bpf_mem_alloc_init (& smap -> selem_ma , smap -> elem_size , false);
800- if (err )
801- goto free_smap ;
802-
803- err = bpf_mem_alloc_init (& smap -> storage_ma , sizeof (struct bpf_local_storage ), false);
804- if (err ) {
805- bpf_mem_alloc_destroy (& smap -> selem_ma );
806- goto free_smap ;
807- }
808- }
749+ smap -> use_kmalloc_nolock = IS_ENABLED (CONFIG_PREEMPT_RT ) ? true : use_kmalloc_nolock ;
809750
810751 smap -> cache_idx = bpf_local_storage_cache_idx_get (cache );
811752 return & smap -> map ;
@@ -875,12 +816,9 @@ void bpf_local_storage_map_free(struct bpf_map *map,
875816 */
876817 synchronize_rcu ();
877818
878- if (smap -> bpf_ma ) {
819+ if (smap -> use_kmalloc_nolock ) {
879820 rcu_barrier_tasks_trace ();
880- if (!rcu_trace_implies_rcu_gp ())
881- rcu_barrier ();
882- bpf_mem_alloc_destroy (& smap -> selem_ma );
883- bpf_mem_alloc_destroy (& smap -> storage_ma );
821+ rcu_barrier ();
884822 }
885823 kvfree (smap -> buckets );
886824 bpf_map_area_free (smap );
0 commit comments