|  | // SPDX-License-Identifier: GPL-2.0 | 
|  |  | 
|  | #include "alloc_cache.h" | 
|  |  | 
|  | void io_alloc_cache_free(struct io_alloc_cache *cache, | 
|  | void (*free)(const void *)) | 
|  | { | 
|  | void *entry; | 
|  |  | 
|  | if (!cache->entries) | 
|  | return; | 
|  |  | 
|  | while ((entry = io_alloc_cache_get(cache)) != NULL) | 
|  | free(entry); | 
|  |  | 
|  | kvfree(cache->entries); | 
|  | cache->entries = NULL; | 
|  | } | 
|  |  | 
|  | /* returns false if the cache was initialized properly */ | 
|  | bool io_alloc_cache_init(struct io_alloc_cache *cache, | 
|  | unsigned max_nr, unsigned int size, | 
|  | unsigned int init_bytes) | 
|  | { | 
|  | cache->entries = kvmalloc_array(max_nr, sizeof(void *), GFP_KERNEL); | 
|  | if (!cache->entries) | 
|  | return true; | 
|  |  | 
|  | cache->nr_cached = 0; | 
|  | cache->max_cached = max_nr; | 
|  | cache->elem_size = size; | 
|  | cache->init_clear = init_bytes; | 
|  | return false; | 
|  | } | 
|  |  | 
|  | void *io_cache_alloc_new(struct io_alloc_cache *cache, gfp_t gfp) | 
|  | { | 
|  | void *obj; | 
|  |  | 
|  | obj = kmalloc(cache->elem_size, gfp); | 
|  | if (obj && cache->init_clear) | 
|  | memset(obj, 0, cache->init_clear); | 
|  | return obj; | 
|  | } |