trace rtsl的代码分析和使用

  1. 概念

Cyclictest是目前测试实时系统最主要和最常用的工具,但cyclictest有其局限性,它只提供了测试得到延时的结果,但从调度路径的角度来看,从中断到高优先级任务的调度要分成如下几部分,中断响应,任务抢占,任务切换等,期间还有关中断,关抢占等操作干扰,cyclictest的测试结果是不能给出这些步骤具体的执行时间以便分析延时产生的原因的。所以,cyclictest被定义为一个黑盒测试。

RTSL定义了系统调度路径中的如下参数:

poid  = Preemption or Interrupt disabled [ not to schedule ] window

paie  = Preemption and Interrupts enabled                               

psd   = Preemption disabled to schedule window                         

dst   = Delay of scheduling tail                                           

ifl   = Interference free latency

INT   = Interrupts

IRQ   = Maskable interrupts

NMI   = Non-maskable interrupts

oWCET = Observed Worst Case Execution Time

oMIAT = Observed Minimun Inter-arrival Time

并在kernel的tracer中定义了tracer的hook函数,用于获取上述过程的运行时间,进而用于分析,如cyclictest,测试中延时产生的具体原因,帮助开发者定位和修复问题。

2)Kernel

  • Tracepoint hook函数的注册

调用函数tracepoint_probe_register注册hook函数,涉及到的tracepoint包括irq_enable/disable,preempt_enable_disable,nmi_entry/exit, irq_handler_entry/exit等18个函数,这样,当系统运行到上述18个tracepoint,注册的hook函数也会被调用(trace point除了trace event定义的函数,如trace_irq_handler_entry之外,还可以 注册其他的钩子函数,当系统行至该trace point之后,hook函数被依次调用,见 include/linux/tracepoint.h中register_trace_##name和int __traceiter_##_name -- ++it_func_ptr)->func)

  • Poid的计算

在handle_irq_disable--handle_irq_disable_normal中记录poid计算的初始时间,这条代码路径是在该进程运行中,代码主动调用irq_disable的情况,poid的目的是记录代码的该类行为。

在handle_irq_enable--handle_irq_enable_normal中记录poid的结束时间,同时用结束时间减去初始时间,得到关中断的间隔,并调用trace_poid(duration)将信息输出到ftrace的ringbuffer,如果超过poid->max,则调用trace_max_poid(duration)将信息输出到ftrace的ringbuffer。

在进程运行期间,如果是系统接收到了外部的中断,进入中断处理例程而关闭中断,则进入代码handle_irq_disable--handle_irq_disable_irq,记录关中断的初始时间irq->delta_start,在中断例程结束后,调用代码handle_irq_enable--handle_irq_enable_irq--irq_occurence,记录中断例程的运行时间,并调用trace_irq_execution将信息输出到ftrace的ringbuffer,同时,调整poid,paie,dst的初始时间delta_start(delta_start += duration),减去中断例程时间对计算的干扰。

此外,handle_preempt_disable--handle_preempt_disable_nosched和handle_preempt_enable--handle_preempt_enable_nosched也同样记录poid的duration。

  • psd计算

handle_preempt_disable--handle_preempt_disable_sched是psd的起始时间,调度器在此时关闭抢占开始调度(_schedule),进入任务抢占和切换。

handle_preempt_enable--handle_preempt_enable_sched是psd的结束时间(开始),调度器在此时开启抢占,同时返回到下一个被调度的任务执行。

  • Paie的计算

当调度器运行preempt_schedule_irq--__schedule后会调用preempt_enable_sched,此时会进入handle_preempt_enable--handle_preempt_enable_sched记录paie,当抢占再次开启时,进入handle_preempt_disable--handle_preempt_disable_sched,结束paie计时,并记录duration。

  • Dst的计算

当运行preempt_schedule_irq--__schedule之前,会调用preempt_disable_sched,此时通过handle_preempt_disable_sched记录当前pid(dst->pid = current->pid),这个时段中断时打开的,如果此时有关闭中断的动作,则调用handle_irq_disable--handle_irq_disable_normal记录dst的起始时间(在dst->pid == current->pid的条件下),然后在handle_preempt_enable_sched记录dst的结束时间和duration。

  • Nmi的计算

handle_nmi_entry是nmi开始计时的初始时间,handle_nmi_exit是nmi的技术时间,其中的duration为nmi中断处理所经过的时长,trace_nmi_execution将该信息输出到ftrace的ringbuffer中,同时,poid,paie,dst,psd都要减去nmi的时长,irq的duration也要减去nmi的时长(irq处理期间nmi是有可能发生的),保证测量的准确性以及数据的纯度。

  • Irq的计算

在进程运行期间,如果是系统接收到了外部的中断,进入中断处理例程而关闭中断,则进入代码handle_irq_disable--handle_irq_disable_irq,记录关中断的初始时间irq->delta_start,在中断例程结束后,调用代码handle_irq_enable--handle_irq_enable_irq--irq_occurence,记录中断例程的运行时间,并调用trace_irq_execution将信息输出到ftrace的ringbuffer,同时,调整poid,paie,dst的初始时间delta_start(delta_start += duration),减去中断例程时间对计算的干扰。

总体来讲,rtsl所涉及到的监控参数,poid,irq,nmi的概念相对容易理解,paie,psd,dst的采样点可以从代码中理解,但其对于实时系统延时分析的作用,还需要进一步阅读调度器的代码,了解场景,进而理解其作用。

3)App

Rtsl用户空间包含两部分,python是应用逻辑部分,包括调用trace-cmd获取ftrace log,同时解析log中包含的上述各参数信息,并展示;trace_plugin是数据库部分,将上述分析过程的中间值和结果保存到数据库中,数据库为sqlite3.

具体使用方法见https://github.com/bristot/rtsl

4)备注

https://github.com/bristot/rtsl

https://bristot.me/demystifying-the-real-time-linux-latency

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值