AIRobot

AIRobot quick note


  • 首页

  • 关于

  • 标签

  • 分类

  • 归档

  • 搜索

SFP SFP+

发表于 2020-01-08
本文字数: 1.6k 阅读时长 ≈ 1 分钟

sfp光纤网卡

SFP端口主要作用是用于信号转换和数据传输,支持热插拔的I / O接口(指输入/输出接口),具备较强的灵活性,适用于多种产品,如可以与1000BASE-SX,1000BASE-LX / LH,1000BASE-ZX或1000BASE -BX10-D / U的端口进行交换,另外SFP端口可向下兼容,支持10/100 / 1000Mbps。其端口符合IEEE 802.3ab标准,最大传输距离可达1000 Mbps

SFP光纤网卡是一种小型可热拨插模块的光纤网卡。在网卡集成SFP插槽,用户可根据实际需要,插入多模SFP光模块或者单模SFP光模块,根据实际传输距离选择光模块,而不需要根据网卡本身。这就给用户很大的选择空间。

SFP光纤网卡根据端口数量可以分为:单端口SFP光纤网卡、双端口SFP光纤网卡、四端口SFP光纤网卡。

SFP光纤网卡主要特性

即插即用(plug and play)
与 IEEE 802.3z 1000Base-SX / 1000Base-LX以太网标准兼容
1000Mbps以太网光纤接入,可工作于全/半双工模式,全双工模式下可提供2000Mbps的带宽
支持IEEE 802.3x流量控制
支持IP单播、广播、多播地址过滤机制
支持优先级队列
支持IEEE 802.1Q/VLAN标记
支持IP多播包过滤,降低了CPU占有率

SFP SFP+区别

10G模块经历了从 300Pin,XENPAK,X2,XFP的发展,最终实现了用和SFP一样的尺寸传输10G的信号,这就是SFP+。SFP凭借其小型化低成本等优势满 足了设备对光模块高密度的需求,从2002年标准推行了,到2010年已经取代XFP成为10G 市场主流。

SFP+光模块优点:

  1. SFP+具有比X2和XFP封装更紧凑的外形尺寸(与SFP尺寸相同);
  2. 可以和同类型的XFP,X2,XENPAK直接连接;
  3. 成本比XFP,X2,XENPAK产品低。

SFP+和SFP的区别:

  1. SFP 和SFP+ 外观尺寸相同;
  2. SFP协议规范:IEEE802.3、SFF-8472 ;

SFP+ 和XFP 的区别:

  1. SFP+和XFP 都是10G 的光纤模块,且与其它类型的10G模块可以互通;
  2. SFP+比XFP 外观尺寸更小;
  3. 因为体积更小SFP+将信号调制功能,串行/解串器、MAC、时钟和数据恢复(CDR),以及电子色散补偿(EDC)功能从模块移到主板卡上;
  4. XFP 遵从的协议:XFP MSA协议;
  5. SFP+遵从的协议:IEEE 802.3ae、SFF-8431、SFF-8432;
  6. SFP+是更主流的设计。
  7. SFP+ 协议规范:IEEE 802.3ae、SFF-8431、SFF-8432。

附:

可用的光学SFP模块一般分为如下类别:850纳米波长/550米距离的 MMF (SX)、1310纳米波长/10公里距离的 SMF (LX)、1550 纳米波长/40公里距离的XD、80公里距离的ZX、120公里距离的EX或EZX,以及DWDM。

关于X2接口:

X2是一个规范的形式从10.3 Gb / s的为10.5 Gb / s的数据传输速率为10Gb / s的光纤光纤转发器它是特定协议:

10G 以太网或10G光纤通道版本。 X2的转发器,用于在数据通信光纤链路(电信),他们比老一代的XENPAK转发小。其电气接口的主板也规范,被称为XAUI(4 × 3.125 Gb /秒)。 WZT制造X2 300M,X210公里,X220公里,X240公里,X280公里光学模块。所有模块支持数字光学监测(DOM)的功能。

DWDM X2:密集波分复用(DWDM)的X2可插拔模块允许企业公司和服务供应商提供可扩展性和易于部署的10千兆位以太网服务,在他们的网络。双方的DWDM X2 ER 40km和DWDM X2 ZR80公里可用于DWDM 10G以太网应用。

Linux RSS/RPS/RFS/XPS

发表于 2020-01-07
本文字数: 4.2k 阅读时长 ≈ 4 分钟

一、概述

RSS和RPS都是网卡为了在接受数据包的时候使用多核架构而进行的性能增强,RSS是在硬件层面而RPS在软件层面。在数据包接收到之后在用户态的处理逻辑怎么处理,应用层的响应数据包如何发送都会影响系统性能,RFS(Receive Flow Steering)和XPS(Transmit Packet Steering)这两个机制就是为了解决这两个问题而产生的。

二、网卡处理的基本概念

2.1 硬中断(Hardware Interrupt)

硬件设备产生输入核输出事件的时候,会向CPU发送信号,这个信号就是硬中断。CPU在接收到硬中断之后,会停止现在的工作,以最高优先级处理这个硬件中断事件。

2.2 软中断(SoftIRQ)

软中断与硬中断在机制上类似只是优先级稍微低一点。在网卡传输数据的过程中,典型的过程是数据到达网卡,网卡通过DMA将数据拷贝到为网卡驱动指定的内存区域,产生硬中断,然后CPU需要自己负责处理中断,将网卡的数据拷贝到内核指定区域,进行TCP/IP协议栈的处理,再通知应用层并将数据拷贝的应用层。在这种情况下,如果一旦一个硬中断来了之后,CPU一直忙碌于处理网卡的这个请求和服务上层应用,那网卡后续数据到来产生的硬中断也会被延后处理,而且其它设备和进程也无法使用这个CPU资源,造成CPU饥饿状态。所以在处理设备硬中断的时候,将整个过程分成两个阶段;第一阶段,CPU只是使用ISR简单而快速响应硬中断,产生一个软中断,然后CPU可以继续进行后续调度处理而网卡可以继续收发数据;第二阶段,CPU会根据scheduler对一系列软中断按照优先级进行排队处理,将数据包移动到TCP/IP协议栈和后续应用程序。

2.3 接收队列

网卡驱动通过DMA将接收到的数据会拷贝到socket buffer并由一个socket descriptor进行标记,所有待处理的数据包的socket descriptor将被存储在接收队列里面,如果有多个接收队列,则网卡会将packet按照某个算法匹配到一个接收队列上。现在的许多网卡都是通过一种叫RSS(Receive Side Scaling)的技术(将数据包的处理任务分配到多个CPU)在硬件上支持Rx多队列的。

三、RSS(Receive Side Scaling)

Contemporary NICs support multiple receive and transmit descriptor queues (multi-queue). On reception, a NIC can send different packets to different

queues to distribute processing among CPUs. The NIC distributes packets by applying a filter to each packet that assigns it to one of a small number

of logical flows. Packets for each flow are steered to a separate receive queue, which in turn can be processed by separate CPUs. This mechanism is

generally known as RSS.

当数据包到达NIC之后,将被放到接收队列;在网卡驱动初始化阶段,接收队列会被赋予一个IRQ号,并且会分配一个CPU来处理这个IRQ,这个CPU需要执行这个IRQ的ISR并且在一般情况下还要负责执行后续的数据包在内核阶段的处理。在单核系统中,这是一个很好的工作模型,但是在多核系统中,这种方式在大流量的时候无法发挥多核的作用,只能使用一个内核,进行耗时的TCP/IP协议栈的处理。

所以在现在的NIC中,多数都支持RSS的功能,启用这种功能之后,网卡会有多个接收和发送队列,这些队列对被分配不同的CPU进行处理。

RSS为网卡数据传输使用多核提供了支持,RSS在硬件/驱动级别实现多队列并且使用一个hash函数对数据包进行多队列分离处理,这个hash根据源IP、目的IP、源端口和目的端口进行数据包分布选择,这样同一数据流的数据包会被放置到同一个队列进行处理并且能一定程度上保证数据处理的均衡性。

四、RPS(Receive Packet Steering)

Receive Packet Steering (RPS) is logically a software implementation of RSS.

RPS requires a kernel compiled with the CONFIG_RPS kconfig symbol (on by default for SMP). Even when compiled in, RPS remains disabled until

explicitly configured. The list of CPUs to which RPS may forward traffic can be configured for each receive queue using a sysfs file entry:

/sys/class/net/ /queues/rx- /rps_cpus

RPS是和RSS类似的一个技术,区别在于RSS是网的硬件实现而RPS是内核软件实现。RPS帮助单队列网卡将其产生的SoftIRQ分派到多个CPU内核进行处理。在这个方案中,为网卡单队列分配的CPU只处理所有硬件中断,由于硬件中断的快速高效,即使在同一个CPU进行处理,影响也是有限的,而耗时的软中断处理会被分派到不同CPU进行处理,可以有效的避免处理瓶颈。

五、RFS(Receive Flow Steering)

While RPS steers packets solely based on hash, and thus generally provides good load distribution, it does not take into account

application locality. This is accomplished by Receive Flow Steering (RFS).

RFS is only available if the kconfig symbol CONFIG_RPS is enabled (on by default for SMP). The functionality remains disabled until explicitly

configured. The number of entries in the global flow table is set through:

/proc/sys/net/core/rps_sock_flow_entries

The number of entries in the per-queue flow table are set through:

/sys/class/net/ /queues/rx- /rps_flow_cnt

在使用RPS接收数据包之后,会在指定的CPU进行软中断处理,之后就会在用户态进行处理;如果用户态处理的CPU不在软中断处理的CPU,则会造成CPU cache miss,造成很大的性能影响。RFS能够保证处理软中断和处理应用程序是同一个CPU,这样会保证local cache hit,提升处理效率。RFS需要和RPS一起配合使用。

六、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.

XPS is only available if the kconfig symbol CONFIG_XPS is enabled (on by default for SMP). The functionality remains disabled until explicitly

configured. To enable XPS, the bitmap of CPUs/receive-queues that may use a transmit queue is configured using the sysfs file entry:

For selection based on CPUs map:

/sys/class/net/ /queues/tx- /xps_cpus

For selection based on receive-queues map:

/sys/class/net/ /queues/tx- /xps_rxqs

XPS通过创建CPU到网卡发送队列的对应关系,来保证处理发送软中断请求的CPU和向外发送数据包的CPU是同一个CPU,用来保证发送数据包时候的局部性。

总结

RSS(Receive Side Scaling):网卡多队列,需要硬件支持。网卡接收到网络数据包之后,要发送一个硬件中断,通知CPU取数据包。默认配置,都是由CPU0去做。

RPS(Receive Packet Steering):向某CPU发送一个软中断,来接收数据包,并递交给应用程序。

RFS(Receive Flow Steering):维护两张hash表,实现将软中断分散到多颗CPU去处理。

XPS(Transmit Packet Steering):创建CPU到网卡发送队列的对应关系,主要是为了避免cpu由RX队列的中断进入到TX队列的中断时发生切换,导致cpu cache失效损失性能。

堆栈

发表于 2019-12-27 更新于 2020-12-29
本文字数: 2.9k 阅读时长 ≈ 3 分钟

函数调用栈

EIP, EBP, ESP三个指针寄存器与函数调用的关系

函数调用离不开这三个寄存器,函数调用时三者的作用:

  • EIP中保存CPU下次要执行的指令地址即调用完函数后要执行的指令地址;

  • EBP中保存的是当前函数栈基地址,一直不变,即栈底;

  • ESP 中保存的是当前函数调用栈顶

函数参数与EBP关系

由上图我们可以看出,函数的参数与EBP的关系,第一个参数与EBP之间隔着上一级函数的EIP,EBP。由于EIP, EBP都是指针所以占4个字节, 第一个参数与EBP相隔8个字节。函数参数是由右向左依次压栈的,所以得如下结论:

第一个参数地址 = EBP的值 + 8

第二个参数地址 = EBP的值 + 8 + sizeof(参数1)

第N个参数地址 = EBP的值+8 + sizeof(参数1) + sizeof(参数2) …sizeof(参数N-1);

依此类推可以根据EBP的值和各参数的类型我们可以找到所有参数

注:如果是C++的类型成员函数则第一个参数是this指针

test.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>

struct teststruct
{
int nTest;
};

int test_fun(struct teststruct *pTs, int n)
{
int b = 3;
int c =4;
pTs->nTest = n;
printf("b = %d\n",b);
return 0;
}
int main()
{
struct teststruct test;
test_fun(&test, 1);

return 0;
}

test.s

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
	.file	"test.c"
.text
.globl test_fun
.type test_fun,@function
test_fun:
pushl %ebp //main函数的 ebp 压栈
movl %esp, %ebp //设置 test_fun()的 ebp
sub $0x8,%esp
movl $0x3,0xfffffffc(%ebp) //%ebp-4; b = 3
movl $0x4,0xfffffff8(%ebp) //%ebp-8; c = 4
mov 0x8(%ebp),%eax
mov 0xc(%ebp),%edx
mov %edx,(%eax)
sub $0x8,%esp
pushl 0xfffffffc(%ebp)
push $0x8048548
call 0x80482e4 <printf>
add $0x10,%esp
mov $0x0,%eax
leave //MOV EBP,ESP;POP EBP
ret
.Lfe1:
.size test_fun,.Lfe1-test_fun
.globl main
.type main,@function
main:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
andl $-16, %esp
movl $0, %eax
subl %eax, %esp
subl $8, %esp

// test_fun(&test, 1); 调用过程
pushl $1
leal -4(%ebp), %eax => 0xfffffffc($ebp)
pushl %eax

call test_fun

addl $16, %esp => 清理栈
movl $0, %eax
leave
ret
.Lfe2:
.size main,.Lfe2-main
.ident "GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)"
  • call *8(%eax)
    调用 %eax+8 ,的函数指针指向的函数。
  • incw 0xffffffc8(%ebp,%ecx,2)
    (ebp + 2ecx) - (0x100-0xc8),这个值进行++操作
    这是基址变址寻址方式,disp(base, index, scale),计算方法:base+index
    scale+disp 。
  • movb 0x15 0x16(%esp,1)
    移动字节0x15,到%esp*1+0x16,这个地址上。
    属变址寻址方式

linux中一个进程的内存布局如下图所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

-----------------
高地址 | | ---> 命令行参数和环境变量 (只读) 0xff..ff
-----------------
| 栈 |
|- - - - - - - -|
| | | |
| \ / |
| |
| |
| / \ |
| | | |
|- - - - - - - -|
| 堆 |
|---------------|
           | 未初始化的变量 |
| (bss) | ---> 由 exec 初始化为零
|---------------|
          | 初始化后的变量 | \
|---------------| |
| text(数据区) | | 由 exec 从程序中读取
     | | /
|---------------|
低地址     | 代码区 | 0x00..01
|---------------|

int a=16777220,十六进制是0x01 00 00 04则04属于低字节,01属于高字节

大端 网络 小端 主机
0x0004 04 01
0x0003 00 00
0x0002 00 00
0x0001 01 04

(1)一个整数类型内部

低地址存储低位,高地址存储高位。比如int a=1,则存储情况为0000(高地址) 0000 0000 0001(低地址)

(2)若干个局部变量(在栈中存储的)

先定义的高地址,后定义的低地址

(3)类、结构体或数组的元素

先定义的低地址,后定义的高地址

ldd,nm,readelf,ar,objdump

发表于 2019-12-23
本文字数: 194 阅读时长 ≈ 1 分钟

ldd

ldd命令用于输出可执行文件或者库文件所依赖的共享库列表。

nm

nm命令用于输出可执行文件或者库文件的符号表。

readelf

readelf命令用来显示一个或者多个elf格式的目标文件的信息,可以通过它的选项来控制显示哪些信息。

ar

ar命令可以用来创建、修改库,也可以从库中提出单个模块。

objdump

objdump命令是用查看目标文件或者可执行的目标文件的构成的gcc工具。

RCU API

发表于 2019-12-07
本文字数: 581 阅读时长 ≈ 1 分钟

RCU(Read-Copy Update),是 Linux 中比较重要的一种同步机制。顾名思义就是“读,拷贝更新”,再直白点是“随意读,但更新数据的时候,需要先复制一份副本,在副本上完成修改,再一次性地替换旧数据”。这是 Linux 内核实现的一种针对“读多写少”的共享数据的同步机制。

CU由三种基础机制构成,第一个机制用于插入,第二个用于删除,第三个用于让读者可以不受并发的插入和删除干扰。分别是:

  • 发布/订阅机制,用于插入。

  • 等待已有的RCU读者完成的机制,用于删除。

  • 维护对象多个版本的机制,以允许并发的插入和删除操作。

类别 发布 删除 订阅
指针 rcu_assign_pointer rcu_assign_pointer rcu_dereference
链表 list_add_rcu list_add_tail_rcu list_replace_rcu list_del_rcu list_for_each_entry_rcu
哈希链表 hlist_add_head_rcu hlist_add_tail_rcu hlist_add_before_rcu hlist_add_behind_rcu hlist_replace_rcu hlist_del_rcu hlist_for_each_entry_rcu
1…8910…26
AIRobot

AIRobot

AIRobot quick note
130 日志
15 分类
23 标签
GitHub E-Mail
Creative Commons
0%
© 2023 AIRobot | 716k | 10:51