xref: /openbmc/linux/io_uring/alloc_cache.h (revision e1fe7ee885dc0712e982ee465d9f8b96254c30c1)
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 {
169731bc98SJens Axboe 	if (cache->nr_cached < IO_ALLOC_CACHE_MAX) {
179731bc98SJens Axboe 		cache->nr_cached++;
18efba1a9eSBreno Leitao 		wq_stack_add_head(&entry->node, &cache->list);
19*e1fe7ee8SBreno Leitao 		/* KASAN poisons object */
20*e1fe7ee8SBreno 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);
32*e1fe7ee8SBreno 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*e1fe7ee8SBreno Leitao static inline void io_alloc_cache_init(struct io_alloc_cache *cache, size_t size)
429b797a37SJens Axboe {
43efba1a9eSBreno Leitao 	cache->list.next = NULL;
449731bc98SJens Axboe 	cache->nr_cached = 0;
45*e1fe7ee8SBreno Leitao 	cache->elem_size = size;
469b797a37SJens Axboe }
479b797a37SJens Axboe 
489b797a37SJens Axboe static inline void io_alloc_cache_free(struct io_alloc_cache *cache,
499b797a37SJens Axboe 					void (*free)(struct io_cache_entry *))
509b797a37SJens Axboe {
51efba1a9eSBreno Leitao 	while (1) {
52efba1a9eSBreno Leitao 		struct io_cache_entry *entry = io_alloc_cache_get(cache);
539b797a37SJens Axboe 
54efba1a9eSBreno Leitao 		if (!entry)
55efba1a9eSBreno Leitao 			break;
56efba1a9eSBreno Leitao 		free(entry);
579b797a37SJens Axboe 	}
589731bc98SJens Axboe 	cache->nr_cached = 0;
599b797a37SJens Axboe }
609b797a37SJens Axboe #endif
61