xref: /openbmc/linux/io_uring/alloc_cache.h (revision 528407b1)
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  */
79731bc98SJens Axboe #define IO_ALLOC_CACHE_MAX	512
89731bc98SJens Axboe 
99b797a37SJens Axboe struct io_cache_entry {
10efba1a9eSBreno Leitao 	struct io_wq_work_node node;
119b797a37SJens Axboe };
129b797a37SJens Axboe 
io_alloc_cache_put(struct io_alloc_cache * cache,struct io_cache_entry * entry)139731bc98SJens Axboe static inline bool io_alloc_cache_put(struct io_alloc_cache *cache,
149b797a37SJens Axboe 				      struct io_cache_entry *entry)
159b797a37SJens Axboe {
1669bbc6adSPavel Begunkov 	if (cache->nr_cached < cache->max_cached) {
179731bc98SJens Axboe 		cache->nr_cached++;
18efba1a9eSBreno Leitao 		wq_stack_add_head(&entry->node, &cache->list);
19e1fe7ee8SBreno Leitao 		/* KASAN poisons object */
20e1fe7ee8SBreno Leitao 		kasan_slab_free_mempool(entry);
219731bc98SJens Axboe 		return true;
229731bc98SJens Axboe 	}
239731bc98SJens Axboe 	return false;
249b797a37SJens Axboe }
259b797a37SJens Axboe 
io_alloc_cache_empty(struct io_alloc_cache * cache)26*528407b1SPavel Begunkov static inline bool io_alloc_cache_empty(struct io_alloc_cache *cache)
27*528407b1SPavel Begunkov {
28*528407b1SPavel Begunkov 	return !cache->list.next;
29*528407b1SPavel Begunkov }
30*528407b1SPavel Begunkov 
io_alloc_cache_get(struct io_alloc_cache * cache)319b797a37SJens Axboe static inline struct io_cache_entry *io_alloc_cache_get(struct io_alloc_cache *cache)
329b797a37SJens Axboe {
33efba1a9eSBreno Leitao 	if (cache->list.next) {
34efba1a9eSBreno Leitao 		struct io_cache_entry *entry;
359b797a37SJens Axboe 
36efba1a9eSBreno Leitao 		entry = container_of(cache->list.next, struct io_cache_entry, node);
37e1fe7ee8SBreno Leitao 		kasan_unpoison_range(entry, cache->elem_size);
38efba1a9eSBreno Leitao 		cache->list.next = cache->list.next->next;
39fd30d1cdSPavel Begunkov 		cache->nr_cached--;
40efba1a9eSBreno Leitao 		return entry;
419b797a37SJens Axboe 	}
429b797a37SJens Axboe 
439b797a37SJens Axboe 	return NULL;
449b797a37SJens Axboe }
459b797a37SJens Axboe 
io_alloc_cache_init(struct io_alloc_cache * cache,unsigned max_nr,size_t size)4669bbc6adSPavel Begunkov static inline void io_alloc_cache_init(struct io_alloc_cache *cache,
4769bbc6adSPavel Begunkov 				       unsigned max_nr, size_t size)
489b797a37SJens Axboe {
49efba1a9eSBreno Leitao 	cache->list.next = NULL;
509731bc98SJens Axboe 	cache->nr_cached = 0;
5169bbc6adSPavel Begunkov 	cache->max_cached = max_nr;
52e1fe7ee8SBreno Leitao 	cache->elem_size = size;
539b797a37SJens Axboe }
549b797a37SJens Axboe 
io_alloc_cache_free(struct io_alloc_cache * cache,void (* free)(struct io_cache_entry *))559b797a37SJens Axboe static inline void io_alloc_cache_free(struct io_alloc_cache *cache,
569b797a37SJens Axboe 					void (*free)(struct io_cache_entry *))
579b797a37SJens Axboe {
58efba1a9eSBreno Leitao 	while (1) {
59efba1a9eSBreno Leitao 		struct io_cache_entry *entry = io_alloc_cache_get(cache);
609b797a37SJens Axboe 
61efba1a9eSBreno Leitao 		if (!entry)
62efba1a9eSBreno Leitao 			break;
63efba1a9eSBreno Leitao 		free(entry);
649b797a37SJens Axboe 	}
659731bc98SJens Axboe 	cache->nr_cached = 0;
669b797a37SJens Axboe }
679b797a37SJens Axboe #endif
68