Re: [PATCH bpf-next 12/16] bpf: Use bpf_mem_cache_alloc/free in bpf_selem_alloc/free

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 3/6/23 7:47 PM, Alexei Starovoitov wrote:
@@ -80,12 +80,32 @@ bpf_selem_alloc(struct bpf_local_storage_map *smap, void *owner,
         if (charge_mem && mem_charge(smap, owner, smap->elem_size))
                 return NULL;

-       selem = bpf_map_kzalloc(&smap->map, smap->elem_size,
-                               gfp_flags | __GFP_NOWARN);
+       migrate_disable();
+       selem = bpf_mem_cache_alloc(&smap->selem_ma);
+       migrate_enable();
+       if (!selem && (gfp_flags & GFP_KERNEL)) {
+               void *ma_node;
+
+               ma_node = bpf_map_kzalloc(&smap->map,
+                                         BPF_MA_SIZE(smap->elem_size),
+                                         gfp_flags | __GFP_NOWARN);
+               if (ma_node)
+                       selem = BPF_MA_PTR(ma_node);
+       }

If I understand it correctly the code is not trying
to free selem the same way it allocated it.
So we can have kzalloc-ed selems freed into bpf_mem_cache_alloc free-list.
That feels dangerous.
I don't think we can do such things in local storage,
but if we add this api to bpf_mem_alloc it might be acceptable.
I mean mem alloc will try to take from the free list and if empty
and GFP_KERNEL it will kzalloc it.
The knowledge of hidden llist_node shouldn't leave the bpf/memalloc.c file.
reuse_now should probably be a memalloc api flag too.
The implementation detail that it's scary but ok-ish to kfree or
bpf_mem_cache_free depending on circumstances should stay in memalloc.c

All make sense. I will create a bpf_mem_cache_alloc_flags(..., gfp_t flags) to hide the llist_node and kzalloc details. For free, local storage still needs to use the selem->rcu head in its call_rcu_tasks_trace(), so I will create a bpf_mem_cache_raw_free(void *ptr) to hide the llist_node details, like:

/* 'struct bpf_mem_alloc *ma' is not available at this
 * point but the caller knows it is percpu or not and
 * call different raw_free function.
 */
void bpf_mem_cache_raw_free(void *ptr)
{
        kfree(ptr - LLIST_NODE_SZ);
}



[Index of Archives]     [Linux Samsung SoC]     [Linux Rockchip SoC]     [Linux Actions SoC]     [Linux for Synopsys ARC Processors]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]


  Powered by Linux