Chapter 11. Buffer and Memory Management

Table of Contents

Buffer Types
External Hardware Buffers
Non-Contiguous Buffers
Vmalloc'ed Buffers

Buffer Types

ALSA provides several different buffer allocation functions depending on the bus and the architecture. All these have a consistent API. The allocation of physically-contiguous pages is done via snd_malloc_xxx_pages() function, where xxx is the bus type.

The allocation of pages with fallback is snd_malloc_xxx_pages_fallback(). This function tries to allocate the specified pages but if the pages are not available, it tries to reduce the page sizes until enough space is found.

The release the pages, call snd_free_xxx_pages() function.

Usually, ALSA drivers try to allocate and reserve a large contiguous physical space at the time the module is loaded for the later use. This is called “pre-allocation”. As already written, you can call the following function at pcm instance construction time (in the case of PCI bus).


  snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV,
                                        snd_dma_pci_data(pci), size, max);

          

where size is the byte size to be pre-allocated and the max is the maximum size to be changed via the prealloc proc file. The allocator will try to get an area as large as possible within the given size.

The second argument (type) and the third argument (device pointer) are dependent on the bus. In the case of the ISA bus, pass snd_dma_isa_data() as the third argument with SNDRV_DMA_TYPE_DEV type. For the continuous buffer unrelated to the bus can be pre-allocated with SNDRV_DMA_TYPE_CONTINUOUS type and the snd_dma_continuous_data(GFP_KERNEL) device pointer, where GFP_KERNEL is the kernel allocation flag to use. For the PCI scatter-gather buffers, use SNDRV_DMA_TYPE_DEV_SG with snd_dma_pci_data(pci) (see the Non-Contiguous Buffers section).

Once the buffer is pre-allocated, you can use the allocator in the hw_params callback:


  snd_pcm_lib_malloc_pages(substream, size);

          

Note that you have to pre-allocate to use this function.