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

时间:2013-12-06 06:55:11

标签: debugging linux-kernel timestamp

我正在尝试检查使用usb的内核模块,因此我从模块本身使用ftracetrace_printk写了一条消息;然后我想检查一下USB Bulk Out URB Submit什么时候出现在系统中。

问题在于我的Ubuntu Lucid 11.04(内核2.6.38-16),local中只有globalftrace个时钟 - 尽管它们的分辨率是相同的(微秒)作为usbmon的时间戳,它们的值差别很大。

所以不知道更好(因为我在其他任何地方都没有发现这个问题),我所做的是尝试使用usbmontrace_marker重定向到cat

# ... 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

因此,当内核时间戳为44989.404202时,usbmon时间戳为3237.249791(= 3237249791 / 1e6);秒和微秒部分都不匹配。为了使眼睛更容易一些,这里只有相同的片段,只剩下时间信息:

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

因此,根据内核时间戳判断,事件(3)和事件(4)之间的时间间隔为32μs - 但是根据usbmon时间戳判断,相同事件之间的时间间隔为348μs!谁现在相信?!

现在,如果我们假设usbmon时间戳对于那些消息更正确,假设它们在它们最终开始于ftrace缓冲区之前被“打印” - 我们可以假设第一个usb消息(3)可能在(1)执行后立即安排,但有些东西抢占了它 - 因此第二个USB消息(4)触发了(3)和(3)的“打印输出”(或更确切地说,“输入”) (4)在ftrace缓冲区(这就是为什么它们的内核时间戳如此紧密相连?)

所以,如果我假设(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

...而且那种看起来更好(现在USB现在可以在MYF之后激发282μs,316μs和44μs) - 用于第一和第二个MYF / USB对(如果它确实是这样的话);但是第三步并没有真正匹配,依此类推......真的不能想到一个算法来帮助我根据usbmon时间戳中的数据调整USB事件位置......

1 个答案:

答案 0 :(得分:0)

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

Using both usbmon and ftrace? [linux-usb mailing list]

  

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

     
#include <linux/time.h>

static unsigned usbmon_timestamp(void)
{
  struct timeval tval;
  unsigned stamp;

  do_gettimeofday(&tval);
  stamp = tval.tv_sec & 0xFFF;
  stamp = stamp * 1000000 + tval.tv_usec;
  return stamp;
}
     

例如,

     
pr_info("The usbmon time is: %u\n", usbmon_timestamp());