dma_buf: try to use kmem_cache pool for dmabuf allocations
These get allocated and freed millions of times on this kernel tree. Use a dedicated kmem_cache pool and avoid costly dynamic memory allocations. Most allocations' size is: (sizeof(struct dma_buf) + sizeof(struct reservation_object)). Put those under kmem_cache pool and distinguish them with dmabuf->from_kmem flag. Signed-off-by: Park Ju Hyung <qkrwngud825@gmail.com> [@0ctobot: Adapted for 4.19] Signed-off-by: Adam W. Willis <return.of.octobot@gmail.com>
This commit is contained in:
parent
774d7449d5
commit
26d295a1b4
@ -49,10 +49,15 @@
|
||||
static atomic_long_t name_counter;
|
||||
|
||||
static struct kmem_cache *kmem_attach_pool;
|
||||
static struct kmem_cache *kmem_dma_buf_pool;
|
||||
|
||||
void __init init_dma_buf_kmem_pool(void)
|
||||
{
|
||||
kmem_attach_pool = KMEM_CACHE(dma_buf_attachment, SLAB_HWCACHE_ALIGN | SLAB_PANIC);
|
||||
kmem_dma_buf_pool = kmem_cache_create("dma_buf",
|
||||
(sizeof(struct dma_buf) + sizeof(struct reservation_object)),
|
||||
(sizeof(struct dma_buf) + sizeof(struct reservation_object)),
|
||||
SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
|
||||
}
|
||||
|
||||
static inline int is_dma_buf_file(struct file *);
|
||||
@ -81,6 +86,9 @@ static void dmabuf_dent_put(struct dma_buf *dmabuf)
|
||||
{
|
||||
if (atomic_dec_and_test(&dmabuf->dent_count)) {
|
||||
kfree(dmabuf->name);
|
||||
if (dmabuf->from_kmem)
|
||||
kmem_cache_free(kmem_dma_buf_pool, dmabuf);
|
||||
else
|
||||
kfree(dmabuf);
|
||||
}
|
||||
}
|
||||
@ -606,6 +614,7 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
|
||||
char *bufname;
|
||||
int ret;
|
||||
long cnt;
|
||||
bool from_kmem;
|
||||
|
||||
if (!exp_info->resv)
|
||||
alloc_size += sizeof(struct reservation_object);
|
||||
@ -633,7 +642,16 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
|
||||
goto err_module;
|
||||
}
|
||||
|
||||
from_kmem = (alloc_size ==
|
||||
(sizeof(struct dma_buf) + sizeof(struct reservation_object)));
|
||||
|
||||
if (from_kmem) {
|
||||
dmabuf = kmem_cache_zalloc(kmem_dma_buf_pool, GFP_KERNEL);
|
||||
dmabuf->from_kmem = true;
|
||||
} else {
|
||||
dmabuf = kzalloc(alloc_size, GFP_KERNEL);
|
||||
}
|
||||
|
||||
if (!dmabuf) {
|
||||
ret = -ENOMEM;
|
||||
goto err_name;
|
||||
@ -681,6 +699,9 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
|
||||
return dmabuf;
|
||||
|
||||
err_dmabuf:
|
||||
if (from_kmem)
|
||||
kmem_cache_free(kmem_dma_buf_pool, dmabuf);
|
||||
else
|
||||
kfree(dmabuf);
|
||||
err_name:
|
||||
kfree(bufname);
|
||||
|
@ -463,6 +463,8 @@ struct dma_buf {
|
||||
dma_buf_destructor dtor;
|
||||
void *dtor_data;
|
||||
atomic_t dent_count;
|
||||
|
||||
bool from_kmem;
|
||||
};
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user