Skip to content

Commit 281a226

Browse files
gaoxiang17ChristianKoenigAMD
authored andcommitted
dma-buf: add some tracepoints to debug.
Since we can only inspect dmabuf by iterating over process FDs or the dmabuf_list, we need to add our own tracepoints to track its status in real time in production. For example: binder:3016_1-3102 [006] ...1. 255.126521: dma_buf_export: exp_name=qcom,system size=12685312 ino=2738 binder:3016_1-3102 [006] ...1. 255.126528: dma_buf_fd: exp_name=qcom,system size=12685312 ino=2738 fd=8 binder:3016_1-3102 [006] ...1. 255.126642: dma_buf_mmap_internal: exp_name=qcom,system size=28672 ino=2739 kworker/6:1-86 [006] ...1. 255.127194: dma_buf_put: exp_name=qcom,system size=12685312 ino=2738 RenderThread-9293 [006] ...1. 316.618179: dma_buf_get: exp_name=qcom,system size=12771328 ino=2762 fd=176 RenderThread-9293 [006] ...1. 316.618195: dma_buf_dynamic_attach: exp_name=qcom,system size=12771328 ino=2762 attachment:ffffff880a18dd00 is_dynamic=0 dev_name=kgsl-3d0 RenderThread-9293 [006] ...1. 318.878220: dma_buf_detach: exp_name=qcom,system size=12771328 ino=2762 attachment:ffffff880a18dd00 is_dynamic=0 dev_name=kgsl-3d0 Signed-off-by: Xiang Gao <gaoxiang17@xiaomi.com> Reviewed-by: Christian König <christian.koenig@amd.com> Link: https://lore.kernel.org/r/20251218062853.819744-1-gxxa03070307@gmail.com Signed-off-by: Christian König <christian.koenig@amd.com>
1 parent b440baf commit 281a226

2 files changed

Lines changed: 206 additions & 2 deletions

File tree

drivers/dma-buf/dma-buf.c

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,28 @@
3535

3636
#include "dma-buf-sysfs-stats.h"
3737

38+
#define CREATE_TRACE_POINTS
39+
#include <trace/events/dma_buf.h>
40+
41+
/*
42+
* dmabuf->name must be accessed with holding dmabuf->name_lock.
43+
* we need to take the lock around the tracepoint call itself where
44+
* it is called in the code.
45+
*
46+
* Note: FUNC##_enabled() is a static branch that will only
47+
* be set when the trace event is enabled.
48+
*/
49+
#define DMA_BUF_TRACE(FUNC, ...) \
50+
do { \
51+
if (FUNC##_enabled()) { \
52+
guard(spinlock)(&dmabuf->name_lock); \
53+
FUNC(__VA_ARGS__); \
54+
} else if (IS_ENABLED(CONFIG_LOCKDEP)) { \
55+
/* Expose this lock when lockdep is enabled */ \
56+
guard(spinlock)(&dmabuf->name_lock); \
57+
} \
58+
} while (0)
59+
3860
/* Wrapper to hide the sg_table page link from the importer */
3961
struct dma_buf_sg_table_wrapper {
4062
struct sg_table *original;
@@ -226,6 +248,8 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma)
226248
dmabuf->size >> PAGE_SHIFT)
227249
return -EINVAL;
228250

251+
DMA_BUF_TRACE(trace_dma_buf_mmap_internal, dmabuf);
252+
229253
return dmabuf->ops->mmap(dmabuf, vma);
230254
}
231255

@@ -751,6 +775,8 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info)
751775

752776
__dma_buf_list_add(dmabuf);
753777

778+
DMA_BUF_TRACE(trace_dma_buf_export, dmabuf);
779+
754780
return dmabuf;
755781

756782
err_dmabuf:
@@ -774,10 +800,16 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_export, "DMA_BUF");
774800
*/
775801
int dma_buf_fd(struct dma_buf *dmabuf, int flags)
776802
{
803+
int fd;
804+
777805
if (!dmabuf || !dmabuf->file)
778806
return -EINVAL;
779807

780-
return FD_ADD(flags, dmabuf->file);
808+
fd = FD_ADD(flags, dmabuf->file);
809+
if (fd >= 0)
810+
DMA_BUF_TRACE(trace_dma_buf_fd, dmabuf, fd);
811+
812+
return fd;
781813
}
782814
EXPORT_SYMBOL_NS_GPL(dma_buf_fd, "DMA_BUF");
783815

@@ -792,6 +824,7 @@ EXPORT_SYMBOL_NS_GPL(dma_buf_fd, "DMA_BUF");
792824
struct dma_buf *dma_buf_get(int fd)
793825
{
794826
struct file *file;
827+
struct dma_buf *dmabuf;
795828

796829
file = fget(fd);
797830

@@ -803,7 +836,11 @@ struct dma_buf *dma_buf_get(int fd)
803836
return ERR_PTR(-EINVAL);
804837
}
805838

806-
return file->private_data;
839+
dmabuf = file->private_data;
840+
841+
DMA_BUF_TRACE(trace_dma_buf_get, dmabuf, fd);
842+
843+
return dmabuf;
807844
}
808845
EXPORT_SYMBOL_NS_GPL(dma_buf_get, "DMA_BUF");
809846

@@ -823,6 +860,8 @@ void dma_buf_put(struct dma_buf *dmabuf)
823860
return;
824861

825862
fput(dmabuf->file);
863+
864+
DMA_BUF_TRACE(trace_dma_buf_put, dmabuf);
826865
}
827866
EXPORT_SYMBOL_NS_GPL(dma_buf_put, "DMA_BUF");
828867

@@ -1015,6 +1054,9 @@ dma_buf_dynamic_attach(struct dma_buf *dmabuf, struct device *dev,
10151054
list_add(&attach->node, &dmabuf->attachments);
10161055
dma_resv_unlock(dmabuf->resv);
10171056

1057+
DMA_BUF_TRACE(trace_dma_buf_dynamic_attach, dmabuf, attach,
1058+
dma_buf_attachment_is_dynamic(attach), dev);
1059+
10181060
return attach;
10191061

10201062
err_attach:
@@ -1059,6 +1101,9 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach)
10591101
if (dmabuf->ops->detach)
10601102
dmabuf->ops->detach(dmabuf, attach);
10611103

1104+
DMA_BUF_TRACE(trace_dma_buf_detach, dmabuf, attach,
1105+
dma_buf_attachment_is_dynamic(attach), attach->dev);
1106+
10621107
kfree(attach);
10631108
}
10641109
EXPORT_SYMBOL_NS_GPL(dma_buf_detach, "DMA_BUF");
@@ -1525,6 +1570,8 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma,
15251570
vma_set_file(vma, dmabuf->file);
15261571
vma->vm_pgoff = pgoff;
15271572

1573+
DMA_BUF_TRACE(trace_dma_buf_mmap, dmabuf);
1574+
15281575
return dmabuf->ops->mmap(dmabuf, vma);
15291576
}
15301577
EXPORT_SYMBOL_NS_GPL(dma_buf_mmap, "DMA_BUF");

include/trace/events/dma_buf.h

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#undef TRACE_SYSTEM
3+
#define TRACE_SYSTEM dma_buf
4+
5+
#if !defined(_TRACE_DMA_BUF_H) || defined(TRACE_HEADER_MULTI_READ)
6+
#define _TRACE_DMA_BUF_H
7+
8+
#include <linux/dma-buf.h>
9+
#include <linux/tracepoint.h>
10+
11+
DECLARE_EVENT_CLASS(dma_buf,
12+
13+
TP_PROTO(struct dma_buf *dmabuf),
14+
15+
TP_ARGS(dmabuf),
16+
17+
TP_STRUCT__entry(
18+
__string(exp_name, dmabuf->exp_name)
19+
__field(size_t, size)
20+
__field(ino_t, ino)
21+
),
22+
23+
TP_fast_assign(
24+
__assign_str(exp_name);
25+
__entry->size = dmabuf->size;
26+
__entry->ino = dmabuf->file->f_inode->i_ino;
27+
),
28+
29+
TP_printk("exp_name=%s size=%zu ino=%lu",
30+
__get_str(exp_name),
31+
__entry->size,
32+
__entry->ino)
33+
);
34+
35+
DECLARE_EVENT_CLASS(dma_buf_attach_dev,
36+
37+
TP_PROTO(struct dma_buf *dmabuf, struct dma_buf_attachment *attach,
38+
bool is_dynamic, struct device *dev),
39+
40+
TP_ARGS(dmabuf, attach, is_dynamic, dev),
41+
42+
TP_STRUCT__entry(
43+
__string(dev_name, dev_name(dev))
44+
__string(exp_name, dmabuf->exp_name)
45+
__field(size_t, size)
46+
__field(ino_t, ino)
47+
__field(struct dma_buf_attachment *, attach)
48+
__field(bool, is_dynamic)
49+
),
50+
51+
TP_fast_assign(
52+
__assign_str(dev_name);
53+
__assign_str(exp_name);
54+
__entry->size = dmabuf->size;
55+
__entry->ino = dmabuf->file->f_inode->i_ino;
56+
__entry->is_dynamic = is_dynamic;
57+
__entry->attach = attach;
58+
),
59+
60+
TP_printk("exp_name=%s size=%zu ino=%lu attachment:%p is_dynamic=%d dev_name=%s",
61+
__get_str(exp_name),
62+
__entry->size,
63+
__entry->ino,
64+
__entry->attach,
65+
__entry->is_dynamic,
66+
__get_str(dev_name))
67+
);
68+
69+
DECLARE_EVENT_CLASS(dma_buf_fd,
70+
71+
TP_PROTO(struct dma_buf *dmabuf, int fd),
72+
73+
TP_ARGS(dmabuf, fd),
74+
75+
TP_STRUCT__entry(
76+
__string(exp_name, dmabuf->exp_name)
77+
__field(size_t, size)
78+
__field(ino_t, ino)
79+
__field(int, fd)
80+
),
81+
82+
TP_fast_assign(
83+
__assign_str(exp_name);
84+
__entry->size = dmabuf->size;
85+
__entry->ino = dmabuf->file->f_inode->i_ino;
86+
__entry->fd = fd;
87+
),
88+
89+
TP_printk("exp_name=%s size=%zu ino=%lu fd=%d",
90+
__get_str(exp_name),
91+
__entry->size,
92+
__entry->ino,
93+
__entry->fd)
94+
);
95+
96+
DEFINE_EVENT(dma_buf, dma_buf_export,
97+
98+
TP_PROTO(struct dma_buf *dmabuf),
99+
100+
TP_ARGS(dmabuf)
101+
);
102+
103+
DEFINE_EVENT(dma_buf, dma_buf_mmap_internal,
104+
105+
TP_PROTO(struct dma_buf *dmabuf),
106+
107+
TP_ARGS(dmabuf)
108+
);
109+
110+
DEFINE_EVENT(dma_buf, dma_buf_mmap,
111+
112+
TP_PROTO(struct dma_buf *dmabuf),
113+
114+
TP_ARGS(dmabuf)
115+
);
116+
117+
DEFINE_EVENT(dma_buf, dma_buf_put,
118+
119+
TP_PROTO(struct dma_buf *dmabuf),
120+
121+
TP_ARGS(dmabuf)
122+
);
123+
124+
DEFINE_EVENT(dma_buf_attach_dev, dma_buf_dynamic_attach,
125+
126+
TP_PROTO(struct dma_buf *dmabuf, struct dma_buf_attachment *attach,
127+
bool is_dynamic, struct device *dev),
128+
129+
TP_ARGS(dmabuf, attach, is_dynamic, dev)
130+
);
131+
132+
DEFINE_EVENT(dma_buf_attach_dev, dma_buf_detach,
133+
134+
TP_PROTO(struct dma_buf *dmabuf, struct dma_buf_attachment *attach,
135+
bool is_dynamic, struct device *dev),
136+
137+
TP_ARGS(dmabuf, attach, is_dynamic, dev)
138+
);
139+
140+
DEFINE_EVENT(dma_buf_fd, dma_buf_fd,
141+
142+
TP_PROTO(struct dma_buf *dmabuf, int fd),
143+
144+
TP_ARGS(dmabuf, fd)
145+
);
146+
147+
DEFINE_EVENT(dma_buf_fd, dma_buf_get,
148+
149+
TP_PROTO(struct dma_buf *dmabuf, int fd),
150+
151+
TP_ARGS(dmabuf, fd)
152+
);
153+
154+
#endif /* _TRACE_DMA_BUF_H */
155+
156+
/* This part must be outside protection */
157+
#include <trace/define_trace.h>

0 commit comments

Comments
 (0)