Debugging 使用usbmon和ftrace的可靠Linux内核时间戳(或其调整)?

Debugging 使用usbmon和ftrace的可靠Linux内核时间戳(或其调整)?,debugging,linux-kernel,timestamp,Debugging,Linux Kernel,Timestamp,我试图检查一个使用usb的内核模块,因此我正在从模块本身使用trace_printk向ftrace写入一条消息;然后我想检查在那之后USB批量输出URB提交何时出现在系统中 问题是在我的UbuntuLucid11.04(内核2.6.38-16)上,ftrace中只有local和global时钟,尽管它们的分辨率与usbmon的时间戳相同(微秒),但它们的值差别很大 因此,我不知道还有什么更好的方法(因为我找不到其他地方谈论这个),我所做的是尝试使用cat将usbmon重定向到trace\u ma

我试图检查一个使用usb的内核模块,因此我正在从模块本身使用
trace_printk
ftrace
写入一条消息;然后我想检查在那之后USB批量输出URB提交何时出现在系统中

问题是在我的UbuntuLucid11.04(内核2.6.38-16)上,
ftrace
中只有
local
global
时钟,尽管它们的分辨率与usbmon的时间戳相同(微秒),但它们的值差别很大

因此,我不知道还有什么更好的方法(因为我找不到其他地方谈论这个),我所做的是尝试使用
cat
usbmon
重定向到
trace\u marker

# ... activate ftrace here ...
usbpid=$(sudo bash -c 'cat /sys/kernel/debug/usb/usbmon/2u > /sys/kernel/debug/tracing/trace_marker & echo $!')
sleep 3 # do test, etc.
sudo kill $usbpid
# ... deactivate ftrace here...
。。。然后,当我从
/sys/kernel/debug/tracing/trace
读取时,我会得到一个带有问题时间戳的日志(见下文)。所以我想知道的是:

  • 有没有办法使
    usbmon
    的消息直接出现在
    /debug/tracing/trace
    中,而不是出现在
    /debug/usb/usbmon/2u
    中?(我看不出来,但我想确认一下)
  • 如果没有,是否有更好的方法“直接”重定向
    /sys/kernel/debug/usb/usbmon/2u
    的输出,而不存在
    cat
    和/或shell重定向的任何可能的开销/缓冲问题
  • 如果没有,是否有某种算法,我可以使用额外的
    usbmon
    时间戳,以某种方式“纠正”这些事件在内核时间戳域中的位置?(见下面的示例)

下面是我得到的
/sys/kernel/debug/tracing/trace
日志的一个简短示例片段:

      <idle>-0     [000] 44989.403572: my_kernel_function: 1 00 00 64 1 64 5
       <...>-29765 [000] 44989.403918: my_kernel_function: 1 00 00 64 2 128 2
       <...>-29787 [000] 44989.404202: 0: f1f47280 3237249791 S Bo:2:002:2 -115 64 = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
       <...>-29787 [000] 44989.404234: 0: f1f47080 3237250139 S Bo:2:002:2 -115 64 = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
      <idle>-0     [000] 44989.404358: my_kernel_function: 1 00 00 64 3 192 4
       <...>-29787 [000] 44989.404402: 0: f1f47c00 3237250515 S Bo:2:002:2 -115 64 = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
因此,从内核时间戳判断,在事件(3)和事件(4)之间有32μs过期-但是从
usbmon
时间戳判断,在相同的事件之间有348μs过期!现在该相信谁

现在,如果我们假设
usbmon
时间戳对于这些消息更为正确,假设它们在进入
ftrace
缓冲区之前就已经被“打印”了,那么我们可以假设第一条usb消息(3)可能在(1)执行之后就被调度了,但是有什么东西抢占了它——因此第二条USB消息(4)触发了
ftrace
缓冲区中(3)和(4)的“打印输出”(或者更确切地说是“输入”)(这就是为什么它们的内核时间戳如此紧密地连在一起?)

因此,如果我假设(4)是更正确的,我可以尝试将(3)推回348μs:

(1) 44989.403572 MYF  0
(3) 44989.403854 USB  |           0          3237.249791  0
(2) 44989.403918 MYF  0.000346    |                       |
(4) 44989.404234 USB  |           0.000380   3237.250139  0.000348
(5) 44989.404358 MYF  0.000440    |                       |
(6) 44989.404402 USB              0.000168   3237.250515  0.000376

。。。对于第一个和第二个MYF/USB对(如果它们确实是这样的话),这种情况看起来更好(现在USB在MYF后发射282μs、316μs和44μs);但是第三步并不匹配,等等。。。无法真正想出一种算法来帮助我根据
usbmon
时间戳中的数据调整USB事件位置…

虽然将usbmon输出重定向到ftrace的最佳方法仍然是一个悬而未决的问题,但我得到了一个关于从该线程关联其时间戳的答案:

你可以打以下电话 获取usbmon样式时间戳值的子例程,然后 添加到ftrace消息或仅打印在内核日志中:

#包括
静态无符号usbmon_时间戳(void)
{
结构timeval-tval;
未签名邮票;
do_gettimeofday(&tval);
stamp=tval.tv_sec&0xFFF;
邮票=邮票*1000000+tval.tv_usec;
返回印章;
}
比如说,

pr_info(“usbmon时间为:%u\n”,usbmon_timestamp());
(1) 44989.403572 MYF  0
(3) 44989.403854 USB  |           0          3237.249791  0
(2) 44989.403918 MYF  0.000346    |                       |
(4) 44989.404234 USB  |           0.000380   3237.250139  0.000348
(5) 44989.404358 MYF  0.000440    |                       |
(6) 44989.404402 USB              0.000168   3237.250515  0.000376