Skip to content

Commit bb2bb90

Browse files
greghackmannsumitsemwal
authored andcommitted
dma-buf: add DMA_BUF_SET_NAME ioctls
This patch adds complimentary DMA_BUF_SET_NAME ioctls, which lets userspace processes attach a free-form name to each buffer. This information can be extremely helpful for tracking and accounting shared buffers. For example, on Android, we know what each buffer will be used for at allocation time: GL, multimedia, camera, etc. The userspace allocator can use DMA_BUF_SET_NAME to associate that information with the buffer, so we can later give developers a breakdown of how much memory they're allocating for graphics, camera, etc. Signed-off-by: Greg Hackmann <[email protected]> Signed-off-by: Chenbo Feng <[email protected]> Signed-off-by: Sumit Semwal <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent ed63bb1 commit bb2bb90

File tree

3 files changed

+69
-4
lines changed

3 files changed

+69
-4
lines changed

drivers/dma-buf/dma-buf.c

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,24 @@ struct dma_buf_list {
4848

4949
static struct dma_buf_list db_list;
5050

51+
static char *dmabuffs_dname(struct dentry *dentry, char *buffer, int buflen)
52+
{
53+
struct dma_buf *dmabuf;
54+
char name[DMA_BUF_NAME_LEN];
55+
size_t ret = 0;
56+
57+
dmabuf = dentry->d_fsdata;
58+
mutex_lock(&dmabuf->lock);
59+
if (dmabuf->name)
60+
ret = strlcpy(name, dmabuf->name, DMA_BUF_NAME_LEN);
61+
mutex_unlock(&dmabuf->lock);
62+
63+
return dynamic_dname(dentry, buffer, buflen, "/%s:%s",
64+
dentry->d_name.name, ret > 0 ? name : "");
65+
}
66+
5167
static const struct dentry_operations dma_buf_dentry_ops = {
52-
.d_dname = simple_dname,
68+
.d_dname = dmabuffs_dname,
5369
};
5470

5571
static struct vfsmount *dma_buf_mnt;
@@ -301,6 +317,43 @@ static __poll_t dma_buf_poll(struct file *file, poll_table *poll)
301317
return events;
302318
}
303319

320+
/**
321+
* dma_buf_set_name - Set a name to a specific dma_buf to track the usage.
322+
* The name of the dma-buf buffer can only be set when the dma-buf is not
323+
* attached to any devices. It could theoritically support changing the
324+
* name of the dma-buf if the same piece of memory is used for multiple
325+
* purpose between different devices.
326+
*
327+
* @dmabuf [in] dmabuf buffer that will be renamed.
328+
* @buf: [in] A piece of userspace memory that contains the name of
329+
* the dma-buf.
330+
*
331+
* Returns 0 on success. If the dma-buf buffer is already attached to
332+
* devices, return -EBUSY.
333+
*
334+
*/
335+
static long dma_buf_set_name(struct dma_buf *dmabuf, const char __user *buf)
336+
{
337+
char *name = strndup_user(buf, DMA_BUF_NAME_LEN);
338+
long ret = 0;
339+
340+
if (IS_ERR(name))
341+
return PTR_ERR(name);
342+
343+
mutex_lock(&dmabuf->lock);
344+
if (!list_empty(&dmabuf->attachments)) {
345+
ret = -EBUSY;
346+
kfree(name);
347+
goto out_unlock;
348+
}
349+
kfree(dmabuf->name);
350+
dmabuf->name = name;
351+
352+
out_unlock:
353+
mutex_unlock(&dmabuf->lock);
354+
return ret;
355+
}
356+
304357
static long dma_buf_ioctl(struct file *file,
305358
unsigned int cmd, unsigned long arg)
306359
{
@@ -339,6 +392,10 @@ static long dma_buf_ioctl(struct file *file,
339392
ret = dma_buf_begin_cpu_access(dmabuf, direction);
340393

341394
return ret;
395+
396+
case DMA_BUF_SET_NAME:
397+
return dma_buf_set_name(dmabuf, (const char __user *)arg);
398+
342399
default:
343400
return -ENOTTY;
344401
}
@@ -380,6 +437,7 @@ static struct file *dma_buf_getfile(struct dma_buf *dmabuf, int flags)
380437
goto err_alloc_file;
381438
file->f_flags = flags & (O_ACCMODE | O_NONBLOCK);
382439
file->private_data = dmabuf;
440+
file->f_path.dentry->d_fsdata = dmabuf;
383441

384442
return file;
385443

@@ -1112,12 +1170,13 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused)
11121170
continue;
11131171
}
11141172

1115-
seq_printf(s, "%08zu\t%08x\t%08x\t%08ld\t%s\t%08lu\n",
1173+
seq_printf(s, "%08zu\t%08x\t%08x\t%08ld\t%s\t%08lu\t%s\n",
11161174
buf_obj->size,
11171175
buf_obj->file->f_flags, buf_obj->file->f_mode,
11181176
file_count(buf_obj->file),
11191177
buf_obj->exp_name,
1120-
file_inode(buf_obj->file)->i_ino);
1178+
file_inode(buf_obj->file)->i_ino,
1179+
buf_obj->name ?: "");
11211180

11221181
robj = buf_obj->resv;
11231182
while (true) {

include/linux/dma-buf.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,10 +280,12 @@ struct dma_buf_ops {
280280
* @file: file pointer used for sharing buffers across, and for refcounting.
281281
* @attachments: list of dma_buf_attachment that denotes all devices attached.
282282
* @ops: dma_buf_ops associated with this buffer object.
283-
* @lock: used internally to serialize list manipulation, attach/detach and vmap/unmap
283+
* @lock: used internally to serialize list manipulation, attach/detach and
284+
* vmap/unmap, and accesses to name
284285
* @vmapping_counter: used internally to refcnt the vmaps
285286
* @vmap_ptr: the current vmap ptr if vmapping_counter > 0
286287
* @exp_name: name of the exporter; useful for debugging.
288+
* @name: userspace-provided name; useful for accounting and debugging.
287289
* @owner: pointer to exporter module; used for refcounting when exporter is a
288290
* kernel module.
289291
* @list_node: node for dma_buf accounting and debugging.
@@ -311,6 +313,7 @@ struct dma_buf {
311313
unsigned vmapping_counter;
312314
void *vmap_ptr;
313315
const char *exp_name;
316+
const char *name;
314317
struct module *owner;
315318
struct list_head list_node;
316319
void *priv;

include/uapi/linux/dma-buf.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,10 @@ struct dma_buf_sync {
3535
#define DMA_BUF_SYNC_VALID_FLAGS_MASK \
3636
(DMA_BUF_SYNC_RW | DMA_BUF_SYNC_END)
3737

38+
#define DMA_BUF_NAME_LEN 32
39+
3840
#define DMA_BUF_BASE 'b'
3941
#define DMA_BUF_IOCTL_SYNC _IOW(DMA_BUF_BASE, 0, struct dma_buf_sync)
42+
#define DMA_BUF_SET_NAME _IOW(DMA_BUF_BASE, 1, const char *)
4043

4144
#endif

0 commit comments

Comments
 (0)