如Perf报告分析所示,我的用户应用程序在从PCI设备读取数据时与内核交互,特别是通过名为pci_user_write_config_dword的函数.

我感兴趣的是探索这个函数,以理解它为什么调用_RAW_SPIN_LOCK_IRQ.

我一直无法找到该函数的实际实现. 我只在内核源代码中的以下位置找到了它的定义:https://elixir.bootlin.com/linux/v5.18.19/source/include/linux/pci.h#L1235

在Linux内核源代码中的哪里可以找到pci_user_write_config_dword的实现?

user_ application         [kernel.kallsyms]                        [k] do_syscall_64
            |          
            |--90.82%--do_syscall_64
            |          |          
            |          |--61.22%--__x64_sys_pwrite64
            |          |          |          
            |          |           --61.21%--ksys_pwrite64
            |          |                     |          
            |          |                      --61.05%--vfs_write
            |          |                                |          
            |          |                                 --60.87%--__vfs_write
            |          |                                           |          
            |          |                                            --60.79%--kernfs_fop_write
            |          |                                                      |          
            |          |                                                       --60.19%--sysfs_kf_bin_write
            |          |                                                                 |          
            |          |                                                                  --60.18%--pci_write_config
            |          |                                                                            |          
            |          |                                                                            |--57.62%--pci_user_write_config_dword
            |          |                                                                            |          |          
            |          |                                                                            |          |--35.92%--_raw_spin_lock_irq
            |          |                                                                            |          |          |          
            |          |                                                                            |          |           --35.88%--native_queued_spin_lock_slowpath

推荐答案

您可以在驱动程序/pci/acces.c中找到它:

    /* Returns 0 on success, negative values indicate error. */
#define PCI_USER_WRITE_CONFIG(size, type)                               \
int pci_user_write_config_##size                                        \
        (struct pci_dev *dev, int pos, type val)                        \
{                                                                       \
        int ret = PCIBIOS_SUCCESSFUL;                                   \
        if (PCI_##size##_BAD)                                           \
                return -EINVAL;                                         \
        raw_spin_lock_irq(&pci_lock);                           \
        if (unlikely(dev->block_cfg_access))                            \
                pci_wait_cfg(dev);                                      \
        ret = dev->bus->ops->write(dev->bus, dev->devfn,                \
                                        pos, sizeof(type), val);        \
        raw_spin_unlock_irq(&pci_lock);                         \
        return pcibios_err_to_errno(ret);                               \
}                                                                       \
EXPORT_SYMBOL_GPL(pci_user_write_config_##size);

您可能会发现搜索起来比平时更加困难,因为整个函数类(对字节、字、双字的操作)都是通过使用C预处理器的令牌连接特性加上一个方便的帮助器宏一次性定义的.这在代码方面是经济的,但可以击败代码浏览器,如CSCOPE.如果您不熟悉,可以阅读有关C令牌串联here的内容,并开始使用它来使您自己的内核代码更紧凑.

Linux相关问答推荐

在shell 中使用排除模式的grep

一个关于Linux中的fork()和物理地址的奇怪问题

如何在REPL控制台中使用PowerShell将特定的CSV列转换为TitleCase?

如何在 ERE 中结束这个正则表达式

删除一行和它之前的一行

如何在 Linux 上使用 -grep 构建过滤间隔的命令

在 cron 作业(job)中执行 PHP 脚本

何时判断 EINTR 并重复函数调用?

将以前忽略的目录添加到 Git 存储库

你如何在 C 中的 Linux 上进行非阻塞控制台 I/O?

Linux 的 TextMate 替代品

如何在python中找到文件或目录的所有者

在亚马逊 ec2 linux 微型实例上的 virtualenv 中安装 scipy 时遇到问题

自动化 Amazon EBS 快照 任何人在 linux 上都有一个好的脚本或解决方案

如何删除 Mercurial 存储库

使远程目录保持最新

Linux 中的直接内存访问

Linux 配置/制作,--prefix?

如何在 Linux 中查看日志(log)文件并在查看时应用自定义过滤器?

sed - 如何使用 sed 进行正则表达式组