mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-04-13 09:59:31 +00:00
mm/percpu.c: introduce pcpu_alloc_size()
Introduce pcpu_alloc_size() to get the size of the dynamic per-cpu area. It will be used by bpf memory allocator in the following patches. BPF memory allocator maintains per-cpu area caches for multiple area sizes and its free API only has the to-be-freed per-cpu pointer, so it needs the size of dynamic per-cpu area to select the corresponding cache when bpf program frees the dynamic per-cpu pointer. Acked-by: Dennis Zhou <dennis@kernel.org> Signed-off-by: Hou Tao <houtao1@huawei.com> Link: https://lore.kernel.org/r/20231020133202.4043247-3-houtao@huaweicloud.com Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
394e6869f0
commit
b460bc8302
2 changed files with 32 additions and 0 deletions
|
@ -132,6 +132,7 @@ extern void __init setup_per_cpu_areas(void);
|
||||||
extern void __percpu *__alloc_percpu_gfp(size_t size, size_t align, gfp_t gfp) __alloc_size(1);
|
extern void __percpu *__alloc_percpu_gfp(size_t size, size_t align, gfp_t gfp) __alloc_size(1);
|
||||||
extern void __percpu *__alloc_percpu(size_t size, size_t align) __alloc_size(1);
|
extern void __percpu *__alloc_percpu(size_t size, size_t align) __alloc_size(1);
|
||||||
extern void free_percpu(void __percpu *__pdata);
|
extern void free_percpu(void __percpu *__pdata);
|
||||||
|
extern size_t pcpu_alloc_size(void __percpu *__pdata);
|
||||||
|
|
||||||
DEFINE_FREE(free_percpu, void __percpu *, free_percpu(_T))
|
DEFINE_FREE(free_percpu, void __percpu *, free_percpu(_T))
|
||||||
|
|
||||||
|
|
31
mm/percpu.c
31
mm/percpu.c
|
@ -2244,6 +2244,37 @@ static void pcpu_balance_workfn(struct work_struct *work)
|
||||||
mutex_unlock(&pcpu_alloc_mutex);
|
mutex_unlock(&pcpu_alloc_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* pcpu_alloc_size - the size of the dynamic percpu area
|
||||||
|
* @ptr: pointer to the dynamic percpu area
|
||||||
|
*
|
||||||
|
* Returns the size of the @ptr allocation. This is undefined for statically
|
||||||
|
* defined percpu variables as there is no corresponding chunk->bound_map.
|
||||||
|
*
|
||||||
|
* RETURNS:
|
||||||
|
* The size of the dynamic percpu area.
|
||||||
|
*
|
||||||
|
* CONTEXT:
|
||||||
|
* Can be called from atomic context.
|
||||||
|
*/
|
||||||
|
size_t pcpu_alloc_size(void __percpu *ptr)
|
||||||
|
{
|
||||||
|
struct pcpu_chunk *chunk;
|
||||||
|
unsigned long bit_off, end;
|
||||||
|
void *addr;
|
||||||
|
|
||||||
|
if (!ptr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
addr = __pcpu_ptr_to_addr(ptr);
|
||||||
|
/* No pcpu_lock here: ptr has not been freed, so chunk is still alive */
|
||||||
|
chunk = pcpu_chunk_addr_search(addr);
|
||||||
|
bit_off = (addr - chunk->base_addr) / PCPU_MIN_ALLOC_SIZE;
|
||||||
|
end = find_next_bit(chunk->bound_map, pcpu_chunk_map_bits(chunk),
|
||||||
|
bit_off + 1);
|
||||||
|
return (end - bit_off) * PCPU_MIN_ALLOC_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* free_percpu - free percpu area
|
* free_percpu - free percpu area
|
||||||
* @ptr: pointer to area to free
|
* @ptr: pointer to area to free
|
||||||
|
|
Loading…
Add table
Reference in a new issue