【发布时间】:2021-01-19 18:46:46
【问题描述】:
我希望通过 FreeBSD 来改进界面破坏时间。在我的运行 -CURRENT 的测试机器上销毁数千个接口需要几分钟时间,虽然 - 不可否认 - 我的用例可能是一个不寻常的用例,但我想了解是什么让系统花费了这么长时间。
根据我最初的观察,我能够确定大部分时间都花在了 if_detach_internal() 内部的某个地方等待。所以为了分析这个函数,我想出了下面的 DTrace 脚本:
#!/usr/sbin/dtrace -s
#pragma D option quiet
#pragma D option dynvarsize=256m
fbt:kernel:if_detach_internal:entry
{
self->traceme = 1;
t[probefunc] = timestamp;
}
fbt:kernel:if_detach_internal:return
{
dt = timestamp - t[probefunc];
@ft[probefunc] = sum(dt);
t[probefunc] = 0;
self->traceme = 0;
}
fbt:kernel::entry
/self->traceme/
{
t[probefunc] = timestamp;
}
fbt:kernel::return
/self->traceme/
{
dt = timestamp - t[probefunc];
@ft[probefunc] = sum(dt);
t[probefunc] = 0;
}
通过连接到entry 和return fbt 探针,我期望获得if_detach_internal() 调用的每个函数的函数名称和累积执行时间列表(无论堆栈深度如何),并过滤其他的。
然而,我得到的是这样的(破坏 250 个接口):
callout_when 1676 sched_load 1779 if_rele 1801 [...] rt_unlinkrte 10296062843 sched_switch 10408456866 rt_checkdelroute 11562396547 rn_walktree 12404143265 rib_walk_del 12553013469 if_detach_internal 24335505097 uma_zfree_arg 25045046322788 intr_event_schedule_thread 58336370701120 swi_sched 83355263713937 spinlock_enter 116681093870088 [...] 自旋锁退出 4492719328120735 cpu_search_lowest 16750701670277714至少一些函数的时间信息似乎是有意义的,但我希望if_detach_internal() 是列表中的最后一个条目,没有什么比这更长的时间了,因为这个函数位于调用的顶部我正在尝试分析的树。
显然,情况并非如此,因为我还在以看似疯狂的执行时间测量其他功能(uma_zfree_arg()、swi_sched() 等)。这些结果完全摧毁了我对 DTrace 在这里告诉我的其他一切的信任。
我错过了什么?这种方法听起来好吗?
【问题讨论】:
标签: kernel profiling freebsd dtrace