osnoise代码分析和rtla的使用

1,kernel -- osnoise

内核5.14-rc1引入了一个新的tracer,从一个线程的角度讲系统的噪声全部罗列出来,供开发者分析系统状况,其中所述的噪声包括:nmi,irq,softirq以及thread。代码位置在kernel/trace/trace_osnoise.c.

tracer osnoise工作原理如下:

  • 注册traceevent,包括thread_noise,softirq_noise,irq_noise,nmi_noise,sample_threshold (include/trace/events/osnoise.h)
  • 注册一个tracer -- register_tracer(&osnoise_tracer)
  • 获取系统的noise
  • 注册tracepoint irq_entry irq_exit的钩子函数

register_trace_irq_handler_entry(trace_irqentry_callback, NULL);

register_trace_irq_handler_entry(trace_irqentry_callback, NULL);

(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)

  • 在trace_irqentry_callback和trace_irqentry_callback中分别记录该中断的进出时间和运行时间,得到了系统的一次irq noise duration,同时调用trace_irq_noise将duration放到ftrace的ringbuffer中。
  • Thread noise调用register_trace_sched_switch来hook sched_switch
  • Softirq调用register_trace_softirq_entry和register_trace_softirq_exit
  • Nmi比较特殊,在ftrace_nmi_enter和ftrace_nmi_exit中直接调用trace_osnoise_callback获取nmi noise,并调用调用trace_nmi_noise将duration放到ftrace的ringbuffer中。
  • 此外,osnoise还创建了一个内核线程osnoise_main -- run_osnoise,在run_osnoise中做一个循环,根据循环开始和结束的时间,得到osnoise(irq,softirq,nmi,其他thread)的时间(如果没有noise,理论上两个时间基本相等,如果相差较大,说明run_osnoise线程在运行的过程中被打断了),如果osnoise超过设定的threshold,则调用trace_sample_threshold将该信息放到ftrace的ringbuffer中。
  • 最后在一次测量的周期结束后,调用latency_fsnotify通知rtla,在用户空间显示。
  • 用例:

echo osnoise > current_tracer

cat trace

# tracer: osnoise

#

#                                _-----=> irqs-off

#                               / _----=> need-resched

#                              | / _---=> hardirq/softirq

#                              || / _--=> preempt-depth                            MAX

#                              || /                                             SINGLE      Interference counters:

#                              ||||               RUNTIME      NOISE  %% OF CPU  NOISE    +-----------------------------+

#           TASK-PID      CPU# ||||   TIMESTAMP    IN US       IN US  AVAILABLE  IN US     HW    NMI    IRQ   SIRQ THREAD

#              | |         |   ||||      |           |             |    |            |      |      |      |      |      |

           <...>-4735    [000] .....   845.271294: 1000000       3842  99.61580    3306      1      0    360     71    147

           <...>-4736    [001] .....   845.271334: 1000000       2729  99.72710    1339      1      0    384     64    224

           <...>-4737    [002] .....   845.271399: 1000000       1638  99.83620     110      1      0    418     69    205

           <...>-4738    [003] .....   845.271990: 1000000       9167  99.08330    1945      1      0    392     63    258

           <...>-4735    [000] .....   846.271298: 1000000        233  99.97670      25      0      0    360     40    136

           <...>-4736    [001] .....   846.271335: 1000000        838  99.91620     114      0      0    383     37    227

echo osnoise > set_event

cat trace

# tracer: osnoise

#

#                                _-----=> irqs-off

#                               / _----=> need-resched

#                              | / _---=> hardirq/softirq

#                              || / _--=> preempt-depth                            MAX

#                              || /                                             SINGLE      Interference counters:

#                              ||||               RUNTIME      NOISE  %% OF CPU  NOISE    +-----------------------------+

#           TASK-PID      CPU# ||||   TIMESTAMP    IN US       IN US  AVAILABLE  IN US     HW    NMI    IRQ   SIRQ THREAD

#              | |         |   ||||      |           |             |    |            |      |      |      |      |      |

       osnoise/1-3479    [001] .....   751.215049: sample_threshold: start 751.214973595 duration 74929 ns interference 3

       osnoise/1-3479    [001] d.h..   751.215103: irq_noise: call_function_single:251 start 751.215102156 duration 423 ns

       osnoise/1-3479    [001] d.h..   751.218970: irq_noise: local_timer:236 start 751.218967753 duration 2237 ns

       osnoise/1-3479    [001] dNH..   751.218972: irq_noise: irq_work:246 start 751.218970522 duration 1122 ns

       osnoise/1-3479    [001] .Ns..   751.218972: softirq_noise:      RCU:9 start 751.218971991 duration 263 ns

       osnoise/1-3479    [001] .N...   751.218973: sample_threshold: start 751.218967499 duration 5124 ns interference 3

     kworker/1:1-50      [001] d....   751.218975: thread_noise: kworker/1:1:50 start 751.218973223 duration 1673 ns

总体来讲,单次osnoise信息由tracepoint获得,然后通过新定义的tracepoint打印到ftrace的ringbuffer中,统计信息(osnoise的次数)由run_osnoise获取,通过inotify传给应用程序显示。

2,Kernel -- timerlat

与osnoise一起,5.14-rc1同时还引入了一个新的tracer -- timerlat,timerlat在每一个cpu上启动了一个实时任务,像xenomai的测试工具latency一样,使用内核线程来测量系统的延时(cyclictest是在用户空间,相对与内核线程,调度的过程还包括系统调用的返回,work_pending, do_notify_resume等额外的工作)。

与cyclictest和latency不同的是,timerlat在每一次到时记录了两条数据,一个是在irq上下文(preempt rt)的时间信息或在softirq上下文的时间信息,另一个是timerlat实时任务的时间信息,该些信息通过trace_timerlat_sample打印到ftrace的ringbuffer中,同时通过latency_fsnotify发送给rtal。

Timerlat可以设置threshold,如果latency超过threshold,可以设置打印调用栈,供开发者分析。

3, App

Rtla应用是osnoise用户空间的工具程序,主要用于响应osnoise和timerlat通过latency_fsnotify上传的事件并显示信息。Rtla需要借助libtraceevent和libtracefs与osnoise和timerlat两个tracer交换数据。

该程序包含如下内容:

  • rtla osnoise top

获取并显示从latency_fsnotify -- osnoise_trace(由trace_osnoise_sample填充信息)得到的消息,所述信息包括sample数量,nmi/irq/softirq/thread的数量。信息显示如下:

duration:   0 07:00:04 | time is in us

CPU Period       Runtime        Noise  % CPU Aval   Max Noise   Max Single          HW          NMI          IRQ      Softirq       Thread

  0 #4           4000000       178880    95.52800      108642         8184           7            0         2111          646         2725

  1 #4           4000000       436602    89.08495      126965         8670           1            0         2178          659         5558

  2 #4           4000000       269811    93.25472      125137         6704           4            1         3431          826         4556

  3 #4           4000000       414924    89.62690      115139        10989           1            0         2106          656         4039

  • rtla osnoise hist

Histogram在cyclictest中表示为发生延时为X毫秒的次数,在osnoise hist中,rtla周期性的调用osnoise_read_trace_hist统计tracefs/event/osnoise/sample_threshold/hist信息,并通过osnoise_print_stats打印到console。同时,osnoise hist还可以设置latency的threshold,latency超过threshold则停止rtla并停止ftrace,这样ringbuffer的底部就保留了问题现场数据,这点与cyclictest -b参数功能相同。

信息显示如下:

RTLA osnoise histogram

# Time unit is microseconds (us)

# Duration:   0 07:00:09

Index   CPU-000   CPU-001   CPU-002   CPU-003

5           368       266       484       303

6           274       231       470       251

...

255           0         1         0         1

over:       281       441       299       281

count:     3673      3067      7658      2855

min:          5         5         5         5

avg:        109       202        32       137

max:      15992      8082      8289     10180

  • rtla timerlat top

获取并显示从latency_fsnotify -- timerlat_irq/timerlat_main(由trace_timerlat_sample填充信息)得到的消息,所述信息中断上下文和内核线程上下文中产生latency的最大最小和平均值。

信息显示如下:

                  Timer Latency                                              

  0 07:00:03   |          IRQ Timer Latency (us)        |         Thread Timer Latency (us)

CPU COUNT      |      cur       min       avg       max |      cur       min       avg       max

  0 #3652      |        2         0        14        83 |        7         1        27       987

  1 #3652      |        1         0        17       624 |        6         2        30       639

  2 #3652      |        2         0        16        63 |        7         2        28       121

  3 #3652      |        2         0        17        74 |        7         2        30        91

  • rtla timerlat hist

从timerlat得到timer_latency,并记录最大最小和平均值,周期性显示。

# Time unit is microseconds (us)

# Duration:   0 07:00:09

Index   IRQ-000   Thr-000   IRQ-001   Thr-001   IRQ-002   Thr-002   IRQ-003   Thr-003

0             9         0        11         0        32         0        13         0

1           274         0       281         0       773         0       572         0

...

141           0         0         0         0         0         1         0         0

over:         0         1         0         0         0         1         0         0

count:     9569      9569      9570      9570      9569      9569      9570      9570

min:          0         2         0         2         0         2         0         2

avg:         16        29        20        33         4        13         5        14

max:         77      1981        79       115        58      1966        77        84

rtls osnoise/timerlat有很多参数可选,具体信息可以使用rtla --help查阅。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值