ok, thanks.
________________________________ 发件人: Steven Rostedt rostedt@goodmis.org 发送时间: 2025年11月26日 9:39:24 收件人: Xiang Gao 抄送: sumit.semwal@linaro.org; christian.koenig@amd.com; mhiramat@kernel.org; linux-media@vger.kernel.org; dri-devel@lists.freedesktop.org; linaro-mm-sig@lists.linaro.org; linux-kernel@vger.kernel.org; mathieu.desnoyers@efficios.com; dhowells@redhat.com; kuba@kernel.org; brauner@kernel.org; akpm@linux-foundation.org; linux-trace-kernel@vger.kernel.org; 高翔 主题: [External Mail]Re: [PATCH v2] dma-buf: add some tracepoints to debug.
[外部邮件] 此邮件来源于小米公司外部,请谨慎处理。若对邮件安全性存疑,请将邮件转发给misec@xiaomi.com进行反馈
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>