.. | .. |
---|
| 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 |
---|