Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lib/genalloc.c: Add algorithm, align and zeroed family of DMA allocators

Provide the algorithm option to DMA allocators as well, along with
convenience variants for zeroed and aligned memory. The following
four functions are added:

- gen_pool_dma_alloc_algo()
- gen_pool_dma_alloc_align()
- gen_pool_dma_zalloc_algo()
- gen_pool_dma_zalloc_align()

Signed-off-by: Fredrik Noring <noring@nocrew.org>
Tested-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Christoph Hellwig <hch@lst.de>

authored by

Fredrik Noring and committed by
Christoph Hellwig
cf394fc5 b1acd4b8

+105 -5
+9 -1
include/linux/genalloc.h
··· 121 121 genpool_algo_t algo, void *data); 122 122 extern void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, 123 123 dma_addr_t *dma); 124 - void *gen_pool_dma_zalloc(struct gen_pool *pool, size_t size, dma_addr_t *dma); 124 + extern void *gen_pool_dma_alloc_algo(struct gen_pool *pool, size_t size, 125 + dma_addr_t *dma, genpool_algo_t algo, void *data); 126 + extern void *gen_pool_dma_alloc_align(struct gen_pool *pool, size_t size, 127 + dma_addr_t *dma, int align); 128 + extern void *gen_pool_dma_zalloc(struct gen_pool *pool, size_t size, dma_addr_t *dma); 129 + extern void *gen_pool_dma_zalloc_algo(struct gen_pool *pool, size_t size, 130 + dma_addr_t *dma, genpool_algo_t algo, void *data); 131 + extern void *gen_pool_dma_zalloc_align(struct gen_pool *pool, size_t size, 132 + dma_addr_t *dma, int align); 125 133 extern void gen_pool_free(struct gen_pool *, unsigned long, size_t); 126 134 extern void gen_pool_for_each_chunk(struct gen_pool *, 127 135 void (*)(struct gen_pool *, struct gen_pool_chunk *, void *), void *);
+96 -4
lib/genalloc.c
··· 348 348 */ 349 349 void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, dma_addr_t *dma) 350 350 { 351 + return gen_pool_dma_alloc_algo(pool, size, dma, pool->algo, pool->data); 352 + } 353 + EXPORT_SYMBOL(gen_pool_dma_alloc); 354 + 355 + /** 356 + * gen_pool_dma_alloc_algo - allocate special memory from the pool for DMA 357 + * usage with the given pool algorithm 358 + * @pool: pool to allocate from 359 + * @size: number of bytes to allocate from the pool 360 + * @dma: DMA-view physical address return value. Use %NULL if unneeded. 361 + * @algo: algorithm passed from caller 362 + * @data: data passed to algorithm 363 + * 364 + * Allocate the requested number of bytes from the specified pool. Uses the 365 + * given pool allocation function. Can not be used in NMI handler on 366 + * architectures without NMI-safe cmpxchg implementation. 367 + * 368 + * Return: virtual address of the allocated memory, or %NULL on failure 369 + */ 370 + void *gen_pool_dma_alloc_algo(struct gen_pool *pool, size_t size, 371 + dma_addr_t *dma, genpool_algo_t algo, void *data) 372 + { 351 373 unsigned long vaddr; 352 374 353 375 if (!pool) 354 376 return NULL; 355 377 356 - vaddr = gen_pool_alloc(pool, size); 378 + vaddr = gen_pool_alloc_algo(pool, size, algo, data); 357 379 if (!vaddr) 358 380 return NULL; 359 381 ··· 384 362 385 363 return (void *)vaddr; 386 364 } 387 - EXPORT_SYMBOL(gen_pool_dma_alloc); 365 + EXPORT_SYMBOL(gen_pool_dma_alloc_algo); 366 + 367 + /** 368 + * gen_pool_dma_alloc_align - allocate special memory from the pool for DMA 369 + * usage with the given alignment 370 + * @pool: pool to allocate from 371 + * @size: number of bytes to allocate from the pool 372 + * @dma: DMA-view physical address return value. Use %NULL if unneeded. 373 + * @align: alignment in bytes for starting address 374 + * 375 + * Allocate the requested number bytes from the specified pool, with the given 376 + * alignment restriction. Can not be used in NMI handler on architectures 377 + * without NMI-safe cmpxchg implementation. 378 + * 379 + * Return: virtual address of the allocated memory, or %NULL on failure 380 + */ 381 + void *gen_pool_dma_alloc_align(struct gen_pool *pool, size_t size, 382 + dma_addr_t *dma, int align) 383 + { 384 + struct genpool_data_align data = { .align = align }; 385 + 386 + return gen_pool_dma_alloc_algo(pool, size, dma, 387 + gen_pool_first_fit_align, &data); 388 + } 389 + EXPORT_SYMBOL(gen_pool_dma_alloc_align); 388 390 389 391 /** 390 392 * gen_pool_dma_zalloc - allocate special zeroed memory from the pool for ··· 426 380 */ 427 381 void *gen_pool_dma_zalloc(struct gen_pool *pool, size_t size, dma_addr_t *dma) 428 382 { 429 - void *vaddr = gen_pool_dma_alloc(pool, size, dma); 383 + return gen_pool_dma_zalloc_algo(pool, size, dma, pool->algo, pool->data); 384 + } 385 + EXPORT_SYMBOL(gen_pool_dma_zalloc); 386 + 387 + /** 388 + * gen_pool_dma_zalloc_algo - allocate special zeroed memory from the pool for 389 + * DMA usage with the given pool algorithm 390 + * @pool: pool to allocate from 391 + * @size: number of bytes to allocate from the pool 392 + * @dma: DMA-view physical address return value. Use %NULL if unneeded. 393 + * @algo: algorithm passed from caller 394 + * @data: data passed to algorithm 395 + * 396 + * Allocate the requested number of zeroed bytes from the specified pool. Uses 397 + * the given pool allocation function. Can not be used in NMI handler on 398 + * architectures without NMI-safe cmpxchg implementation. 399 + * 400 + * Return: virtual address of the allocated zeroed memory, or %NULL on failure 401 + */ 402 + void *gen_pool_dma_zalloc_algo(struct gen_pool *pool, size_t size, 403 + dma_addr_t *dma, genpool_algo_t algo, void *data) 404 + { 405 + void *vaddr = gen_pool_dma_alloc_algo(pool, size, dma, algo, data); 430 406 431 407 if (vaddr) 432 408 memset(vaddr, 0, size); 433 409 434 410 return vaddr; 435 411 } 436 - EXPORT_SYMBOL(gen_pool_dma_zalloc); 412 + EXPORT_SYMBOL(gen_pool_dma_zalloc_algo); 413 + 414 + /** 415 + * gen_pool_dma_zalloc_align - allocate special zeroed memory from the pool for 416 + * DMA usage with the given alignment 417 + * @pool: pool to allocate from 418 + * @size: number of bytes to allocate from the pool 419 + * @dma: DMA-view physical address return value. Use %NULL if unneeded. 420 + * @align: alignment in bytes for starting address 421 + * 422 + * Allocate the requested number of zeroed bytes from the specified pool, 423 + * with the given alignment restriction. Can not be used in NMI handler on 424 + * architectures without NMI-safe cmpxchg implementation. 425 + * 426 + * Return: virtual address of the allocated zeroed memory, or %NULL on failure 427 + */ 428 + void *gen_pool_dma_zalloc_align(struct gen_pool *pool, size_t size, 429 + dma_addr_t *dma, int align) 430 + { 431 + struct genpool_data_align data = { .align = align }; 432 + 433 + return gen_pool_dma_zalloc_algo(pool, size, dma, 434 + gen_pool_first_fit_align, &data); 435 + } 436 + EXPORT_SYMBOL(gen_pool_dma_zalloc_align); 437 437 438 438 /** 439 439 * gen_pool_free - free allocated special memory back to the pool