实时Linux通信

对用于实时机器人应用程序的Linux通信堆栈的评估

本文的内容来自 https://arxiv.org/pdf/1808.10821.pdf上的 实时Linux通信:对用于实时机器人应用程序的Linux通信堆栈的评估与Carlos San VicenteGutiérrez,Lander Usategui San Juan和 Irati Zamalloa Ugarte 一起写作的同er

Linux网络堆栈传输路径
随着机器人系统变得更加分散,不同机器人模块之间的通信对于整体机器人控制的可靠性起着关键作用。 在本文中,我们将研究用于实时机器人应用程序的Linux通信堆栈。 我们评估Linux在多核嵌入式设备作为测试平台上基于UDP的通信的实时性能。 我们证明,在适当的配置下,Linux内核极大地增强了使用UDP协议进行通信的确定性。 此外,我们证明并发流量会破坏有限的等待时间,并提出了通过将实时应用程序和CPU中的相应中断分开的解决方案。

介绍

以太网通信标准因其普及性和降低的成本而被广泛用于机器人系统。 在实时通信方面,虽然以太网一直是流行的竞争者,但许多制造商还是选择了现场总线。 正如先前工作[1]所介绍的,我们开始观察到变化。 随着“时间敏感网络”(TSN)标准的到来,以太网有望在实时机器人应用中得到更广泛的采用。 当前有几种基于以太网协议的通信技术。 诸如Profinet RT [2]或Powerlink [3]之类的某些协议使用专门为协议1设计的网络堆栈。 其他协议,例如数据分布式服务(DDS)[4],OPC-UA [5]或Profinet,则建立在众所周知的TCP / IP和UDP / IP OSI层之上。 这有助于与通用传输协议进行互操作,并确保设备之间的高度兼容性。 但是,它们的相应网络堆栈和驱动程序通常没有针对实时通信进行优化。 与具有特定网络堆栈的其他以太网替代产品相比,实时性能受到限制。

在这项工作中,我们旨在测量和评估具有UDP和IP协议的Linux网络子系统的实时性能。 UDP由多种实时传输协议使用,例如实时发布订阅协议(RTPS)。 我们旨在确定在混合关键流量情况下哪种配置可提供更好的隔离。 为了实现实时性能,网络堆栈将部署在实时操作系统(RTOS)中。 对于Linux,标准内核不提供实时功能。 但是,使用实时抢占补丁程序(PREEMPT-RT),可以实现实时计算功能,如所示[6]。 尽管Linux网络子系统并未针对有限的最大延迟进行优化,但是通过这项工作,我们希望能够与PREEMPT-RT以及合适的配置实现合理的确定性通信。

在Linux中设置实时通信

实时抢占补丁(PREEMPT-RT)

当前,有多种方法可以将Linux用于实时应用程序。 常见的方法是将最关键的任务留给嵌入式RTOS,并向Linux提供最高级别的命令。 第二种方法是使用双内核方案,例如Xenomai [7]和RTAI [8],它们部署了与单独的Linux内核并行运行的微内核。 这种解决方案的问题在于它需要特殊的工具和库。

第三种方法是使用单个内核。 实时Linux(RTL)协作项目[9]是与此选项最相关的开源解决方案。 该项目基于PREEMPT-RT补丁,旨在创建一个可预测的确定性环境,将Linux内核转变为可行的实时平台。 RTL项目的最终目标是使PREEMPT-RT补丁主线化。 这项工作背后的重要性与基于Linux的RTOS的创建无关,而是为Linux内核提供实时功能。 主要好处是可以使用Linux标准工具和库而无需特定的实时API。 另外,Linux得到了广泛的使用并得到了强烈的支持,这有助于使OS保持新技术和功能的更新,这在较小的项目中常常由于资源限制而成为问题。

Linux网络架构

尽管可以使用自定义驱动程序或用户空间网络库绕过Linux网络堆栈,但我们对使用Linux网络堆栈很感兴趣。 主要是因为它更易于维护和与用户空间应用程序或通信中间件集成。 另外,Linux网络堆栈支持各种驱动程序,这些驱动程序允许在不同设备中部署应用程序。

Linux流量控制
网络子系统的一个重要模块是Linux内核数据包调度程序,它使用用户空间工具Linux Traffic Control(TC)进行配置[10]。 TC提供了控制已排队数据包发送和接收方式的机制。 它提供了一组功能,例如整形,调度,管制和丢弃网络流量。

Linux数据包调度程序模块的主要元素是排队规则(Qdisc),它是网络流量规则,用于创建队列和用于接收和传输的服务质量(QoS)规则。 有分别用于接收和发送的入口Qdisc和出口Qdisc。 出口Qdisc提供整形,调度和过滤功能,用于从网络协议层到网络接口环形缓冲区的数据传输。 另一方面,入口Qdisc为从网络接口环缓冲区到网络协议层的接收路径提供了过滤和丢弃功能(尽管通常较少使用)。

对于出口Qdisc,有两种基本类型的规则:无类Qdisc和有类Qdisc。 无类Qdisc不包含另一个Qdisc,因此只有一个排队级别。 无类Qdisc仅确定数据包是分类,延迟还是丢弃。 有类的Qdisc可以包含另一个Qdisc,因此可能会有多个队列。 在这种情况下,可能会有不同的过滤器来确定将从哪个Qdisc数据包发送出去。

Qdisc可用于避免传输路径上的非实时流量造成流量拥塞(不计数字)。 对于无类Qdisc,默认规则是PFIFO_FAST,它具有三个FIFO优先级带。 对于有类Qdisc,有PRIO qdisc可以包含任意数量的具有不同优先级的类。 还有用于多队列网络设备的特定出口Qdisc,例如MQPRIO Qdisc [11],它是一种队列规则,用于根据数据包的优先级将流量映射到硬件队列。 该Qdisc将使具有较高优先级的数据包出队,从而避免了传输路径中的竞争问题。 除了优先级Qdisc,通常还连接一个整形器以限制低优先级的业务带宽,例如“令牌桶过滤器” TBF Qdisc [12]。

最近,由于对在Linux网络堆栈中支持TSN的兴趣,新的Qdiscs已创建或正在开发中。 内核4.15中已包含IEEE 802.1Q-2014基于信用的整形器(CBS)[13] Qdisc。 CBS用于通过限制流量类别的数据速率来实施服务质量。 当前有两个Qdisc正在开发中,“最早发送时间优先(ETF)” [14]提供基于每个队列发送时间的调度,以及“时间感知优先级调度器”(TAPRIO)提供每个端口调度。 这些Qdisc将允许在软件中创建确定性调度,或者在支持的情况下将工作分担给网络硬件。

交通分类
为了将流量引导到Qdisc或环形缓冲区,通常必须通过将流量标记为优先级来对流量进行分类。 有几种方法来设置特定流量的优先级:a)使用套接字选项SO_PRIORITY和IP_TOS在用户空间中进行设置,b)使用iptables和c)使用net_prio cgroups。 设置流的优先级会将来自套接字(或应用程序)的流量映射到套接字缓冲区(SKB)优先级,这是内核网络层的内部优先级。 MQPRIO Qdisc使用SKB优先级将业务流映射到Qdisc的业务类。 同时,每个流量类别都映射到TX环形缓冲区。

网络硬IRQ线程和softirqs
在接收路径上,数据包的处理由内核中断处理机制和“新API”(NAPI)网络驱动程序驱动。 NAPI是一种旨在提高高网络负载性能的机制。 当有大量传入流量时,将产生大量中断。 当已经有许多数据包排队时,处理每个中断来处理数据包的效率不是很高。 因此,当检测到高带宽传入数据包时,NAPI使用中断缓解措施。 然后,内核切换到基于轮询的处理,并定期检查是否有排队的数据包。 当负载不足时,将再次重新启用中断。 总而言之,Linux内核默认情况下使用中断驱动模式,并且仅在传入数据包的流量超过特定阈值(称为网络接口的“权重”)时才切换到轮询模式。 这种方法在延迟和吞吐量之间做出折衷,效果很好,可以使其行为适应网络负载状态。 问题在于,例如当流量突发时,NAPI可能会引入额外的延迟。

PREEMPT-RT和普通内核如何处理中断以及因此如何在接收路径上处理数据包之间存在一些差异。 PREEMPT-RT的修改允许配置系统以改善网络堆栈的确定性。

在PREEMPT-RT中,大多数中断请求(IRQ)处理程序都必须在专门为该中断创建的线程中运行。 这些线程称为IRQ线程[15]。 将IRQ作为内核线程处理,可以分别管理优先级和CPU亲和力。 线程中运行的IRQ处理程序本身可以被中断,从而减少了由于中断引起的等待时间。 对于多队列NIC,网络接口的每个TX和RX队列都有一个IRQ,从而可以对每个队列的处理分别进行优先级排序。 例如,可以将一个队列用于实时流量,并将该队列的优先级提高到其他队列IRQ线程之上。

另一个重要的区别是执行softirq的上下文。 从版本3.6.1-rt1开始,软IRQ处理程序在引发该软IRQ [16]的线程的上下文中执行。 这意味着NET_RX软IRQ将通常在网络设备IRQ线程的上下文中执行,从而可以对网络处理上下文进行精细控制。 但是,如果网络IRQ线程被抢占或耗尽了NAPI权重时间片,则以ksoftirqd / n(其中n是CPU的逻辑数)执行该线程。

在ksoftirqd / n上下文中处理数据包对于实时性很麻烦,因为该线程被不同的进程用于延迟的工作,并且会增加延迟。 另外,由于ksoftirqd使用SCHED_OTHER策略运行,因此可以轻松地抢先执行线程。 实际上,软IRQ通常在NIC IRQ线程的上下文中和ksoftirqd / n线程中执行,以应对较高的网络负载并承受较大的压力(CPU,内存,I / O等)。

套接字分配
网络堆栈对有限延迟的当前限制之一是套接字内存分配。 网络堆栈中的每个数据包都需要一个sckbuff结构,其中包含该数据包的元数据。 需要为每个数据包分配此结构,并且分配所需的时间代表了处理数据包和抖动源的大部分开销。

Linux网络开发人员的最后一个项目之一是XDP或eXpress数据路径[17],其目的是在Linux内核中提供高性能的可编程网络数据路径。 XDP将通过消除套接字元数据分配来提供更快的数据包处理。 尽管实时通信并不是该项目的主要动机,但XDP似乎是一个有趣的功能,可以用作实时通信的快速数据路径[18]。

实验结果

为了评估网络堆栈的实时性能,我们使用了两个嵌入式设备,用于测量往返测试的延迟。

往返测试

网络等待时间以往返时间(RTT)进行衡量,也称为乒乓测试。 对于测试,我们在其中一台设备中使用客户端,在另一台设备中使用服务器。 往返延迟是将消息从客户端传播到服务器,再从服务器传播回客户端所花费的时间。 对于客户端和服务器,我们使用了循环测试的修改版本[19],该版本可以保存统计信息并创建延迟直方图,以显示测试的抖动量和最坏情况下的延迟。 此外,我们还计算了1毫秒目标循环时间内错过的最后期限的数量。

对于定时循环,我们使用clock_nanosleep原语。 我们还使用了内存锁定,FIFO调度程序,并将实时优先级设置为80。在所有测试中,我们使用套接字选项SO_PRIORITY将流量标记为优先流量。 为了在系统中产生负载,我们使用了程序压力,并使用了程序iperf来产生流量。

测得的往返延迟的图形表示。 T1是从往返客户端发送数据时的时间戳,T2是从往返客户端再次接收数据时的时间戳。 往返延迟定义为T2-T1。
任务和IRQ关联性以及CPU屏蔽

在实时系统中,可以将实时任务和中断固定到特定的CPU,以将其资源与非实时任务分开。 这是防止非实时过程干扰的有效方法。

有几种方法可以设置任务和IRQ与CPU的关联性。 对于实验,我们决定比较两个隔离级别。 在第一种情况下,我们将实时任务的实时流量队列的IRQ固定到同一CPU。 我们使用“ pthread_setaffinity_np”和“ smp irq相似性”来设置IRQ的优先级。

在第二种情况下,我们使用cpusets [20],这是Linux cgroup的一部分,可以为实时任务分配CPU。 使用这种方法,我们还可以迁移在隔离CPU中运行的所有进程,以便仅允许实时任务在该CPU中运行。 我们还设置了所有IRQ对非实时CPU的关联性,而实时队列(网络设备)的IRQ在隔离的CPU中设置了关联性。

在实验设置中,我们使用描述的方法隔离发送和接收实时流量的应用程序。 测试使用不同的配置运行: no-rtrt-normalrt-affinitiesrt-isolation 。 在第一种情况下, no-rt ,我们使用香草内核。 在第二种情况下, rt-normal ,我们使用PREEMPT-RT内核,而没有将往返程序和网络IRQ绑定到任何CPU。 在第三种情况下, rt-affinities ,我们将优先级队列的IRQ线程以及客户端和服务器程序绑定到每个设备的CPU 1。 最后,在第四种情况下, rt-isolation ,我们在隔离的CPU中运行往返应用程序。 在所有情况下,我们都将RTT测试客户端和服务器的优先级设置为80。

为了对每种配置的确定性有一个直观的了解,我们进行了1小时的循环测试,获得了以下最坏情况的延迟:no-rt:13197 µs,rtnormal / rt-affinities:110 µs和rt-isolation:88 µs 。

系统和网络负载
对于每种情况,我们在不同的负载条件下运行测试:空闲,压力,tx流量和rx流量:

  • idle :除了客户端和服务器之外,没有其他用户空间程序正在运行。
  • 压力 :我们产生一些负载来给CPU和内存以及块内存施加压力。
  • tx-traffic :我们在客户端的传输路径中生成一些并发流量。 我们从客户端向PC发送100 Mbps流量。
  • rx-traffic :我们在服务器的接收路径中生成一些并发流量。 我们从PC向服务器发送100 Mbps流量

在生成并发流量时,两个设备的MAC队列中也都存在拥塞。 但是,由于优先考虑测试流量,因此链路层增加的延迟对于测试没有意义。

结果

我们比较了持续3小时的往返测试所获得的结果,以1毫秒的速率发送了500字节的UDP数据包。 下表显示了在不同条件下使用的不同配置的统计信息。 对于实时基准测试,最重要的指标是最坏情况(Max),数据包丢失和错过的截止日期数。 在这种情况下,我们决定将最后期限设置为1毫秒,以使其与发送速率相匹配。

从表I可以看出,非实时内核似乎是最佳的平均性能,但是相比之下,它错过了大量的截止期限,并且具有最大的最大延迟值。 即使系统处于空闲状态。 当系统由于内核中缺少抢占而受到压力时,延迟会特别受到影响。

对于rt-normal(表II),当系统处于压力状态时,延迟是有限的。 在生成并发流量时,我们观察到较高的延迟值和一些错过的截止日期。

对于rt亲和力,我们可以看到与以前的方案相比有所改善。 专门用于并发流量(表III)。 我们还可以看到,将优先级的往返线程和以太网IRQ固定到同一CPU时,延迟似乎受到限制。

在无隔离的情况下(表IV),与亲和性情况相比,我们欣赏类似的行为。 我们可以看到,强调非隔离式CPU对隔离式内核的任务有一些影响。 但是,在空闲情况下,对于短期测试,我们观察到非常低的抖动。 据我们所知,这种延迟的主要贡献之一是调度程序滴答声,它每10毫秒产生一次。 虽然可以在客户端中避免它,因为它以定时循环运行,但是在服务器端,却无法避免这种情况。 由于两个设备都不同步,因此在某些时候,服务器端的时钟会从客户端偏移,并且调度程序代码会干扰服务器的执行。 下图可以看出这种效果:

隔离CPU的时间图。 在开始时,我们可以观察到调度程序自动收录器抢占实时任务并为往返测试延迟增加延迟的效果。

使用200 Mbps RX流量运行测试时,我们观察到尽力而为流量是在ksoftirqd / 0上下文中连续处理的。 即使在隔离情况下,这在所有情况下都会产生高延迟尖峰。 要跟踪这些延迟峰值的来源,我们应该跟踪发生延迟时拍摄快照的内核。

空闲系统的实时以太网往返时间直方图。
系统在负载(压力)下的实时以太网往返时间直方图。
实时以太网往返时间直方图,用于传输路径中并发的低优先级流量。
接收路径中并发低优先级流量的实时以太网往返时间直方图。

结论与未来工作

获得的结果证明,所提出的Linux实时设置大大改善了使用UDP协议进行通信的确定性。 首先,我们确认通过使用实时内核并以实时优先级运行应用程序,可以减轻系统在重负载下导致的通信延迟。
其次,我们证明,只要有并发流量,仅设置实时进程的优先级是不够的。 在CPU中分离实时应用程序和相应的中断似乎是避免高延迟的有效方法。 但是,对于更高的并发流量负载,我们仍然可以看到无限的延迟,因此需要进一步的研究来克服当前设置中的这一限制。

我们得出的结论是,在某些情况下以及在各种压力和流量过载情况下,Linux确实可以满足通信的某些实时约束。 因此,我们对用于实时机器人应用程序的Linux通信堆栈进行了评估。 未来的工作应考虑到网络堆栈尚未针对低延迟和有限延迟进行完全优化; 当然还有改进的空间。 在我们看来,Linux网络堆栈内部正在进行一些工作,例如XDP [17]项目,这显示了改善实时性能的希望。 在以后的工作中,测试其中一些功能并比较结果可能会很有趣。

参考文献

[1] CSVGutiérrez,LUS Juan,IZ Ugarte和VM Vilches,“机器人的时间敏感网络”,CoRR,第1卷。 abs / 1804.07643,2018. [在线]。 可用: http//arxiv.org/abs/1804.07643

[2]“ PROFINET领先的工业以太网标准”, https://www.cn。 profibus.com/technology/profinet/,访问:2018年4月12日。

[3]“ POWERLINK-Powerlink标准化小组”, https:// www。 ethernet-powerlink.org/powerlink/technology,访问:2018年4月12日。

[4]“数据分发服务规范,版本1.4”, https:// www。 omg.org/spec/DDS/1.4/,访问:2018年4月12日。

[5]“ OPC-UA-OPC统一架构(ua)”, https:// opcfoundation。 org / about / opc-technologies / opc-ua /,访问:2018年4月12日。

[6] H. Fayyad-Kazan,L。Perneel和M. Timmerman,“ Linuxpreempt-rt与商用rtoss:性能差距有多大?” GSTF计算杂志(JoC),第1卷。 3号 2018年1月1日。[在线]。 可用: http : //dl6.globalstf.org/index.php/joc/article/view/1088

[7]“ Xenomai项目主页”,2018年4月,[访问:2018年4月12日]。 [线上]。 可用: https//xenomai.org/

[8]“ Rtai项目主页”,2018年4月,[访问:2018–04–12]。 [线上]。 可用: https//www.rtai.org/

[9]“ RTL协作项目”, https ://wiki.linuxfoundation.org/realtime/rtl/start,访问:2018年4月12日。

[10]“流量控制-Linux排队学科”, http ://man7.org/linux/man-pages/man8/tc.8.html,访问:2018年4月12日。

[11]“ Multiqueue Priority Qdisc-linux手册页”, https:// www。 systutorials.com/docs/linux/man/8-tc-mqprio/,访问:2018年4月12日。

[12]“令牌桶过滤器-Linux排队规则”, https://www.cn.ibm.com。 systutorials.com/docs/linux/man/8-tc-tbf/,访问:2018年4月12日。

[13]“ CBS-基于信用的成形器(CBS)Qdisc”, http ://man7.org/linux/man-pages/man8/tc-cbs.8.html,访问时间:2018年4月12日

[14]“计划的数据包传输:Etf”,[访问:2018年4月12日]。 [线上]。 可用: https : //lwn.net/Articles/758592/

[15] J. Edge,“将中断移至线程”,2008年10月,[访问时间:2018年4月12日]。 [线上]。 可用: https : //lwn.net/Articles/302043/

[16] J. Corbet,“软件中断和实时”,2012年10月,[访问时间:2018年4月12日]。 [线上]。 可用: https: //lwn.net/Articles/ 520076 /

[17]“ XDP(eXpress数据路径)文档”, https: //lwn.net/Articles/701701/,访问:2018年4月12日。

[18]“通往linux tsn基础架构的道路,耶稣桑切斯帕伦西亚”,2018年4月,[访问:2018年4月12日]。 [线上]。 可用: https : //elinux.org/images/5/56/ELC-2018-USA-TSNonLinux.pdf

[19]“ Cyclictest”,2018年4月,[访问:2018年4月12日]。 [线上]。 可用: https ://wiki.linuxfoundation.org/realtime/documentation/howto/tools/cyclictest

[20] S. Derr,“ CPUSETS”, https ://www.kernel.org/doc/Documentation/cgroup-v1/cpusets.txt,访问:2018年4月12日。

From: https://hackernoon.com/real-time-linux-communications-2faabf31cf5e

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值