性能:内核模块符号在分析中未显示出来。

3
加载和运行内核模块,然后通过perf进行性能分析。
$ perf record -a -g --call-graph dwarf sleep 30
$ perf report

我的内核模块的符号在性能报告中不存在。 尽管这些符号存在于/proc/kallsyms中。 而且该模块也不存在于perf buildid-list中。 根据this的回答,我尝试将该模块变成内核模块,但没有帮助。 可能有什么原因导致这种情况呢?

你的模块是否需要长时间计算或调用需要长时间计算的函数?如果在模块函数中没有进行性能分析采样,或者在通过你的模块函数调用的某个函数中也没有进行性能分析采样,那么在性能报告中将不会显示任何信息。 - osgx
我的函数运行时间足够长。我怎么知道呢?因为我从用户空间程序中运行了相同的函数,并在性能分析报告中看到了它的符号,占用了一定比例的CPU时间。我想知道是否有一种方法,perf无法访问我外部内核模块的符号? - Saty Anand
以下警告是否导致获取分析报告时出现问题?`/sbin/dhclient中未找到符号,也许需要安装一个调试包? /bin/kmod中未找到符号,也许需要安装一个调试包? 无法打开[thrUserCtrl],继续进行不带符号的操作 /usr/sbin/dnsmasq中未找到符号,也许需要安装一个调试包? - Saty Anand
Saty,那么模块本身有很长的函数吗?每个没有调试符号的DSO都有消息,大多数是用户空间程序,但'thrUserCtrl'是您的模块吗?Perf找不到它,它是否安装在/lib/modules/\uname -r`/extra中(https://wiki.centos.org/HowTos/BuildingKernelModules)?您的内核版本是什么(uname -a`)? - osgx
回答你的问题:是的,模块本身有很长的函数。是的,'thrUserCtrl' 是我的模块。不,我还没有在 /lib/modules/uname -r/extra 安装 I。内核版本是 3.13.0-32-generic。 - Saty Anand
1个回答

2
这条信息“Failed to open [thrUserCtrl],continuing without symbols”听起来像perf无法找到您的模块。尝试将其安装到系统中。
/lib/modules/`uname -r`/extra

https://wiki.centos.org/HowTos/BuildingKernelModules中所述,目录是指:

6. In this example, the file cifs.ko has just been created. 
 As root, copy the .ko file to the /lib/modules/<kernel-version>/extra/
 directory.
   [root@host linux-2.6.18.i686]# cp fs/cifs/cifs.ko /lib/modules/`uname -r`/extra

请在更改 /lib/modules 文件后不要忘记运行 depmod -a 命令。
此消息在 map__load 中生成:http://elixir.free-electrons.com/linux/v4.11/source/tools/perf/util/map.c#L284
int map__load(struct map *map)
{
    const char *name = map->dso->long_name;
    int nr;
    ...
    nr = dso__load(map->dso, map);
    if (nr < 0) {
        if (map->dso->has_build_id) {
         ...
        } else
            pr_warning("Failed to open %s", name);

        pr_warning(", continuing without symbols\n");
        return -1;

dso__load 函数返回错误时。

尝试使用--kallsyms=选项将kallsyms文件指定给perf report命令。 - osgx
正如它所说,将模块安装在'/lib/modules/uname -r/extra'中,这难道不是将模块作为内核的一部分吗?通过指定我的模块的.ko文件路径或类似的方式,perf无法对使用insmod加载的模块进行性能分析吗? - Saty Anand
我将模块复制到'/lib/modules/uname -r/extra'并使用modprobe加载它。现在我可以看到我的模块及其顶层函数(传递给线程的函数),但perf报告中仍然缺少其他函数(由线程函数调用的函数)的符号。 - Saty Anand
1
你好,你的模块的内部函数可能会被内联到顶层函数中(重新编译时禁用内联 -fno-inline 或不开启优化 -O0 可以看到所有函数)。现在你可以看到你的模块的函数并解决问题了。不,将其复制到额外位置并不会使模块成为内核的一部分。还不清楚perf如何搜索该模块,但可能insmod没有记录任何完整路径,或者它可能在更新的内核版本中起作用(在 http://elixir.free-electrons.com/linux/v3.13/source/tools/perf/util/dso.h#L24 中仅支持DSO_BINARY_TYPE__SYSTEM_PATH_KMODULE)。 - osgx

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接