xref: /linux-6.15/io_uring/alloc_cache.c (revision d19af0e9)
1*d19af0e9SPavel Begunkov // SPDX-License-Identifier: GPL-2.0
2*d19af0e9SPavel Begunkov 
3*d19af0e9SPavel Begunkov #include "alloc_cache.h"
4*d19af0e9SPavel Begunkov 
io_alloc_cache_free(struct io_alloc_cache * cache,void (* free)(const void *))5*d19af0e9SPavel Begunkov void io_alloc_cache_free(struct io_alloc_cache *cache,
6*d19af0e9SPavel Begunkov 			 void (*free)(const void *))
7*d19af0e9SPavel Begunkov {
8*d19af0e9SPavel Begunkov 	void *entry;
9*d19af0e9SPavel Begunkov 
10*d19af0e9SPavel Begunkov 	if (!cache->entries)
11*d19af0e9SPavel Begunkov 		return;
12*d19af0e9SPavel Begunkov 
13*d19af0e9SPavel Begunkov 	while ((entry = io_alloc_cache_get(cache)) != NULL)
14*d19af0e9SPavel Begunkov 		free(entry);
15*d19af0e9SPavel Begunkov 
16*d19af0e9SPavel Begunkov 	kvfree(cache->entries);
17*d19af0e9SPavel Begunkov 	cache->entries = NULL;
18*d19af0e9SPavel Begunkov }
19*d19af0e9SPavel Begunkov 
20*d19af0e9SPavel Begunkov /* returns false if the cache was initialized properly */
io_alloc_cache_init(struct io_alloc_cache * cache,unsigned max_nr,unsigned int size,unsigned int init_bytes)21*d19af0e9SPavel Begunkov bool io_alloc_cache_init(struct io_alloc_cache *cache,
22*d19af0e9SPavel Begunkov 			 unsigned max_nr, unsigned int size,
23*d19af0e9SPavel Begunkov 			 unsigned int init_bytes)
24*d19af0e9SPavel Begunkov {
25*d19af0e9SPavel Begunkov 	cache->entries = kvmalloc_array(max_nr, sizeof(void *), GFP_KERNEL);
26*d19af0e9SPavel Begunkov 	if (!cache->entries)
27*d19af0e9SPavel Begunkov 		return true;
28*d19af0e9SPavel Begunkov 
29*d19af0e9SPavel Begunkov 	cache->nr_cached = 0;
30*d19af0e9SPavel Begunkov 	cache->max_cached = max_nr;
31*d19af0e9SPavel Begunkov 	cache->elem_size = size;
32*d19af0e9SPavel Begunkov 	cache->init_clear = init_bytes;
33*d19af0e9SPavel Begunkov 	return false;
34*d19af0e9SPavel Begunkov }
35*d19af0e9SPavel Begunkov 
io_cache_alloc_new(struct io_alloc_cache * cache,gfp_t gfp)36*d19af0e9SPavel Begunkov void *io_cache_alloc_new(struct io_alloc_cache *cache, gfp_t gfp)
37*d19af0e9SPavel Begunkov {
38*d19af0e9SPavel Begunkov 	void *obj;
39*d19af0e9SPavel Begunkov 
40*d19af0e9SPavel Begunkov 	obj = kmalloc(cache->elem_size, gfp);
41*d19af0e9SPavel Begunkov 	if (obj && cache->init_clear)
42*d19af0e9SPavel Begunkov 		memset(obj, 0, cache->init_clear);
43*d19af0e9SPavel Begunkov 	return obj;
44*d19af0e9SPavel Begunkov }
45