sound/core/memalloc.c
Source file repositories/reference/linux-study-clean/sound/core/memalloc.c
File Facts
- System
- Linux kernel
- Corpus path
sound/core/memalloc.c- Extension
.c- Size
- 24265 bytes
- Lines
- 913
- Domain
- Driver Families
- Bucket
- sound/core
- Inferred role
- Driver Families: exported/initcall integration point
- Status
- integration implementation candidate
Why This File Exists
Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/slab.hlinux/mm.hlinux/dma-mapping.hlinux/dma-map-ops.hlinux/genalloc.hlinux/highmem.hlinux/vmalloc.hasm/set_memory.hsound/memalloc.h
Detected Declarations
struct snd_malloc_opsstruct snd_dma_sg_fallbackfunction snd_dma_alloc_dir_pagesfunction snd_dma_alloc_pages_fallbackfunction snd_dma_alloc_pagesfunction __snd_release_pagesfunction snd_dma_alloc_pagesfunction snd_dma_buffer_mmapfunction snd_dma_buffer_syncfunction snd_sgbuf_get_addrfunction snd_sgbuf_get_chunk_sizefunction do_free_pagesfunction snd_dma_continuous_freefunction snd_dma_continuous_mmapfunction snd_dma_vmalloc_freefunction snd_dma_vmalloc_mmapfunction snd_dma_vmalloc_get_addrfunction snd_dma_vmalloc_get_chunk_sizefunction snd_dma_iram_freefunction snd_dma_iram_mmapfunction snd_dma_dev_freefunction snd_dma_dev_mmapfunction snd_dma_wc_freefunction snd_dma_wc_mmapfunction snd_dma_wc_freefunction snd_dma_wc_mmapfunction snd_dma_noncontig_freefunction snd_dma_noncontig_mmapfunction snd_dma_noncontig_syncfunction snd_dma_noncontig_iter_setfunction snd_dma_noncontig_get_addrfunction snd_dma_noncontig_get_chunk_sizefunction __snd_dma_sg_fallback_freefunction snd_dma_sg_fallback_freefunction snd_dma_sg_fallback_mmapfunction snd_dma_noncoherent_freefunction snd_dma_noncoherent_mmapfunction snd_dma_noncoherent_syncexport snd_dma_alloc_dir_pagesexport snd_dma_alloc_pages_fallbackexport snd_dma_free_pagesexport snd_devm_alloc_dir_pagesexport snd_dma_buffer_mmapexport snd_dma_buffer_syncexport snd_sgbuf_get_addrexport snd_sgbuf_get_pageexport snd_sgbuf_get_chunk_size
Annotated Snippet
struct snd_malloc_ops {
void *(*alloc)(struct snd_dma_buffer *dmab, size_t size);
void (*free)(struct snd_dma_buffer *dmab);
dma_addr_t (*get_addr)(struct snd_dma_buffer *dmab, size_t offset);
struct page *(*get_page)(struct snd_dma_buffer *dmab, size_t offset);
unsigned int (*get_chunk_size)(struct snd_dma_buffer *dmab,
unsigned int ofs, unsigned int size);
int (*mmap)(struct snd_dma_buffer *dmab, struct vm_area_struct *area);
void (*sync)(struct snd_dma_buffer *dmab, enum snd_dma_sync_mode mode);
};
#define DEFAULT_GFP \
(GFP_KERNEL | \
__GFP_RETRY_MAYFAIL | /* don't trigger OOM-killer */ \
__GFP_NOWARN) /* no stack trace print - this call is non-critical */
static const struct snd_malloc_ops *snd_dma_get_ops(struct snd_dma_buffer *dmab);
static void *__snd_dma_alloc_pages(struct snd_dma_buffer *dmab, size_t size)
{
const struct snd_malloc_ops *ops = snd_dma_get_ops(dmab);
if (WARN_ON_ONCE(!ops || !ops->alloc))
return NULL;
return ops->alloc(dmab, size);
}
/**
* snd_dma_alloc_dir_pages - allocate the buffer area according to the given
* type and direction
* @type: the DMA buffer type
* @device: the device pointer
* @dir: DMA direction
* @size: the buffer size to allocate
* @dmab: buffer allocation record to store the allocated data
*
* Calls the memory-allocator function for the corresponding
* buffer type.
*
* Return: Zero if the buffer with the given size is allocated successfully,
* otherwise a negative value on error.
*/
int snd_dma_alloc_dir_pages(int type, struct device *device,
enum dma_data_direction dir, size_t size,
struct snd_dma_buffer *dmab)
{
if (WARN_ON(!size))
return -ENXIO;
if (WARN_ON(!dmab))
return -ENXIO;
size = PAGE_ALIGN(size);
dmab->dev.type = type;
dmab->dev.dev = device;
dmab->dev.dir = dir;
dmab->bytes = 0;
dmab->addr = 0;
dmab->private_data = NULL;
dmab->area = __snd_dma_alloc_pages(dmab, size);
if (!dmab->area)
return -ENOMEM;
dmab->bytes = size;
return 0;
}
EXPORT_SYMBOL(snd_dma_alloc_dir_pages);
/**
* snd_dma_alloc_pages_fallback - allocate the buffer area according to the given type with fallback
* @type: the DMA buffer type
* @device: the device pointer
* @size: the buffer size to allocate
* @dmab: buffer allocation record to store the allocated data
*
* Calls the memory-allocator function for the corresponding
* buffer type. When no space is left, this function reduces the size and
* tries to allocate again. The size actually allocated is stored in
* res_size argument.
*
* Return: Zero if the buffer with the given size is allocated successfully,
* otherwise a negative value on error.
*/
int snd_dma_alloc_pages_fallback(int type, struct device *device, size_t size,
struct snd_dma_buffer *dmab)
{
int err;
while ((err = snd_dma_alloc_pages(type, device, size, dmab)) < 0) {
if (err != -ENOMEM)
return err;
if (size <= PAGE_SIZE)
Annotation
- Immediate include surface: `linux/slab.h`, `linux/mm.h`, `linux/dma-mapping.h`, `linux/dma-map-ops.h`, `linux/genalloc.h`, `linux/highmem.h`, `linux/vmalloc.h`, `asm/set_memory.h`.
- Detected declarations: `struct snd_malloc_ops`, `struct snd_dma_sg_fallback`, `function snd_dma_alloc_dir_pages`, `function snd_dma_alloc_pages_fallback`, `function snd_dma_alloc_pages`, `function __snd_release_pages`, `function snd_dma_alloc_pages`, `function snd_dma_buffer_mmap`, `function snd_dma_buffer_sync`, `function snd_sgbuf_get_addr`.
- Atlas domain: Driver Families / sound/core.
- Implementation status: integration implementation candidate.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.