Skip to content

Commit 3ad796c

Browse files
committed
ALSA: pcm: Use SG-buffer only when direct DMA is available
The DMA-coherent SG-buffer is tricky to use, as it does need the mapping. It used to work stably on x86 over years (and that's why we had enabled SG-buffer on solely x86) with the default mmap handler and vmap(), but our luck seems no forever success. The chance of breakage is high when the special DMA handling is introduced in the arch side. In this patch, we change the buffer allocation to use the SG-buffer only when the device in question is with the direct DMA. It's a bit hackish, but it's currently the only condition that may work (more or less) reliably with the default mmap and vmap() for mapping the pages that are deduced via virt_to_page(). In theory, we can apply the similar hack in the sound/core memory allocation helper, too; but it's used by SOF for allocating SG pages without re-mapping via vmap() or mmap, and it's fine to use it in that way, so let's keep it and adds the workaround in PCM side. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Takashi Iwai <[email protected]>
1 parent 2a1f336 commit 3ad796c

File tree

1 file changed

+13
-0
lines changed

1 file changed

+13
-0
lines changed

sound/core/pcm_memory.c

+13
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/moduleparam.h>
1212
#include <linux/vmalloc.h>
1313
#include <linux/export.h>
14+
#include <linux/dma-mapping.h>
1415
#include <sound/core.h>
1516
#include <sound/pcm.h>
1617
#include <sound/info.h>
@@ -39,6 +40,18 @@ static int do_alloc_pages(struct snd_card *card, int type, struct device *dev,
3940
if (max_alloc_per_card &&
4041
card->total_pcm_alloc_bytes + size > max_alloc_per_card)
4142
return -ENOMEM;
43+
44+
if (IS_ENABLED(CONFIG_SND_DMA_SGBUF) &&
45+
(type == SNDRV_DMA_TYPE_DEV_SG || type == SNDRV_DMA_TYPE_DEV_UC_SG) &&
46+
!dma_is_direct(get_dma_ops(dev))) {
47+
/* mutate to continuous page allocation */
48+
dev_dbg(dev, "Use continuous page allocator\n");
49+
if (type == SNDRV_DMA_TYPE_DEV_SG)
50+
type = SNDRV_DMA_TYPE_DEV;
51+
else
52+
type = SNDRV_DMA_TYPE_DEV_UC;
53+
}
54+
4255
err = snd_dma_alloc_pages(type, dev, size, dmab);
4356
if (!err) {
4457
mutex_lock(&card->memory_mutex);

0 commit comments

Comments
 (0)