| 1 |
|
| 2 | #ifndef IOU_ALLOC_CACHE_H
|
| 3 | #define IOU_ALLOC_CACHE_H
|
| 4 |
|
| 5 | #include <linux/io_uring_types.h>
|
| 6 | #include <linux/kasan.h>
|
| 7 |
|
| 8 | |
| 9 | * Don't allow the cache to grow beyond this size.
|
| 10 |
|
| 11 | #define IO_ALLOC_CACHE_MAX 128
|
| 12 |
|
| 13 | void io_alloc_cache_free(struct io_alloc_cache *cache,
|
| 14 | void (*free)(const void *));
|
| 15 | bool io_alloc_cache_init(struct io_alloc_cache *cache,
|
| 16 | unsigned max_nr, unsigned int size,
|
| 17 | unsigned int init_bytes);
|
| 18 |
|
| 19 | void *io_cache_alloc_new(struct io_alloc_cache *cache, gfp_t gfp);
|
| 20 |
|
| 21 | static inline bool io_alloc_cache_put(struct io_alloc_cache *cache,
|
| 22 | void *entry)
|
| 23 | {
|
| 24 | if (cache->nr_cached < cache->max_cached) {
|
| 25 | if (!kasan_mempool_poison_object(entry))
|
| 26 | return false;
|
| 27 | cache->entries[cache->nr_cached++] = entry;
|
| 28 | return true;
|
| 29 | }
|
| 30 | return false;
|
| 31 | }
|
| 32 |
|
| 33 | static inline void *io_alloc_cache_get(struct io_alloc_cache *cache)
|
| 34 | {
|
| 35 | if (cache->nr_cached) {
|
| 36 | void *entry = cache->entries[--cache->nr_cached];
|
| 37 |
|
| 38 | |
| 39 | * If KASAN is enabled, always clear the initial bytes that
|
| 40 | * must be zeroed post alloc, in case any of them overlap
|
| 41 | * with KASAN storage.
|
| 42 |
|
| 43 | #if defined(CONFIG_KASAN)
|
| 44 | kasan_mempool_unpoison_object(entry, cache->elem_size);
|
| 45 | if (cache->init_clear)
|
| 46 | memset(entry, 0, cache->init_clear);
|
| 47 | #endif
|
| 48 | return entry;
|
| 49 | }
|
| 50 |
|
| 51 | return NULL;
|
| 52 | }
|
| 53 |
|
| 54 | static inline void *io_cache_alloc(struct io_alloc_cache *cache, gfp_t gfp)
|
| 55 | {
|
| 56 | void *obj;
|
| 57 |
|
| 58 | obj = io_alloc_cache_get(cache);
|
| 59 | if (obj)
|
| 60 | return obj;
|
| 61 | return io_cache_alloc_new(cache, gfp);
|
| 62 | }
|
| 63 |
|
| 64 | static inline void io_cache_free(struct io_alloc_cache *cache, void *obj)
|
| 65 | {
|
| 66 | if (!io_alloc_cache_put(cache, obj))
|
| 67 | kvfree(obj);
|
| 68 | }
|
| 69 |
|
| 70 | #endif
|