xref: /openbmc/linux/io_uring/alloc_cache.h (revision 69bbc6ade9d9d4e3c556cb83e77b6f3cd9ad3d18)
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 
139731bc98SJens Axboe static inline bool io_alloc_cache_put(struct io_alloc_cache *cache,
149b797a37SJens Axboe 				      struct io_cache_entry *entry)
159b797a37SJens Axboe {
16*69bbc6adSPavel 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 
269b797a37SJens Axboe static inline struct io_cache_entry *io_alloc_cache_get(struct io_alloc_cache *cache)
279b797a37SJens Axboe {
28efba1a9eSBreno Leitao 	if (cache->list.next) {
29efba1a9eSBreno Leitao 		struct io_cache_entry *entry;
309b797a37SJens Axboe 
31efba1a9eSBreno Leitao 		entry = container_of(cache->list.next, struct io_cache_entry, node);
32e1fe7ee8SBreno Leitao 		kasan_unpoison_range(entry, cache->elem_size);
33efba1a9eSBreno Leitao 		cache->list.next = cache->list.next->next;
34fd30d1cdSPavel Begunkov 		cache->nr_cached--;
35efba1a9eSBreno Leitao 		return entry;
369b797a37SJens Axboe 	}
379b797a37SJens Axboe 
389b797a37SJens Axboe 	return NULL;
399b797a37SJens Axboe }
409b797a37SJens Axboe 
41*69bbc6adSPavel Begunkov static inline void io_alloc_cache_init(struct io_alloc_cache *cache,
42*69bbc6adSPavel Begunkov 				       unsigned max_nr, size_t size)
439b797a37SJens Axboe {
44efba1a9eSBreno Leitao 	cache->list.next = NULL;
459731bc98SJens Axboe 	cache->nr_cached = 0;
46*69bbc6adSPavel Begunkov 	cache->max_cached = max_nr;
47e1fe7ee8SBreno Leitao 	cache->elem_size = size;
489b797a37SJens Axboe }
499b797a37SJens Axboe 
509b797a37SJens Axboe static inline void io_alloc_cache_free(struct io_alloc_cache *cache,
519b797a37SJens Axboe 					void (*free)(struct io_cache_entry *))
529b797a37SJens Axboe {
53efba1a9eSBreno Leitao 	while (1) {
54efba1a9eSBreno Leitao 		struct io_cache_entry *entry = io_alloc_cache_get(cache);
559b797a37SJens Axboe 
56efba1a9eSBreno Leitao 		if (!entry)
57efba1a9eSBreno Leitao 			break;
58efba1a9eSBreno Leitao 		free(entry);
599b797a37SJens Axboe 	}
609731bc98SJens Axboe 	cache->nr_cached = 0;
619b797a37SJens Axboe }
629b797a37SJens Axboe #endif
63