On Wed, 26 Nov 2025 00:29:49 +0800 Xiang Gao gxxa03070307@gmail.com wrote:
+++ b/include/trace/events/dma_buf.h @@ -0,0 +1,281 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM dma_buf
+#if !defined(_TRACE_DMA_BUF_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_DMA_BUF_H
+#include <linux/dma-buf.h> +#include <linux/tracepoint.h>
+TRACE_EVENT(dma_buf_export,
- TP_PROTO(struct dma_buf *dmabuf),
- TP_ARGS(dmabuf),
- TP_STRUCT__entry(
__string(exp_name, dmabuf->exp_name)__string(name, dmabuf->name)__field(size_t, size)__field(ino_t, ino)__field(long, f_refcnt)- ),
- TP_fast_assign(
__assign_str(exp_name);spin_lock(&dmabuf->name_lock);__assign_str(name);spin_unlock(&dmabuf->name_lock);
The above isn't doing what you think it's doing. The name is assigned before this by the above __string(name, dmabuf->name).
You really shouldn't be taking any locks in a tracepoint. A tracepoint is a callback, that isn't called most of the time. You could be hiding very hard to find deadlocks by taking a lock in a tracepoint callback.
You need to take the lock around the tracepoint call itself where it is called in the code. Not in the TRACE_EVENT.
You may need to have something like:
@@ -220,6 +223,8 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma) dmabuf->size >> PAGE_SHIFT) return -EINVAL;
+ if (trace_dma_buf_mmap_internal_enabled()) { + guard(spinlock)(&dmabuf->namelock); + trace_dma_buf_mmap_internal(dmabuf); + } + return dmabuf->ops->mmap(dmabuf, vma); }
The "trace_dma_buf_mmap_internal_enabled()" is a static branch, where it is either a nop or a jump to the tracing code. It's not a normal conditional branch. It acts the same as tracepoints themselves do.
__entry->size = dmabuf->size;__entry->ino = dmabuf->file->f_inode->i_ino;__entry->f_refcnt = file_count(dmabuf->file);- ),
- TP_printk("exp_name=%s name=%s size=%zu ino=%lu f_refcnt=%ld",
__get_str(exp_name),__get_str(name),__entry->size,__entry->ino,__entry->f_refcnt)+);
Below seems to be a lot of very similar TRACE_EVENT()s. A TRACE_EVENT() is literally defined as:
#define TRACE_EVENT(name, proto, args, tstruct, assign, print) \ DECLARE_EVENT_CLASS(name, \ PARAMS(proto), \ PARAMS(args), \ PARAMS(tstruct), \ PARAMS(assign), \ PARAMS(print)); \ DEFINE_EVENT(name, name, PARAMS(proto), PARAMS(args));
That is, it is both a DECLARE_EVENT_CLASS() and a DEFINE_EVENT(). You can make one DECLARE_EVENT_CLASS() and use many DEFINE_EVENT()s with it.
Each DECLARE_EVENT_CLASS() takes up around 4 to 5 kilobytes of memory. Each DEFINE_EVENT() takes around 300 bytes to 1K of memory. The more DEFINE_EVENT()s you use with a single DECLARE_EVENT_CLASS(), the more memory you save. Please try to do that.
-- Steve
+TRACE_EVENT(dma_buf_fd,
- TP_PROTO(struct dma_buf *dmabuf, int fd),
- TP_ARGS(dmabuf, fd),
- TP_STRUCT__entry(
__string(exp_name, dmabuf->exp_name)__string(name, dmabuf->name)__field(size_t, size)__field(ino_t, ino)__field(int, fd)__field(long, f_refcnt)- ),
- TP_fast_assign(
__assign_str(exp_name);spin_lock(&dmabuf->name_lock);__assign_str(name);spin_unlock(&dmabuf->name_lock);__entry->size = dmabuf->size;__entry->ino = dmabuf->file->f_inode->i_ino;__entry->fd = fd;__entry->f_refcnt = file_count(dmabuf->file);- ),
- TP_printk("exp_name=%s name=%s size=%zu ino=%lu fd=%d f_refcnt=%ld",
__get_str(exp_name),__get_str(name),__entry->size,__entry->ino,__entry->fd,__entry->f_refcnt)+);
+TRACE_EVENT(dma_buf_mmap_internal,
- TP_PROTO(struct dma_buf *dmabuf),
- TP_ARGS(dmabuf),
- TP_STRUCT__entry(
__string(exp_name, dmabuf->exp_name)__string(name, dmabuf->name)__field(size_t, size)__field(ino_t, ino)__field(long, f_refcnt)- ),
- TP_fast_assign(
__assign_str(exp_name);spin_lock(&dmabuf->name_lock);__assign_str(name);spin_unlock(&dmabuf->name_lock);__entry->size = dmabuf->size;__entry->ino = dmabuf->file->f_inode->i_ino;__entry->f_refcnt = file_count(dmabuf->file);- ),
- TP_printk("exp_name=%s name=%s size=%zu ino=%lu f_refcnt=%ld",
__get_str(exp_name),__get_str(name),__entry->size,__entry->ino,__entry->f_refcnt)+);
+TRACE_EVENT(dma_buf_mmap,
- TP_PROTO(struct dma_buf *dmabuf),
- TP_ARGS(dmabuf),
- TP_STRUCT__entry(
__string(exp_name, dmabuf->exp_name)__string(name, dmabuf->name)__field(size_t, size)__field(ino_t, ino)__field(long, f_refcnt)- ),
- TP_fast_assign(
__assign_str(exp_name);spin_lock(&dmabuf->name_lock);__assign_str(name);spin_unlock(&dmabuf->name_lock);__entry->size = dmabuf->size;__entry->ino = dmabuf->file->f_inode->i_ino;__entry->f_refcnt = file_count(dmabuf->file);- ),
- TP_printk("exp_name=%s name=%s size=%zu ino=%lu f_refcnt=%ld",
__get_str(exp_name),__get_str(name),__entry->size,__entry->ino,__entry->f_refcnt)+);
+TRACE_EVENT(dma_buf_attach,
- TP_PROTO(struct dma_buf *dmabuf, struct device *dev),
- TP_ARGS(dmabuf, dev),
- TP_STRUCT__entry(
__string(dname, dev_name(dev))__string(exp_name, dmabuf->exp_name)__string(name, dmabuf->name)__field(size_t, size)__field(ino_t, ino)__field(long, f_refcnt)- ),
- TP_fast_assign(
__assign_str(dname);__assign_str(exp_name);spin_lock(&dmabuf->name_lock);__assign_str(name);spin_unlock(&dmabuf->name_lock);__entry->size = dmabuf->size;__entry->ino = dmabuf->file->f_inode->i_ino;__entry->f_refcnt = file_count(dmabuf->file);- ),
- TP_printk("dev_name=%s exp_name=%s name=%s size=%zu ino=%lu f_refcnt=%ld",
__get_str(dname),__get_str(exp_name),__get_str(name),__entry->size,__entry->ino,__entry->f_refcnt)+);
+TRACE_EVENT(dma_buf_detach,
- TP_PROTO(struct dma_buf *dmabuf),
- TP_ARGS(dmabuf),
- TP_STRUCT__entry(
__string(exp_name, dmabuf->exp_name)__string(name, dmabuf->name)__field(size_t, size)__field(ino_t, ino)__field(long, f_refcnt)- ),
- TP_fast_assign(
__assign_str(exp_name);spin_lock(&dmabuf->name_lock);__assign_str(name);spin_unlock(&dmabuf->name_lock);__entry->size = dmabuf->size;__entry->ino = dmabuf->file->f_inode->i_ino;__entry->f_refcnt = file_count(dmabuf->file);- ),
- TP_printk("exp_name=%s name=%s size=%zu ino=%lu f_refcnt=%ld",
__get_str(exp_name),__get_str(name),__entry->size,__entry->ino,__entry->f_refcnt)+);
+TRACE_EVENT(dma_buf_get,
- TP_PROTO(int fd, struct file *file),
- TP_ARGS(fd, file),
- TP_STRUCT__entry(
__string(exp_name, ((struct dma_buf *)file->private_data)->exp_name)__string(name, ((struct dma_buf *)file->private_data)->name)__field(size_t, size)__field(ino_t, ino)__field(int, fd)__field(long, f_refcnt)- ),
- TP_fast_assign(
struct dma_buf *dmabuf = (struct dma_buf *)file->private_data;__assign_str(exp_name);spin_lock(&dmabuf->name_lock);__assign_str(name);spin_unlock(&dmabuf->name_lock);__entry->size = dmabuf->size;__entry->ino = dmabuf->file->f_inode->i_ino;__entry->fd = fd;__entry->f_refcnt = file_count(file);- ),
- TP_printk("exp_name=%s name=%s size=%zu ino=%lu fd=%d f_refcnt=%ld",
__get_str(exp_name),__get_str(name),__entry->size,__entry->ino,__entry->fd,__entry->f_refcnt)+);
+TRACE_EVENT(dma_buf_put,
- TP_PROTO(struct dma_buf *dmabuf),
- TP_ARGS(dmabuf),
- TP_STRUCT__entry(
__string(exp_name, dmabuf->exp_name)__string(name, dmabuf->name)__field(size_t, size)__field(ino_t, ino)__field(long, f_refcnt)- ),
- TP_fast_assign(
__assign_str(exp_name);spin_lock(&dmabuf->name_lock);__assign_str(name);spin_unlock(&dmabuf->name_lock);__entry->size = dmabuf->size;__entry->ino = dmabuf->file->f_inode->i_ino;__entry->f_refcnt = file_count(dmabuf->file);- ),
- TP_printk("exp_name=%s name=%s size=%zu ino=%lu f_refcnt=%ld",
__get_str(exp_name),__get_str(name),__entry->size,__entry->ino,__entry->f_refcnt)+);
+#endif /* _TRACE_DMA_BUF_H */
+/* This part must be outside protection */ +#include <trace/define_trace.h>