mempool.c (552c69b36ebd966186573b9c7a286b390935cce1) | mempool.c (c1a67fefd0546a5552289c65fe31b1d60e64b643) |
---|---|
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * linux/mm/mempool.c 4 * 5 * memory buffer pool support. Such pools are mostly used 6 * for guaranteed, deadlock-free memory allocations during 7 * extreme VM load. 8 * --- 124 unchanged lines hidden (view full) --- 133 134 BUG_ON(pool->curr_nr < 0); 135 kasan_unpoison_element(pool, element, flags); 136 check_element(pool, element); 137 return element; 138} 139 140/** | 1// SPDX-License-Identifier: GPL-2.0 2/* 3 * linux/mm/mempool.c 4 * 5 * memory buffer pool support. Such pools are mostly used 6 * for guaranteed, deadlock-free memory allocations during 7 * extreme VM load. 8 * --- 124 unchanged lines hidden (view full) --- 133 134 BUG_ON(pool->curr_nr < 0); 135 kasan_unpoison_element(pool, element, flags); 136 check_element(pool, element); 137 return element; 138} 139 140/** |
141 * mempool_exit - exit a mempool initialized with mempool_init() 142 * @pool: pointer to the memory pool which was initialized with 143 * mempool_init(). 144 * 145 * Free all reserved elements in @pool and @pool itself. This function 146 * only sleeps if the free_fn() function sleeps. 147 * 148 * May be called on a zeroed but uninitialized mempool (i.e. allocated with 149 * kzalloc()). 150 */ 151void mempool_exit(mempool_t *pool) 152{ 153 while (pool->curr_nr) { 154 void *element = remove_element(pool, GFP_KERNEL); 155 pool->free(element, pool->pool_data); 156 } 157 kfree(pool->elements); 158 pool->elements = NULL; 159} 160EXPORT_SYMBOL(mempool_exit); 161 162/** |
|
141 * mempool_destroy - deallocate a memory pool 142 * @pool: pointer to the memory pool which was allocated via 143 * mempool_create(). 144 * 145 * Free all reserved elements in @pool and @pool itself. This function 146 * only sleeps if the free_fn() function sleeps. 147 */ 148void mempool_destroy(mempool_t *pool) 149{ 150 if (unlikely(!pool)) 151 return; 152 | 163 * mempool_destroy - deallocate a memory pool 164 * @pool: pointer to the memory pool which was allocated via 165 * mempool_create(). 166 * 167 * Free all reserved elements in @pool and @pool itself. This function 168 * only sleeps if the free_fn() function sleeps. 169 */ 170void mempool_destroy(mempool_t *pool) 171{ 172 if (unlikely(!pool)) 173 return; 174 |
153 while (pool->curr_nr) { 154 void *element = remove_element(pool, GFP_KERNEL); 155 pool->free(element, pool->pool_data); 156 } 157 kfree(pool->elements); | 175 mempool_exit(pool); |
158 kfree(pool); 159} 160EXPORT_SYMBOL(mempool_destroy); 161 | 176 kfree(pool); 177} 178EXPORT_SYMBOL(mempool_destroy); 179 |
180int mempool_init_node(mempool_t *pool, int min_nr, mempool_alloc_t *alloc_fn, 181 mempool_free_t *free_fn, void *pool_data, 182 gfp_t gfp_mask, int node_id) 183{ 184 spin_lock_init(&pool->lock); 185 pool->min_nr = min_nr; 186 pool->pool_data = pool_data; 187 pool->alloc = alloc_fn; 188 pool->free = free_fn; 189 init_waitqueue_head(&pool->wait); 190 191 pool->elements = kmalloc_array_node(min_nr, sizeof(void *), 192 gfp_mask, node_id); 193 if (!pool->elements) 194 return -ENOMEM; 195 196 /* 197 * First pre-allocate the guaranteed number of buffers. 198 */ 199 while (pool->curr_nr < pool->min_nr) { 200 void *element; 201 202 element = pool->alloc(gfp_mask, pool->pool_data); 203 if (unlikely(!element)) { 204 mempool_exit(pool); 205 return -ENOMEM; 206 } 207 add_element(pool, element); 208 } 209 210 return 0; 211} 212EXPORT_SYMBOL(mempool_init_node); 213 |
|
162/** | 214/** |
215 * mempool_init - initialize a memory pool 216 * @min_nr: the minimum number of elements guaranteed to be 217 * allocated for this pool. 218 * @alloc_fn: user-defined element-allocation function. 219 * @free_fn: user-defined element-freeing function. 220 * @pool_data: optional private data available to the user-defined functions. 221 * 222 * Like mempool_create(), but initializes the pool in (i.e. embedded in another 223 * structure). 224 */ 225int mempool_init(mempool_t *pool, int min_nr, mempool_alloc_t *alloc_fn, 226 mempool_free_t *free_fn, void *pool_data) 227{ 228 return mempool_init_node(pool, min_nr, alloc_fn, free_fn, 229 pool_data, GFP_KERNEL, NUMA_NO_NODE); 230 231} 232EXPORT_SYMBOL(mempool_init); 233 234/** |
|
163 * mempool_create - create a memory pool 164 * @min_nr: the minimum number of elements guaranteed to be 165 * allocated for this pool. 166 * @alloc_fn: user-defined element-allocation function. 167 * @free_fn: user-defined element-freeing function. 168 * @pool_data: optional private data available to the user-defined functions. 169 * 170 * this function creates and allocates a guaranteed size, preallocated --- 10 unchanged lines hidden (view full) --- 181} 182EXPORT_SYMBOL(mempool_create); 183 184mempool_t *mempool_create_node(int min_nr, mempool_alloc_t *alloc_fn, 185 mempool_free_t *free_fn, void *pool_data, 186 gfp_t gfp_mask, int node_id) 187{ 188 mempool_t *pool; | 235 * mempool_create - create a memory pool 236 * @min_nr: the minimum number of elements guaranteed to be 237 * allocated for this pool. 238 * @alloc_fn: user-defined element-allocation function. 239 * @free_fn: user-defined element-freeing function. 240 * @pool_data: optional private data available to the user-defined functions. 241 * 242 * this function creates and allocates a guaranteed size, preallocated --- 10 unchanged lines hidden (view full) --- 253} 254EXPORT_SYMBOL(mempool_create); 255 256mempool_t *mempool_create_node(int min_nr, mempool_alloc_t *alloc_fn, 257 mempool_free_t *free_fn, void *pool_data, 258 gfp_t gfp_mask, int node_id) 259{ 260 mempool_t *pool; |
261 |
|
189 pool = kzalloc_node(sizeof(*pool), gfp_mask, node_id); 190 if (!pool) 191 return NULL; | 262 pool = kzalloc_node(sizeof(*pool), gfp_mask, node_id); 263 if (!pool) 264 return NULL; |
192 pool->elements = kmalloc_array_node(min_nr, sizeof(void *), 193 gfp_mask, node_id); 194 if (!pool->elements) { | 265 266 if (mempool_init_node(pool, min_nr, alloc_fn, free_fn, pool_data, 267 gfp_mask, node_id)) { |
195 kfree(pool); 196 return NULL; 197 } | 268 kfree(pool); 269 return NULL; 270 } |
198 spin_lock_init(&pool->lock); 199 pool->min_nr = min_nr; 200 pool->pool_data = pool_data; 201 init_waitqueue_head(&pool->wait); 202 pool->alloc = alloc_fn; 203 pool->free = free_fn; | |
204 | 271 |
205 /* 206 * First pre-allocate the guaranteed number of buffers. 207 */ 208 while (pool->curr_nr < pool->min_nr) { 209 void *element; 210 211 element = pool->alloc(gfp_mask, pool->pool_data); 212 if (unlikely(!element)) { 213 mempool_destroy(pool); 214 return NULL; 215 } 216 add_element(pool, element); 217 } | |
218 return pool; 219} 220EXPORT_SYMBOL(mempool_create_node); 221 222/** 223 * mempool_resize - resize an existing memory pool 224 * @pool: pointer to the memory pool which was allocated via 225 * mempool_create(). --- 269 unchanged lines hidden --- | 272 return pool; 273} 274EXPORT_SYMBOL(mempool_create_node); 275 276/** 277 * mempool_resize - resize an existing memory pool 278 * @pool: pointer to the memory pool which was allocated via 279 * mempool_create(). --- 269 unchanged lines hidden --- |