Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ALSA: memalloc: Support WC allocation on all architectures

There are the generic DMA API calls for allocating and managing the
pages with the write-combined attribute. Let's use them for all
architectures but x86; x86 still needs the special handling to
override the page attributes.

Acked-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20210802072815.13551-5-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>

+39 -7
+39 -7
sound/core/memalloc.c
··· 373 373 }; 374 374 #endif /* CONFIG_GENERIC_ALLOCATOR */ 375 375 376 + #define DEFAULT_GFP \ 377 + (GFP_KERNEL | \ 378 + __GFP_COMP | /* compound page lets parts be mapped */ \ 379 + __GFP_NORETRY | /* don't trigger OOM-killer */ \ 380 + __GFP_NOWARN) /* no stack trace print - this call is non-critical */ 381 + 376 382 /* 377 383 * Coherent device pages allocator 378 384 */ 379 385 static void *snd_dma_dev_alloc(struct snd_dma_buffer *dmab, size_t size) 380 386 { 381 - gfp_t gfp_flags; 382 387 void *p; 383 388 384 - gfp_flags = GFP_KERNEL 385 - | __GFP_COMP /* compound page lets parts be mapped */ 386 - | __GFP_NORETRY /* don't trigger OOM-killer */ 387 - | __GFP_NOWARN; /* no stack trace print - this call is non-critical */ 388 - p = dma_alloc_coherent(dmab->dev.dev, size, &dmab->addr, gfp_flags); 389 + p = dma_alloc_coherent(dmab->dev.dev, size, &dmab->addr, DEFAULT_GFP); 389 390 #ifdef CONFIG_X86 390 391 if (p && dmab->dev.type == SNDRV_DMA_TYPE_DEV_WC) 391 392 set_memory_wc((unsigned long)p, PAGE_ALIGN(size) >> PAGE_SHIFT); ··· 416 415 .free = snd_dma_dev_free, 417 416 .mmap = snd_dma_dev_mmap, 418 417 }; 418 + 419 + /* 420 + * Write-combined pages 421 + */ 422 + #ifdef CONFIG_X86 423 + /* On x86, share the same ops as the standard dev ops */ 424 + #define snd_dma_wc_ops snd_dma_dev_ops 425 + #else /* CONFIG_X86 */ 426 + static void *snd_dma_wc_alloc(struct snd_dma_buffer *dmab, size_t size) 427 + { 428 + return dma_alloc_wc(dmab->dev.dev, size, &dmab->addr, DEFAULT_GFP); 429 + } 430 + 431 + static void snd_dma_wc_free(struct snd_dma_buffer *dmab) 432 + { 433 + dma_free_wc(dmab->dev.dev, dmab->bytes, dmab->area, dmab->addr); 434 + } 435 + 436 + static int snd_dma_wc_mmap(struct snd_dma_buffer *dmab, 437 + struct vm_area_struct *area) 438 + { 439 + return dma_mmap_wc(dmab->dev.dev, area, 440 + dmab->area, dmab->addr, dmab->bytes); 441 + } 442 + 443 + static const struct snd_malloc_ops snd_dma_wc_ops = { 444 + .alloc = snd_dma_wc_alloc, 445 + .free = snd_dma_wc_free, 446 + .mmap = snd_dma_wc_mmap, 447 + }; 448 + #endif /* CONFIG_X86 */ 419 449 #endif /* CONFIG_HAS_DMA */ 420 450 421 451 /* ··· 457 425 [SNDRV_DMA_TYPE_VMALLOC] = &snd_dma_vmalloc_ops, 458 426 #ifdef CONFIG_HAS_DMA 459 427 [SNDRV_DMA_TYPE_DEV] = &snd_dma_dev_ops, 460 - [SNDRV_DMA_TYPE_DEV_WC] = &snd_dma_dev_ops, 428 + [SNDRV_DMA_TYPE_DEV_WC] = &snd_dma_wc_ops, 461 429 #ifdef CONFIG_GENERIC_ALLOCATOR 462 430 [SNDRV_DMA_TYPE_DEV_IRAM] = &snd_dma_iram_ops, 463 431 #endif /* CONFIG_GENERIC_ALLOCATOR */