linux的中断负载均衡和RPS

 

中断类型

异常:又叫同步中断,由cpu产生,只有在一条指令终止后CPU才发出中断;取决于eip的值,又可分为故障fault,陷阱trap和中止abort

中断:硬件外设依照CPU时钟信号随机产生的;分为 可屏蔽和不可屏蔽;

两者分别又称为软件中断(不是软中断)和硬件中断,本文只描述后一种;

硬件中断的处理分为两个阶段,为top halfbottom half

上半部只完成一些比较紧急和必要的功能,比如对中断的到达进行响应确认,最好情况下(SA_INTERRUPT),同级其他中断被屏蔽(锁定当前中断线),最坏情况下,当前CPU所有中断被屏蔽;

下半部则是完成其他那些可以延缓处理的部分,在下半部的执行期间其他CPU可以同时响应软中断。

下半部最常见为软中断softirqtaskletsoftirq为可延迟函数,tasklet建立在其上;

linux 2.6提供6softirq,而tasklet可使用HI_SOFTIRQTASKLET_SOFTIRQ


以网卡处理为例:

从网卡硬件的缓冲区中把网卡收到的网络数据包复制到系统内存中;

对这个数据包进行 TCP/IP 协议栈的处理;

通过 socket将数据包传入用户空间。

如果不分段,在数据传入用户空间之前,所有这些处理都会在中断服务程序中完成,在这段时间内,CPU将不再响应网卡发来的其他中断,网卡将因为自身缓存的不足而丢失数据。

http://download.farsight.com.cn/download/ebooks/Farsight10-LinuxKernel-06.pdf


内核线程

ksoftirqd

每个CPU各有一个,软中断可以自我激活,对于比较繁华的业务譬如网卡数据包泛滥,可能会耗尽CPU

执行期间产生的新的软中断,可以有两种选择:忽略,等到下一次时钟中断才执行;反复检查并执行,可能导致用户态程序一直等待;

ksfotirqd试图找到一个平衡点,若已经执行的软中断又被激活,do_softirq()唤醒该内核线程并终止当前执行,允许用户程序抢占执行(内核线程优先级较低)

kirqd

kirqd周期性调用do_irq_balance(),跟踪最近时间间隔内每个CPU的中断次数,若分布不平衡则尝试转移IRQ

可通过service irqbalance stop关闭;



嵌套执行

内核控制路径可以任意嵌套,即中断可以嵌套,前提是中断处理程序不能阻塞, 即运行期间不可发生进程切换;

内核控制路径:中断切换需要在内核态堆栈保存程序计数器的当前值(eipcs寄存器),其执行的代码不是一个进程(比进程切换轻量级)


CPU affinity

每个能发出中断的外设都有一条IRQ输出线,

I/O APIC包含中断重定向表和可编程寄存器,通过修改中断重定向表,可以把中断信息发生到特定CPU,即CPU affinity

每个CPU都有一个本地的APIC,本地APIC都连接到一个外部的I/OAPIC,设备的IRQ线连接到I/OAPICI/OAPIC接收到中断信号,根据一定的算法,再将中断分配给其中某个本地APIC。也可以通过配置指定某个中断分配给某个CPU


软中断负载均衡与RPS

对于多队列网卡,可直接对网卡接收队列设置CPU affinity,单队列网卡可通过软件先模拟出多队列,然后对每个队列设置affinity,此即为RPS

RPS 全称是 Receive Packet Steering, 这是Google工程师 Tom Herbert (therbert@google.com )提交的内核补丁;

原理:

linux现在网卡的驱动支持两种模式,一种是NAPI,一种是非NAPI模式,这两种模式的区别:

NAPI中,中断收到数据包后调用__napi_schedule调度软中断,然后软中断处理函数中会调用注册的poll回掉函数中调用netif_receive_skb将数据包发送到3层,没有进行任何的软中断负载均衡。

在非NAPI中,中断收到数据包后调用netif_rx,这个函数会将数据包保存到input_pkt_queue,然后调度软中断,这里为了兼容 NAPI的驱动,他的poll方法默认是process_backlog,最终这个函数会从input_pkt_queue中取得数据包然后发送到3层。

不管是NAPI还是非NAPI的话都无法做到软中断的负载均衡,因为软中断此时都是运行在在硬件中断相应的cpu上。也就是说如果始终是cpu0相应网卡的硬件中断,那么始终都是cpu0在处理软中断,而此时cpu1就被浪费了,因为无法并行的执行多个软中断。

google的这个patch的基本原理是这样的,根据数据包的源地址,目的地址以及目的和源端口计算出一个hash值,然后根据这个hash值来选择软中断运行的cpu,从上层来看,也就是说将每个连接和cpu绑定,并通过这个 hash值,来均衡软中断在多个cpu上。

http://www.sklinux.com/522


实现方式

netif_receive_skb()之后还有很多处理工作,也是在软中断上下文中,而且处理工作是和进程无关的。这样就可以把后续的处理工作移到其它的CPU上执行,这也是网络协议栈的软中断的负载均衡的基本思想;

RPS的实现流程:将数据包加入其它CPU的接收队列sd->input_pkt_queue,并激活其它CPUNAPI结构sd->backlog,则其它CPU将会在自己的软中断中执行process_backlogprocess_backlog将会接收sd->input_pkt_queue队列中的所有数据包,并调用__netif_receive_skb()执行后续工作。

http://blog.chinaunix.net/uid-233938-id-3362368.html

RPS也有两种实现方式:

每队列绑定到1CPU

/sys/class/net/eth0/queues/rx-0/rps_cpus 00000001

/sys/class/net/eth0/queues/rx-1/rps_cpus 00000002

/sys/class/net/eth0/queues/rx-2/rps_cpus 00000004

/sys/class/net/eth0/queues/rx-3/rps_cpus 00000008

/sys/class/net/eth0/queues/rx-4/rps_cpus 00000010

/sys/class/net/eth0/queues/rx-5/rps_cpus 00000020

/sys/class/net/eth0/queues/rx-6/rps_cpus 00000040

/sys/class/net/eth0/queues/rx-7/rps_cpus 00000080

每队列绑定到多个或所有CPU

/sys/class/net/eth0/queues/rx-0/rps_cpus 000000ff

/sys/class/net/eth0/queues/rx-1/rps_cpus 000000ff

/sys/class/net/eth0/queues/rx-2/rps_cpus 000000ff

/sys/class/net/eth0/queues/rx-3/rps_cpus 000000ff

/sys/class/net/eth0/queues/rx-4/rps_cpus 000000ff

/sys/class/net/eth0/queues/rx-5/rps_cpus 000000ff

/sys/class/net/eth0/queues/rx-6/rps_cpus 000000ff

/sys/class/net/eth0/queues/rx-7/rps_cpus 000000ff


RFS

http://blog.chinaunix.net/uid-233938-id-3362368.html

全称是 Receive Flow Steering, 这也是Tom提交的内核补丁,它是用来配合RPS补丁使用的,是RPS补丁的扩展补丁,它把接收的数据包送达应用所在的CPU上,提高cache的命中率。

由于RPS只是单纯的把同一流的数据包分发给同一个CPU核来处理了,但是有可能出现这样的情况,即给该数据流分发的CPU核和执行处理该数据流的应用程序的CPU核不是同一个:数据包均衡到不同的cpu,这个时候如果应用程序所在的cpu和软中断处理的cpu不是同一个,此时对于cpu cache的影响会很大。那么RFS补丁就是用来确保应用程序处理的cpu跟软中断处理的cpu是同一个,这样就充分利用cpucache

不仅由于cache缓存的问题,还有一些其它的原因需要把特征相同的数据包分配给同一个CPU处理,例如:

TCPIP包的分段重组问题,一旦乱序就要重传,这种情况下,一个linux主机如果只是作为一台路由器的话,那么进入系统的一个TCP包的不同分段如果被不同的cpu处理并向一个网卡转发了,那么同步问题会很麻烦的,如果你不做同步处理,那么很可能后面的段被一个cpu先发出去了,那么在真正的接收方接收到乱序的包后就会请求重发,这是不希望的,因此还是一个cpu串行处理好。


现在再回过头来看储霸的帖子,感觉轻松不少;http://blog.yufeng.info/archives/2037

某个CPU的软中断偏高:mpstat

调查是谁惹的祸:stap监控softirq.entryworkqueue.executeirq_handler.entry,分别为软中断,工作队列和irq中断线;确定是网卡引起的;

解决方案:换用多队列网卡 + SMP affinity采用RPS软件模拟多队列;


其他链接
http://blog.itpub.net/15480802/viewspace-753982/

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/15480802/viewspace-1408527/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/15480802/viewspace-1408527/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值