diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 7029b477a49e..bd7016cf8a96 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -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,7 +86,10 @@ static void dmabuf_dent_put(struct dma_buf *dmabuf) { if (atomic_dec_and_test(&dmabuf->dent_count)) { kfree(dmabuf->name); - kfree(dmabuf); + 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; } - dmabuf = kzalloc(alloc_size, GFP_KERNEL); + 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,7 +699,10 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info) return dmabuf; err_dmabuf: - kfree(dmabuf); + if (from_kmem) + kmem_cache_free(kmem_dma_buf_pool, dmabuf); + else + kfree(dmabuf); err_name: kfree(bufname); err_module: diff --git a/include/linux/dma-buf.h b/include/linux/dma-buf.h index 077d75354ac5..f9c1b91a4c69 100644 --- a/include/linux/dma-buf.h +++ b/include/linux/dma-buf.h @@ -463,6 +463,8 @@ struct dma_buf { dma_buf_destructor dtor; void *dtor_data; atomic_t dent_count; + + bool from_kmem; }; /**