[PATCH RFC 3/5] ALSA: memalloc: Assign ops field to snd_dma_buffer
Takashi Iwai
tiwai at suse.de
Tue Aug 10 14:21:58 CEST 2021
This is for performance optimization. Instead of deducing the ops
from the type at each time, store the ops table directly in
snd_dma_buffer struct and refer to it. The upcoming sync ops will be
in a hot path, hence some optimization is required.
Signed-off-by: Takashi Iwai <tiwai at suse.de>
---
include/sound/memalloc.h | 2 ++
sound/core/memalloc.c | 53 ++++++++++++++++------------------------
2 files changed, 23 insertions(+), 32 deletions(-)
diff --git a/include/sound/memalloc.h b/include/sound/memalloc.h
index b197e3f431c1..f5f0d32f6d61 100644
--- a/include/sound/memalloc.h
+++ b/include/sound/memalloc.h
@@ -13,6 +13,7 @@
struct device;
struct vm_area_struct;
+struct snd_malloc_ops;
/*
* buffer device info
@@ -55,6 +56,7 @@ struct snd_dma_buffer {
dma_addr_t addr; /* physical address */
size_t bytes; /* buffer size in bytes */
void *private_data; /* private for allocator; don't touch */
+ const struct snd_malloc_ops *ops; /* assigned ops */
};
/*
diff --git a/sound/core/memalloc.c b/sound/core/memalloc.c
index c7c943c661e6..3f42376dfb0b 100644
--- a/sound/core/memalloc.c
+++ b/sound/core/memalloc.c
@@ -29,15 +29,6 @@ static inline gfp_t snd_mem_get_gfp_flags(const struct snd_dma_buffer *dmab,
return (__force gfp_t)(unsigned long)dmab->dev.dev;
}
-static void *__snd_dma_alloc_pages(struct snd_dma_buffer *dmab, size_t size)
-{
- const struct snd_malloc_ops *ops = snd_dma_get_ops(dmab);
-
- if (WARN_ON_ONCE(!ops || !ops->alloc))
- return NULL;
- return ops->alloc(dmab, size);
-}
-
/**
* snd_dma_alloc_pages - allocate the buffer area according to the given type
* @type: the DMA buffer type
@@ -54,6 +45,7 @@ static void *__snd_dma_alloc_pages(struct snd_dma_buffer *dmab, size_t size)
int snd_dma_alloc_pages(int type, struct device *device, size_t size,
struct snd_dma_buffer *dmab)
{
+ const struct snd_malloc_ops *ops;
if (WARN_ON(!size))
return -ENXIO;
if (WARN_ON(!dmab))
@@ -65,9 +57,15 @@ int snd_dma_alloc_pages(int type, struct device *device, size_t size,
dmab->bytes = 0;
dmab->addr = 0;
dmab->private_data = NULL;
- dmab->area = __snd_dma_alloc_pages(dmab, size);
- if (!dmab->area)
+ ops = snd_dma_get_ops(dmab);
+ if (WARN_ON(!ops || !ops->alloc))
+ return -ENXIO;
+ dmab->ops = ops;
+ dmab->area = ops->alloc(dmab, size);
+ if (!dmab->area) {
+ dmab->ops = NULL;
return -ENOMEM;
+ }
dmab->bytes = size;
return 0;
}
@@ -115,10 +113,8 @@ EXPORT_SYMBOL(snd_dma_alloc_pages_fallback);
*/
void snd_dma_free_pages(struct snd_dma_buffer *dmab)
{
- const struct snd_malloc_ops *ops = snd_dma_get_ops(dmab);
-
- if (ops && ops->free)
- ops->free(dmab);
+ if (dmab->ops && dmab->ops->free)
+ dmab->ops->free(dmab);
}
EXPORT_SYMBOL(snd_dma_free_pages);
@@ -176,10 +172,8 @@ EXPORT_SYMBOL_GPL(snd_devm_alloc_pages);
int snd_dma_buffer_mmap(struct snd_dma_buffer *dmab,
struct vm_area_struct *area)
{
- const struct snd_malloc_ops *ops = snd_dma_get_ops(dmab);
-
- if (ops && ops->mmap)
- return ops->mmap(dmab, area);
+ if (dmab && dmab->ops && dmab->ops->mmap)
+ return dmab->ops->mmap(dmab, area);
else
return -ENOENT;
}
@@ -192,10 +186,8 @@ EXPORT_SYMBOL(snd_dma_buffer_mmap);
*/
dma_addr_t snd_sgbuf_get_addr(struct snd_dma_buffer *dmab, size_t offset)
{
- const struct snd_malloc_ops *ops = snd_dma_get_ops(dmab);
-
- if (ops && ops->get_addr)
- return ops->get_addr(dmab, offset);
+ if (dmab->ops && dmab->ops->get_addr)
+ return dmab->ops->get_addr(dmab, offset);
else
return dmab->addr + offset;
}
@@ -208,10 +200,8 @@ EXPORT_SYMBOL(snd_sgbuf_get_addr);
*/
struct page *snd_sgbuf_get_page(struct snd_dma_buffer *dmab, size_t offset)
{
- const struct snd_malloc_ops *ops = snd_dma_get_ops(dmab);
-
- if (ops && ops->get_page)
- return ops->get_page(dmab, offset);
+ if (dmab->ops && dmab->ops->get_page)
+ return dmab->ops->get_page(dmab, offset);
else
return virt_to_page(dmab->area + offset);
}
@@ -227,10 +217,8 @@ EXPORT_SYMBOL(snd_sgbuf_get_page);
unsigned int snd_sgbuf_get_chunk_size(struct snd_dma_buffer *dmab,
unsigned int ofs, unsigned int size)
{
- const struct snd_malloc_ops *ops = snd_dma_get_ops(dmab);
-
- if (ops && ops->get_chunk_size)
- return ops->get_chunk_size(dmab, ofs, size);
+ if (dmab->ops && dmab->ops->get_chunk_size)
+ return dmab->ops->get_chunk_size(dmab, ofs, size);
else
return size;
}
@@ -362,7 +350,8 @@ static void *snd_dma_iram_alloc(struct snd_dma_buffer *dmab, size_t size)
* so if we fail to malloc, try to fetch memory traditionally.
*/
dmab->dev.type = SNDRV_DMA_TYPE_DEV;
- return __snd_dma_alloc_pages(dmab, size);
+ dmab->ops = snd_dma_get_ops(dmab);
+ return dmab->ops->alloc(dmab, size);
}
static void snd_dma_iram_free(struct snd_dma_buffer *dmab)
--
2.26.2
More information about the Alsa-devel
mailing list