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

Commit f397df63 authored by Liam Mark's avatar Liam Mark
Browse files

dma-buf: Make dma-buf anon file name unique



Making the dma-buf anon file name unique will allow clients to be able
to uniquely identify a dma-buf.

One advantage of this is that dma-buf memory leaks can be more easily
debugged as now we will be able to identify which dma-buf buffers a client
is using.

Change-Id: I5cff7baafdda16d2812201b73693fc32b38e86b4
Signed-off-by: default avatarLiam Mark <lmark@codeaurora.org>
parent 5027ffca
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -34,9 +34,13 @@
#include <linux/poll.h>
#include <linux/reservation.h>
#include <linux/mm.h>
#include <linux/kernel.h>
#include <linux/atomic.h>

#include <uapi/linux/dma-buf.h>

static atomic_long_t name_counter;

static inline int is_dma_buf_file(struct file *);

struct dma_buf_list {
@@ -77,6 +81,7 @@ static int dma_buf_release(struct inode *inode, struct file *file)
		reservation_object_fini(dmabuf->resv);

	module_put(dmabuf->owner);
	kfree(dmabuf->name);
	kfree(dmabuf);
	return 0;
}
@@ -407,7 +412,9 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
	struct reservation_object *resv = exp_info->resv;
	struct file *file;
	size_t alloc_size = sizeof(struct dma_buf);
	char *bufname;
	int ret;
	long cnt;

	if (!exp_info->resv)
		alloc_size += sizeof(struct reservation_object);
@@ -429,10 +436,17 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
	if (!try_module_get(exp_info->owner))
		return ERR_PTR(-ENOENT);

	cnt = atomic_long_inc_return(&name_counter);
	bufname = kasprintf(GFP_KERNEL, "dmabuf%ld", cnt);
	if (!bufname) {
		ret = -ENOMEM;
		goto err_module;
	}

	dmabuf = kzalloc(alloc_size, GFP_KERNEL);
	if (!dmabuf) {
		ret = -ENOMEM;
		goto err_module;
		goto err_name;
	}

	dmabuf->priv = exp_info->priv;
@@ -443,6 +457,7 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
	init_waitqueue_head(&dmabuf->poll);
	dmabuf->cb_excl.poll = dmabuf->cb_shared.poll = &dmabuf->poll;
	dmabuf->cb_excl.active = dmabuf->cb_shared.active = 0;
	dmabuf->name = bufname;

	if (!resv) {
		resv = (struct reservation_object *)&dmabuf[1];
@@ -450,7 +465,7 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
	}
	dmabuf->resv = resv;

	file = anon_inode_getfile("dmabuf", &dma_buf_fops, dmabuf,
	file = anon_inode_getfile(bufname, &dma_buf_fops, dmabuf,
					exp_info->flags);
	if (IS_ERR(file)) {
		ret = PTR_ERR(file);
@@ -471,6 +486,8 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)

err_dmabuf:
	kfree(dmabuf);
err_name:
	kfree(bufname);
err_module:
	module_put(exp_info->owner);
	return ERR_PTR(ret);
+2 −0
Original line number Diff line number Diff line
@@ -382,6 +382,7 @@ struct dma_buf_ops {
 * @vmapping_counter: used internally to refcnt the vmaps
 * @vmap_ptr: the current vmap ptr if vmapping_counter > 0
 * @exp_name: name of the exporter; useful for debugging.
 * @name: unique name for the buffer
 * @owner: pointer to exporter module; used for refcounting when exporter is a
 *         kernel module.
 * @list_node: node for dma_buf accounting and debugging.
@@ -409,6 +410,7 @@ struct dma_buf {
	unsigned vmapping_counter;
	void *vmap_ptr;
	const char *exp_name;
	char *name;
	struct module *owner;
	struct list_head list_node;
	void *priv;