hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
kernel/lib/genalloc.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Basic general purpose allocator for managing special purpose
34 * memory, for example, memory that is not managed by the regular
....@@ -23,9 +24,6 @@
2324 * CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG.
2425 *
2526 * Copyright 2005 (C) Jes Sorensen <jes@trained-monkey.org>
26
- *
27
- * This source code is licensed under the GNU General Public License,
28
- * Version 2. See the file COPYING for more details.
2927 */
3028
3129 #include <linux/slab.h>
....@@ -169,20 +167,21 @@
169167 EXPORT_SYMBOL(gen_pool_create);
170168
171169 /**
172
- * gen_pool_add_virt - add a new chunk of special memory to the pool
170
+ * gen_pool_add_owner- add a new chunk of special memory to the pool
173171 * @pool: pool to add new memory chunk to
174172 * @virt: virtual starting address of memory chunk to add to pool
175173 * @phys: physical starting address of memory chunk to add to pool
176174 * @size: size in bytes of the memory chunk to add to pool
177175 * @nid: node id of the node the chunk structure and bitmap should be
178176 * allocated on, or -1
177
+ * @owner: private data the publisher would like to recall at alloc time
179178 *
180179 * Add a new chunk of special memory to the specified pool.
181180 *
182181 * Returns 0 on success or a -ve errno on failure.
183182 */
184
-int gen_pool_add_virt(struct gen_pool *pool, unsigned long virt, phys_addr_t phys,
185
- size_t size, int nid)
183
+int gen_pool_add_owner(struct gen_pool *pool, unsigned long virt, phys_addr_t phys,
184
+ size_t size, int nid, void *owner)
186185 {
187186 struct gen_pool_chunk *chunk;
188187 unsigned long nbits = size >> pool->min_alloc_order;
....@@ -196,6 +195,7 @@
196195 chunk->phys_addr = phys;
197196 chunk->start_addr = virt;
198197 chunk->end_addr = virt + size - 1;
198
+ chunk->owner = owner;
199199 atomic_long_set(&chunk->avail, size);
200200
201201 spin_lock(&pool->lock);
....@@ -204,7 +204,7 @@
204204
205205 return 0;
206206 }
207
-EXPORT_SYMBOL(gen_pool_add_virt);
207
+EXPORT_SYMBOL(gen_pool_add_owner);
208208
209209 /**
210210 * gen_pool_virt_to_phys - return the physical address of memory
....@@ -261,35 +261,20 @@
261261 EXPORT_SYMBOL(gen_pool_destroy);
262262
263263 /**
264
- * gen_pool_alloc - allocate special memory from the pool
265
- * @pool: pool to allocate from
266
- * @size: number of bytes to allocate from the pool
267
- *
268
- * Allocate the requested number of bytes from the specified pool.
269
- * Uses the pool allocation function (with first-fit algorithm by default).
270
- * Can not be used in NMI handler on architectures without
271
- * NMI-safe cmpxchg implementation.
272
- */
273
-unsigned long gen_pool_alloc(struct gen_pool *pool, size_t size)
274
-{
275
- return gen_pool_alloc_algo(pool, size, pool->algo, pool->data);
276
-}
277
-EXPORT_SYMBOL(gen_pool_alloc);
278
-
279
-/**
280
- * gen_pool_alloc_algo - allocate special memory from the pool
264
+ * gen_pool_alloc_algo_owner - allocate special memory from the pool
281265 * @pool: pool to allocate from
282266 * @size: number of bytes to allocate from the pool
283267 * @algo: algorithm passed from caller
284268 * @data: data passed to algorithm
269
+ * @owner: optionally retrieve the chunk owner
285270 *
286271 * Allocate the requested number of bytes from the specified pool.
287272 * Uses the pool allocation function (with first-fit algorithm by default).
288273 * Can not be used in NMI handler on architectures without
289274 * NMI-safe cmpxchg implementation.
290275 */
291
-unsigned long gen_pool_alloc_algo(struct gen_pool *pool, size_t size,
292
- genpool_algo_t algo, void *data)
276
+unsigned long gen_pool_alloc_algo_owner(struct gen_pool *pool, size_t size,
277
+ genpool_algo_t algo, void *data, void **owner)
293278 {
294279 struct gen_pool_chunk *chunk;
295280 unsigned long addr = 0;
....@@ -299,6 +284,9 @@
299284 #ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG
300285 BUG_ON(in_nmi());
301286 #endif
287
+
288
+ if (owner)
289
+ *owner = NULL;
302290
303291 if (size == 0)
304292 return 0;
....@@ -327,32 +315,58 @@
327315 addr = chunk->start_addr + ((unsigned long)start_bit << order);
328316 size = nbits << order;
329317 atomic_long_sub(size, &chunk->avail);
318
+ if (owner)
319
+ *owner = chunk->owner;
330320 break;
331321 }
332322 rcu_read_unlock();
333323 return addr;
334324 }
335
-EXPORT_SYMBOL(gen_pool_alloc_algo);
325
+EXPORT_SYMBOL(gen_pool_alloc_algo_owner);
336326
337327 /**
338328 * gen_pool_dma_alloc - allocate special memory from the pool for DMA usage
339329 * @pool: pool to allocate from
340330 * @size: number of bytes to allocate from the pool
341
- * @dma: dma-view physical address return value. Use NULL if unneeded.
331
+ * @dma: dma-view physical address return value. Use %NULL if unneeded.
342332 *
343333 * Allocate the requested number of bytes from the specified pool.
344334 * Uses the pool allocation function (with first-fit algorithm by default).
345335 * Can not be used in NMI handler on architectures without
346336 * NMI-safe cmpxchg implementation.
337
+ *
338
+ * Return: virtual address of the allocated memory, or %NULL on failure
347339 */
348340 void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, dma_addr_t *dma)
341
+{
342
+ return gen_pool_dma_alloc_algo(pool, size, dma, pool->algo, pool->data);
343
+}
344
+EXPORT_SYMBOL(gen_pool_dma_alloc);
345
+
346
+/**
347
+ * gen_pool_dma_alloc_algo - allocate special memory from the pool for DMA
348
+ * usage with the given pool algorithm
349
+ * @pool: pool to allocate from
350
+ * @size: number of bytes to allocate from the pool
351
+ * @dma: DMA-view physical address return value. Use %NULL if unneeded.
352
+ * @algo: algorithm passed from caller
353
+ * @data: data passed to algorithm
354
+ *
355
+ * Allocate the requested number of bytes from the specified pool. Uses the
356
+ * given pool allocation function. Can not be used in NMI handler on
357
+ * architectures without NMI-safe cmpxchg implementation.
358
+ *
359
+ * Return: virtual address of the allocated memory, or %NULL on failure
360
+ */
361
+void *gen_pool_dma_alloc_algo(struct gen_pool *pool, size_t size,
362
+ dma_addr_t *dma, genpool_algo_t algo, void *data)
349363 {
350364 unsigned long vaddr;
351365
352366 if (!pool)
353367 return NULL;
354368
355
- vaddr = gen_pool_alloc(pool, size);
369
+ vaddr = gen_pool_alloc_algo(pool, size, algo, data);
356370 if (!vaddr)
357371 return NULL;
358372
....@@ -361,19 +375,116 @@
361375
362376 return (void *)vaddr;
363377 }
364
-EXPORT_SYMBOL(gen_pool_dma_alloc);
378
+EXPORT_SYMBOL(gen_pool_dma_alloc_algo);
365379
366380 /**
367
- * gen_pool_free - free allocated special memory back to the pool
381
+ * gen_pool_dma_alloc_align - allocate special memory from the pool for DMA
382
+ * usage with the given alignment
383
+ * @pool: pool to allocate from
384
+ * @size: number of bytes to allocate from the pool
385
+ * @dma: DMA-view physical address return value. Use %NULL if unneeded.
386
+ * @align: alignment in bytes for starting address
387
+ *
388
+ * Allocate the requested number bytes from the specified pool, with the given
389
+ * alignment restriction. Can not be used in NMI handler on architectures
390
+ * without NMI-safe cmpxchg implementation.
391
+ *
392
+ * Return: virtual address of the allocated memory, or %NULL on failure
393
+ */
394
+void *gen_pool_dma_alloc_align(struct gen_pool *pool, size_t size,
395
+ dma_addr_t *dma, int align)
396
+{
397
+ struct genpool_data_align data = { .align = align };
398
+
399
+ return gen_pool_dma_alloc_algo(pool, size, dma,
400
+ gen_pool_first_fit_align, &data);
401
+}
402
+EXPORT_SYMBOL(gen_pool_dma_alloc_align);
403
+
404
+/**
405
+ * gen_pool_dma_zalloc - allocate special zeroed memory from the pool for
406
+ * DMA usage
407
+ * @pool: pool to allocate from
408
+ * @size: number of bytes to allocate from the pool
409
+ * @dma: dma-view physical address return value. Use %NULL if unneeded.
410
+ *
411
+ * Allocate the requested number of zeroed bytes from the specified pool.
412
+ * Uses the pool allocation function (with first-fit algorithm by default).
413
+ * Can not be used in NMI handler on architectures without
414
+ * NMI-safe cmpxchg implementation.
415
+ *
416
+ * Return: virtual address of the allocated zeroed memory, or %NULL on failure
417
+ */
418
+void *gen_pool_dma_zalloc(struct gen_pool *pool, size_t size, dma_addr_t *dma)
419
+{
420
+ return gen_pool_dma_zalloc_algo(pool, size, dma, pool->algo, pool->data);
421
+}
422
+EXPORT_SYMBOL(gen_pool_dma_zalloc);
423
+
424
+/**
425
+ * gen_pool_dma_zalloc_algo - allocate special zeroed memory from the pool for
426
+ * DMA usage with the given pool algorithm
427
+ * @pool: pool to allocate from
428
+ * @size: number of bytes to allocate from the pool
429
+ * @dma: DMA-view physical address return value. Use %NULL if unneeded.
430
+ * @algo: algorithm passed from caller
431
+ * @data: data passed to algorithm
432
+ *
433
+ * Allocate the requested number of zeroed bytes from the specified pool. Uses
434
+ * the given pool allocation function. Can not be used in NMI handler on
435
+ * architectures without NMI-safe cmpxchg implementation.
436
+ *
437
+ * Return: virtual address of the allocated zeroed memory, or %NULL on failure
438
+ */
439
+void *gen_pool_dma_zalloc_algo(struct gen_pool *pool, size_t size,
440
+ dma_addr_t *dma, genpool_algo_t algo, void *data)
441
+{
442
+ void *vaddr = gen_pool_dma_alloc_algo(pool, size, dma, algo, data);
443
+
444
+ if (vaddr)
445
+ memset(vaddr, 0, size);
446
+
447
+ return vaddr;
448
+}
449
+EXPORT_SYMBOL(gen_pool_dma_zalloc_algo);
450
+
451
+/**
452
+ * gen_pool_dma_zalloc_align - allocate special zeroed memory from the pool for
453
+ * DMA usage with the given alignment
454
+ * @pool: pool to allocate from
455
+ * @size: number of bytes to allocate from the pool
456
+ * @dma: DMA-view physical address return value. Use %NULL if unneeded.
457
+ * @align: alignment in bytes for starting address
458
+ *
459
+ * Allocate the requested number of zeroed bytes from the specified pool,
460
+ * with the given alignment restriction. Can not be used in NMI handler on
461
+ * architectures without NMI-safe cmpxchg implementation.
462
+ *
463
+ * Return: virtual address of the allocated zeroed memory, or %NULL on failure
464
+ */
465
+void *gen_pool_dma_zalloc_align(struct gen_pool *pool, size_t size,
466
+ dma_addr_t *dma, int align)
467
+{
468
+ struct genpool_data_align data = { .align = align };
469
+
470
+ return gen_pool_dma_zalloc_algo(pool, size, dma,
471
+ gen_pool_first_fit_align, &data);
472
+}
473
+EXPORT_SYMBOL(gen_pool_dma_zalloc_align);
474
+
475
+/**
476
+ * gen_pool_free_owner - free allocated special memory back to the pool
368477 * @pool: pool to free to
369478 * @addr: starting address of memory to free back to pool
370479 * @size: size in bytes of memory to free
480
+ * @owner: private data stashed at gen_pool_add() time
371481 *
372482 * Free previously allocated special memory back to the specified
373483 * pool. Can not be used in NMI handler on architectures without
374484 * NMI-safe cmpxchg implementation.
375485 */
376
-void gen_pool_free(struct gen_pool *pool, unsigned long addr, size_t size)
486
+void gen_pool_free_owner(struct gen_pool *pool, unsigned long addr, size_t size,
487
+ void **owner)
377488 {
378489 struct gen_pool_chunk *chunk;
379490 int order = pool->min_alloc_order;
....@@ -382,6 +493,9 @@
382493 #ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG
383494 BUG_ON(in_nmi());
384495 #endif
496
+
497
+ if (owner)
498
+ *owner = NULL;
385499
386500 nbits = (size + (1UL << order) - 1) >> order;
387501 rcu_read_lock();
....@@ -393,6 +507,8 @@
393507 BUG_ON(remain);
394508 size = nbits << order;
395509 atomic_long_add(size, &chunk->avail);
510
+ if (owner)
511
+ *owner = chunk->owner;
396512 rcu_read_unlock();
397513 return;
398514 }
....@@ -400,7 +516,7 @@
400516 rcu_read_unlock();
401517 BUG();
402518 }
403
-EXPORT_SYMBOL(gen_pool_free);
519
+EXPORT_SYMBOL(gen_pool_free_owner);
404520
405521 /**
406522 * gen_pool_for_each_chunk - call func for every chunk of generic memory pool
....@@ -425,7 +541,7 @@
425541 EXPORT_SYMBOL(gen_pool_for_each_chunk);
426542
427543 /**
428
- * addr_in_gen_pool - checks if an address falls within the range of a pool
544
+ * gen_pool_has_addr - checks if an address falls within the range of a pool
429545 * @pool: the generic memory pool
430546 * @start: start address
431547 * @size: size of the region
....@@ -433,7 +549,7 @@
433549 * Check if the range of addresses falls within the specified pool. Returns
434550 * true if the entire range is contained in the pool and false otherwise.
435551 */
436
-bool addr_in_gen_pool(struct gen_pool *pool, unsigned long start,
552
+bool gen_pool_has_addr(struct gen_pool *pool, unsigned long start,
437553 size_t size)
438554 {
439555 bool found = false;
....@@ -452,6 +568,7 @@
452568 rcu_read_unlock();
453569 return found;
454570 }
571
+EXPORT_SYMBOL(gen_pool_has_addr);
455572
456573 /**
457574 * gen_pool_avail - get available free space of the pool