Skip to content

Commit 2c95b92

Browse files
committed
ALSA: memalloc: Unify x86 SG-buffer handling (take#3)
This is a second attempt to unify the x86-specific SG-buffer handling code with the new standard non-contiguous page handler. The first try (in commit 2d9ea39) failed due to the wrong page and address calculations, hence reverted. (And the second try failed due to a copy&paste error.) Now it's corrected with the previous fix for noncontig pages, and the proper sg page iteration by this patch. After the migration, SNDRV_DMA_TYPE_DMA_SG becomes identical with SNDRV_DMA_TYPE_NONCONTIG on x86, while others still fall back to SNDRV_DMA_TYPE_DEV. Tested-by: Alex Xu (Hello71) <alex_y_xu@yahoo.ca> Tested-by: Harald Arnesen <harald@skogtun.org> Link: https://lore.kernel.org/r/20211017074859.24112-4-tiwai@suse.de Link: https://lore.kernel.org/r/20211109062235.22310-1-tiwai@suse.de Link: https://lore.kernel.org/r/20211116073358.19741-1-tiwai@suse.de Signed-off-by: Takashi Iwai <tiwai@suse.de>
1 parent 7206998 commit 2c95b92

4 files changed

Lines changed: 56 additions & 213 deletions

File tree

include/sound/memalloc.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,6 @@ struct snd_dma_device {
3636
#define SNDRV_DMA_TYPE_CONTINUOUS 1 /* continuous no-DMA memory */
3737
#define SNDRV_DMA_TYPE_DEV 2 /* generic device continuous */
3838
#define SNDRV_DMA_TYPE_DEV_WC 5 /* continuous write-combined */
39-
#ifdef CONFIG_SND_DMA_SGBUF
40-
#define SNDRV_DMA_TYPE_DEV_SG 3 /* generic device SG-buffer */
41-
#define SNDRV_DMA_TYPE_DEV_WC_SG 6 /* SG write-combined */
42-
#else
43-
#define SNDRV_DMA_TYPE_DEV_SG SNDRV_DMA_TYPE_DEV /* no SG-buf support */
44-
#define SNDRV_DMA_TYPE_DEV_WC_SG SNDRV_DMA_TYPE_DEV_WC
45-
#endif
4639
#ifdef CONFIG_GENERIC_ALLOCATOR
4740
#define SNDRV_DMA_TYPE_DEV_IRAM 4 /* generic device iram-buffer */
4841
#else
@@ -51,6 +44,13 @@ struct snd_dma_device {
5144
#define SNDRV_DMA_TYPE_VMALLOC 7 /* vmalloc'ed buffer */
5245
#define SNDRV_DMA_TYPE_NONCONTIG 8 /* non-coherent SG buffer */
5346
#define SNDRV_DMA_TYPE_NONCOHERENT 9 /* non-coherent buffer */
47+
#ifdef CONFIG_SND_DMA_SGBUF
48+
#define SNDRV_DMA_TYPE_DEV_SG SNDRV_DMA_TYPE_NONCONTIG
49+
#define SNDRV_DMA_TYPE_DEV_WC_SG 6 /* SG write-combined */
50+
#else
51+
#define SNDRV_DMA_TYPE_DEV_SG SNDRV_DMA_TYPE_DEV /* no SG-buf support */
52+
#define SNDRV_DMA_TYPE_DEV_WC_SG SNDRV_DMA_TYPE_DEV_WC
53+
#endif
5454

5555
/*
5656
* info for buffer allocation

sound/core/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ snd-$(CONFIG_SND_JACK) += ctljack.o jack.o
1919
snd-pcm-y := pcm.o pcm_native.o pcm_lib.o pcm_misc.o \
2020
pcm_memory.o memalloc.o
2121
snd-pcm-$(CONFIG_SND_PCM_TIMER) += pcm_timer.o
22-
snd-pcm-$(CONFIG_SND_DMA_SGBUF) += sgbuf.o
2322
snd-pcm-$(CONFIG_SND_PCM_ELD) += pcm_drm_eld.o
2423
snd-pcm-$(CONFIG_SND_PCM_IEC958) += pcm_iec958.o
2524

sound/core/memalloc.c

Lines changed: 49 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -620,6 +620,52 @@ static const struct snd_malloc_ops snd_dma_noncontig_ops = {
620620
.get_chunk_size = snd_dma_noncontig_get_chunk_size,
621621
};
622622

623+
/* x86-specific SG-buffer with WC pages */
624+
#ifdef CONFIG_SND_DMA_SGBUF
625+
#define sg_wc_address(it) ((unsigned long)page_address(sg_page_iter_page(it)))
626+
627+
static void *snd_dma_sg_wc_alloc(struct snd_dma_buffer *dmab, size_t size)
628+
{
629+
void *p = snd_dma_noncontig_alloc(dmab, size);
630+
struct sg_table *sgt = dmab->private_data;
631+
struct sg_page_iter iter;
632+
633+
if (!p)
634+
return NULL;
635+
for_each_sgtable_page(sgt, &iter, 0)
636+
set_memory_wc(sg_wc_address(&iter), 1);
637+
return p;
638+
}
639+
640+
static void snd_dma_sg_wc_free(struct snd_dma_buffer *dmab)
641+
{
642+
struct sg_table *sgt = dmab->private_data;
643+
struct sg_page_iter iter;
644+
645+
for_each_sgtable_page(sgt, &iter, 0)
646+
set_memory_wb(sg_wc_address(&iter), 1);
647+
snd_dma_noncontig_free(dmab);
648+
}
649+
650+
static int snd_dma_sg_wc_mmap(struct snd_dma_buffer *dmab,
651+
struct vm_area_struct *area)
652+
{
653+
area->vm_page_prot = pgprot_writecombine(area->vm_page_prot);
654+
return dma_mmap_noncontiguous(dmab->dev.dev, area,
655+
dmab->bytes, dmab->private_data);
656+
}
657+
658+
static const struct snd_malloc_ops snd_dma_sg_wc_ops = {
659+
.alloc = snd_dma_sg_wc_alloc,
660+
.free = snd_dma_sg_wc_free,
661+
.mmap = snd_dma_sg_wc_mmap,
662+
.sync = snd_dma_noncontig_sync,
663+
.get_addr = snd_dma_noncontig_get_addr,
664+
.get_page = snd_dma_noncontig_get_page,
665+
.get_chunk_size = snd_dma_noncontig_get_chunk_size,
666+
};
667+
#endif /* CONFIG_SND_DMA_SGBUF */
668+
623669
/*
624670
* Non-coherent pages allocator
625671
*/
@@ -679,14 +725,13 @@ static const struct snd_malloc_ops *dma_ops[] = {
679725
[SNDRV_DMA_TYPE_DEV_WC] = &snd_dma_wc_ops,
680726
[SNDRV_DMA_TYPE_NONCONTIG] = &snd_dma_noncontig_ops,
681727
[SNDRV_DMA_TYPE_NONCOHERENT] = &snd_dma_noncoherent_ops,
728+
#ifdef CONFIG_SND_DMA_SGBUF
729+
[SNDRV_DMA_TYPE_DEV_WC_SG] = &snd_dma_sg_wc_ops,
730+
#endif
682731
#ifdef CONFIG_GENERIC_ALLOCATOR
683732
[SNDRV_DMA_TYPE_DEV_IRAM] = &snd_dma_iram_ops,
684733
#endif /* CONFIG_GENERIC_ALLOCATOR */
685734
#endif /* CONFIG_HAS_DMA */
686-
#ifdef CONFIG_SND_DMA_SGBUF
687-
[SNDRV_DMA_TYPE_DEV_SG] = &snd_dma_sg_ops,
688-
[SNDRV_DMA_TYPE_DEV_WC_SG] = &snd_dma_sg_ops,
689-
#endif
690735
};
691736

692737
static const struct snd_malloc_ops *snd_dma_get_ops(struct snd_dma_buffer *dmab)

sound/core/sgbuf.c

Lines changed: 0 additions & 201 deletions
This file was deleted.

0 commit comments

Comments
 (0)