* Allocator for zstd decompression context using mempool_allocator with * fallback to reserved memory if allocation fails */
| 572 | * fallback to reserved memory if allocation fails |
| 573 | */ |
| 574 | static void * |
| 575 | zstd_dctx_alloc(void *opaque __maybe_unused, size_t size) |
| 576 | { |
| 577 | size_t nbytes = sizeof (struct zstd_kmem) + size; |
| 578 | struct zstd_kmem *z = NULL; |
| 579 | enum zstd_kmem_type type = ZSTD_KMEM_DEFAULT; |
| 580 | |
| 581 | z = (struct zstd_kmem *)zstd_mempool_alloc(zstd_mempool_dctx, nbytes); |
| 582 | if (!z) { |
| 583 | /* Try harder, decompression shall not fail */ |
| 584 | z = vmem_alloc(nbytes, KM_SLEEP); |
| 585 | if (z) { |
| 586 | z->pool = NULL; |
| 587 | } |
| 588 | ZSTDSTAT_BUMP(zstd_stat_alloc_fail); |
| 589 | } else { |
| 590 | return ((void*)z + (sizeof (struct zstd_kmem))); |
| 591 | } |
| 592 | |
| 593 | /* Fallback if everything fails */ |
| 594 | if (!z) { |
| 595 | /* |
| 596 | * Barrier since we only can handle it in a single thread. All |
| 597 | * other following threads need to wait here until decompression |
| 598 | * is completed. zstd_free will release this barrier later. |
| 599 | */ |
| 600 | mutex_enter(&zstd_dctx_fallback.barrier); |
| 601 | |
| 602 | z = zstd_dctx_fallback.mem; |
| 603 | type = ZSTD_KMEM_DCTX; |
| 604 | ZSTDSTAT_BUMP(zstd_stat_alloc_fallback); |
| 605 | } |
| 606 | |
| 607 | /* Allocation should always be successful */ |
| 608 | if (!z) { |
| 609 | return (NULL); |
| 610 | } |
| 611 | |
| 612 | z->kmem_type = type; |
| 613 | z->kmem_size = nbytes; |
| 614 | |
| 615 | return ((void*)z + (sizeof (struct zstd_kmem))); |
| 616 | } |
| 617 | |
| 618 | /* Free allocated memory by its specific type */ |
| 619 | static void |
nothing calls this directly
no test coverage detected