70 lines · 1.6 KB · C
RawDownload
/* SPDX-License-Identifier: GPL-2.0 */#ifndef IOU_ALLOC_CACHE_H#define IOU_ALLOC_CACHE_H #include <linux/io_uring_types.h>#include <linux/kasan.h> /* * Don't allow the cache to grow beyond this size. */#define IO_ALLOC_CACHE_MAX	128 void io_alloc_cache_free(struct io_alloc_cache *cache,			 void (*free)(const void *));bool io_alloc_cache_init(struct io_alloc_cache *cache,			 unsigned max_nr, unsigned int size,			 unsigned int init_bytes); void *io_cache_alloc_new(struct io_alloc_cache *cache, gfp_t gfp); static inline bool io_alloc_cache_put(struct io_alloc_cache *cache,				      void *entry){	if (cache->nr_cached < cache->max_cached) {		if (!kasan_mempool_poison_object(entry))			return false;		cache->entries[cache->nr_cached++] = entry;		return true;	}	return false;} static inline void *io_alloc_cache_get(struct io_alloc_cache *cache){	if (cache->nr_cached) {		void *entry = cache->entries[--cache->nr_cached]; 		/*		 * If KASAN is enabled, always clear the initial bytes that		 * must be zeroed post alloc, in case any of them overlap		 * with KASAN storage.		 */#if defined(CONFIG_KASAN)		kasan_mempool_unpoison_object(entry, cache->elem_size);		if (cache->init_clear)			memset(entry, 0, cache->init_clear);#endif		return entry;	} 	return NULL;} static inline void *io_cache_alloc(struct io_alloc_cache *cache, gfp_t gfp){	void *obj; 	obj = io_alloc_cache_get(cache);	if (obj)		return obj;	return io_cache_alloc_new(cache, gfp);} static inline void io_cache_free(struct io_alloc_cache *cache, void *obj){	if (!io_alloc_cache_put(cache, obj))		kfree(obj);} #endif