diff mbox series

[1/2] ALSA: memalloc: Explicit SG-allocations for Xen PV and non-IOMMU systems

Message ID 20230124092744.27370-2-tiwai@suse.de (mailing list archive)
State New, archived
Headers show
Series ALSA: memalloc: Fix for Xen PV and non-IOMMU systems | expand

Commit Message

Takashi Iwai Jan. 24, 2023, 9:27 a.m. UTC
For non-IOMMU systems, it makes little sense (or even buggy) to use
dma_alloc_noncontiguous() as an x86 SG-buffer allocation, as it always
results in the big continuous pages instead of SG buffer.  Also, for
Xen PV, this seems also not working well as the pages allocated there
aren't guaranteed to be coherent.

This patch is a first step to address those problems.  It changes the
memalloc helper to go for the explicit SG-page allocations via the
existing fallback allocation primarily for such a platform instead of
dma_alloc_noncontiguous().

Fixes: a8d302a0b770 ("ALSA: memalloc: Revive x86-specific WC page allocations again")
Fixes: 9736a325137b ("ALSA: memalloc: Don't fall back for SG-buffer with IOMMU")
Reported-and-tested-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
Link: https://lore.kernel.org/r/87tu256lqs.wl-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
 sound/core/memalloc.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)
diff mbox series

Patch

diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index 81025f50a542..30c9ad192986 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -541,10 +541,9 @@  static void *snd_dma_noncontig_alloc(struct snd_dma_buffer *dmab, size_t size)
 	struct sg_table *sgt;
 	void *p;
 
-	sgt = dma_alloc_noncontiguous(dmab->dev.dev, size, dmab->dev.dir,
-				      DEFAULT_GFP, 0);
 #ifdef CONFIG_SND_DMA_SGBUF
-	if (!sgt && !get_dma_ops(dmab->dev.dev)) {
+	if (cpu_feature_enabled(X86_FEATURE_XENPV) ||
+	    !get_dma_ops(dmab->dev.dev)) {
 		if (dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC_SG)
 			dmab->dev.type = SNDRV_DMA_TYPE_DEV_WC_SG_FALLBACK;
 		else
@@ -552,6 +551,8 @@  static void *snd_dma_noncontig_alloc(struct snd_dma_buffer *dmab, size_t size)
 		return snd_dma_sg_fallback_alloc(dmab, size);
 	}
 #endif
+	sgt = dma_alloc_noncontiguous(dmab->dev.dev, size, dmab->dev.dir,
+				      DEFAULT_GFP, 0);
 	if (!sgt)
 		return NULL;