xref: /linux/io_uring/alloc_cache.h (revision 414d0f45)
19b797a37SJens Axboe #ifndef IOU_ALLOC_CACHE_H
29b797a37SJens Axboe #define IOU_ALLOC_CACHE_H
39b797a37SJens Axboe 
49731bc98SJens Axboe /*
59731bc98SJens Axboe  * Don't allow the cache to grow beyond this size.
69731bc98SJens Axboe  */
70ae9b9a1SJens Axboe #define IO_ALLOC_CACHE_MAX	128
89731bc98SJens Axboe 
io_alloc_cache_put(struct io_alloc_cache * cache,void * entry)99731bc98SJens Axboe static inline bool io_alloc_cache_put(struct io_alloc_cache *cache,
10*414d0f45SJens Axboe 				      void *entry)
119b797a37SJens Axboe {
1269bbc6adSPavel Begunkov 	if (cache->nr_cached < cache->max_cached) {
13*414d0f45SJens Axboe 		if (!kasan_mempool_poison_object(entry))
14*414d0f45SJens Axboe 			return false;
15*414d0f45SJens Axboe 		cache->entries[cache->nr_cached++] = entry;
169731bc98SJens Axboe 		return true;
179731bc98SJens Axboe 	}
189731bc98SJens Axboe 	return false;
199b797a37SJens Axboe }
209b797a37SJens Axboe 
io_alloc_cache_get(struct io_alloc_cache * cache)21*414d0f45SJens Axboe static inline void *io_alloc_cache_get(struct io_alloc_cache *cache)
22528407b1SPavel Begunkov {
23*414d0f45SJens Axboe 	if (cache->nr_cached) {
24*414d0f45SJens Axboe 		void *entry = cache->entries[--cache->nr_cached];
25528407b1SPavel Begunkov 
268ab3b097SAndrey Konovalov 		kasan_mempool_unpoison_object(entry, cache->elem_size);
27efba1a9eSBreno Leitao 		return entry;
289b797a37SJens Axboe 	}
299b797a37SJens Axboe 
309b797a37SJens Axboe 	return NULL;
319b797a37SJens Axboe }
329b797a37SJens Axboe 
33*414d0f45SJens Axboe /* returns false if the cache was initialized properly */
io_alloc_cache_init(struct io_alloc_cache * cache,unsigned max_nr,size_t size)34*414d0f45SJens Axboe static inline bool io_alloc_cache_init(struct io_alloc_cache *cache,
3569bbc6adSPavel Begunkov 				       unsigned max_nr, size_t size)
369b797a37SJens Axboe {
37*414d0f45SJens Axboe 	cache->entries = kvmalloc_array(max_nr, sizeof(void *), GFP_KERNEL);
38*414d0f45SJens Axboe 	if (cache->entries) {
399731bc98SJens Axboe 		cache->nr_cached = 0;
4069bbc6adSPavel Begunkov 		cache->max_cached = max_nr;
41e1fe7ee8SBreno Leitao 		cache->elem_size = size;
42*414d0f45SJens Axboe 		return false;
43*414d0f45SJens Axboe 	}
44*414d0f45SJens Axboe 	return true;
459b797a37SJens Axboe }
469b797a37SJens Axboe 
io_alloc_cache_free(struct io_alloc_cache * cache,void (* free)(const void *))479b797a37SJens Axboe static inline void io_alloc_cache_free(struct io_alloc_cache *cache,
48*414d0f45SJens Axboe 				       void (*free)(const void *))
499b797a37SJens Axboe {
50*414d0f45SJens Axboe 	void *entry;
519b797a37SJens Axboe 
52*414d0f45SJens Axboe 	if (!cache->entries)
53*414d0f45SJens Axboe 		return;
54*414d0f45SJens Axboe 
55*414d0f45SJens Axboe 	while ((entry = io_alloc_cache_get(cache)) != NULL)
56efba1a9eSBreno Leitao 		free(entry);
57*414d0f45SJens Axboe 
58*414d0f45SJens Axboe 	kvfree(cache->entries);
59*414d0f45SJens Axboe 	cache->entries = NULL;
609b797a37SJens Axboe }
619b797a37SJens Axboe #endif
62