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 #if defined(CONFIG_KASAN) 10 static inline void io_alloc_cache_kasan(struct iovec **iov, int *nr) 11 { 12 kfree(*iov); 13 *iov = NULL; 14 *nr = 0; 15 } 16 #else 17 static inline void io_alloc_cache_kasan(struct iovec **iov, int *nr) 18 { 19 } 20 #endif 21 22 static inline bool io_alloc_cache_put(struct io_alloc_cache *cache, 23 void *entry) 24 { 25 if (cache->nr_cached < cache->max_cached) { 26 if (!kasan_mempool_poison_object(entry)) 27 return false; 28 cache->entries[cache->nr_cached++] = entry; 29 return true; 30 } 31 return false; 32 } 33 34 static inline void *io_alloc_cache_get(struct io_alloc_cache *cache) 35 { 36 if (cache->nr_cached) { 37 void *entry = cache->entries[--cache->nr_cached]; 38 39 /* 40 * If KASAN is enabled, always clear the initial bytes that 41 * must be zeroed post alloc, in case any of them overlap 42 * with KASAN storage. 43 */ 44 #if defined(CONFIG_KASAN) 45 kasan_mempool_unpoison_object(entry, cache->elem_size); 46 if (cache->init_clear) 47 memset(entry, 0, cache->init_clear); 48 #endif 49 return entry; 50 } 51 52 return NULL; 53 } 54 55 static inline void *io_cache_alloc(struct io_alloc_cache *cache, gfp_t gfp) 56 { 57 void *obj; 58 59 obj = io_alloc_cache_get(cache); 60 if (obj) 61 return obj; 62 63 obj = kmalloc(cache->elem_size, gfp); 64 if (obj && cache->init_clear) 65 memset(obj, 0, cache->init_clear); 66 return obj; 67 } 68 69 /* returns false if the cache was initialized properly */ 70 static inline bool io_alloc_cache_init(struct io_alloc_cache *cache, 71 unsigned max_nr, unsigned int size, 72 unsigned int init_bytes) 73 { 74 cache->entries = kvmalloc_array(max_nr, sizeof(void *), GFP_KERNEL); 75 if (cache->entries) { 76 cache->nr_cached = 0; 77 cache->max_cached = max_nr; 78 cache->elem_size = size; 79 cache->init_clear = init_bytes; 80 return false; 81 } 82 return true; 83 } 84 85 static inline void io_alloc_cache_free(struct io_alloc_cache *cache, 86 void (*free)(const void *)) 87 { 88 void *entry; 89 90 if (!cache->entries) 91 return; 92 93 while ((entry = io_alloc_cache_get(cache)) != NULL) 94 free(entry); 95 96 kvfree(cache->entries); 97 cache->entries = NULL; 98 } 99 #endif 100