Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

gaoxiang17 and committed by
Christian König
281a2263 b440baf3

+206 -2
+49 -2
drivers/dma-buf/dma-buf.c
··· 35 35 36 36 #include "dma-buf-sysfs-stats.h" 37 37 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 + 38 60 /* Wrapper to hide the sg_table page link from the importer */ 39 61 struct dma_buf_sg_table_wrapper { 40 62 struct sg_table *original; ··· 247 225 if (vma->vm_pgoff + vma_pages(vma) > 248 226 dmabuf->size >> PAGE_SHIFT) 249 227 return -EINVAL; 228 + 229 + DMA_BUF_TRACE(trace_dma_buf_mmap_internal, dmabuf); 250 230 251 231 return dmabuf->ops->mmap(dmabuf, vma); 252 232 } ··· 775 751 776 752 __dma_buf_list_add(dmabuf); 777 753 754 + DMA_BUF_TRACE(trace_dma_buf_export, dmabuf); 755 + 778 756 return dmabuf; 779 757 780 758 err_dmabuf: ··· 800 774 */ 801 775 int dma_buf_fd(struct dma_buf *dmabuf, int flags) 802 776 { 777 + int fd; 778 + 803 779 if (!dmabuf || !dmabuf->file) 804 780 return -EINVAL; 805 781 806 - return FD_ADD(flags, dmabuf->file); 782 + fd = FD_ADD(flags, dmabuf->file); 783 + if (fd >= 0) 784 + DMA_BUF_TRACE(trace_dma_buf_fd, dmabuf, fd); 785 + 786 + return fd; 807 787 } 808 788 EXPORT_SYMBOL_NS_GPL(dma_buf_fd, "DMA_BUF"); 809 789 ··· 824 792 struct dma_buf *dma_buf_get(int fd) 825 793 { 826 794 struct file *file; 795 + struct dma_buf *dmabuf; 827 796 828 797 file = fget(fd); 829 798 ··· 836 803 return ERR_PTR(-EINVAL); 837 804 } 838 805 839 - return file->private_data; 806 + dmabuf = file->private_data; 807 + 808 + DMA_BUF_TRACE(trace_dma_buf_get, dmabuf, fd); 809 + 810 + return dmabuf; 840 811 } 841 812 EXPORT_SYMBOL_NS_GPL(dma_buf_get, "DMA_BUF"); 842 813 ··· 860 823 return; 861 824 862 825 fput(dmabuf->file); 826 + 827 + DMA_BUF_TRACE(trace_dma_buf_put, dmabuf); 863 828 } 864 829 EXPORT_SYMBOL_NS_GPL(dma_buf_put, "DMA_BUF"); 865 830 ··· 1054 1015 list_add(&attach->node, &dmabuf->attachments); 1055 1016 dma_resv_unlock(dmabuf->resv); 1056 1017 1018 + DMA_BUF_TRACE(trace_dma_buf_dynamic_attach, dmabuf, attach, 1019 + dma_buf_attachment_is_dynamic(attach), dev); 1020 + 1057 1021 return attach; 1058 1022 1059 1023 err_attach: ··· 1100 1058 1101 1059 if (dmabuf->ops->detach) 1102 1060 dmabuf->ops->detach(dmabuf, attach); 1061 + 1062 + DMA_BUF_TRACE(trace_dma_buf_detach, dmabuf, attach, 1063 + dma_buf_attachment_is_dynamic(attach), attach->dev); 1103 1064 1104 1065 kfree(attach); 1105 1066 } ··· 1569 1524 /* readjust the vma */ 1570 1525 vma_set_file(vma, dmabuf->file); 1571 1526 vma->vm_pgoff = pgoff; 1527 + 1528 + DMA_BUF_TRACE(trace_dma_buf_mmap, dmabuf); 1572 1529 1573 1530 return dmabuf->ops->mmap(dmabuf, vma); 1574 1531 }
+157
include/trace/events/dma_buf.h
··· 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>