linux 如何降低入向软中断占比
最近遇到一个问题,当tcp收包的时候,我们的服务器的入向软中断比例很高。
我们知道,napi模式,可以降低收包入向软中断占比,那么,针对napi模式,能不能优化?本文针对2.6.32-358内核进行分析:
static void net_rx_action(struct softirq_action *h)
{
struct list_head *list = &__get_cpu_var(softnet_data).poll_list;
unsigned long time_limit = jiffies + ;
int budget = netdev_budget;----------------这个值可以通过/proc/sys/net/core/netdev_budget修改,默认是300
void *have;
int select;
struct rps_remote_softirq_cpus *rcpus; local_irq_disable(); while (!list_empty(list)) {-------------------不为空,则一直循环
struct napi_struct *n;
int work, weight; /* If softirq window is exhuasted then punt.
* Allow this to run for 2 jiffies since which will allow
* an average latency of 1.5/HZ.
*/
if (unlikely(budget <= || time_after(jiffies, time_limit)))----------时间到,或者配额到了,则退出循环。
goto softnet_break; local_irq_enable(); /* Even though interrupts have been re-enabled, this
* access is safe because interrupts can only add new
* entries to the tail of this list, and only ->poll()
* calls can remove this head entry from the list.
*/
n = list_first_entry(list, struct napi_struct, poll_list); have = netpoll_poll_lock(n); weight = n->weight;--------------napi配置的weight,这个是一次poll的配额,和上面总的配合一起控制收包,这个在netif_napi_add 函数中设置。
/* This NAPI_STATE_SCHED test is for avoiding a race * with netpoll's poll_napi(). Only the entity which * obtains the lock and sees NAPI_STATE_SCHED set will * actually make the ->poll() call. Therefore we avoid * accidently calling ->poll() when NAPI is not scheduled. */ work = ; if (test_bit(NAPI_STATE_SCHED, &n->state)) { work = n->poll(n, weight);------------回调poll,不同的厂家有不同的实现,比如intel的ixgbe_poll实现 trace_napi_poll(n); } WARN_ON_ONCE(work > weight); budget -= work; local_irq_disable(); /* Drivers must not modify the NAPI state if they * consume the entire weight. In such cases this code * still "owns" the NAPI instance and therefore can * move the instance around on the list at-will. */ if (unlikely(work == weight)) { if (unlikely(napi_disable_pending(n))) { local_irq_enable(); napi_complete(n); local_irq_disable(); } else list_move_tail(&n->poll_list, list); } netpoll_poll_unlock(have); } out: rcpus = &__get_cpu_var(rps_remote_softirq_cpus); select = rcpus->select; rcpus->select ^= ; local_irq_enable(); net_rps_action(&rcpus->mask[select]); #ifdef CONFIG_NET_DMA /* * There may not be any more sk_buffs coming right now, so push * any pending DMA copies to hardware */ dma_issue_pending_all(); #endif return; softnet_break: __get_cpu_var(netdev_rx_stat).time_squeeze++; __raise_softirq_irqoff(NET_RX_SOFTIRQ); goto out; }
从代码可以看出,限制一次调用net_rx_action的地方,无非是时间,还有netdev_budget,如果把netdev_budget 调大,是不是就可以一次性多收一点包呢,意味着触发软中断的次数就会减少,答案是肯定的。
那么默认值来看,netdev_budget 比napi配置的weight要大。
/* initialize NAPI */
netif_napi_add(adapter->netdev, &q_vector->napi,ixgbe_poll, 64);-------传入64
void netif_napi_add(struct net_device *dev, struct napi_struct *napi,
int (*poll)(struct napi_struct *, int), int weight)
{
INIT_LIST_HEAD(&napi->poll_list);
napi->gro_count = ;
napi->gro_list = NULL;
napi->skb = NULL;
napi->poll = poll;
if (weight > NAPI_POLL_WEIGHT)
pr_err_once("netif_napi_add() called with weight %d on device %s\n",--------会打印,但是也不会限制
weight, dev->name);
napi->weight = weight;
list_add(&napi->dev_list, &dev->napi_list);
napi->dev = dev;
#ifdef CONFIG_NETPOLL
spin_lock_init(&napi->poll_lock);
napi->poll_owner = -;
#endif
set_bit(NAPI_STATE_SCHED, &napi->state);
我们通过将传入的64改大到256,因为在ixgbe_poll 函数中,这个值控制了一次循环收包的个数。
int ixgbe_poll(struct napi_struct *napi, int budget)
{
struct ixgbe_q_vector *q_vector =
container_of(napi, struct ixgbe_q_vector, napi);
struct ixgbe_adapter *adapter = q_vector->adapter;
struct ixgbe_ring *ring;
int per_ring_budget;
bool clean_complete = true; #ifdef CONFIG_IXGBE_DCA
if (adapter->flags & IXGBE_FLAG_DCA_ENABLED)
ixgbe_update_dca(q_vector);
#endif ixgbe_for_each_ring(ring, q_vector->tx)----------------------遍历tx队列,跟本文讨论的内容不相关,本文讨论收包
clean_complete &= !!ixgbe_clean_tx_irq(q_vector, ring); if (!ixgbe_qv_lock_napi(q_vector))
return budget; /* attempt to distribute budget to each queue fairly, but don't allow
* the budget to go below 1 because we'll exit polling */
if (q_vector->rx.count > )
per_ring_budget = max(budget/q_vector->rx.count, );---通过增大 budget,从64改大到256,增加了一次循环收包的个数
else
per_ring_budget = budget; ixgbe_for_each_ring(ring, q_vector->rx)-----------遍历收包队列,
clean_complete &= (ixgbe_clean_rx_irq(q_vector, ring,
per_ring_budget) < per_ring_budget); ixgbe_qv_unlock_napi(q_vector);
/* If all work not completed, return budget and keep polling */
if (!clean_complete)
return budget; /* all work done, exit the polling mode */
napi_complete(napi);
if (adapter->rx_itr_setting & )
ixgbe_set_itr(q_vector);
if (!test_bit(__IXGBE_DOWN, &adapter->state))
ixgbe_irq_enable_queues(adapter, ((u64) << q_vector->v_idx)); return ;
}
通过将 budget 从64改大到256,同样的入向流量,软中断从25%降低到23%,效果很明显。
那么,能否无限制改大呢,显然不行,一则是改大后,各个队列收包就很难均衡,因为每个队列收完对应的报文之后(除非收空了),才能返回,这样,就关中断时间太长了。
可能有人会问,这个改大收包个数,但是处理软中断的总时间应该没变化,为什么会降低呢,取个极限的例子,napi出来就是应对以前单个包就需要一个中断的问题的,所以单次收包
多一些应该是有用的。
除此之外,通过设置网卡的rx-usecs属性,将这个值改大些,也可以降低软中断的占比。
ethtool -c eth0
Coalesce parameters for eth0:
Adaptive RX: off TX: off
stats-block-usecs:
sample-interval:
pkt-rate-low:
pkt-rate-high: rx-usecs: 1-------------默认是1,改成512 ethtool –C eth0 rx-usecs 512
这个减少了硬中断的触发次数,但是呢,显而易见的是,增加了延迟,如果你的系统是要求实时性极高的,可能要减少该值。
第三个方法就是开启gro了,gro开启之后,收包的时候,如果是同一个流的包,且网卡支持gro属性的话,根据协议的回调会尝试进行合并报文,当前由于目前这个流的宏值
只有最多8个流,超过的会直接送上协议栈,不会合并。当然如果是服务器,发包为主的话,其实gro是有害无益的,因为目前的flow个数限制太多,而且对于tcp来说,ack的报文也不会合并。
所以如果是服务器端,要定制化自己的gro,比如使用hash链来管理flow,使用ack合并来减少软中断消耗。
linux 如何降低入向软中断占比的更多相关文章
- linux top命令中各cpu占用率含义
linux top命令中各cpu占用率含义 [尊重原创文章摘自:http://www.iteye.com/topic/1137848]0.3% us 用户空间占用CPU百分比 1.0% sy 内核空间 ...
- (转)linux top命令中各cpu占用率含义及案例分析
原文:https://blog.csdn.net/ydyang1126/article/details/72820349 linux top命令中各cpu占用率含义 0 性能监控介绍 1 确定应用类型 ...
- Linux显示登入系统的帐号名称和总人数
Linux显示登入系统的帐号名称和总人数 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ who -q youhaidong youhaidong # 用户数= ...
- Linux下分析某个进程CPU占用率高的原因
Linux下分析某个进程CPU占用率高的原因 通过top命令找出消耗资源高的线程id,利用strace命令查看该线程所有系统调用 1.top 查到占用cpu高的进程pid 2.查看该pid的线程 ...
- Linux系统下如何查看物理内存占用率
Linux系统下如何查看物理内存占用率 Linux下看内存和CPU使用率一般都用top命令,但是实际在用的时候,用top查看出来的内存占用率都非常高,如:Mem: 4086496k total, ...
- Linux下如何查看高CPU占用率线程
转于:http://www.cnblogs.com/lidabo/p/4738113.html 目录(?)[-] proc文件系统 proccpuinfo文件 procstat文件 procpidst ...
- Linux下如何查看高CPU占用率线程 LINUX CPU利用率计算
目录(?)[-] proc文件系统 proccpuinfo文件 procstat文件 procpidstat文件 procpidtasktidstat文件 系统中有关进程cpu使用率的常用命令 ps ...
- linux中断源码分析 - 软中断(四)
本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 在上一篇文章中,我们看到中断实际分为了两个部分,俗称就是一部分是硬中断,一部分是软中断.软中断是专门用于处理中断 ...
- Linux环境下进程的CPU占用率
阿里云服务器网站:https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=qqwovx6h 文字来源:http://www.s ...
随机推荐
- js 客户端打印html 并且去掉页眉、页脚
print() 方法用于打印当前窗口的内容,支持部分或者整个网页打印. 调用 print() 方法所引发的行为就像用户单击浏览器的打印按钮.通常,这会产生一个对话框,让用户可以取消或定制打印请求. w ...
- Pandas库的使用--Series
一.概念 Series相当于一维数组. 1.调用Series的原生方法创建 import pandas as pd s1 = pd.Series(data=[1,2,4,6,7],index=['a' ...
- sublime自动保存(失去焦点自动保存)
sublime是轻量的编辑器,经常用sublime编辑器来做一些小例子,使用起来很方便. 在使用sublime的时候需要不断的 ctrl + s 保存代码,才能看到效果. 这样的操作很繁琐,保存的多了 ...
- Docker三十分钟快速入门(下)
一.背景 上篇文章我们进行了Docker的快速入门,基本命令的讲解,以及简单的实战,那么本篇我们就来实战一个真实的项目,看看怎么在产线上来通过容器技术来运行我们的项目,来达到学会容器间通信以及dock ...
- 设计一个有getMin功能的栈(2)
题目: 实现一个特殊的栈,在实现栈的基本功能的基础上,再实现返回栈中最小元素的操作. 要求: 1.pop.push.getMin操作的时间复杂度都是O(1) 2.设计的栈类型可以输用现成的栈结构 解答 ...
- 1、ABPZero系列教程之拼多多卖家工具 前言
此系列文章围绕着拼多多卖家工具来介绍ABPZero的使用,内容包括手机登录.手机注册.拼团提醒.微信公众号绑定帐号.有拼团发送消息到微信公众号(只要关注过微信公众号并已绑定系统帐号). 学习此系列必备 ...
- 【转载】MySQL5.6.27 Release Note解读(innodb及复制模块)
新功能 问题描述(Bug #18871046, Bug #72811): 主要为了解决一个比较“古老”的MySQL在NUMA架构下的“swap insanity”问题,其表现为尽管为InnoDB ...
- uImage和zImage的区别
1.各种文件的意义 vmlinux 编译出来的最原始的内核文件,未压缩. zImage 是vmlinux经过gzip压缩后的文件. bzImage bz表示“big zImage”,不是用bzi ...
- 解决前端开发sublime text 3编辑器无法安装插件的问题
今天在笔记本电脑上安装了个sublime,但是却出现无法装插件的问题.于是稍微在网上查了些资料,并试验了一番,写了如下文章. 安装插件的步骤: 弹出 选中install package 如果出现如下问 ...
- Vijos-P1057题解
题目如下: https://www.vijos.org/p/1057 思路分析: 输入文件第一行为两个整数n,m(1<=n,m<=1000),接下来n行,每行m个数字,用空格隔开.0表示该 ...