Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ea1dd125 authored by Park Ju Hyung's avatar Park Ju Hyung Committed by KakatkarAkshay
Browse files

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: default avatarPark Ju Hyung <qkrwngud825@gmail.com>
[@0ctobot: Adapted for 4.19]
Signed-off-by: default avatarAdam W. Willis <return.of.octobot@gmail.com>
Signed-off-by: default avatarLibXZR <xzr467706992@163.com>
parent eccb867f
Loading
Loading
Loading
Loading
+24 −3
Original line number Diff line number Diff line
@@ -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);
	}
}
@@ -597,6 +605,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);
@@ -624,7 +633,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;
@@ -672,6 +690,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);
+2 −0
Original line number Diff line number Diff line
@@ -448,6 +448,8 @@ struct dma_buf {
	dma_buf_destructor dtor;
	void *dtor_data;
	atomic_t dent_count;

	bool from_kmem;
};

/**