Android dmabuf_dump 如何工作的

本文是极客笔记出品,基于Android 13源码分析dmabuf_dump工具如何工作的。

DmaBuffer

DmaBuffer结构体定义如下:

DmaBuffer结构体

主要成员变量

  • 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的关系:

FD和Inode的关系

dmabuf_dump

直接执行dmabuf_dump会dump 整个系统的dmabuf 信息,代码执行流程如下:

dmabuf_dump

ReadDmaBufFdRefs

读取 /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

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里面去。

ReadDmaBufMapRefs

读取/proc/<pid>/maps下面的信息,只处理name以 /dmabuf 开头的map(也就是dmabuf的map)

注:如果从maps里面读到的inode不在fdrefs_ 里面,则会尝试到 /sys/kernel/dmabuf/buffers 里面去读该dmabuf的size,name,exp_name。 理论上不可能?

然后调用DmaBuffer的AddMapRef,添加到maprefs_ map里面去。

dmabuf_dump <pid>

流程跟dump 整個系统的dmabuf info类似,只是这里只dump指定pid的dmabuf info。

dambuf_dump_pid

dmabuf_dump -a

以Table[buffer x process]方式呈现dmabuf info。

跟dmabuf_dump相比,只是打印DmaBuffer的方式不一样。

dambuf_dump_a

dmabuf_dump -b

Dmabuf Sysfs Stats统计,有三个相关类:

定义 作用
DmabufSysfsStats dambuf_dump_b Dmabuf sysfs 统计信息每一块Dmabuf信息exporter信息总Dmabuf信息
DmabufInfo dambuf_dump_b 统计一块Dmabuf 信息,包括inode、exporter name、size
DmabufTotal dambuf_dump_b 统计整个系统的Dmabuf信息,包括buffer总数、buffer总大小

代码流程:

dambuf_dump_b

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程