xref: /linux/io_uring/alloc_cache.h (revision 4b132aacb0768ac1e652cf517097ea6f237214b9)
1 #ifndef IOU_ALLOC_CACHE_H
2 #define IOU_ALLOC_CACHE_H
3 
4 /*
5  * Don't allow the cache to grow beyond this size.
6  */
7 #define IO_ALLOC_CACHE_MAX	128
8 
9 static inline bool io_alloc_cache_put(struct io_alloc_cache *cache,
10 				      void *entry)
11 {
12 	if (cache->nr_cached < cache->max_cached) {
13 		if (!kasan_mempool_poison_object(entry))
14 			return false;
15 		cache->entries[cache->nr_cached++] = entry;
16 		return true;
17 	}
18 	return false;
19 }
20 
21 static inline void *io_alloc_cache_get(struct io_alloc_cache *cache)
22 {
23 	if (cache->nr_cached) {
24 		void *entry = cache->entries[--cache->nr_cached];
25 
26 		kasan_mempool_unpoison_object(entry, cache->elem_size);
27 		return entry;
28 	}
29 
30 	return NULL;
31 }
32 
33 /* returns false if the cache was initialized properly */
34 static inline bool io_alloc_cache_init(struct io_alloc_cache *cache,
35 				       unsigned max_nr, size_t size)
36 {
37 	cache->entries = kvmalloc_array(max_nr, sizeof(void *), GFP_KERNEL);
38 	if (cache->entries) {
39 		cache->nr_cached = 0;
40 		cache->max_cached = max_nr;
41 		cache->elem_size = size;
42 		return false;
43 	}
44 	return true;
45 }
46 
47 static inline void io_alloc_cache_free(struct io_alloc_cache *cache,
48 				       void (*free)(const void *))
49 {
50 	void *entry;
51 
52 	if (!cache->entries)
53 		return;
54 
55 	while ((entry = io_alloc_cache_get(cache)) != NULL)
56 		free(entry);
57 
58 	kvfree(cache->entries);
59 	cache->entries = NULL;
60 }
61 #endif
62