3

我正在寻找将跟踪/日志记录挂钩插入到一些对性能非常敏感的驱动程序代码中开销最小的方法。这个日志记录的东西必须总是编译进去,但大多数时候什么都不做(但什么也不做非常快)。

没有什么比拥有一个全局开/关词更简单的了,做一个if(enabled){log()}. 但是,如果可能的话,我什至想避免每次我碰到一个钩子时加载那个词的成本。我突然想到,我可能会为此使用自修改代码——即,在我调用跟踪函数的任何地方,当我想禁用钩子时,我用 NOP 覆盖跳转,并在我想要时替换跳转启用它们。

一个快速的谷歌没有找到任何关于这方面的现有技术——有人做过吗?是否可行,是否有我没有预见到的主要绊脚石?

(Linux,x86_64)

4

4 回答 4

4

如果您编译的驱动程序突然变大两倍,这有关系吗?

构建两个代码路径——一个有日志记录,一个没有。使用全局函数指针跳转到对性能敏感的部分,并根据需要覆盖它们。

于 2010-12-29T01:33:55.197 回答
4

是的,该技术已在 Linux 内核中实现,目的完全相同(跟踪挂钩)。

有关起点,请参阅有关跳转标签的 LWN 文章。

实际上并没有任何主要的绊脚石,而是一些次要的障碍:多线程进程(在启用或禁用代码时必须停止所有其他线程);不连贯的指令缓存(您需要确保在每个内核上刷新 I-cache)。

于 2010-12-29T04:31:47.740 回答
0

如果有办法以某种方式声明一个全局寄存器,您可以在每个入口点从外部将您的单词值加载到您的驱动程序中,然后检查该寄存器。当然,那么您将拒绝优化器使用该寄存器,这可能会产生一些令人不快的性能后果。

于 2010-12-29T01:26:30.210 回答
0

我写的不是关于这是否可能的问题,而是你是否获得了任何重要的东西。

一方面,您不想在每次出现日志记录可能性时测试“启用日志记录”,另一方面需要测试“启用日志记录”并用是或否代码覆盖代码。或者你的司机是否“记得”上次不是,因为这次请求没有,所以不需要做任何事情?

与每次测试相比,必要的逻辑似乎并不简单。

于 2011-01-24T03:32:24.200 回答