目录
dmabuf是什么?
dmabuf_dump工具介绍(基于Android 14)
Android.bp
dmabuf_dump.cpp
团体架构结构如下
dmabuf_dump主要包含以下功能
前置背景知识
fdinfo
思考
bufinfo
Dump整个手机体系的dmabuf
Dump某个进程的dmabuf
以Table[buffer x process]方式出现dmabuf
Dump整个体系DMA-BUF per-buffer, per-exporter and per-device statistics
DMA_BUF 在内核中的实现
dmabuf_dump原理分析
源码路径:
DmaBuffer
主要成员变量
FD和Inode的关系
dump整个体系流程原理
ReadDmaBufFdRefs
AddFdRef
ReadDmaBufMapRefs
AddMapRef
dmabuf_dump
dmabuf_dump -a
dmabuf_dump -b
代码流程
dmabuf的运用
实例分析
背景
解决方案
加tracepoint
tracepoint实现patch
使用simpleperf抓取dmabuf申请点所有backtrace
举例
Provider进程基于vendor.qti.hardware.display.allocator-service申请驻留分析
dmabuf是什么?
可以参考我之前写的一篇文章,在这篇文章中有介绍dma_buf:BufferManager_驱动的buffermanager-CSDN博客
dmabuf_dump工具介绍(基于Android 14)
dmabuf_dump是一个可执行文件,接收参数调用libdmabufinfo.a的接口完成dump功能,源码在:system/memory/libmeminfo/libdmabufinfo/tools/
安卓源代码目录下主要有下面2个文件,一个 Android.bp ,一个是 dmabuf_dump.cpp
Android.bp
- // Copyright (C) 2019 The Android Open Source Project
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- package {
- default_applicable_licenses: ["Android-Apache-2.0"],
- }
- cc_binary {
- name: "dmabuf_dump",
- cflags: [
- "-Wall",
- "-Werror",
- ],
- srcs: ["dmabuf_dump.cpp"],
- shared_libs: [
- "libbase",
- ],
- static_libs: [
- "libdmabufinfo",
- ],
- vendor_available: true,
- }
复制代码
dmabuf_dump.cpp
- xref: /mivendor_u_sm8650/system/memory/libmeminfo/libdmabufinfo/tools/dmabuf_dump.cpp (revision unknown)
- HomeHistoryAnnotateLine# Scopes# Navigate#Raw Download
- current directory
- /*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #include <dirent.h>
- #include <errno.h>
- #include <getopt.h>
- #include <inttypes.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <fstream>
- #include <iostream>
- #include <map>
- #include <set>
- #include <sstream>
- #include <string>
- #include <vector>
- #include <android-base/stringprintf.h>
- #include <dmabufinfo/dmabufinfo.h>
- #include <dmabufinfo/dmabuf_sysfs_stats.h>
- using DmaBuffer = ::android::dmabufinfo::DmaBuffer;
- [[noreturn]] static void usage(int exit_status) {
- fprintf(stderr,
- "Usage: %s [-abh] [per-process/per-buffer stats] \n"
- "-a\t show all dma buffers (ion) in big table, [buffer x process] grid \n"
- "-b\t show DMA-BUF per-buffer, per-exporter and per-device statistics \n"
- "-h\t show this help\n"
- " \t If PID is supplied, the dmabuf information for that process is shown.\n"
- " \t Per-buffer DMA-BUF stats do not take an argument.\n",
- getprogname());
- exit(exit_status);
- }
- static std::string GetProcessComm(const pid_t pid) {
- std::string pid_path = android::base::StringPrintf("/proc/%d/comm", pid);
- std::ifstream in{pid_path};
- if (!in) return std::string("N/A");
- std::string line;
- std::getline(in, line);
- if (!in) return std::string("N/A");
- return line;
- }
- static void PrintDmaBufTable(const std::vector<DmaBuffer>& bufs) {
- if (bufs.empty()) {
- printf("dmabuf info not found ¯\\_(ツ)_/¯\n");
- return;
- }
- // Find all unique pids in the input vector, create a set
- std::set<pid_t> pid_set;
- for (auto& buf : bufs) {
- pid_set.insert(buf.pids().begin(), buf.pids().end());
- }
- // Format the header string spaced and separated with '|'
- printf(" Dmabuf Inode | Size | Fd Ref Counts | Map Ref Counts |");
- for (auto pid : pid_set) {
- printf("%16s:%-5d |", GetProcessComm(pid).c_str(), pid);
- }
- printf("\n");
- // holds per-process dmabuf size in kB
- std::map<pid_t, uint64_t> per_pid_size = {};
- uint64_t dmabuf_total_size = 0;
- // Iterate through all dmabufs and collect per-process sizes, refs
- for (auto& buf : bufs) {
- printf("%16ju |%13" PRIu64 " kB |%16zu |%16zu |",
- static_cast<uintmax_t>(buf.inode()), buf.size() / 1024, buf.fdrefs().size(),
- buf.maprefs().size());
- // Iterate through each process to find out per-process references for each buffer,
- // gather total size used by each process etc.
- for (pid_t pid : pid_set) {
- int pid_fdrefs = 0, pid_maprefs = 0;
- if (buf.fdrefs().count(pid) == 1) {
- // Get the total number of ref counts the process is holding
- // on this buffer. We don't differentiate between mmap or fd.
- pid_fdrefs += buf.fdrefs().at(pid);
- }
- if (buf.maprefs().count(pid) == 1) {
- pid_maprefs += buf.maprefs().at(pid);
- }
- if (pid_fdrefs || pid_maprefs) {
- // Add up the per-pid total size. Note that if a buffer is mapped
- // in 2 different processes, the size will be shown as mapped or opened
- // in both processes. This is intended for visibility.
- //
- // If one wants to get the total *unique* dma buffers, they can simply
- // sum the size of all dma bufs shown by the tool
- per_pid_size[pid] += buf.size() / 1024;
- printf("%9d(%6d) refs |", pid_fdrefs, pid_maprefs);
- } else {
- printf("%22s |", "--");
- }
- }
- dmabuf_total_size += buf.size() / 1024;
- printf("\n");
- }
- printf("------------------------------------\n");
- printf("%-16s %13" PRIu64 " kB |%16s |%16s |", "TOTALS", dmabuf_total_size, "n/a", "n/a");
- for (auto pid : pid_set) {
- printf("%19" PRIu64 " kB |", per_pid_size[pid]);
- }
- printf("\n");
- return;
- }
- static void PrintDmaBufPerProcess(const std::vector<DmaBuffer>& bufs) {
- if (bufs.empty()) {
- printf("dmabuf info not found ¯\\_(ツ)_/¯\n");
- return;
- }
- // Create a reverse map from pid to dmabufs
- std::unordered_map<pid_t, std::set<ino_t>> pid_to_inodes = {};
- uint64_t userspace_size = 0; // Size of userspace dmabufs in the system
- for (auto& buf : bufs) {
- for (auto pid : buf.pids()) {
- pid_to_inodes[pid].insert(buf.inode());
- }
- userspace_size += buf.size();
- }
- // Create an inode to dmabuf map. We know inodes are unique..
- std::unordered_map<ino_t, DmaBuffer> inode_to_dmabuf;
- for (auto buf : bufs) {
- inode_to_dmabuf[buf.inode()] = buf;
- }
- uint64_t total_rss = 0, total_pss = 0;
- for (auto& [pid, inodes] : pid_to_inodes) {
- uint64_t pss = 0;
- uint64_t rss = 0;
- printf("%16s:%-5d\n", GetProcessComm(pid).c_str(), pid);
- printf("%22s %16s %16s %16s %16s\n", "Name", "Rss", "Pss", "nr_procs", "Inode");
- for (auto& inode : inodes) {
- DmaBuffer& buf = inode_to_dmabuf[inode];
- printf("%22s %13" PRIu64 " kB %13" PRIu64 " kB %16zu %16" PRIuMAX "\n",
- buf.name().empty() ? "<unknown>" : buf.name().c_str(), buf.size() / 1024,
- buf.Pss() / 1024, buf.pids().size(), static_cast<uintmax_t>(buf.inode()));
- rss += buf.size();
- pss += buf.Pss();
- }
- printf("%22s %13" PRIu64 " kB %13" PRIu64 " kB %16s\n", "PROCESS TOTAL", rss / 1024,
- pss / 1024, "");
- printf("----------------------\n");
- total_rss += rss;
- total_pss += pss;
- }
- uint64_t kernel_rss = 0; // Total size of dmabufs NOT mapped or opened by a process
- if (android::dmabufinfo::GetDmabufTotalExportedKb(&kernel_rss)) {
- kernel_rss *= 1024; // KiB -> bytes
- if (kernel_rss >= userspace_size)
- kernel_rss -= userspace_size;
- else
- printf("Warning: Total dmabufs < userspace dmabufs\n");
- } else {
- printf("Warning: Could not get total exported dmabufs. Kernel size will be 0.\n");
- }
- printf("dmabuf total: %" PRIu64 " kB kernel_rss: %" PRIu64 " kB userspace_rss: %" PRIu64
- " kB userspace_pss: %" PRIu64 " kB\n ",
- (userspace_size + kernel_rss) / 1024, kernel_rss / 1024, total_rss / 1024,
- total_pss / 1024);
- }
- static void DumpDmabufSysfsStats() {
- android::dmabufinfo::DmabufSysfsStats stats;
- if (!android::dmabufinfo::GetDmabufSysfsStats(&stats)) {
- printf("Unable to read DMA-BUF sysfs stats from device\n");
- return;
- }
- auto buffer_stats = stats.buffer_stats();
- auto exporter_stats = stats.exporter_info();
- printf("\n\n----------------------- DMA-BUF per-buffer stats -----------------------\n");
- printf(" Dmabuf Inode | Size(bytes) | Exporter Name |\n");
- for (const auto& buf : buffer_stats) {
- printf("%16lu |%" PRIu64 " | %16s \n", buf.inode, buf.size, buf.exp_name.c_str());
- }
- printf("\n\n----------------------- DMA-BUF exporter stats -----------------------\n");
- printf(" Exporter Name | Total Count | Total Size(bytes) |\n");
- for (const auto& it : exporter_stats) {
- printf("%32s | %12u| %" PRIu64 "\n", it.first.c_str(), it.second.buffer_count,
- it.second.size);
- }
- printf("\n\n----------------------- DMA-BUF total stats --------------------------\n");
- printf("Total DMA-BUF count: %u, Total DMA-BUF size(bytes): %" PRIu64 "\n", stats.total_count(),
- stats.total_size());
- }
- int main(int argc, char* argv[]) {
- struct option longopts[] = {{"all", no_argument, nullptr, 'a'},
- {"per-buffer", no_argument, nullptr, 'b'},
- {"help", no_argument, nullptr, 'h'},
- {0, 0, nullptr, 0}};
- int opt;
- bool show_table = false;
- bool show_dmabuf_sysfs_stats = false;
- while ((opt = getopt_long(argc, argv, "abh", longopts, nullptr)) != -1) {
- switch (opt) {
- case 'a':
- show_table = true;
- break;
- case 'b':
- show_dmabuf_sysfs_stats = true;
- break;
- case 'h':
- usage(EXIT_SUCCESS);
- default:
- usage(EXIT_FAILURE);
- }
- }
- pid_t pid = -1;
- if (optind < argc) {
- if (show_table || show_dmabuf_sysfs_stats) {
- fprintf(stderr, "Invalid arguments: -a and -b does not need arguments\n");
- usage(EXIT_FAILURE);
- }
- if (optind != (argc - 1)) {
- fprintf(stderr, "Invalid arguments - only one [PID] argument is allowed\n");
- usage(EXIT_FAILURE);
- }
- pid = atoi(argv[optind]);
- if (pid == 0) {
- fprintf(stderr, "Invalid process id %s\n", argv[optind]);
- usage(EXIT_FAILURE);
- }
- }
- if (show_dmabuf_sysfs_stats) {
- DumpDmabufSysfsStats();
- return 0;
- }
- std::vector<DmaBuffer> bufs;
- if (pid != -1) {
- if (!ReadDmaBufInfo(pid, &bufs)) {
- fprintf(stderr, "Unable to read dmabuf info for %d\n", pid);
- exit(EXIT_FAILURE);
- }
- } else {
- if (!ReadProcfsDmaBufs(&bufs)) {
- fprintf(stderr, "Failed to ReadProcfsDmaBufs, check logcat for info\n");
- exit(EXIT_FAILURE);
- }
- }
- // Show the old dmabuf table, inode x process
- if (show_table) {
- PrintDmaBufTable(bufs);
- return 0;
- }
- PrintDmaBufPerProcess(bufs);
- return 0;
- }
复制代码 团体架构结构如下
dmabuf_dump主要包含以下功能
- Dump整个体系DMA-BUF per-buffer, per-exporter and per-device statistics(dmabuf_dump -b),在kernel版本>= 5.10上见效。
- Dump整个体系的dmabuf info (dmabuf_dump)
- Dump某个PID的dmabuf info (dmabuf_dump )
- 以Table[buffer x process]方式出现dmabuf info (dmabuf_dump -a)
前置背景知识
- Rss的含义:是当前段现实加载到物理内存中的大小。
- Pss 指的是:进程按比例分配当前段所占物理内存的大小。
- 下面dump整个手机体系在某一时刻的 dmabuf信息,可以看到有 binder进程的dmabuf信息、surfaceflinger进程的dmabuf信息、system_server进程的dmabuf信息等等。
- nr_procs是指有多少个进程在使用这块dmabuf。
- Name是指dmabuf的名字
- Inode是这块 dmabuf的唯一标识,注意Inode是全局唯一的。
- PROCESS TOTAL 是统计 Rss 或者 Pss的总和。
- dmabuf total 是整个体系dambuf的总和
- userspace_rss 是用户空间 rss的总和。
- userspace_pss 是用户空间 pss的总和。
- kernel_rss 目前初步以为是 内核空间rss的总和,但不特殊准确,这个kernel_rss大有来头,后面有时间详细深度剖析。真实的项目过程中,会偶先 kernel_rss占用过大,或泄露的情况,这种问题还特殊难分析和解决。
fdinfo
/proc/<pid>/fdinfo/ 下面的所有fd,针对每个fd读取如下信息:
- count
- exp_name,有exp_name则表示是 dmabuf 的file。
- name
- size
- ino:inode
以下是camera provider的 fdinfo
- wj@wj:~/Downloads$ adb shell ps -e | grep camera
- cameraserver 1601 1 14307344 680656 binder_ioctl_write_read 0 S vendor.qti.camera.provider-service_64
- cameraserver 2785 1 2720288 25620 binder_ioctl_write_read 0 S cameraserver
- u0_a139 11065 1444 9305388 343752 do_epoll_wait 0 S com.android.camera
- wj@wj:~/Downloads$ adb shell
- aurora:/ # cd /proc/1601/fdinfo/
- aurora:/proc/1601/fdinfo # ls
- 0 110 1137 117 123 15 19 22 26 3 33 36 383 399 406 43 47 50 54 56 6 63 67 7 73 745 751 79 82 899
- 1 111 114 118 124 16 2 23 27 30 336 37 384 4 407 44 48 51 55 57 60 64 68 70 731 748 76 8 84 9
- 10 112 115 121 13 17 20 24 28 31 34 38 386 40 41 45 49 52 557 58 61 65 687 71 74 75 77 80 85
- 11 113 116 122 14 18 21 25 29 32 35 382 39 400 42 46 5 53 558 59 62 66 69 72 743 750 78 81 86
复制代码 可以看到 fdinfo 有以下这些:
- aurora:/proc/1601/fdinfo # ls
- 0 110 1137 117 123 15 19 22 26 3 33 36 383 399 406 43 47 50 54 56 6 63 67 7 73 745 751 79 82 899
- 1 111 114 118 124 16 2 23 27 30 336 37 384 4 407 44 48 51 55 57 60 64 68 70 731 748 76 8 84 9
- 10 112 115 121 13 17 20 24 28 31 34 38 386 40 41 45 49 52 557 58 61 65 687 71 74 75 77 80 85
- 11 113 116 122 14 18 21 25 29 32 35 382 39 400 42 46 5 53 558 59 62 66 69 72 743 750 78 81 86
复制代码 思考
我们知道每一个进程都有一个 fd,用户空间差别进程的 fd,是可以共享内核空间的同一块 dmabuf的,那么怎么样找到进程 fd 和对应 dmabuf的对应关系呢?
那么这个时候 inode 就要出场了,因为 dmabuf的inode是唯一确定的,所以这个时候我们可以把同一时刻的,这个进程的 dmabuf_dump给 dump下来,如下所示。
- wj@wj:~$ adb shell ps -e | grep camera
- cameraserver 1601 1 14307344 680656 binder_ioctl_write_read 0 S vendor.qti.camera.provider-service_64
- cameraserver 2785 1 2720288 25620 binder_ioctl_write_read 0 S cameraserver
- u0_a139 11065 1444 9305388 343752 do_epoll_wait 0 S com.android.camera
- wj@wj:~$ adb shell dmabuf_dump 1601
- vendor.qti.came:1601
- Name Rss Pss nr_procs Inode
- system 4 kB 4 kB 1 134
- system 4 kB 4 kB 1 135
- system 4 kB 4 kB 1 723
- system 4 kB 4 kB 1 724
- system 4 kB 4 kB 1 725
- system 4320 kB 4320 kB 1 727
- system 736 kB 736 kB 1 729
- system 148 kB 148 kB 1 731
- system 32768 kB 32768 kB 1 733
- system 4 kB 4 kB 1 996
- system 4 kB 4 kB 1 1010
- system 4 kB 4 kB 1 1011
- system 736 kB 736 kB 1 1017
- system 148 kB 148 kB 1 1019
- system 6848 kB 6848 kB 1 1342
- system 1024 kB 1024 kB 1 1359
- system 32768 kB 32768 kB 1 1363
- system 4 kB 4 kB 1 1367
- system 4 kB 4 kB 1 1371
- system 4 kB 4 kB 1 1372
- PROCESS TOTAL 79540 kB 79540 kB
- ----------------------
- dmabuf total: 298652 kB kernel_rss: 219112 kB userspace_rss: 79540 kB userspace_pss: 79540 kB
复制代码
然后我们可以用 grep -nr 命令进行查察,如下所示:
- aurora:/proc/1601/fdinfo # grep -nr 733
- ./124:4:ino: 733
- aurora:/proc/1601/fdinfo # grep -nr 1372
- ./751:4:ino: 1372
复制代码 inode为733的dmabuf 所对应的进程为:124
inode为1372的dmabuf所对应的进程为:751
bufinfo
我们可以通过获取 bufferinfo 来获取 dmabuf的详细信息。
adb shell cat /sys/kernel/debug/dma_buf/bufinfo
- wj@wj:~/Downloads$ adb shell cat /sys/kernel/debug/dma_buf/bufinfo
- Dma-buf Objects:
- size flags mode count exp_name ino name
- 00032768 00000002 00080007 00000002 qcom,system 00002275 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00770048 00000002 00080007 00000001 qcom,system 00002274 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00032768 00000002 00080007 00000002 qcom,system 00002273 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00770048 00000002 00080007 00000001 qcom,system 00002272 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00032768 00000002 00080007 00000002 qcom,system 00002271 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00770048 00000002 00080007 00000001 qcom,system 00002270 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00002269 qcom,system
- Attached Devices:
- Total 0 devices attached
- 10522624 00000002 00080007 00000004 qcom,system 00002268 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000002 qcom,system 00002267 qcom,system
- Attached Devices:
- Total 0 devices attached
- 10522624 00000002 00080007 00000001 qcom,system 00002266 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00032768 00000002 00080007 00000002 qcom,system 00002265 qcom,system
- Attached Devices:
- Total 0 devices attached
- 10522624 00000002 00080007 00000001 qcom,system 00002264 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00032768 00000002 00080007 00000002 qcom,system 00002263 qcom,system
- Attached Devices:
- Total 0 devices attached
- 10522624 00000002 00080007 00000001 qcom,system 00002262 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00002261 qcom,system
- Attached Devices:
- Total 0 devices attached
- 10522624 00000002 00080007 00000004 qcom,system 00002260 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00002249 qcom,system
- Attached Devices:
- Total 0 devices attached
- 10522624 00000002 00080007 00000003 qcom,system 00002248 qcom,system
- Attached Devices:
- kgsl-3d0
- Total 1 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00002188 qcom,system
- Attached Devices:
- Total 0 devices attached
- 10444800 00000002 00080007 00000003 qcom,system 00002187 qcom,system
- Attached Devices:
- kgsl-3d0
- Total 1 devices attached
- 00004096 00000002 00080007 00000003 system 00002039 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb5
- Total 1 devices attached
- 00004096 00000002 00080007 00000003 system 00002034 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb5
- Total 1 devices attached
- 00004096 00000002 00080007 00000003 system 00002033 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb5
- Total 1 devices attached
- 33554432 00000002 00080007 00000003 system 00002029 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb5
- Total 1 devices attached
- 00151552 00000002 00080007 00000003 system 00002025 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb5
- Total 1 devices attached
- 00106496 00000002 00080007 00000002 system 00002018 system
- Attached Devices:
- Total 0 devices attached
- 00753664 00000002 00080007 00000003 system 00002017 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb5
- Total 1 devices attached
- 07012352 00000002 00080007 00000003 system 00002008 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb5
- Total 1 devices attached
- 00004096 00000002 00080007 00000003 system 00002005 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb5
- Total 1 devices attached
- 00004096 00000002 00080007 00000003 system 00002004 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb5
- Total 1 devices attached
- 00004096 00000002 00080007 00000003 system 00001958 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb5
- Total 1 devices attached
- 00032768 00000002 00080007 00000002 qcom,system 00001953 qcom,system
- Attached Devices:
- Total 0 devices attached
- 10444800 00000002 00080007 00000001 qcom,system 00001952 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00032768 00000002 00080007 00000002 qcom,system 00001502 qcom,system
- Attached Devices:
- Total 0 devices attached
- 10522624 00000002 00080007 00000002 qcom,system 00001501 qcom,system
- Attached Devices:
- kgsl-3d0
- Total 1 devices attached
- 00073728 00000002 00080007 00000002 qcom,system 00001460 qcom,system
- Attached Devices:
- Total 0 devices attached
- 02506752 00000002 00080007 00000002 qcom,system 00001459 qcom,system
- Attached Devices:
- kgsl-3d0
- Total 1 devices attached
- 00004096 00000002 00080007 00000003 system 00001372 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb4
- Total 1 devices attached
- 00004096 00000002 00080007 00000003 system 00001371 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb4
- Total 1 devices attached
- 00004096 00000002 00080007 00000003 system 00001367 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb4
- Total 1 devices attached
- 33554432 00000002 00080007 00000003 system 00001363 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb4
- Total 1 devices attached
- 01048576 00000002 00080007 00000003 system 00001359 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb4
- Total 1 devices attached
- 07012352 00000002 00080007 00000003 system 00001342 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb4
- Total 1 devices attached
- 00151552 00000002 00080007 00000003 system 00001019 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb4
- Total 1 devices attached
- 00753664 00000002 00080007 00000003 system 00001017 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb4
- Total 1 devices attached
- 00004096 00000002 00080007 00000002 system 00001011 system
- Attached Devices:
- Total 0 devices attached
- 00004096 00000002 00080007 00000003 system 00001010 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb4
- Total 1 devices attached
- 00004096 00000002 00080007 00000003 system 00000996 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb4
- Total 1 devices attached
- 33554432 00000002 00080007 00000003 system 00000733 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb3
- Total 1 devices attached
- 00151552 00000002 00080007 00000003 system 00000731 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb3
- Total 1 devices attached
- 00753664 00000002 00080007 00000003 system 00000729 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb3
- Total 1 devices attached
- 04423680 00000002 00080007 00000003 system 00000727 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb3
- Total 1 devices attached
- 00004096 00000002 00080007 00000002 system 00000725 system
- Attached Devices:
- Total 0 devices attached
- 00004096 00000002 00080007 00000003 system 00000724 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb3
- Total 1 devices attached
- 00004096 00000002 00080007 00000003 system 00000723 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb3
- Total 1 devices attached
- 00032768 00000002 00080007 00000002 qcom,system 00000669 qcom,system
- Attached Devices:
- Total 0 devices attached
- 10522624 00000002 00080007 00000002 qcom,system 00000668 qcom,system
- Attached Devices:
- kgsl-3d0
- Total 1 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000665 qcom,system
- Attached Devices:
- Total 0 devices attached
- 10522624 00000002 00080007 00000005 qcom,system 00000664 qcom,system
- Attached Devices:
- soc:qcom,smmu_sde_unsec_cb
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000663 qcom,system
- Attached Devices:
- Total 0 devices attached
- 10522624 00000002 00080007 00000004 qcom,system 00000662 qcom,system
- Attached Devices:
- soc:qcom,smmu_sde_unsec_cb
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000343 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00491520 00000002 00080007 00000004 qcom,system 00000342 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000341 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00491520 00000002 00080007 00000004 qcom,system 00000340 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000339 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00491520 00000002 00080007 00000004 qcom,system 00000338 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000337 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00491520 00000002 00080007 00000004 qcom,system 00000336 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000002 qcom,system 00000321 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00131072 00000002 00080007 00000003 qcom,system 00000320 qcom,system
- Attached Devices:
- kgsl-3d0
- Total 1 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000319 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00212992 00000002 00080007 00000004 qcom,system 00000318 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000317 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00212992 00000002 00080007 00000004 qcom,system 00000316 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000315 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00212992 00000002 00080007 00000004 qcom,system 00000314 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000313 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00212992 00000002 00080007 00000004 qcom,system 00000312 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000311 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00352256 00000002 00080007 00000004 qcom,system 00000310 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000309 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00974848 00000002 00080007 00000004 qcom,system 00000308 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000307 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00974848 00000002 00080007 00000004 qcom,system 00000306 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000305 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00974848 00000002 00080007 00000004 qcom,system 00000304 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000303 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00974848 00000002 00080007 00000004 qcom,system 00000302 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000293 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00974848 00000002 00080007 00000004 qcom,system 00000292 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000291 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00974848 00000002 00080007 00000004 qcom,system 00000290 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000289 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00974848 00000002 00080007 00000004 qcom,system 00000288 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000286 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00974848 00000002 00080007 00000004 qcom,system 00000285 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000258 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00352256 00000002 00080007 00000004 qcom,system 00000257 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000220 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00393216 00000002 00080007 00000004 qcom,system 00000219 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000218 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00393216 00000002 00080007 00000004 qcom,system 00000217 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000216 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00393216 00000002 00080007 00000004 qcom,system 00000215 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000214 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00393216 00000002 00080007 00000004 qcom,system 00000213 qcom,system
- Attached Devices:
- kgsl-3d0
- kgsl-3d0
- Total 2 devices attached
- 00020480 00000002 00080007 00000003 qcom,system 00000172 qcom,system
- Attached Devices:
- soc:qcom,smmu_sde_unsec_cb
- Total 1 devices attached
- 00020480 00000002 00080007 00000003 qcom,system 00000171 qcom,system
- Attached Devices:
- soc:qcom,smmu_sde_unsec_cb
- Total 1 devices attached
- 00020480 00000002 00080007 00000003 qcom,system 00000170 qcom,system
- Attached Devices:
- soc:qcom,smmu_sde_unsec_cb
- Total 1 devices attached
- 00032768 00000002 00080007 00000002 qcom,system 00000167 qcom,system
- Attached Devices:
- Total 0 devices attached
- 14745600 00000002 00080007 00000003 qcom,system 00000166 qcom,system
- Attached Devices:
- soc:qcom,smmu_sde_unsec_cb
- Total 1 devices attached
- 02097152 00000002 00080007 00000002 qcom,qseecom 00000165 qcom,qseecom
- Attached Devices:
- Total 0 devices attached
- 00004096 00000002 00080007 00000002 qcom,qseecom 00000164 qcom,qseecom
- Attached Devices:
- Total 0 devices attached
- 00012288 00000002 00080007 00000002 qcom,qseecom 00000162 qcom,qseecom
- Attached Devices:
- Total 0 devices attached
- 00262144 00000002 00080007 00000003 system 00000160 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb1
- Total 1 devices attached
- 00004096 00000002 00080007 00000003 system 00000158 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb1
- Total 1 devices attached
- 00262144 00000002 00080007 00000003 system 00000157 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb10
- Total 1 devices attached
- 00004096 00000002 00080007 00000002 system 00000156 system
- Attached Devices:
- Total 0 devices attached
- 00004096 00000002 00080007 00000003 system 00000155 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb10
- Total 1 devices attached
- 00032768 00000002 00080007 00000003 system 00000154 <none>
- Attached Devices:
- soc:spf_core_platform:qcom,msm-audio-ion
- Total 1 devices attached
- 00032768 00000002 00080007 00000004 qcom,system 00000153 qcom,system
- Attached Devices:
- Total 0 devices attached
- 10522624 00000002 00080007 00000005 qcom,system 00000152 qcom,system
- Attached Devices:
- soc:qcom,smmu_sde_unsec_cb
- kgsl-3d0
- Total 2 devices attached
- 00004096 00000002 00080007 00000002 system 00000135 system
- Attached Devices:
- Total 0 devices attached
- 00004096 00000002 00080007 00000003 system 00000134 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb11
- Total 1 devices attached
- 00004096 00000002 00080007 00000002 system 00000079 system
- Attached Devices:
- Total 0 devices attached
- 00004096 00000002 00080007 00000003 system 00000078 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb12
- Total 1 devices attached
- 00032768 00000002 00080007 00000002 qcom,system 00000074 qcom,system
- Attached Devices:
- Total 0 devices attached
- 00065536 00000002 00080007 00000002 qcom,system 00000073 qcom,system
- Attached Devices:
- kgsl-3d0
- Total 1 devices attached
- 00004096 00000002 00080007 00000002 system 00000072 system
- Attached Devices:
- Total 0 devices attached
- 00004096 00000002 00080007 00000003 system 00000071 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb11
- Total 1 devices attached
- 00004096 00000002 00080007 00000002 qcom,qseecom 00000057 qcom,qseecom
- Attached Devices:
- Total 0 devices attached
- 00004096 00000002 00080007 00000002 system 00000048 system
- Attached Devices:
- Total 0 devices attached
- 00004096 00000002 00080007 00000003 system 00000047 system
- Attached Devices:
- soc:qcom,msm_fastrpc:qcom,msm_fastrpc_compute_cb2
- Total 1 devices attached
- 00008192 00000002 00080007 00000002 qcom,qseecom 00000046 qcom,qseecom
- Attached Devices:
- Total 0 devices attached
- 00008192 00000002 00080007 00000002 qcom,qseecom 00000045 qcom,qseecom
- Attached Devices:
- Total 0 devices attached
- 01200128 00000002 00080007 00000001 qcom,system 00000043 <none>
- Attached Devices:
- soc:qcom,cam_smmu:msm_cam_smmu_icp
- Total 1 devices attached
- 00024576 00000002 00080007 00000002 qcom,qseecom 00000036 qcom,qseecom
- Attached Devices:
- Total 0 devices attached
- 01048576 00000000 00080005 00000001 qcom,system 00000018 <none>
- Attached Devices:
- ab00000.qcom,cvp:cvp_non_secure_cb
- Total 1 devices attached
- 03141632 00000000 00080005 00000001 qcom,system 00000017 <none>
- Attached Devices:
- ab00000.qcom,cvp:cvp_non_secure_cb
- Total 1 devices attached
- 00004096 00000002 00080007 00000002 qcom,qseecom 00000016 qcom,qseecom
- Attached Devices:
- Total 0 devices attached
- 00028672 00000002 00080007 00000003 qcom,qseecom 00000013 qcom,qseecom
- Attached Devices:
- firmware:qcom_smcinvoke
- Total 1 devices attached
- 00004096 00000002 00080007 00000003 qcom,qseecom 00000012 qcom,qseecom
- Attached Devices:
- firmware:qcom_smcinvoke
- Total 1 devices attached
- 00028672 00000002 00080007 00000003 qcom,qseecom 00000011 qcom,qseecom
- Attached Devices:
- firmware:qcom_smcinvoke
- Total 1 devices attached
- 00020480 00000002 00080007 00000003 qcom,qseecom 00000010 qcom,qseecom
- Attached Devices:
- firmware:qcom_smcinvoke
- Total 1 devices attached
- 00516096 00000002 00080007 00000003 qcom,qseecom 00000009 qcom,qseecom
- Attached Devices:
- firmware:qcom_smcinvoke
- Total 1 devices attached
- 00020480 00000002 00080007 00000003 qcom,qseecom 00000008 qcom,qseecom
- Attached Devices:
- firmware:qcom_smcinvoke
- Total 1 devices attached
- 00020480 00000002 00080007 00000003 qcom,qseecom 00000007 qcom,qseecom
- Attached Devices:
- firmware:qcom_smcinvoke
- Total 1 devices attached
- 00020480 00000002 00080007 00000003 qcom,qseecom 00000006 qcom,qseecom
- Attached Devices:
- firmware:qcom_smcinvoke
- Total 1 devices attached
- 00020480 00000002 00080007 00000003 qcom,qseecom 00000005 qcom,qseecom
- Attached Devices:
- firmware:qcom_smcinvoke
- Total 1 devices attached
- 00028672 00000002 00080007 00000003 qcom,qseecom 00000004 qcom,qseecom
- Attached Devices:
- firmware:qcom_smcinvoke
- Total 1 devices attached
- 00004096 00000000 00080005 00000001 qcom,system 00000003 <none>
- Attached Devices:
- aa00000.qcom,vidc:non_secure_cb
- Total 1 devices attached
- 00004096 00000000 00080005 00000001 qcom,system 00000002 <none>
- Attached Devices:
- aa00000.qcom,vidc:non_secure_cb
- Total 1 devices attached
- 03133440 00000000 00080005 00000001 qcom,system 00000001 <none>
- Attached Devices:
- aa00000.qcom,vidc:non_secure_cb
- Total 1 devices attached
- Total 154 objects, 305819648 bytes
复制代码 可以看到有更多的dmabuf信息输出:size 、 flags、Attached Devices、mode 、count 、exp_name 、ino 、name
Dump整个手机体系的dmabuf
- wj@wj:~/Downloads$ adb shell
- aurora:/ # dmabuf_dump
- binder:3072_2:3072
- Name Rss Pss nr_procs Inode
- qcom,qseecom 12 kB 12 kB 1 160
- PROCESS TOTAL 12 kB 12 kB
- ----------------------
- mfp-daemon:3041
- Name Rss Pss nr_procs Inode
- qcom,qseecom 4 kB 4 kB 1 163
- qcom,qseecom 2048 kB 2048 kB 1 164
- PROCESS TOTAL 2052 kB 2052 kB
- ----------------------
- cdsprpcd:2824
- Name Rss Pss nr_procs Inode
- system 4 kB 4 kB 1 139
- system 256 kB 256 kB 1 141
- system 104 kB 104 kB 1 1994
- PROCESS TOTAL 364 kB 364 kB
- ----------------------
- binder:1817_2:1817
- Name Rss Pss nr_procs Inode
- qcom,qseecom 8 kB 8 kB 1 37
- PROCESS TOTAL 8 kB 8 kB
- ----------------------
- .android.camera:8920
- Name Rss Pss nr_procs Inode
- system 4 kB 4 kB 1 1979
- system 4 kB 4 kB 1 1987
- system 4 kB 4 kB 1 1988
- system 6848 kB 6848 kB 1 1990
- system 736 kB 736 kB 1 1993
- system 148 kB 148 kB 1 1996
- system 32768 kB 32768 kB 1 1997
- system 4 kB 4 kB 1 2000
- system 4 kB 4 kB 1 2001
- system 4 kB 4 kB 1 2002
- qcom,system 2392 kB 2392 kB 1 2415
- qcom,system 72 kB 72 kB 1 2416
- qcom,system 2448 kB 2448 kB 1 2636
- qcom,system 72 kB 72 kB 1 2637
- PROCESS TOTAL 45508 kB 45508 kB
- ----------------------
- iui.miwallpaper:4872
- Name Rss Pss nr_procs Inode
- qcom,system 10276 kB 5138 kB 2 3711
- qcom,system 32 kB 16 kB 2 3712
- qcom,system 10276 kB 5138 kB 2 3723
- qcom,system 32 kB 16 kB 2 3724
- PROCESS TOTAL 20616 kB 10308 kB
- ----------------------
- fidoca:1813
- Name Rss Pss nr_procs Inode
- qcom,qseecom 24 kB 24 kB 1 25
- PROCESS TOTAL 24 kB 24 kB
- ----------------------
- binder:1808_2:1808
- Name Rss Pss nr_procs Inode
- system 4 kB 4 kB 1 43
- system 4 kB 4 kB 1 44
- PROCESS TOTAL 8 kB 8 kB
- ----------------------
- binder:3079_2:3079
- Name Rss Pss nr_procs Inode
- qcom,system 14400 kB 14400 kB 1 165
- qcom,system 32 kB 32 kB 1 166
- PROCESS TOTAL 14432 kB 14432 kB
- ----------------------
- android.hardwar:1607
- Name Rss Pss nr_procs Inode
- qcom,qseecom 4 kB 4 kB 1 22
- PROCESS TOTAL 4 kB 4 kB
- ----------------------
- surfaceflinger:1929
- Name Rss Pss nr_procs Inode
- qcom,system 64 kB 64 kB 1 71
- qcom,system 32 kB 32 kB 1 72
- qcom,system 10276 kB 5138 kB 2 133
- qcom,system 32 kB 16 kB 2 134
- qcom,system 384 kB 192 kB 2 225
- qcom,system 32 kB 16 kB 2 226
- qcom,system 384 kB 192 kB 2 227
- qcom,system 32 kB 16 kB 2 228
- qcom,system 384 kB 192 kB 2 229
- qcom,system 32 kB 16 kB 2 230
- qcom,system 384 kB 192 kB 2 231
- qcom,system 32 kB 16 kB 2 232
- qcom,system 344 kB 172 kB 2 247
- qcom,system 32 kB 16 kB 2 248
- qcom,system 952 kB 476 kB 2 292
- qcom,system 32 kB 16 kB 2 293
- qcom,system 952 kB 476 kB 2 298
- qcom,system 32 kB 16 kB 2 299
- qcom,system 952 kB 476 kB 2 302
- qcom,system 32 kB 16 kB 2 303
- qcom,system 952 kB 476 kB 2 304
- qcom,system 32 kB 16 kB 2 305
- qcom,system 952 kB 476 kB 2 308
- qcom,system 32 kB 16 kB 2 309
- qcom,system 952 kB 476 kB 2 310
- qcom,system 32 kB 16 kB 2 311
- qcom,system 952 kB 476 kB 2 312
- qcom,system 32 kB 16 kB 2 313
- qcom,system 952 kB 476 kB 2 314
- qcom,system 32 kB 16 kB 2 315
- qcom,system 344 kB 172 kB 2 323
- qcom,system 32 kB 16 kB 2 324
- qcom,system 208 kB 104 kB 2 325
- qcom,system 32 kB 16 kB 2 326
- qcom,system 208 kB 104 kB 2 327
- qcom,system 32 kB 16 kB 2 328
- qcom,system 208 kB 104 kB 2 329
- qcom,system 32 kB 16 kB 2 330
- qcom,system 208 kB 104 kB 2 331
- qcom,system 32 kB 16 kB 2 332
- qcom,system 128 kB 128 kB 1 333
- qcom,system 32 kB 32 kB 1 334
- qcom,system 480 kB 240 kB 2 349
- qcom,system 32 kB 16 kB 2 350
- qcom,system 480 kB 240 kB 2 351
- qcom,system 32 kB 16 kB 2 352
- qcom,system 480 kB 240 kB 2 353
- qcom,system 32 kB 16 kB 2 354
- qcom,system 480 kB 240 kB 2 355
- qcom,system 32 kB 16 kB 2 356
- qcom,system 10276 kB 5138 kB 2 645
- qcom,system 32 kB 16 kB 2 646
- qcom,system 10276 kB 5138 kB 2 647
- qcom,system 32 kB 16 kB 2 648
- qcom,system 10276 kB 10276 kB 1 829
- qcom,system 32 kB 32 kB 1 830
- qcom,system 10276 kB 10276 kB 1 2694
- qcom,system 32 kB 32 kB 1 2695
- qcom,system 10276 kB 5138 kB 2 3711
- qcom,system 32 kB 16 kB 2 3712
- qcom,system 10276 kB 5138 kB 2 3723
- qcom,system 32 kB 16 kB 2 3724
- qcom,system 10276 kB 5138 kB 2 3731
- qcom,system 32 kB 16 kB 2 3732
- PROCESS TOTAL 96016 kB 58444 kB
- ----------------------
- mrmd:1809
- Name Rss Pss nr_procs Inode
- qcom,qseecom 8 kB 8 kB 1 27
- PROCESS TOTAL 8 kB 8 kB
- ----------------------
- binder:1671_2:1671
- Name Rss Pss nr_procs Inode
- qcom,system 10276 kB 5138 kB 2 133
- qcom,system 32 kB 16 kB 2 134
- qcom,system 20 kB 20 kB 1 169
- qcom,system 20 kB 20 kB 1 170
- qcom,system 20 kB 20 kB 1 171
- qcom,system 10276 kB 5138 kB 2 645
- qcom,system 32 kB 16 kB 2 646
- qcom,system 10276 kB 5138 kB 2 647
- qcom,system 32 kB 16 kB 2 648
- PROCESS TOTAL 30984 kB 15522 kB
- ----------------------
- vendor.qti.came:1650
- Name Rss Pss nr_procs Inode
- system 4 kB 4 kB 1 142
- system 4 kB 4 kB 1 143
- system 4 kB 4 kB 1 1180
- system 4 kB 4 kB 1 1194
- system 4 kB 4 kB 1 1195
- system 736 kB 736 kB 1 1201
- system 148 kB 148 kB 1 1203
- system 6848 kB 6848 kB 1 1601
- system 1024 kB 1024 kB 1 1620
- system 32768 kB 32768 kB 1 1621
- system 4 kB 4 kB 1 1625
- system 4 kB 4 kB 1 1627
- system 4 kB 4 kB 1 1628
- PROCESS TOTAL 41556 kB 41556 kB
- ----------------------
- adsprpcd:2822
- Name Rss Pss nr_procs Inode
- system 4 kB 4 kB 1 136
- system 4 kB 4 kB 1 137
- system 256 kB 256 kB 1 138
- PROCESS TOTAL 264 kB 264 kB
- ----------------------
- system_server:2293
- Name Rss Pss nr_procs Inode
- qcom,system 10200 kB 5100 kB 2 3693
- qcom,system 32 kB 16 kB 2 3694
- PROCESS TOTAL 10232 kB 5116 kB
- ----------------------
- ndroid.systemui:5329
- Name Rss Pss nr_procs Inode
- qcom,system 952 kB 476 kB 2 292
- qcom,system 32 kB 16 kB 2 293
- qcom,system 952 kB 476 kB 2 298
- qcom,system 32 kB 16 kB 2 299
- qcom,system 952 kB 476 kB 2 302
- qcom,system 32 kB 16 kB 2 303
- qcom,system 952 kB 476 kB 2 304
- qcom,system 32 kB 16 kB 2 305
- qcom,system 952 kB 476 kB 2 308
- qcom,system 32 kB 16 kB 2 309
- qcom,system 952 kB 476 kB 2 310
- qcom,system 32 kB 16 kB 2 311
- qcom,system 952 kB 476 kB 2 312
- qcom,system 32 kB 16 kB 2 313
- qcom,system 952 kB 476 kB 2 314
- qcom,system 32 kB 16 kB 2 315
- qcom,system 208 kB 104 kB 2 325
- qcom,system 32 kB 16 kB 2 326
- qcom,system 208 kB 104 kB 2 327
- qcom,system 32 kB 16 kB 2 328
- qcom,system 208 kB 104 kB 2 329
- qcom,system 32 kB 16 kB 2 330
- qcom,system 208 kB 104 kB 2 331
- qcom,system 32 kB 16 kB 2 332
- qcom,system 480 kB 240 kB 2 349
- qcom,system 32 kB 16 kB 2 350
- qcom,system 480 kB 240 kB 2 351
- qcom,system 32 kB 16 kB 2 352
- qcom,system 480 kB 240 kB 2 353
- qcom,system 32 kB 16 kB 2 354
- qcom,system 480 kB 240 kB 2 355
- qcom,system 32 kB 16 kB 2 356
- qcom,system 752 kB 752 kB 1 463
- qcom,system 32 kB 32 kB 1 464
- qcom,system 752 kB 752 kB 1 465
- qcom,system 32 kB 32 kB 1 466
- qcom,system 752 kB 752 kB 1 467
- qcom,system 32 kB 32 kB 1 468
- qcom,system 10276 kB 10276 kB 1 3725
- qcom,system 32 kB 32 kB 1 3726
- qcom,system 10276 kB 10276 kB 1 3727
- qcom,system 32 kB 32 kB 1 3728
- qcom,system 10276 kB 10276 kB 1 3729
- qcom,system 32 kB 32 kB 1 3730
- qcom,system 10276 kB 5138 kB 2 3731
- qcom,system 32 kB 16 kB 2 3732
- qcom,system 752 kB 752 kB 1 3733
- qcom,system 32 kB 32 kB 1 3734
- qcom,system 752 kB 752 kB 1 3735
- qcom,system 32 kB 32 kB 1 3736
- qcom,system 752 kB 752 kB 1 3737
- qcom,system 32 kB 32 kB 1 3738
- PROCESS TOTAL 56816 kB 46222 kB
- ----------------------
- sscrpcd:1281
- Name Rss Pss nr_procs Inode
- system 4 kB 4 kB 1 76
- system 4 kB 4 kB 1 77
- PROCESS TOTAL 8 kB 8 kB
- ----------------------
- binder:1589_2:1589
- Name Rss Pss nr_procs Inode
- <unknown> 32 kB 32 kB 1 135
- PROCESS TOTAL 32 kB 32 kB
- ----------------------
- com.miui.home:5380
- Name Rss Pss nr_procs Inode
- qcom,system 384 kB 192 kB 2 225
- qcom,system 32 kB 16 kB 2 226
- qcom,system 384 kB 192 kB 2 227
- qcom,system 32 kB 16 kB 2 228
- qcom,system 384 kB 192 kB 2 229
- qcom,system 32 kB 16 kB 2 230
- qcom,system 384 kB 192 kB 2 231
- qcom,system 32 kB 16 kB 2 232
- qcom,system 344 kB 172 kB 2 247
- qcom,system 32 kB 16 kB 2 248
- qcom,system 344 kB 172 kB 2 323
- qcom,system 32 kB 16 kB 2 324
- qcom,system 10200 kB 10200 kB 1 3665
- qcom,system 32 kB 32 kB 1 3666
- qcom,system 10200 kB 5100 kB 2 3693
- qcom,system 32 kB 16 kB 2 3694
- PROCESS TOTAL 22880 kB 16556 kB
- ----------------------
- qseecomd:1079
- Name Rss Pss nr_procs Inode
- qcom,qseecom 28 kB 28 kB 1 1
- qcom,qseecom 20 kB 20 kB 1 2
- qcom,qseecom 20 kB 20 kB 1 3
- qcom,qseecom 20 kB 20 kB 1 4
- qcom,qseecom 20 kB 20 kB 1 5
- qcom,qseecom 504 kB 504 kB 1 6
- qcom,qseecom 20 kB 20 kB 1 7
- qcom,qseecom 28 kB 28 kB 1 8
- qcom,qseecom 4 kB 4 kB 1 9
- qcom,qseecom 28 kB 28 kB 1 10
- PROCESS TOTAL 692 kB 692 kB
- ----------------------
- tee-supplicant:1525
- Name Rss Pss nr_procs Inode
- qcom,qseecom 4 kB 4 kB 1 16
- PROCESS TOTAL 4 kB 4 kB
- ----------------------
- audioadsprpcd:490
- Name Rss Pss nr_procs Inode
- system 4 kB 4 kB 1 79
- system 4 kB 4 kB 1 80
- PROCESS TOTAL 8 kB 8 kB
- ----------------------
- dmabuf total: 265484 kB kernel_rss: 8332 kB userspace_rss: 342528 kB userspace_pss: 257152 kB
复制代码
Dump某个进程的dmabuf
下面Dump Camera Provider进程的dmabuf使用情况。
- wj@wj:~/Downloads$ adb shell ps -e | grep camera
- cameraserver 1650 1 14121844 661800 binder_ioctl_write_read 0 S vendor.qti.camera.provider-service_64
- cameraserver 2691 1 3069520 23404 binder_ioctl_write_read 0 S cameraserver
- u0_a139 8920 1478 9591760 333440 do_epoll_wait 0 S com.android.camera
- wj@wj:~/Downloads$ adb shell dmabuf_dump 1650
- vendor.qti.came:1650
- Name Rss Pss nr_procs Inode
- system 4 kB 4 kB 1 142
- system 4 kB 4 kB 1 143
- system 4 kB 4 kB 1 1180
- system 4 kB 4 kB 1 1194
- system 4 kB 4 kB 1 1195
- system 736 kB 736 kB 1 1201
- system 148 kB 148 kB 1 1203
- system 6848 kB 6848 kB 1 1601
- system 1024 kB 1024 kB 1 1620
- system 32768 kB 32768 kB 1 1621
- system 4 kB 4 kB 1 1625
- system 4 kB 4 kB 1 1627
- system 4 kB 4 kB 1 1628
- PROCESS TOTAL 41556 kB 41556 kB
- ----------------------
- dmabuf total: 265484 kB kernel_rss: 223928 kB userspace_rss: 41556 kB userspace_pss: 41556 kB
复制代码
以Table[buffer x process]方式出现dmabuf
注意,该方式只能看整个体系的dambuf
上述dump说明:
- Fd Ref Counts :表示该FD有多少个进程在引用
- Map Ref Counts:表示该FD当前有多少个进程已经做过Map
- FD( Map) refs : 该进程持有该Buffer的参考计数的总数量以及Map的总次数
Dump整个体系DMA-BUF per-buffer, per-exporter and per-device statistics
在kernel版本>= 5.10上见效。
执行:dmabuf_dump -b
会从sysfs(/sys/kernel/dmabuf/buffers)中dump dmabuf统计信息,显示如下内容:
- wj@wj:~/Downloads$ adb shell
- aurora:/ # dmabuf_dump -b
- ----------------------- DMA-BUF per-buffer stats -----------------------
- Dmabuf Inode | Size(bytes) | Exporter Name |
- 2262 |10522624 | qcom,system
- 2017 |753664 | system
- 1372 |4096 | system
- 315 |32768 | qcom,system
- 17 |3141632 | qcom,system
- 343 |32768 | qcom,system
- 220 |32768 | qcom,system
- 164 |4096 | qcom,qseecom
- 45 |8192 | qcom,qseecom
- 305 |32768 | qcom,system
- 73 |65536 | qcom,system
- 154 |32768 | system
- 663 |32768 | qcom,system
- 7 |20480 | qcom,qseecom
- 2270 |770048 | qcom,system
- 2025 |151552 | system
- 1342 |7012352 | system
- 2260 |10522624 | qcom,system
- 172 |20480 | qcom,system
- 313 |32768 | qcom,system
- 257 |352256 | qcom,system
- 134 |4096 | system
- 341 |32768 | qcom,system
- 285 |974848 | qcom,system
- 219 |393216 | qcom,system
- 162 |12288 | qcom,qseecom
- 2005 |4096 | system
- 43 |1200128 | qcom,system
- 303 |32768 | qcom,system
- 2033 |4096 | system
- 1501 |10522624 | qcom,system
- 71 |4096 | system
- 152 |10522624 | qcom,system
- 5 |20480 | qcom,qseecom
- 2269 |32768 | qcom,system
- 321 |32768 | qcom,system
- 1010 |4096 | system
- 293 |32768 | qcom,system
- 170 |20480 | qcom,system
- 311 |32768 | qcom,system
- 13 |28672 | qcom,qseecom
- 217 |393216 | qcom,system
- 2249 |32768 | qcom,system
- 160 |262144 | system
- 1359 |1048576 | system
- 1952 |10444800 | qcom,system
- 1019 |151552 | system
- 3 |4096 | qcom,system
- 2267 |32768 | qcom,system
- 291 |32768 | qcom,system
- 1367 |4096 | system
- 78 |4096 | system
- 11 |28672 | qcom,qseecom
- 338 |491520 | qcom,system
- 215 |393216 | qcom,system
- 2247 |32768 | qcom,system
- 724 |4096 | system
- 668 |10522624 | qcom,system
- 2275 |32768 | qcom,system
- 1017 |753664 | system
- 1 |3133440 | qcom,system
- 2265 |32768 | qcom,system
- 318 |212992 | qcom,system
- 167 |32768 | qcom,system
- 48 |4096 | system
- 308 |974848 | qcom,system
- 336 |491520 | qcom,system
- 213 |393216 | qcom,system
- 157 |262144 | system
- 996 |4096 | system
- 2273 |32768 | qcom,system
- 2263 |32768 | qcom,system
- 2018 |106496 | system
- 316 |212992 | qcom,system
- 18 |1048576 | qcom,system
- 288 |974848 | qcom,system
- 165 |2097152 | qcom,qseecom
- 2008 |7012352 | system
- 46 |8192 | qcom,qseecom
- 1363 |33554432 | system
- 306 |974848 | qcom,system
- 74 |32768 | qcom,system
- 155 |4096 | system
- 2187 |10444800 | qcom,system
- 664 |10522624 | qcom,system
- 36 |24576 | qcom,qseecom
- 8 |20480 | qcom,qseecom
- 2271 |32768 | qcom,system
- 2261 |32768 | qcom,system
- 1371 |4096 | system
- 314 |212992 | qcom,system
- 258 |32768 | qcom,system
- 135 |4096 | system
- 16 |4096 | qcom,qseecom
- 342 |491520 | qcom,system
- 286 |32768 | qcom,system
- 729 |753664 | system
- 304 |974848 | qcom,system
- 2034 |4096 | system
- 1502 |32768 | qcom,system
- 72 |4096 | system
- 153 |32768 | qcom,system
- 662 |10522624 | qcom,system
- 6 |20480 | qcom,qseecom
- 1011 |4096 | system
- 171 |20480 | qcom,system
- 312 |212992 | qcom,system
- 340 |491520 | qcom,system
- 218 |32768 | qcom,system
- 727 |4423680 | system
- 2004 |4096 | system
- 302 |974848 | qcom,system
- 1953 |32768 | qcom,system
- 4 |28672 | qcom,qseecom
- 2268 |10522624 | qcom,system
- 320 |131072 | qcom,system
- 292 |974848 | qcom,system
- 310 |352256 | qcom,system
- 79 |4096 | system
- 12 |4096 | qcom,qseecom
- 339 |32768 | qcom,system
- 216 |32768 | qcom,system
- 2248 |10522624 | qcom,system
- 725 |4096 | system
- 669 |32768 | qcom,system
- 2 |4096 | qcom,system
- 2266 |10522624 | qcom,system
- 319 |32768 | qcom,system
- 1460 |73728 | qcom,system
- 290 |974848 | qcom,system
- 733 |33554432 | system
- 309 |32768 | qcom,system
- 2039 |4096 | system
- 10 |20480 | qcom,qseecom
- 337 |32768 | qcom,system
- 214 |32768 | qcom,system
- 2246 |10444800 | qcom,system
- 158 |4096 | system
- 723 |4096 | system
- 2274 |770048 | qcom,system
- 2029 |33554432 | system
- 2264 |10522624 | qcom,system
- 57 |4096 | qcom,qseecom
- 317 |32768 | qcom,system
- 1459 |2506752 | qcom,system
- 289 |32768 | qcom,system
- 166 |14745600 | qcom,system
- 731 |151552 | system
- 47 |4096 | system
- 307 |32768 | qcom,system
- 1958 |4096 | system
- 156 |4096 | system
- 2188 |32768 | qcom,system
- 665 |32768 | qcom,system
- 9 |516096 | qcom,qseecom
- 2272 |770048 | qcom,system
- ----------------------- DMA-BUF exporter stats -----------------------
- Exporter Name | Total Count | Total Size(bytes) |
- qcom,system | 95| 189779968
- system | 43| 123645952
- qcom,qseecom | 18| 2871296
- ----------------------- DMA-BUF total stats --------------------------
- Total DMA-BUF count: 156, Total DMA-BUF size(bytes): 316297216
复制代码
DMA_BUF 在内核中的实现
源代码位置:kernel_platform/msm-kernel/drivers/dma-buf/
这篇文章不深入这块内容,后面有时间可以专门写文章进行深入分析。
dmabuf_dump原理分析
源码路径:
system/memory/libmeminfo/libdmabufinfo/
DmaBuffer
DmaBuffer结构体定义如下:
- struct DmaBuffer {
- public:
- DmaBuffer(ino_t inode, uint64_t size, uint64_t count, const std::string& exporter,
- const std::string& name)
- : inode_(inode), size_(size), count_(count), exporter_(exporter), name_(name) {
- total_refs_ = 0;
- }
- DmaBuffer() = default;
- ~DmaBuffer() = default;
- // Adds one file descriptor reference for the given pid
- void AddFdRef(pid_t pid) {
- AddRefToPidMap(pid, &fdrefs_);
- total_refs_++;
- }
- // Adds one map reference for the given pid
- void AddMapRef(pid_t pid) {
- AddRefToPidMap(pid, &maprefs_);
- total_refs_++;
- }
- // Getters for each property
- uint64_t size() const { return size_; }
- const std::unordered_map<pid_t, int>& fdrefs() const { return fdrefs_; }
- const std::unordered_map<pid_t, int>& maprefs() const { return maprefs_; }
- ino_t inode() const { return inode_; }
- uint64_t total_refs() const { return total_refs_; }
- uint64_t count() const { return count_; };
- const std::set<pid_t>& pids() const { return pids_; }
- const std::string& name() const { return name_; }
- const std::string& exporter() const { return exporter_; }
- void SetName(const std::string& name) { name_ = name; }
- void SetExporter(const std::string& exporter) { exporter_ = exporter; }
- void SetCount(uint64_t count) { count_ = count; }
- uint64_t Pss() const { return size_ / pids_.size(); }
- bool operator==(const DmaBuffer& rhs) {
- return (inode_ == rhs.inode()) && (size_ == rhs.size()) && (name_ == rhs.name()) &&
- (exporter_ == rhs.exporter());
- }
- private:
- ino_t inode_;
- uint64_t size_;
- uint64_t count_;
- uint64_t total_refs_;
- std::set<pid_t> pids_;
- std::string exporter_;
- std::string name_;
- std::unordered_map<pid_t, int> fdrefs_;
- std::unordered_map<pid_t, int> maprefs_;
- void AddRefToPidMap(pid_t pid, std::unordered_map<pid_t, int>* map) {
- // The first time we find a ref, we set the ref count to 1
- // otherwise, increment the existing ref count
- auto [it, inserted] = map->insert(std::make_pair(pid, 1));
- if (!inserted) it->second++;
- pids_.insert(pid);
- }
- };
复制代码 主要成员变量
- name_ : 该dmabuf的name,如果读不到name,默以为 ‘<unknown>’
- pids_: 有dup或map该dmabuf的pid 集合。
- count_: fdinfo内里的count,目前看dambuf_dump并没有用。
- size_: 该dmabuf占用的内存大小,单元是byte。
- inode_: 该dmabuf的inode。
- exporter_: 申请该dmabuf的name,如果读不到name,默以为'<unknown>’。
- total_refs_: fdrefs 个数 + maprefs 个数,目前看dambuf_dump并没有用。
- fdrefs_: 有open或dup该dmabuf的pid集合。注:一个pid对同一个dmabuf(inode)可能有多个reference。
- maprefs_: 有map该dmabuf的pid集合。注:一个pid对同一个dmabuf(inode)可能有多个reference。
FD和Inode的关系
为了实现buffer的共享,在内核中将DMA-BUF将buffer与file关联起来,一个Buffer对应唯一一个File,一个File对应唯一一个 inode,将这个file的fd返回给应用层,通过binder实现进程之间的fd传递(dup),进而拿到唯一的File 和 Buffer。
dump整个体系流程原理
直接执行dmabuf_dump会dump 整个体系的dmabuf 信息,代码执行流程如下:
ReadDmaBufFdRefs
- // Public methods
- bool ReadDmaBufFdRefs(int pid, std::vector<DmaBuffer>* dmabufs,
- const std::string& procfs_path) {
- constexpr char permission_err_msg[] =
- "Failed to read fdinfo - requires either PTRACE_MODE_READ or root depending on "
- "the device kernel";
- static bool logged_permission_err = false;
- std::string fdinfo_dir_path =
- ::android::base::StringPrintf("%s/%d/fdinfo", procfs_path.c_str(), pid);
- std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(fdinfo_dir_path.c_str()), &closedir);
- if (!dir) {
- // Don't log permission errors to reduce log spam on devices where fdinfo
- // of other processes can only be read by root.
- if (errno != EACCES) {
- PLOG(ERROR) << "Failed to open " << fdinfo_dir_path << " directory";
- } else if (!logged_permission_err) {
- LOG(ERROR) << permission_err_msg;
- logged_permission_err = true;
- }
- return false;
- }
- struct dirent* dent;
- while ((dent = readdir(dir.get()))) {
- int fd;
- if (!::android::base::ParseInt(dent->d_name, &fd)) {
- continue;
- }
- // Set defaults in case the kernel doesn't give us the information
- // we need in fdinfo
- std::string name = "<unknown>";
- std::string exporter = "<unknown>";
- uint64_t count = 0;
- uint64_t size = 0;
- uint64_t inode = -1;
- bool is_dmabuf_file = false;
- auto fdinfo_result = ReadDmaBufFdInfo(pid, fd, &name, &exporter, &count, &size, &inode,
- &is_dmabuf_file, procfs_path);
- if (fdinfo_result != OK) {
- if (fdinfo_result == NOT_FOUND) {
- continue;
- }
- // Don't log permission errors to reduce log spam when the process doesn't
- // have the PTRACE_MODE_READ permission.
- if (errno != EACCES) {
- LOG(ERROR) << "Failed to read fd info for pid: " << pid << ", fd: " << fd;
- } else if (!logged_permission_err) {
- LOG(ERROR) << permission_err_msg;
- logged_permission_err = true;
- }
- return false;
- }
- if (!is_dmabuf_file) {
- continue;
- }
- if (inode == static_cast<uint64_t>(-1)) {
- // Fallback to stat() on the fd path to get inode number
- std::string fd_path =
- ::android::base::StringPrintf("%s/%d/fd/%d", procfs_path.c_str(), pid, fd);
- struct stat sb;
- if (stat(fd_path.c_str(), &sb) < 0) {
- if (errno == ENOENT) {
- continue;
- }
- PLOG(ERROR) << "Failed to stat: " << fd_path;
- return false;
- }
- inode = sb.st_ino;
- // If root, calculate size from the allocated blocks.
- size = sb.st_blocks * 512;
- }
- auto buf = std::find_if(dmabufs->begin(), dmabufs->end(),
- [&inode](const DmaBuffer& dbuf) { return dbuf.inode() == inode; });
- if (buf != dmabufs->end()) {
- if (buf->name() == "" || buf->name() == "<unknown>") buf->SetName(name);
- if (buf->exporter() == "" || buf->exporter() == "<unknown>") buf->SetExporter(exporter);
- if (buf->count() == 0) buf->SetCount(count);
- buf->AddFdRef(pid);
- continue;
- }
- DmaBuffer& db = dmabufs->emplace_back(inode, size, count, exporter, name);
- db.AddFdRef(pid);
- }
- return true;
- }
复制代码 读取 /proc/<pid>/fdinfo/ 下面的所有fd,针对每个fd读取如下信息
- count
- exp_name,有exp_name则表示是 dmabuf 的file。
- name
- size
- ino:inode
如果是dmabuf file,但没有读到inode,则:
读取 /proc/<pid>/fdinfo/fd的stat,从内里去读取size和inode
- if (inode == static_cast<uint64_t>(-1)) {
- // Fallback to stat() on the fd path to get inode number
- std::string fd_path =
- ::android::base::StringPrintf("%s/%d/fd/%d", procfs_path.c_str(), pid, fd);
- struct stat sb;
- if (stat(fd_path.c_str(), &sb) < 0) {
- if (errno == ENOENT) {
- continue;
- }
- PLOG(ERROR) << "Failed to stat: " << fd_path;
- return false;
- }
- inode = sb.st_ino;
- // If root, calculate size from the allocated blocks.
- size = sb.st_blocks * 512;
- }
复制代码 末了,调用DmaBuffer的AddFdRef,添加到fdrefs_ map内里去。
AddFdRef
- // Adds one file descriptor reference for the given pid
- void AddFdRef(pid_t pid) {
- AddRefToPidMap(pid, &fdrefs_);
- total_refs_++;
- }
复制代码
ReadDmaBufMapRefs
- bool ReadDmaBufMapRefs(pid_t pid, std::vector<DmaBuffer>* dmabufs,
- const std::string& procfs_path,
- const std::string& dmabuf_sysfs_path) {
- std::string mapspath = ::android::base::StringPrintf("%s/%d/maps", procfs_path.c_str(), pid);
- std::ifstream fp(mapspath);
- if (!fp) {
- LOG(ERROR) << "Failed to open " << mapspath << " for pid: " << pid;
- return false;
- }
- // Process the map if it is dmabuf. Add map reference to existing object in 'dmabufs'
- // if it was already found. If it wasn't create a new one and append it to 'dmabufs'
- auto account_dmabuf = [&](const android::procinfo::MapInfo& mapinfo) {
- // no need to look into this mapping if it is not dmabuf
- if (!FileIsDmaBuf(mapinfo.name)) {
- return;
- }
- auto buf = std::find_if(
- dmabufs->begin(), dmabufs->end(),
- [&mapinfo](const DmaBuffer& dbuf) { return dbuf.inode() == mapinfo.inode; });
- if (buf != dmabufs->end()) {
- buf->AddMapRef(pid);
- return;
- }
- // We have a new buffer, but unknown count and name and exporter name
- // Try to lookup exporter name in sysfs
- std::string exporter;
- bool sysfs_stats = ReadBufferExporter(mapinfo.inode, &exporter, dmabuf_sysfs_path);
- if (!sysfs_stats) {
- exporter = "<unknown>";
- }
- // Using the VMA range as the size of the buffer can be misleading,
- // due to partially mapped buffers or VMAs that extend beyond the
- // buffer size.
- //
- // Attempt to retrieve the real buffer size from sysfs.
- uint64_t size = 0;
- if (!sysfs_stats || !ReadBufferSize(mapinfo.inode, &size, dmabuf_sysfs_path)) {
- size = mapinfo.end - mapinfo.start;
- }
- DmaBuffer& dbuf = dmabufs->emplace_back(mapinfo.inode, size, 0, exporter, "<unknown>");
- dbuf.AddMapRef(pid);
- };
- for (std::string line; getline(fp, line);) {
- if (!::android::procinfo::ReadMapFileContent(line.data(), account_dmabuf)) {
- LOG(ERROR) << "Failed to parse " << mapspath << " for pid: " << pid;
- return false;
- }
- }
- return true;
- }
复制代码 读取/proc/<pid>/maps下面的信息,只处理name以 /dmabuf 开头的map(也就是dmabuf的map)。
注:如果从maps内里读到的inode不在fdrefs_ 内里,则会尝试到 /sys/kernel/dmabuf/buffers 内里去读该dmabuf的size,name,exp_name。
然后调用DmaBuffer的AddMapRef,添加到maprefs_ map内里去。
AddMapRef
- // Adds one map reference for the given pid
- void AddMapRef(pid_t pid) {
- AddRefToPidMap(pid, &maprefs_);
- total_refs_++;
- }
复制代码
dmabuf_dump <pid>
流程跟dump 整個体系的dmabuf info雷同,只是这里只dump指定pid的dmabuf info。
dmabuf_dump -a
以Table[buffer x process]方式出现dmabuf info。
跟dmabuf_dump相比,只是打印DmaBuffer的方式不一样。
dmabuf_dump -b
Dmabuf Sysfs Stats统计,有三个相关类:
类定义作用DmabufSysfsStats
Dmabuf sysfs 统计信息每一块Dmabuf信息exporter信息总Dmabuf信息DmabufInfo
统计一块Dmabuf 信息,包罗inode、exporter name、sizeDmabufTotal
统计整个体系的Dmabuf信息,包罗buffer总数、buffer总大小
代码流程
dmabuf的运用
实例分析
背景
项目中具体走漏场景:sat模式拍照退出相机 dma-buf heaps出现内存走漏。关闭相机后查察dmabuf内存占用,当为0情况是没有出现内存走漏,非0我们以为有内存走漏。
- adb shell dmabuf_dump 30618
- vendor.qti.came:30618
- Name Rss Pss nr_procs Inode
- <unknown> 4 kB 4 kB 1 348915
- <unknown> 144 kB 144 kB 1 348916
- <unknown> 32768 kB 32768 kB 1 348948
- <unknown> 4 kB 4 kB 1 349013
- <unknown> 148 kB 148 kB 1 349091
- <unknown> 4 kB 4 kB 1 349092
- <unknown> 4 kB 4 kB 1 349093
- <unknown> 4 kB 4 kB 1 349094
- <unknown> 32768 kB 32768 kB 1 357177
- <unknown> 148 kB 148 kB 1 358102点
- <unknown> 4 kB 4 kB 1 358103
- <unknown> 4 kB 4 kB 1 358104
- <unknown> 4 kB 4 kB 1 358105
- <unknown> 1024 kB 1024 kB 1 359590
- <unknown> 4 kB 4 kB 1 361040
- <unknown> 532 kB 532 kB 1 361101
- <unknown> 5308 kB 5308 kB 1 362040
- <unknown> 568 kB 568 kB 1 362057
- PROCESS TOTAL 73444 kB 73444 kB
- dmabuf total: 73444 kB kernel_rss: 0 kB userspace_rss: 73444 kB userspace_pss: 73444 kB
复制代码 可以看到一次利用走漏73444 kB。
解决方案
怎么去定位具体的走漏backtrace,进而定位到具体的代码?
通用的处理方式是在kernel底层dma-buf申请内存的位置参加tracepoint,用simpleperf去跟踪所有dma-buf申请时的backtrace,基于走漏点Inode去找到对应backtrace
加tracepoint
Using the Linux Kernel Tracepoints — The Linux Kernel documentation
tracepoint实现patch
drivers/dma-buf/dma-heap.c
- // SPDX-License-Identifier: GPL-2.0
- /*
- * Framework for userspace DMA-BUF allocations
- *
- * Copyright (C) 2011 Google, Inc.
- * Copyright (C) 2019 Linaro Ltd.
- */
- #include <linux/cdev.h>
- #include <linux/debugfs.h>
- #include <linux/device.h>
- #include <linux/dma-buf.h>
- #include <linux/err.h>
- #include <linux/xarray.h>
- #include <linux/list.h>
- #include <linux/slab.h>
- #include <linux/uaccess.h>
- #include <linux/syscalls.h>
- #include <linux/dma-heap.h>
- #include <uapi/linux/dma-heap.h>
- #define CREATE_TRACE_POINTS
- #include <trace/events/dma_buf.h>
- #define DEVNAME "dma_heap"
- #define NUM_HEAP_MINORS 128
- /**
- * struct dma_heap - represents a dmabuf heap in the system
- * @name: used for debugging/device-node name
- * @ops: ops struct for this heap
- * @heap_devt heap device node
- * @list list head connecting to list of heaps
- * @heap_cdev heap char device
- * @heap_dev heap device struct
- *
- * Represents a heap of memory from which buffers can be made.
- */
- struct dma_heap {
- const char *name;
- const struct dma_heap_ops *ops;
- void *priv;
- dev_t heap_devt;
- struct list_head list;
- struct cdev heap_cdev;
- struct kref refcount;
- struct device *heap_dev;
- };
- static LIST_HEAD(heap_list);
- static DEFINE_MUTEX(heap_list_lock);
- static dev_t dma_heap_devt;
- static struct class *dma_heap_class;
- static DEFINE_XARRAY_ALLOC(dma_heap_minors);
- struct dma_heap *dma_heap_find(const char *name)
- {
- struct dma_heap *h;
- mutex_lock(&heap_list_lock);
- list_for_each_entry(h, &heap_list, list) {
- if (!strcmp(h->name, name)) {
- kref_get(&h->refcount);
- mutex_unlock(&heap_list_lock);
- return h;
- }
- }
- mutex_unlock(&heap_list_lock);
- return NULL;
- }
- EXPORT_SYMBOL_GPL(dma_heap_find);
- void dma_heap_buffer_free(struct dma_buf *dmabuf)
- {
- dma_buf_put(dmabuf);
- }
- EXPORT_SYMBOL_GPL(dma_heap_buffer_free);
- struct dma_buf *dma_heap_buffer_alloc(struct dma_heap *heap, size_t len,
- unsigned int fd_flags,
- unsigned int heap_flags)
- {
- struct dma_buf *dmabuf = NULL;
- if (fd_flags & ~DMA_HEAP_VALID_FD_FLAGS)
- return ERR_PTR(-EINVAL);
- if (heap_flags & ~DMA_HEAP_VALID_HEAP_FLAGS)
- return ERR_PTR(-EINVAL);
- /*
- * Allocations from all heaps have to begin
- * and end on page boundaries.
- */
- len = PAGE_ALIGN(len);
- if (!len)
- return ERR_PTR(-EINVAL);
- dmabuf = heap->ops->allocate(heap, len, fd_flags, heap_flags);
- trace_dmabuf_alloc(dmabuf->exp_name, heap->name, len, file_inode(dmabuf->file)->i_ino);
- return dmabuf;
- }
- EXPORT_SYMBOL_GPL(dma_heap_buffer_alloc);
- int dma_heap_bufferfd_alloc(struct dma_heap *heap, size_t len,
- unsigned int fd_flags,
- unsigned int heap_flags)
- {
- struct dma_buf *dmabuf;
- int fd;
- dmabuf = dma_heap_buffer_alloc(heap, len, fd_flags, heap_flags);
- if (IS_ERR(dmabuf))
- return PTR_ERR(dmabuf);
- fd = dma_buf_fd(dmabuf, fd_flags);
- if (fd < 0) {
- dma_buf_put(dmabuf);
- /* just return, as put will call release and that will free */
- }
- return fd;
- }
- EXPORT_SYMBOL_GPL(dma_heap_bufferfd_alloc);
- static int dma_heap_open(struct inode *inode, struct file *file)
- {
- struct dma_heap *heap;
- heap = xa_load(&dma_heap_minors, iminor(inode));
- if (!heap) {
- pr_err("dma_heap: minor %d unknown.\n", iminor(inode));
- return -ENODEV;
- }
- /* instance data as context */
- file->private_data = heap;
- nonseekable_open(inode, file);
- return 0;
- }
- static long dma_heap_ioctl_allocate(struct file *file, void *data)
- {
- struct dma_heap_allocation_data *heap_allocation = data;
- struct dma_heap *heap = file->private_data;
- int fd;
- if (heap_allocation->fd)
- return -EINVAL;
- fd = dma_heap_bufferfd_alloc(heap, heap_allocation->len,
- heap_allocation->fd_flags,
- heap_allocation->heap_flags);
- if (fd < 0)
- return fd;
- heap_allocation->fd = fd;
- return 0;
- }
- static unsigned int dma_heap_ioctl_cmds[] = {
- DMA_HEAP_IOCTL_ALLOC,
- };
- static long dma_heap_ioctl(struct file *file, unsigned int ucmd,
- unsigned long arg)
- {
- char stack_kdata[128];
- char *kdata = stack_kdata;
- unsigned int kcmd;
- unsigned int in_size, out_size, drv_size, ksize;
- int nr = _IOC_NR(ucmd);
- int ret = 0;
- if (nr >= ARRAY_SIZE(dma_heap_ioctl_cmds))
- return -EINVAL;
- /* Get the kernel ioctl cmd that matches */
- kcmd = dma_heap_ioctl_cmds[nr];
- /* Figure out the delta between user cmd size and kernel cmd size */
- drv_size = _IOC_SIZE(kcmd);
- out_size = _IOC_SIZE(ucmd);
- in_size = out_size;
- if ((ucmd & kcmd & IOC_IN) == 0)
- in_size = 0;
- if ((ucmd & kcmd & IOC_OUT) == 0)
- out_size = 0;
- ksize = max(max(in_size, out_size), drv_size);
- /* If necessary, allocate buffer for ioctl argument */
- if (ksize > sizeof(stack_kdata)) {
- kdata = kmalloc(ksize, GFP_KERNEL);
- if (!kdata)
- return -ENOMEM;
- }
- if (copy_from_user(kdata, (void __user *)arg, in_size) != 0) {
- ret = -EFAULT;
- goto err;
- }
- /* zero out any difference between the kernel/user structure size */
- if (ksize > in_size)
- memset(kdata + in_size, 0, ksize - in_size);
- switch (kcmd) {
- case DMA_HEAP_IOCTL_ALLOC:
- ret = dma_heap_ioctl_allocate(file, kdata);
- break;
- default:
- ret = -ENOTTY;
- goto err;
- }
- if (copy_to_user((void __user *)arg, kdata, out_size) != 0)
- ret = -EFAULT;
- err:
- if (kdata != stack_kdata)
- kfree(kdata);
- return ret;
- }
- static const struct file_operations dma_heap_fops = {
- .owner = THIS_MODULE,
- .open = dma_heap_open,
- .unlocked_ioctl = dma_heap_ioctl,
- #ifdef CONFIG_COMPAT
- .compat_ioctl = dma_heap_ioctl,
- #endif
- };
- /**
- * dma_heap_get_drvdata() - get per-subdriver data for the heap
- * @heap: DMA-Heap to retrieve private data for
- *
- * Returns:
- * The per-subdriver data for the heap.
- */
- void *dma_heap_get_drvdata(struct dma_heap *heap)
- {
- return heap->priv;
- }
- EXPORT_SYMBOL_GPL(dma_heap_get_drvdata);
- static void dma_heap_release(struct kref *ref)
- {
- struct dma_heap *heap = container_of(ref, struct dma_heap, refcount);
- int minor = MINOR(heap->heap_devt);
- /* Note, we already holding the heap_list_lock here */
- list_del(&heap->list);
- device_destroy(dma_heap_class, heap->heap_devt);
- cdev_del(&heap->heap_cdev);
- xa_erase(&dma_heap_minors, minor);
- kfree(heap);
- }
- void dma_heap_put(struct dma_heap *h)
- {
- /*
- * Take the heap_list_lock now to avoid racing with code
- * scanning the list and then taking a kref.
- */
- mutex_lock(&heap_list_lock);
- kref_put(&h->refcount, dma_heap_release);
- mutex_unlock(&heap_list_lock);
- }
- EXPORT_SYMBOL_GPL(dma_heap_put);
- /**
- * dma_heap_get_dev() - get device struct for the heap
- * @heap: DMA-Heap to retrieve device struct from
- *
- * Returns:
- * The device struct for the heap.
- */
- struct device *dma_heap_get_dev(struct dma_heap *heap)
- {
- return heap->heap_dev;
- }
- EXPORT_SYMBOL_GPL(dma_heap_get_dev);
- /**
- * dma_heap_get_name() - get heap name
- * @heap: DMA-Heap to retrieve private data for
- *
- * Returns:
- * The char* for the heap name.
- */
- const char *dma_heap_get_name(struct dma_heap *heap)
- {
- return heap->name;
- }
- EXPORT_SYMBOL_GPL(dma_heap_get_name);
- struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info)
- {
- struct dma_heap *heap, *err_ret;
- unsigned int minor;
- int ret;
- if (!exp_info->name || !strcmp(exp_info->name, "")) {
- pr_err("dma_heap: Cannot add heap without a name\n");
- return ERR_PTR(-EINVAL);
- }
- if (!exp_info->ops || !exp_info->ops->allocate) {
- pr_err("dma_heap: Cannot add heap with invalid ops struct\n");
- return ERR_PTR(-EINVAL);
- }
- /* check the name is unique */
- heap = dma_heap_find(exp_info->name);
- if (heap) {
- pr_err("dma_heap: Already registered heap named %s\n",
- exp_info->name);
- dma_heap_put(heap);
- return ERR_PTR(-EINVAL);
- }
- heap = kzalloc(sizeof(*heap), GFP_KERNEL);
- if (!heap)
- return ERR_PTR(-ENOMEM);
- kref_init(&heap->refcount);
- heap->name = exp_info->name;
- heap->ops = exp_info->ops;
- heap->priv = exp_info->priv;
- /* Find unused minor number */
- ret = xa_alloc(&dma_heap_minors, &minor, heap,
- XA_LIMIT(0, NUM_HEAP_MINORS - 1), GFP_KERNEL);
- if (ret < 0) {
- pr_err("dma_heap: Unable to get minor number for heap\n");
- err_ret = ERR_PTR(ret);
- goto err0;
- }
- /* Create device */
- heap->heap_devt = MKDEV(MAJOR(dma_heap_devt), minor);
- cdev_init(&heap->heap_cdev, &dma_heap_fops);
- ret = cdev_add(&heap->heap_cdev, heap->heap_devt, 1);
- if (ret < 0) {
- pr_err("dma_heap: Unable to add char device\n");
- err_ret = ERR_PTR(ret);
- goto err1;
- }
- heap->heap_dev = device_create(dma_heap_class,
- NULL,
- heap->heap_devt,
- NULL,
- heap->name);
- if (IS_ERR(heap->heap_dev)) {
- pr_err("dma_heap: Unable to create device\n");
- err_ret = ERR_CAST(heap->heap_dev);
- goto err2;
- }
- /* Make sure it doesn't disappear on us */
- heap->heap_dev = get_device(heap->heap_dev);
- /* Add heap to the list */
- mutex_lock(&heap_list_lock);
- list_add(&heap->list, &heap_list);
- mutex_unlock(&heap_list_lock);
- return heap;
- err2:
- cdev_del(&heap->heap_cdev);
- err1:
- xa_erase(&dma_heap_minors, minor);
- err0:
- kfree(heap);
- return err_ret;
- }
- EXPORT_SYMBOL_GPL(dma_heap_add);
- static char *dma_heap_devnode(struct device *dev, umode_t *mode)
- {
- return kasprintf(GFP_KERNEL, "dma_heap/%s", dev_name(dev));
- }
- static ssize_t total_pools_kb_show(struct kobject *kobj,
- struct kobj_attribute *attr, char *buf)
- {
- struct dma_heap *heap;
- u64 total_pool_size = 0;
- mutex_lock(&heap_list_lock);
- list_for_each_entry(heap, &heap_list, list) {
- if (heap->ops->get_pool_size)
- total_pool_size += heap->ops->get_pool_size(heap);
- }
- mutex_unlock(&heap_list_lock);
- return sysfs_emit(buf, "%llu\n", total_pool_size / 1024);
- }
- static struct kobj_attribute total_pools_kb_attr =
- __ATTR_RO(total_pools_kb);
- static struct attribute *dma_heap_sysfs_attrs[] = {
- &total_pools_kb_attr.attr,
- NULL,
- };
- ATTRIBUTE_GROUPS(dma_heap_sysfs);
- static struct kobject *dma_heap_kobject;
- static int dma_heap_sysfs_setup(void)
- {
- int ret;
- dma_heap_kobject = kobject_create_and_add("dma_heap", kernel_kobj);
- if (!dma_heap_kobject)
- return -ENOMEM;
- ret = sysfs_create_groups(dma_heap_kobject, dma_heap_sysfs_groups);
- if (ret) {
- kobject_put(dma_heap_kobject);
- return ret;
- }
- return 0;
- }
- static void dma_heap_sysfs_teardown(void)
- {
- kobject_put(dma_heap_kobject);
- }
- static int dma_heap_init(void)
- {
- int ret;
- ret = dma_heap_sysfs_setup();
- if (ret)
- return ret;
- ret = alloc_chrdev_region(&dma_heap_devt, 0, NUM_HEAP_MINORS, DEVNAME);
- if (ret)
- goto err_chrdev;
- dma_heap_class = class_create(THIS_MODULE, DEVNAME);
- if (IS_ERR(dma_heap_class)) {
- ret = PTR_ERR(dma_heap_class);
- goto err_class;
- }
- dma_heap_class->devnode = dma_heap_devnode;
- return 0;
- err_class:
- unregister_chrdev_region(dma_heap_devt, NUM_HEAP_MINORS);
- err_chrdev:
- dma_heap_sysfs_teardown();
- return ret;
- }
- subsys_initcall(dma_heap_init);
复制代码
include/trace/events/dma_buf.h
- /* 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/types.h>
- #include <linux/tracepoint.h>
- TRACE_EVENT(dmabuf_alloc,
- TP_PROTO(const char *string1, const char *string2,
- uint64_t val1, uint64_t val2),
- TP_ARGS(string1, string2, val1, val2),
- TP_STRUCT__entry(
- __string(string1, string1)
- __string(string2, string2)
- __field(uint64_t, val1)
- __field(uint64_t, val2)
- ),
- TP_fast_assign(
- __assign_str(string1, string1);
- __assign_str(string2, string2);
- __entry->val1 = val1;
- __entry->val2 = val2;
- ),
- TP_printk(
- "%s: %s Len=%llu Inode=%llu",
- __get_str(string1), __get_str(string2),
- __entry->val1, __entry->val2
- )
- );
- #endif /* _TRACE_DMA_BUF_H */
- /* This part must be outside protection */
- #include <trace/define_trace.h>
复制代码
使用simpleperf抓取dmabuf申请点所有backtrace
perf_cam_log.sh
- #!/bin/bash
- adb root; adb remount
- local_path=$(date +%F_%H%M%S)
- #pid=$(adb shell ps | grep camera.provider | awk '{print $2}')
- pid_app=$(adb shell ps | grep com.android.camera | awk '{print $2}')
- pid_server=$(adb shell ps | grep -Eia "cameraserver$" | awk '{print $2}')
- pid_provider=$(adb shell ps | grep camera.provider | awk '{print $2}')
- pid_allocate=$(adb shell ps | grep vendor.qti.hardware.display.allocator-service | awk '{print $2}')
- pid_hidl=$(adb shell ps | grep android.hidl.allocator@1.0-service | awk '{print $2}')
- mkdir $local_path
- echo "Begin to catch perf data..."
- if [ ! -n "$1" ] ;then
- adb shell "simpleperf record -e camera:cam_log_event,dma_buf:dmabuf_alloc -p $pid_app,$pid_server,$pid_provider,$pid_allocate,$pid_hidl --call-graph dwarf --duration 20 -o /data/local/tmp/perf.data"
- else
- adb shell "simpleperf record -e camera:cam_log_event,dma_buf:dmabuf_alloc -p $pid,$pid_server,$pid_provider,$pid_allocate,$pid_hidl --call-graph dwarf --duration $1 -o /data/local/tmp/perf.data"
- fi
- echo "Complete"
- adb shell "simpleperf report -i /data/local/tmp/perf.data" > $local_path/perf.txt
- adb shell "simpleperf report -i /data/local/tmp/perf.data -g --full-callgraph" > $local_path/perf_callgraph.txt
- adb pull /data/local/tmp/perf.data $local_path
- python3 scripts/report_sample.py $local_path/perf.data --show_tracing_data > $local_path/perf_trace_report.txt
复制代码 执行./perf_cam_log.sh
利用一遍复现步调就可以抓到dmabuf申请点所有backtrace。
举例
打开perf_trace_report.txt
搜索inode “348915”找到:
HwBinder:30618_ 31356 [006] 1876.000000: 1 dma_buf:dmabuf_alloc:
ffffffe8c67a714c dma_heap_buffer_alloc ([kernel.kallsyms])
ffffffe8c67a714a dma_heap_buffer_alloc ([kernel.kallsyms])
ffffffe8c67a798a dma_heap_ioctl ([kernel.kallsyms])
ffffffe8c5f88dda __arm64_sys_ioctl ([kernel.kallsyms])
ffffffe8c5a8a4d6 el0_svc_common ([kernel.kallsyms])
ffffffe8c725e272 el0_svc ([kernel.kallsyms])
ffffffe8c725e1e6 el0_sync_handler ([kernel.kallsyms])
ffffffe8c5a120be el0_sync ([kernel.kallsyms])
7c7fe1dc0c __ioctl (/apex/com.android.runtime/lib64/bionic/libc.so)
7c7fdd784c ioctl (/apex/com.android.runtime/lib64/bionic/libc.so)
796f39b020 BufferAllocator:mabufAlloc(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long) (/apex/com.android.vndk.v31/lib64/libdmabufhe
796f39b26c BufferAllocator::Alloc(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long, unsigned int, unsigned long) (/apex/com.android.vnd
796f39e1bc DmabufHeapAlloc (/apex/com.android.vndk.v31/lib64/libdmabufheap.so)
796b8ce17c rpcmem_alloc_internal (/vendor/lib64/libcdsprpc.so)
796b8cc628 apps_mem_request_map64 (/vendor/lib64/libcdsprpc.so)
796b8cce9c apps_mem_skel_invoke.cfi (/vendor/lib64/libcdsprpc.so)
796b8c46c0 listener_start_thread.cfi (/vendor/lib64/libcdsprpc.so)
7c7fe329a4 __pthread_start(void*) (/apex/com.android.runtime/lib64/bionic/libc.so)
tracing data:
common_type : 693
common_flags : 0
common_preempt_count : 1
common_pid : 31356
string1 : system
string2 : system
val1 : 4096
val2 : 348915
上面的信息就是走漏点的backtrace。
基于上面点可以看到是libcdsprpc.so内部走漏,那接下来就需要看到底哪些算法使用到cdsp
Android 中 gralloc buffer和image buffer底层都是基于 dma_buf来实现的。
Provider进程基于vendor.qti.hardware.display.allocator-service申请驻留分析
libdmabufheaps.so
platform/system/memory/libdmabufheap
Android.bp
- //
- // Copyright (C) 2020 The Android Open Source Project
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // http://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- //
- package {
- default_applicable_licenses: ["Android-Apache-2.0"],
- }
- cc_library {
- srcs: [
- "BufferAllocator.cpp",
- "BufferAllocatorWrapper.cpp",
- ],
- name: "libdmabufheap",
- vendor_available: true,
- vndk: {
- enabled: true,
- support_system_process: true,
- },
- // Added because codec2 is double_loadable.
- // See b/147147883, b/147147992
- double_loadable:true,
- apex_available: [
- "//apex_available:platform",
- "//apex_available:anyapex",
- ],
- min_sdk_version: "29",
- cflags: [
- "-Wall",
- "-Werror",
- ],
- local_include_dirs: [
- "include",
- ],
- export_include_dirs: [
- "include",
- ],
- static_libs: [
- "libbase",
- "libion",
- "libutils",
- ],
- shared_libs: [
- "libcutils",
- "liblog",
- ],
- export_static_lib_headers: [
- "libbase",
- "libion",
- ],
- }
复制代码
BufferAllocator.cpp
- /*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #define LOG_TAG "DMABUFHEAPS"
- #include <BufferAllocator/BufferAllocator.h>
- #include <errno.h>
- #include <fcntl.h>
- #include <ion/ion.h>
- #include <linux/dma-buf.h>
- #include <linux/dma-heap.h>
- #include <linux/ion_4.12.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <unistd.h>
- #include <shared_mutex>
- #include <string>
- #include <unordered_set>
- #include <android-base/logging.h>
- #include <android-base/unique_fd.h>
- #define ATRACE_TAG ATRACE_TAG_ALWAYS
- #include <cutils/trace.h>
- #include <sys/stat.h>
- static constexpr char kDmaHeapRoot[] = "/dev/dma_heap/";
- static constexpr char kIonDevice[] = "/dev/ion";
- static constexpr char kIonSystemHeapName[] = "ion_system_heap";
- void BufferAllocator::LogInterface(const std::string& interface) {
- if (!logged_interface_) {
- LOG(INFO) << "Using : " << interface;
- logged_interface_ = true;
- }
- }
- int BufferAllocator::OpenDmabufHeap(const std::string& heap_name) {
- std::shared_lock<std::shared_mutex> slock(dmabuf_heap_fd_mutex_);
- /* Check if heap has already been opened. */
- auto it = dmabuf_heap_fds_.find(heap_name);
- if (it != dmabuf_heap_fds_.end())
- return it->second;
- slock.unlock();
- /*
- * Heap device needs to be opened, use a unique_lock since dmabuf_heap_fd_
- * needs to be modified.
- */
- std::unique_lock<std::shared_mutex> ulock(dmabuf_heap_fd_mutex_);
- /*
- * Check if we already opened this heap again to prevent racing threads from
- * opening the heap device multiple times.
- */
- it = dmabuf_heap_fds_.find(heap_name);
- if (it != dmabuf_heap_fds_.end()) return it->second;
- std::string heap_path = kDmaHeapRoot + heap_name;
- int fd = TEMP_FAILURE_RETRY(open(heap_path.c_str(), O_RDONLY | O_CLOEXEC));
- if (fd < 0) return -errno;
- LOG(INFO) << "Using DMA-BUF heap named: " << heap_name;
- auto ret = dmabuf_heap_fds_.insert({heap_name, android::base::unique_fd(fd)});
- CHECK(ret.second);
- return fd;
- }
- void BufferAllocator::QueryIonHeaps() {
- uses_legacy_ion_iface_ = ion_is_legacy(ion_fd_);
- if (uses_legacy_ion_iface_) {
- LogInterface("Legacy ion heaps");
- MapNameToIonMask(kDmabufSystemHeapName, ION_HEAP_SYSTEM_MASK, ION_FLAG_CACHED);
- MapNameToIonMask(kDmabufSystemUncachedHeapName, ION_HEAP_SYSTEM_MASK);
- return;
- }
- int heap_count;
- int ret = ion_query_heap_cnt(ion_fd_, &heap_count);
- if (ret == 0) {
- ion_heap_info_.resize(heap_count, {});
- ret = ion_query_get_heaps(ion_fd_, heap_count, ion_heap_info_.data());
- }
- // Abort if heap query fails
- CHECK(ret == 0)
- << "Non-legacy ION implementation must support heap information queries";
- LogInterface("Non-legacy ION heaps");
- /*
- * No error checking here, it is possible that devices may have used another name for
- * the ion system heap.
- */
- MapNameToIonName(kDmabufSystemHeapName, kIonSystemHeapName, ION_FLAG_CACHED);
- MapNameToIonName(kDmabufSystemUncachedHeapName, kIonSystemHeapName);
- }
- BufferAllocator::BufferAllocator() {
- ion_fd_.reset(TEMP_FAILURE_RETRY(open(kIonDevice, O_RDONLY| O_CLOEXEC)));
- if (ion_fd_ >= 0)
- QueryIonHeaps();
- }
- int BufferAllocator::MapNameToIonMask(const std::string& heap_name, unsigned int ion_heap_mask,
- unsigned int ion_heap_flags) {
- if (!ion_heap_mask)
- return -EINVAL;
- IonHeapConfig heap_config = { ion_heap_mask, ion_heap_flags };
- std::unique_lock<std::shared_mutex> ulock(heap_name_to_config_mutex_);
- heap_name_to_config_[heap_name] = heap_config;
- return 0;
- }
- int BufferAllocator::GetIonHeapIdByName(const std::string& heap_name, unsigned int* heap_id) {
- for (auto& it : ion_heap_info_) {
- if (heap_name == it.name) {
- *heap_id = it.heap_id;
- return 0;
- }
- }
- LOG(ERROR) << "No ion heap of name " << heap_name << " exists";
- return -EINVAL;
- }
- int BufferAllocator::MapNameToIonName(const std::string& heap_name,
- const std::string& ion_heap_name,
- unsigned int ion_heap_flags) {
- unsigned int ion_heap_id = 0;
- auto ret = GetIonHeapIdByName(ion_heap_name, &ion_heap_id);
- if (ret < 0)
- return ret;
- unsigned int ion_heap_mask = 1 << ion_heap_id;
- IonHeapConfig heap_config = { ion_heap_mask, ion_heap_flags };
- std::unique_lock<std::shared_mutex> ulock(heap_name_to_config_mutex_);
- heap_name_to_config_[heap_name] = heap_config;
- return 0;
- }
- int BufferAllocator::MapNameToIonHeap(const std::string& heap_name,
- const std::string& ion_heap_name,
- unsigned int ion_heap_flags,
- unsigned int legacy_ion_heap_mask,
- unsigned int legacy_ion_heap_flags) {
- /* if the DMA-BUF Heap exists, we can ignore ion mappings */
- int ret = OpenDmabufHeap(heap_name);
- if (ret >= 0)
- return 0;
- /* If ION support is not detected, ignore the mappings */
- if (ion_fd_ < 0) return 0;
- if (uses_legacy_ion_iface_ || ion_heap_name == "") {
- ret = MapNameToIonMask(heap_name, legacy_ion_heap_mask, legacy_ion_heap_flags);
- } else if (!ion_heap_name.empty()) {
- ret = MapNameToIonName(heap_name, ion_heap_name, ion_heap_flags);
- }
- return ret;
- }
- int BufferAllocator::GetIonConfig(const std::string& heap_name, IonHeapConfig& heap_config) {
- int ret = 0;
- std::shared_lock<std::shared_mutex> slock(heap_name_to_config_mutex_);
- auto it = heap_name_to_config_.find(heap_name);
- if (it != heap_name_to_config_.end()) {
- heap_config = it->second;
- return ret;
- }
- slock.unlock();
- if (uses_legacy_ion_iface_) {
- ret = -EINVAL;
- } else {
- unsigned int heap_id;
- ret = GetIonHeapIdByName(heap_name, &heap_id);
- if (ret == 0) {
- heap_config.mask = 1 << heap_id;
- heap_config.flags = 0;
- /* save it so that this lookup does not need to happen again */
- std::unique_lock<std::shared_mutex> ulock(heap_name_to_config_mutex_);
- heap_name_to_config_[heap_name] = heap_config;
- }
- }
- if (ret)
- LOG(ERROR) << "No ion heap of name " << heap_name << " exists";
- return ret;
- }
- int BufferAllocator::DmabufAlloc(const std::string& heap_name, size_t len) {
- int fd = OpenDmabufHeap(heap_name);
- if (fd < 0) return fd;
- struct dma_heap_allocation_data heap_data{
- .len = len, // length of data to be allocated in bytes
- .fd_flags = O_RDWR | O_CLOEXEC, // permissions for the memory to be allocated
- };
- auto ret = TEMP_FAILURE_RETRY(ioctl(fd, DMA_HEAP_IOCTL_ALLOC, &heap_data));
- if (ret < 0) {
- PLOG(ERROR) << "Unable to allocate from DMA-BUF heap: " << heap_name;
- return ret;
- }
- return heap_data.fd;
- }
- int BufferAllocator::IonAlloc(const std::string& heap_name, size_t len,
- unsigned int heap_flags, size_t legacy_align) {
- IonHeapConfig heap_config;
- auto ret = GetIonConfig(heap_name, heap_config);
- if (ret)
- return ret;
- int alloc_fd = -1;
- unsigned int flags = heap_config.flags | heap_flags;
- ret = ion_alloc_fd(ion_fd_, len, legacy_align, heap_config.mask, flags, &alloc_fd);
- if (ret) {
- PLOG(ERROR) << "allocation fails for ion heap with mask: " << heap_config.mask
- << " and flags: " << flags;
- return ret;
- }
- return alloc_fd;
- }
- #define TRACE_MARKER_PATH "/sys/kernel/tracing/trace_marker"
- void trace_kernel_buffer(const char *fmt, ...)
- {
- char buf[PAGE_SIZE];
- va_list ap;
- static int fd = -1;
- ssize_t len, ret;
- if (fd < 0) {
- fd = open(TRACE_MARKER_PATH, O_WRONLY | O_CLOEXEC);
- if (fd < 0) {
- return;
- }
- }
- va_start(ap, fmt);
- vsnprintf(buf, sizeof(buf), fmt, ap);
- va_end(ap);
- len = strlen(buf);
- ret = TEMP_FAILURE_RETRY(write(fd, buf, len));
- if (ret < 0) {
- if (errno != EBADF) {
- close(fd);
- fd = -1;
- }
- return;
- }
- }
- int BufferAllocator::Alloc(const std::string& heap_name, size_t len,
- unsigned int heap_flags, size_t legacy_align) {
- int fd = DmabufAlloc(heap_name, len);
- if (fd < 0)
- fd = IonAlloc(heap_name, len, heap_flags, legacy_align);
- struct stat statbuf;
- char trace_name[128];
- fstat(fd, &statbuf);
- sprintf(trace_name,"BufferAllocator inode:%llu", statbuf.st_ino);
- // ATRACE_INT("BufferAllocator", statbuf.st_ino);
- ATRACE_BEGIN(trace_name);
- ATRACE_END();
- //trace_kernel_buffer(trace_name);
- return fd;
- }
- int BufferAllocator::AllocSystem(bool cpu_access_needed, size_t len, unsigned int heap_flags,
- size_t legacy_align) {
- if (!cpu_access_needed) {
- /*
- * CPU does not need to access allocated buffer so we try to allocate in
- * the 'system-uncached' heap after querying for its existence.
- */
- static bool uncached_dmabuf_system_heap_support = [this]() -> bool {
- auto dmabuf_heap_list = this->GetDmabufHeapList();
- return (dmabuf_heap_list.find(kDmabufSystemUncachedHeapName) != dmabuf_heap_list.end());
- }();
- if (uncached_dmabuf_system_heap_support)
- return DmabufAlloc(kDmabufSystemUncachedHeapName, len);
- static bool uncached_ion_system_heap_support = [this]() -> bool {
- IonHeapConfig heap_config;
- auto ret = this->GetIonConfig(kDmabufSystemUncachedHeapName, heap_config);
- return (ret == 0);
- }();
- if (uncached_ion_system_heap_support)
- return IonAlloc(kDmabufSystemUncachedHeapName, len, heap_flags, legacy_align);
- }
- /*
- * Either 1) CPU needs to access allocated buffer OR 2) CPU does not need to
- * access allocated buffer but the "system-uncached" heap is unsupported.
- */
- return Alloc(kDmabufSystemHeapName, len, heap_flags, legacy_align);
- }
- int BufferAllocator::LegacyIonCpuSync(unsigned int dmabuf_fd,
- const CustomCpuSyncLegacyIon& legacy_ion_cpu_sync_custom,
- void *legacy_ion_custom_data) {
- if (!legacy_ion_cpu_sync_custom)
- return ion_sync_fd(ion_fd_, dmabuf_fd);
- // dup ion_fd_ so that we retain its ownership.
- int new_ion_fd = TEMP_FAILURE_RETRY(dup(ion_fd_.get()));
- if (new_ion_fd < 0) {
- PLOG(ERROR) << "Unable to dup ion fd. error: " << new_ion_fd;
- return new_ion_fd;
- }
- int ret = legacy_ion_cpu_sync_custom(new_ion_fd, dmabuf_fd, legacy_ion_custom_data);
- close(new_ion_fd);
- return ret;
- }
- int BufferAllocator::DoSync(unsigned int dmabuf_fd, bool start, SyncType sync_type,
- const CustomCpuSyncLegacyIon& legacy_ion_cpu_sync_custom,
- void *legacy_ion_custom_data) {
- if (uses_legacy_ion_iface_) {
- return LegacyIonCpuSync(dmabuf_fd, legacy_ion_cpu_sync_custom,
- legacy_ion_custom_data);
- }
- struct dma_buf_sync sync = {
- .flags = (start ? DMA_BUF_SYNC_START : DMA_BUF_SYNC_END) |
- static_cast<uint64_t>(sync_type),
- };
- return TEMP_FAILURE_RETRY(ioctl(dmabuf_fd, DMA_BUF_IOCTL_SYNC, &sync));
- }
- int BufferAllocator::CpuSyncStart(unsigned int dmabuf_fd, SyncType sync_type,
- const CustomCpuSyncLegacyIon& legacy_ion_cpu_sync_custom,
- void *legacy_ion_custom_data) {
- int ret = DoSync(dmabuf_fd, true /* start */, sync_type, legacy_ion_cpu_sync_custom,
- legacy_ion_custom_data);
- if (ret) PLOG(ERROR) << "CpuSyncStart() failure";
- return ret;
- }
- int BufferAllocator::CpuSyncEnd(unsigned int dmabuf_fd, SyncType sync_type,
- const CustomCpuSyncLegacyIon& legacy_ion_cpu_sync_custom,
- void* legacy_ion_custom_data) {
- int ret = DoSync(dmabuf_fd, false /* start */, sync_type, legacy_ion_cpu_sync_custom,
- legacy_ion_custom_data);
- if (ret) PLOG(ERROR) << "CpuSyncEnd() failure";
- return ret;
- }
- std::unordered_set<std::string> BufferAllocator::GetDmabufHeapList() {
- std::unordered_set<std::string> heap_list;
- std::unique_ptr<DIR, int (*)(DIR*)> dir(opendir(kDmaHeapRoot), closedir);
- if (dir) {
- struct dirent* dent;
- while ((dent = readdir(dir.get()))) {
- if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) continue;
- heap_list.insert(dent->d_name);
- }
- }
- return heap_list;
- }
- bool BufferAllocator::CheckIonSupport() {
- static bool ion_support = (access(kIonDevice, R_OK) == 0);
- return ion_support;
- }
复制代码
p1_trace.sh
- adb wait-for-device
- adb root
- adb shell setenforce 0
- adb shell "echo 0 > sys/kernel/tracing/tracing_on"
- adb shell setprop vendor.camera.sensor.logsystem 0
- #https://source.n.xiaomi.com/opengrok-s/xref/pangu_8450-s-combine/frameworks/native/cmds/atrace/atrace.cpp
- #adb shell perfetto --out /sdcard/camera_perf.perfetto-trace --app com.android.camera --buffer 300mb --time 5s sched freq idle ss am wm pm gfx view binder_driver hal dalvik camera video audio input res memory bionic
- #adb shell perfetto --out /sdcard/camera_perf.perfetto-trace --buffer 100mb --time 5s sched freq idle ss am wm pm gfx view binder_driver hal dalvik camera input res memory bionic
- cat perfetto_config.pbtx | adb shell "perfetto \
- -c - --txt \
- -o /sdcard/camera_perf.perfetto-trace"
- adb pull sdcard/camera_perf.perfetto-trace
复制代码
可以抓到如下trace:
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |