3

我有一个不断创建和删除网络命名空间的 linux 应用程序(用 C 编写)。通常一个创建/删除周期大约需要 300 毫秒。

在性能调查期间,我对程序运行了 strace 以找出哪个系统调用花费的时间最多。从 strace 输出来看,似乎第一次调用 unshare 在我的系统上只需要 4 毫秒,但随后的调用需要接近 200 毫秒。

strace -p <pid> -T
unshare(CLONE_NEWNET)                   = 0 <0.004150>
unshare(CLONE_NEWNET)                   = 0 <0.192055>
unshare(CLONE_NEWNET)                   = 0 <0.192872>
unshare(CLONE_NEWNET)                   = 0 <0.190303>
unshare(CLONE_NEWNET)                   = 0 <0.193062>

该程序的结构使得在循环(内部控制循环)开始时,它创建一个网络命名空间并在循环结束时删除命名空间。

只是为了试验,我修改了我的应用程序,使其在控制周期结束时不删除网络命名空间——只创建新的网络命名空间,但从不删除它们。这显着提高了性能,并且我在随后的 unshare 系统调用调用中没有任何延迟。每个 unshare 系统调用需要 2-3 毫秒。

strace -p <pid> -T    
unshare(CLONE_NEWNET)                   = 0 <0.003102>
unshare(CLONE_NEWNET)                   = 0 <0.002980>
unshare(CLONE_NEWNET)                   = 0 <0.003070>
unshare(CLONE_NEWNET)                   = 0 <0.003124>
unshare(CLONE_NEWNET)                   = 0 <0.002952>

显然,删除网络命名空间会以某种方式影响/延迟随后的网络命名空间创建。

这里会发生什么?我该如何进一步调试呢?

我正在使用 linux 内核 3.12.9-301.fc20.x86_64。

4

1 回答 1

3

Linux ftrace 对于调试/分析系统调用非常有用。

参考以下文章

  1. http://lwn.net/Articles/365835/
  2. http://lwn.net/Articles/366796/

ftrace-cmd ( http://lwn.net/Articles/410200/ ) 为快速调试提供了方便的前端。然而,对于细粒度的调试,本机 ftrace 接口更好并且相当简单。

什么对我有用——

  1. 检测代码以仅在感兴趣的区域中启用/禁用跟踪点。这基本上涉及将“1”(启用)或“0”(禁用)写入 debug-fs 下的文件“tracing-on”。
  2. 将应用程序 pid 插入到 debug-fs 下的文件“set_ftrace_pid”中。
  3. 在 set_trace_filter 中添加一个或多个系统调用。可用符号位于 debug-fs 下的文件 available_filter_function 中。
  4. 使用您最喜欢的跟踪器来归档 current_tracer。我使用了function_graph。

请注意,第 1 步和第 2 步不是强制性的,但它有助于过滤掉外界的大量噪音并获得与您正在调查的内容相关的数据。

总之,ftrace规则!!!

于 2015-03-03T19:30:26.560 回答