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