Linux Sound subsystem development
 help / color / mirror / Atom feed
From: Takashi Iwai <tiwai@suse.de>
To: linux-sound@vger.kernel.org
Subject: [PATCH 1/2] ALSA: memalloc: Use proper DMA mapping API for x86 WC buffer allocations
Date: Thu, 12 Sep 2024 17:52:24 +0200	[thread overview]
Message-ID: <20240912155227.4078-2-tiwai@suse.de> (raw)
In-Reply-To: <20240912155227.4078-1-tiwai@suse.de>

The x86 WC page allocation assumes incorrectly the DMA address
directly taken from the page.  Also it checks the DMA ops
inappropriately for switching to the own method.

This patch rewrites the stuff to use the proper DMA mapping API
instead.

Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/core/memalloc.c | 51 +++++++++++++++++++++++++++----------------
 1 file changed, 32 insertions(+), 19 deletions(-)

diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index b21dba4b374a..39e97f6fe8ac 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -496,41 +496,54 @@ static const struct snd_malloc_ops snd_dma_dev_ops = {
 /*
  * Write-combined pages
  */
-/* x86-specific allocations */
 #ifdef CONFIG_SND_DMA_SGBUF
-#define x86_fallback(dmab)	(!get_dma_ops(dmab->dev.dev))
-#else
-#define x86_fallback(dmab)	false
-#endif
-
+/* x86-specific allocations */
+static void *snd_dma_wc_alloc(struct snd_dma_buffer *dmab, size_t size)
+{
+	void *p = do_alloc_pages(dmab->dev.dev, size, &dmab->addr, true);
+
+	if (!p)
+		return NULL;
+	dmab->addr = dma_map_single(dmab->dev.dev, p, size, DMA_BIDIRECTIONAL);
+	if (dmab->addr == DMA_MAPPING_ERROR) {
+		do_free_pages(dmab->area, size, true);
+		return NULL;
+	}
+	return p;
+}
+
+static void snd_dma_wc_free(struct snd_dma_buffer *dmab)
+{
+	dma_unmap_single(dmab->dev.dev, dmab->addr, dmab->bytes,
+			 DMA_BIDIRECTIONAL);
+	do_free_pages(dmab->area, dmab->bytes, true);
+}
+
+static int snd_dma_wc_mmap(struct snd_dma_buffer *dmab,
+			   struct vm_area_struct *area)
+{
+	area->vm_page_prot = pgprot_writecombine(area->vm_page_prot);
+	return dma_mmap_coherent(dmab->dev.dev, area,
+				 dmab->area, dmab->addr, dmab->bytes);
+}
+#else
 static void *snd_dma_wc_alloc(struct snd_dma_buffer *dmab, size_t size)
 {
-	if (x86_fallback(dmab))
-		return do_alloc_pages(dmab->dev.dev, size, &dmab->addr, true);
 	return dma_alloc_wc(dmab->dev.dev, size, &dmab->addr, DEFAULT_GFP);
 }
 
 static void snd_dma_wc_free(struct snd_dma_buffer *dmab)
 {
-	if (x86_fallback(dmab)) {
-		do_free_pages(dmab->area, dmab->bytes, true);
-		return;
-	}
 	dma_free_wc(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr);
 }
 
 static int snd_dma_wc_mmap(struct snd_dma_buffer *dmab,
 			   struct vm_area_struct *area)
 {
-#ifdef CONFIG_SND_DMA_SGBUF
-	if (x86_fallback(dmab)) {
-		area->vm_page_prot = pgprot_writecombine(area->vm_page_prot);
-		return snd_dma_continuous_mmap(dmab, area);
-	}
-#endif
 	return dma_mmap_wc(dmab->dev.dev, area,
 			   dmab->area, dmab->addr, dmab->bytes);
 }
+#endif
 
 static const struct snd_malloc_ops snd_dma_wc_ops = {
 	.alloc = snd_dma_wc_alloc,
@@ -804,7 +817,7 @@ static void *snd_dma_sg_alloc(struct snd_dma_buffer *dmab, size_t size)
 
 	dmab->dev.type = type; /* restore the type */
 	/* if IOMMU is present but failed, give up */
-	if (!x86_fallback(dmab))
+	if (get_dma_ops(dmab->dev.dev))
 		return NULL;
 	/* try fallback */
 	return snd_dma_sg_fallback_alloc(dmab, size);
-- 
2.43.0


  reply	other threads:[~2024-09-12 15:51 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-12 15:52 [PATCH 0/2] ALSA: memalloc: Use proper DMA mapping API Takashi Iwai
2024-09-12 15:52 ` Takashi Iwai [this message]
2024-09-12 15:52 ` [PATCH 2/2] ALSA: memalloc: Use proper DMA mapping API for x86 S/G buffer allocations Takashi Iwai

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240912155227.4078-2-tiwai@suse.de \
    --to=tiwai@suse.de \
    --cc=linux-sound@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox