汽车以太网实验7

您所在的位置:网站首页 linux用户id默认是0的是哪个 汽车以太网实验7

汽车以太网实验7

2023-05-08 03:03| 来源: 网络整理| 查看: 265

讲在前面,有很多小伙伴问我I210的网卡用哪一款,个人觉得下面这个性价比比较高,SDP引脚也都引出来了,感兴趣的可以点下面JD的链接进行购买。

Traffic Control简介

Linux流量控制(TC)是一组内核模块和用户空间实用程序,允许管理员控制基于Linux的系统中的网络流量。TC为管理网络流量提供了一个灵活而强大的框架,允许管理员根据各种参数,如带宽、延迟、丢包等,对网络流量进行优先排序、限制和塑造。

TC的工作原理是将网络流量划分为不同的类别,每个类别都有自己的规则和特征。这些类可以进一步细分为子类,允许对网络流量进行细化控制。流量控制是通过三个主要部分进行的:排队规则(qdiscs)、类和过滤器。

Qdiscs定义了数据包在一个类中的排队和处理方式。有几个qdiscs可用,每个qdiscs都有自己的一套功能和特点。例如,pfifo_fast qdisc 提供简单的先进先出(FIFO)队列,而分层令牌桶(HTB)qdisc 提供更先进的流量整形功能。

类定义了一组数据包的特性,如该类的带宽、延迟和数据包丢失。类可以嵌套,以提供对流量的更精细的控制。每个类都与一个qdisc相关联,该qdisc定义了该类中数据包的处理方式。

过滤器定义了将数据包匹配到一个特定类别的标准。过滤器可以基于各种参数,如源或目标IP地址、端口号或协议类型。过滤器可以用来引导流量到一个特定的类,或放弃不符合特定标准的数据包。

使用TC,管理员可以将某些类型的流量优先于其他流量,如确保语音或视频流量优先于文件下载。他们还可以限制某些应用程序或用户的带宽使用量,防止他们垄断网络资源。此外,TC可用于模拟网络条件,允许管理员在各种网络条件下测试应用程序,如高延迟或低带宽。

总结:TC是一个强大的工具,用于管理基于Linux系统的网络流量。它的灵活性和颗粒度使其成为各种应用的理想选择,如网络监控、流量整形和服务质量(QoS)管理。通过对网络流量进行细化控制,TC允许管理员优化网络性能,并确保关键应用程序获得正常运行所需的资源。

实验

活不多说,直接看图,下面是I210网卡的QDISC信息。

tc qdisc show dev ens224 #列出这个设备下的qdisc信息。qdisc mq 0:root

每一个interface都有一个root qdisc和一个ingress qdisc。 root就是输出,ingress是输入,但是现在好一点的MAC都是带有多个硬件队列的(每个队列有独立的中断,独立的Buffer ,硬件级别的队列控制,你甚至可以理解为一个mac可以分为多个子mac),但是又不能搞多个root qdisc出来,所以搞了一个mq,mq:(multi-queue) 也叫 multiqueue dummy schedule。 顺便提一句,TAS的前提就是至少要有2个发送队列。一般最多也就8个TX,8个RX。对应VLAN的8个优先级。看一下i210的参数。

大多数单队列的MAC一般默认是使用pfifo_fast(早期,现在默认用的是fq_codel,后面讲)这个队列,很简单,先进先出。

The mq scheduler does two things: - present device TX queues as classes, allowing to attach different qdiscs to them, which are grafted to the TX queues - present accumulated statistics of all device queue root qdiscs Its used by default for multiqueue devices instead of the regular pfifo_fast qdisc, but can also be attached manually to restore multiqueue behaviour after attaching a non-multiqueue (shared) qdisc.

上面是英文的解读,更到位一些。

qdisc里面还有一个MultiQ,MultiQ vs Mq的区别我问了一下GPT-4:

The MultiQ and MQ (Multiqueue) are both queuing disciplines (qdiscs) used in the Linux traffic control subsystem to manage multiple transmission queues, but they serve slightly different purposes and work in different ways.MultiQ (multiq):MultiQ is a simple queuing discipline that utilizes multiple transmission queues, typically equal to the number of hardware transmit queues available on the network interface card (NIC). The primary purpose of MultiQ is to distribute packets among the hardware queues, allowing the NIC to transmit packets from different queues in parallel, which can improve the overall throughput.MultiQ does not perform any scheduling or prioritization between the queues. It relies on upper-layer protocols, such as the IP stack, to choose the correct queue for each packet. Typically, this decision is based on the packet's priority (e.g., type of service) or flow identification (e.g., 5-tuple).MQ (multiqueue):MQ is another queuing discipline that also utilizes multiple transmission queues. However, unlike MultiQ, MQ provides more control over the scheduling and prioritization of the packets among the different queues. MQ allows the system administrator to configure and use different qdiscs for each queue, enabling more advanced packet scheduling and prioritization policies.With MQ, you can attach different queuing disciplines, like HTB (Hierarchical Token Bucket), FQ (Fair Queuing), or FQ-CoDel (Flow Queuing with Controlled Delay), to each of the queues, effectively creating a hierarchy of qdiscs that can enforce complex traffic shaping and prioritization rules.In summary, MultiQ is a simple queuing discipline that distributes packets among multiple hardware transmit queues for parallel transmission without any scheduling, while MQ allows for more complex and fine-grained control over the scheduling and prioritization of packets among the queues by attaching different qdiscs to each queue.

目前自己对(MultiQ vs Mq)还没有一个很好的理解,先把这个解释放在这里。mq和mulitq创建的结果如下图。

sudo tc qdisc add dev ens224 root handle 1: mq sudo tc qdisc add dev ens224 root handle 1: multiq

0:代表的是默认的,这个时候我们需要手动创建root。直接操作0:会报错的。可以对比一下执行后的区别。

关于multiq的介绍可以看这里https://www.kernel.org/doc/Documentation/networking/multiqueue.txt

现在我们有四个tx队列,每个队列都是fq_codel

qdisc fq_codel 0: parent 1:1 limit 10240p flows 1024 quantum 1514 target 5ms interval 100ms memory_limit 32Mb ecn drop_batch 64

fq_codel:qdisc策略,后面会主要介绍一下这个策略, 一个策略可以包含多个class,每个class都需要一个id(major:miner)

The numbering of handles for classes and qdiscs

major

This parameter is completely free of meaning to the kernel. The user may use an arbitrary numbering scheme, however all objects in the traffic control structure with the same parent must share a major handle number. Conventional numbering schemes start at 1 for objects attached directly to the root qdisc.

minor

This parameter unambiguously identifies the object as a qdisc if minor is 0. Any other value identifies the object as a class. All classes sharing a parent must have unique minor numbers.

上图是一个major:minor 的例子。数据流从10:1,10:2,12:1,12:2来,最终从root(1:1)出。多队列的话,最终就是从1:1,1:2,1:3,1:4出。

下面我们尝试去修改一下fq_codel的参数,改一下limit.

同样的,我们先要创建一个来代替默认的0:

sudo tc qdisc add dev ens224 parent 1:1 handle 10 fq_codel sudo tc qdisc change dev ens224 handle 10 fq_codel limit 10250netem

netem(Network Emulation)是一个Linux内核中的网络模拟模块,它可以通过模拟各种网络条件(如延迟、丢包、抖动等)来帮助测试、调试和评估网络应用程序。通过netem,开发者和网络工程师可以在不同的网络环境下验证应用程序的性能、可靠性和稳定性。netem也是属于qdisc的一种

netem提供了以下主要功能:

延迟和抖动:模拟网络延迟和抖动,以测试应用程序在不同延迟和抖动条件下的性能。分布式延迟:模拟具有不同延迟分布的网络环境,如正态分布、帕累托分布等。丢包:模拟网络中的丢包现象,以检验应用程序的容错性和恢复能力。重复:模拟网络中的数据包重复,以检查应用程序对重复数据包的处理能力。乱序:模拟网络中的数据包乱序,以检验应用程序对乱序数据包的处理和恢复能力。带宽限制:模拟不同的网络带宽,以评估应用程序在低带宽环境下的性能。错误注入:模拟网络中的数据包错误,以测试应用程序的错误检测和处理能力。

RTT:往返时间(Round-Trip Time,简称 RTT)是计算网络通信中数据包从发送端到接收端再返回发送端所需的总时间。在以太网中,RTT 是衡量网络延迟的一个关键指标。它受到网络拥塞、硬件性能、传输距离和其他许多因素的影响。RTT 可以用来评估网络连接的质量和速度,对于网络调优和故障排查具有重要意义。

下面我们通过netem来给queue1增加100ms的延时。(注意,这里我们只会对队列2增加延时,然后我们会介绍如何网络数据包基于某个特定的硬件进行发送)

sudo tc qdisc add dev ens224 parent 1:2 handle 11 netem delay 100ms

这个时候,我们可以试一下ping其他主机,发现延时还是很低,因为我们有4个硬件队列,默认是随机选择的(有待验证,好像不是随机的,是ip,端口号等值的hash作为索引来选择的)。可以用tc的-s来查看每个qdisc的发送情况,默认所有报文现在走的是1:4

tc -s class show dev ens224

那么我们怎么指定特殊的报文走特殊的队列呢。

ndo_select_queue & netdev_pick_tx & XPS

可以看到,如果我们定义了ndo_select_queue,那么就不会执行netdev_pick_tx函数,也就是说不会选择XPS的配置。而我们的igb_avb驱动刚好定义了ndo_select_queue这个函数。

返回一个固定值3(对应的就是1:4)。所以说这里我们需要修改igb_avb驱动,使他能进入netdev_pick_tx 函数(这个地方也是卡了我一会。。)

再来看netdev_pick_tx函数。

u16 netdev_pick_tx(struct net_device *dev, struct sk_buff *skb, struct net_device *sb_dev) { struct sock *sk = skb->sk; int queue_index = sk_tx_queue_get(sk); sb_dev = sb_dev ? : dev; if (queue_index ooo_okay || queue_index >= dev->real_num_tx_queues) { int new_index = get_xps_queue(dev, sb_dev, skb); if (new_index sk_dst_cache)) sk_tx_queue_set(sk, new_index); queue_index = new_index; } return queue_index; }

可以看到,get_xps_queue, skb_tx_hash。

skb_tx_hash 应该就是更加端口ip来计算index,没去细看,主要看一下get_xps_queue。

XPS is configured per transmit queue by setting a bitmap ofCPUs/receive-queues that may use that queue to transmit. The reversemapping, from CPUs to transmit queues or from receive-queues to transmitqueues, is computed and maintained for each network device. Whentransmitting the first packet in a flow, the function get_xps_queue() iscalled to select a queue. This function uses the ID of the receive queuefor the socket connection for a match in the receive queue-to-transmit queuelookup table. Alternatively, this function can also use the ID of therunning CPU as a key into the CPU-to-queue lookup table. If theID matches a single queue, that is used for transmission. If multiplequeues match, one is selected by using the flow hash to compute an indexinto the set. When selecting the transmit queue based on receive queue(s)map, the transmit device is not validated against the receive device as itrequires expensive lookup operation in the datapath.

修改好后,发现流量被分发到4个队列:

XPS配置

要实现cpu和硬件队列的绑定,我们要用的XPS,RPS. Scaling in the Linux Networking Stack

XPS: Transmit Packet Steering

Transmit Packet Steering is a mechanism for intelligently selecting which transmit queue to use when transmitting a packet on a multi-queue device. This can be accomplished by recording two kinds of maps, either a mapping of CPU to hardware queue(s) or a mapping of receive queue(s) to hardware transmit queue(s).

这里,我们主要关心两个寄存器。xps_cpus,xps_rxqs

xps_cpus代表基于CPU来进行映射:

这种映射的目标通常是将队列专门分配给一个CPU子集,这些队列的传输完成在这个子集的CPU上处理。这种选择有两个好处。首先,设备队列锁的争夺明显减少,因为争夺同一队列的CPU较少(如果每个CPU有自己的发送队列,争夺可以完全消除)。其次,传输完成时的缓存缺失率也会降低,特别是对于持有sk_buff结构的数据缓存行。

xps_rxqs代表基于接收队列来进行映射:

这种模式代表的就是某个包从哪个队列接收到的,就从哪个队列发送出去。In this model, sending the packets on the same transmit queue corresponding to the associated receive queue has benefits in keeping the CPU overhead low

这里我们采用xps_cpus的方式,把CPU2 映射到队列1上。

然后把其他cpu分给剩下的队列(20个CPU,对应5个4bit)

现在,我们只需要用cpu2来执行一下ping的命令看看效果:

这里我们用到了taskset 命令。

可以看到,当我们指定CPU2是ping的延时为100ms,其他CPU的时候,延时



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3