| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Basic general purpose allocator for managing special purpose |
|---|
| 3 | 4 | * memory, for example, memory that is not managed by the regular |
|---|
| .. | .. |
|---|
| 23 | 24 | * CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG. |
|---|
| 24 | 25 | * |
|---|
| 25 | 26 | * 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. |
|---|
| 29 | 27 | */ |
|---|
| 30 | 28 | |
|---|
| 31 | 29 | #include <linux/slab.h> |
|---|
| .. | .. |
|---|
| 169 | 167 | EXPORT_SYMBOL(gen_pool_create); |
|---|
| 170 | 168 | |
|---|
| 171 | 169 | /** |
|---|
| 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 |
|---|
| 173 | 171 | * @pool: pool to add new memory chunk to |
|---|
| 174 | 172 | * @virt: virtual starting address of memory chunk to add to pool |
|---|
| 175 | 173 | * @phys: physical starting address of memory chunk to add to pool |
|---|
| 176 | 174 | * @size: size in bytes of the memory chunk to add to pool |
|---|
| 177 | 175 | * @nid: node id of the node the chunk structure and bitmap should be |
|---|
| 178 | 176 | * allocated on, or -1 |
|---|
| 177 | + * @owner: private data the publisher would like to recall at alloc time |
|---|
| 179 | 178 | * |
|---|
| 180 | 179 | * Add a new chunk of special memory to the specified pool. |
|---|
| 181 | 180 | * |
|---|
| 182 | 181 | * Returns 0 on success or a -ve errno on failure. |
|---|
| 183 | 182 | */ |
|---|
| 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) |
|---|
| 186 | 185 | { |
|---|
| 187 | 186 | struct gen_pool_chunk *chunk; |
|---|
| 188 | 187 | unsigned long nbits = size >> pool->min_alloc_order; |
|---|
| .. | .. |
|---|
| 196 | 195 | chunk->phys_addr = phys; |
|---|
| 197 | 196 | chunk->start_addr = virt; |
|---|
| 198 | 197 | chunk->end_addr = virt + size - 1; |
|---|
| 198 | + chunk->owner = owner; |
|---|
| 199 | 199 | atomic_long_set(&chunk->avail, size); |
|---|
| 200 | 200 | |
|---|
| 201 | 201 | spin_lock(&pool->lock); |
|---|
| .. | .. |
|---|
| 204 | 204 | |
|---|
| 205 | 205 | return 0; |
|---|
| 206 | 206 | } |
|---|
| 207 | | -EXPORT_SYMBOL(gen_pool_add_virt); |
|---|
| 207 | +EXPORT_SYMBOL(gen_pool_add_owner); |
|---|
| 208 | 208 | |
|---|
| 209 | 209 | /** |
|---|
| 210 | 210 | * gen_pool_virt_to_phys - return the physical address of memory |
|---|
| .. | .. |
|---|
| 261 | 261 | EXPORT_SYMBOL(gen_pool_destroy); |
|---|
| 262 | 262 | |
|---|
| 263 | 263 | /** |
|---|
| 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 |
|---|
| 281 | 265 | * @pool: pool to allocate from |
|---|
| 282 | 266 | * @size: number of bytes to allocate from the pool |
|---|
| 283 | 267 | * @algo: algorithm passed from caller |
|---|
| 284 | 268 | * @data: data passed to algorithm |
|---|
| 269 | + * @owner: optionally retrieve the chunk owner |
|---|
| 285 | 270 | * |
|---|
| 286 | 271 | * Allocate the requested number of bytes from the specified pool. |
|---|
| 287 | 272 | * Uses the pool allocation function (with first-fit algorithm by default). |
|---|
| 288 | 273 | * Can not be used in NMI handler on architectures without |
|---|
| 289 | 274 | * NMI-safe cmpxchg implementation. |
|---|
| 290 | 275 | */ |
|---|
| 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) |
|---|
| 293 | 278 | { |
|---|
| 294 | 279 | struct gen_pool_chunk *chunk; |
|---|
| 295 | 280 | unsigned long addr = 0; |
|---|
| .. | .. |
|---|
| 299 | 284 | #ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG |
|---|
| 300 | 285 | BUG_ON(in_nmi()); |
|---|
| 301 | 286 | #endif |
|---|
| 287 | + |
|---|
| 288 | + if (owner) |
|---|
| 289 | + *owner = NULL; |
|---|
| 302 | 290 | |
|---|
| 303 | 291 | if (size == 0) |
|---|
| 304 | 292 | return 0; |
|---|
| .. | .. |
|---|
| 327 | 315 | addr = chunk->start_addr + ((unsigned long)start_bit << order); |
|---|
| 328 | 316 | size = nbits << order; |
|---|
| 329 | 317 | atomic_long_sub(size, &chunk->avail); |
|---|
| 318 | + if (owner) |
|---|
| 319 | + *owner = chunk->owner; |
|---|
| 330 | 320 | break; |
|---|
| 331 | 321 | } |
|---|
| 332 | 322 | rcu_read_unlock(); |
|---|
| 333 | 323 | return addr; |
|---|
| 334 | 324 | } |
|---|
| 335 | | -EXPORT_SYMBOL(gen_pool_alloc_algo); |
|---|
| 325 | +EXPORT_SYMBOL(gen_pool_alloc_algo_owner); |
|---|
| 336 | 326 | |
|---|
| 337 | 327 | /** |
|---|
| 338 | 328 | * gen_pool_dma_alloc - allocate special memory from the pool for DMA usage |
|---|
| 339 | 329 | * @pool: pool to allocate from |
|---|
| 340 | 330 | * @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. |
|---|
| 342 | 332 | * |
|---|
| 343 | 333 | * Allocate the requested number of bytes from the specified pool. |
|---|
| 344 | 334 | * Uses the pool allocation function (with first-fit algorithm by default). |
|---|
| 345 | 335 | * Can not be used in NMI handler on architectures without |
|---|
| 346 | 336 | * NMI-safe cmpxchg implementation. |
|---|
| 337 | + * |
|---|
| 338 | + * Return: virtual address of the allocated memory, or %NULL on failure |
|---|
| 347 | 339 | */ |
|---|
| 348 | 340 | 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) |
|---|
| 349 | 363 | { |
|---|
| 350 | 364 | unsigned long vaddr; |
|---|
| 351 | 365 | |
|---|
| 352 | 366 | if (!pool) |
|---|
| 353 | 367 | return NULL; |
|---|
| 354 | 368 | |
|---|
| 355 | | - vaddr = gen_pool_alloc(pool, size); |
|---|
| 369 | + vaddr = gen_pool_alloc_algo(pool, size, algo, data); |
|---|
| 356 | 370 | if (!vaddr) |
|---|
| 357 | 371 | return NULL; |
|---|
| 358 | 372 | |
|---|
| .. | .. |
|---|
| 361 | 375 | |
|---|
| 362 | 376 | return (void *)vaddr; |
|---|
| 363 | 377 | } |
|---|
| 364 | | -EXPORT_SYMBOL(gen_pool_dma_alloc); |
|---|
| 378 | +EXPORT_SYMBOL(gen_pool_dma_alloc_algo); |
|---|
| 365 | 379 | |
|---|
| 366 | 380 | /** |
|---|
| 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 |
|---|
| 368 | 477 | * @pool: pool to free to |
|---|
| 369 | 478 | * @addr: starting address of memory to free back to pool |
|---|
| 370 | 479 | * @size: size in bytes of memory to free |
|---|
| 480 | + * @owner: private data stashed at gen_pool_add() time |
|---|
| 371 | 481 | * |
|---|
| 372 | 482 | * Free previously allocated special memory back to the specified |
|---|
| 373 | 483 | * pool. Can not be used in NMI handler on architectures without |
|---|
| 374 | 484 | * NMI-safe cmpxchg implementation. |
|---|
| 375 | 485 | */ |
|---|
| 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) |
|---|
| 377 | 488 | { |
|---|
| 378 | 489 | struct gen_pool_chunk *chunk; |
|---|
| 379 | 490 | int order = pool->min_alloc_order; |
|---|
| .. | .. |
|---|
| 382 | 493 | #ifndef CONFIG_ARCH_HAVE_NMI_SAFE_CMPXCHG |
|---|
| 383 | 494 | BUG_ON(in_nmi()); |
|---|
| 384 | 495 | #endif |
|---|
| 496 | + |
|---|
| 497 | + if (owner) |
|---|
| 498 | + *owner = NULL; |
|---|
| 385 | 499 | |
|---|
| 386 | 500 | nbits = (size + (1UL << order) - 1) >> order; |
|---|
| 387 | 501 | rcu_read_lock(); |
|---|
| .. | .. |
|---|
| 393 | 507 | BUG_ON(remain); |
|---|
| 394 | 508 | size = nbits << order; |
|---|
| 395 | 509 | atomic_long_add(size, &chunk->avail); |
|---|
| 510 | + if (owner) |
|---|
| 511 | + *owner = chunk->owner; |
|---|
| 396 | 512 | rcu_read_unlock(); |
|---|
| 397 | 513 | return; |
|---|
| 398 | 514 | } |
|---|
| .. | .. |
|---|
| 400 | 516 | rcu_read_unlock(); |
|---|
| 401 | 517 | BUG(); |
|---|
| 402 | 518 | } |
|---|
| 403 | | -EXPORT_SYMBOL(gen_pool_free); |
|---|
| 519 | +EXPORT_SYMBOL(gen_pool_free_owner); |
|---|
| 404 | 520 | |
|---|
| 405 | 521 | /** |
|---|
| 406 | 522 | * gen_pool_for_each_chunk - call func for every chunk of generic memory pool |
|---|
| .. | .. |
|---|
| 425 | 541 | EXPORT_SYMBOL(gen_pool_for_each_chunk); |
|---|
| 426 | 542 | |
|---|
| 427 | 543 | /** |
|---|
| 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 |
|---|
| 429 | 545 | * @pool: the generic memory pool |
|---|
| 430 | 546 | * @start: start address |
|---|
| 431 | 547 | * @size: size of the region |
|---|
| .. | .. |
|---|
| 433 | 549 | * Check if the range of addresses falls within the specified pool. Returns |
|---|
| 434 | 550 | * true if the entire range is contained in the pool and false otherwise. |
|---|
| 435 | 551 | */ |
|---|
| 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, |
|---|
| 437 | 553 | size_t size) |
|---|
| 438 | 554 | { |
|---|
| 439 | 555 | bool found = false; |
|---|
| .. | .. |
|---|
| 452 | 568 | rcu_read_unlock(); |
|---|
| 453 | 569 | return found; |
|---|
| 454 | 570 | } |
|---|
| 571 | +EXPORT_SYMBOL(gen_pool_has_addr); |
|---|
| 455 | 572 | |
|---|
| 456 | 573 | /** |
|---|
| 457 | 574 | * gen_pool_avail - get available free space of the pool |
|---|