首页 > 社交 > 科普中国

25

常驻编辑 科普中国 2022-06-02 子系统   网络   队列   内核   网卡   函数   源码   内存   过程   数据   用户

gEf拜客生活常识网

再回头看一下硬中断触发软中断的源码。gEf拜客生活常识网

//file: drivers/net/ethernet/intel/igb/igb_main.c  
static inline void ____napi_schedule(...){  
 list_add_tail(&napi->poll_list, &sd->poll_list);  
 __raise_softirq_irqoff(NET_RX_SOFTIRQ);  
}  

这里有个很有意思的细节,无论硬中断是因为是有数据要接收,还是说发送完成通知,从硬中断触发的软中断都是 NET_RX_SOFTIRQ。这个我们在第一节说过了,这是软中断统计中 RX 要高于 TX 的一个原因。gEf拜客生活常识网

好我们接着进入软中断的回调函数 igb_poll。在这个函数里,我们注意到有一行 igb_clean_tx_irq,参见源码:gEf拜客生活常识网

//file: drivers/net/ethernet/intel/igb/igb_main.c  
static int igb_poll(struct napi_struct *napi, int budget)  
{  
 //performs the transmit completion operations  
 if (q_vector->tx.ring)  
  clean_complete = igb_clean_tx_irq(q_vector);  
 ...  
}  

我们来看看当传输完成的时候,igb_clean_tx_irq 都干啥了。gEf拜客生活常识网

//file: drivers/net/ethernet/intel/igb/igb_main.c  
static bool igb_clean_tx_irq(struct igb_q_vector *q_vector)  
{  
 //free the skb  
 dev_kfree_skb_any(tx_buffer->skb);  
  
 //clear tx_buffer data  
 tx_buffer->skb = NULL;  
 dma_unmap_len_set(tx_buffer, len, 0);  
  
 // clear last DMA location and unmap remaining buffers */  
 while (tx_desc != eop_desc) {  
 }  
}  

无非就是清理了 skb,解除了 DMA 映射等等。到了这一步,传输才算是基本完成了。gEf拜客生活常识网

为啥我说是基本完成,而不是全部完成了呢?因为传输层需要保证可靠性,所以 skb 其实还没有删除。它得等收到对方的 ACK 之后才会真正删除,那个时候才算是彻底的发送完毕。gEf拜客生活常识网

最后

用一张图总结一下整个发送过程gEf拜客生活常识网

gEf拜客生活常识网

了解了整个发送过程以后,我们回头再来回顾开篇提到的几个问题。gEf拜客生活常识网

1.我们在监控内核发送数据消耗的 CPU 时,是应该看 sy 还是 si ?gEf拜客生活常识网

在网络包的发送过程中,用户进程(在内核态)完成了绝大部分的工作,甚至连调用驱动的事情都干了。只有当内核态进程被切走前才会发起软中断。发送过程中,绝大部分(90%)以上的开销都是在用户进程内核态消耗掉的。只gEf拜客生活常识网

有一少部分情况下才会触发软中断(NET_TX 类型),由软中断 ksoftirqd 内核进程来发送。gEf拜客生活常识网

所以,在监控网络 IO 对服务器造成的 CPU 开销的时候,不能仅仅只看 si,而是应该把 si、sy 都考虑进来。gEf拜客生活常识网

2. 在服务器上查看 /proc/softirqs,为什么 NET_RX 要比 NET_TX 大的多的多?gEf拜客生活常识网

之前我认为 NET_RX 是读取,NET_TX 是传输。对于一个既收取用户请求,又给用户返回的 Server 来说。这两块的数字应该差不多才对,至少不会有数量级的差异。但事实上,飞哥手头的一台服务器是这样的:gEf拜客生活常识网

gEf拜客生活常识网

经过今天的源码分析,发现这个问题的原因有两个。gEf拜客生活常识网

第一个原因是当数据发送完成以后,通过硬中断的方式来通知驱动发送完毕。但是硬中断无论是有数据接收,还是对于发送完毕,触发的软中断都是 NET_RX_SOFTIRQ,而并不是 NET_TX_SOFTIRQ。gEf拜客生活常识网

第二个原因是对于读来说,都是要经过 NET_RX 软中断的,都走 ksoftirqd 内核进程。而对于发送来说,绝大部分工作都是在用户进程内核态处理了,只有系统态配额用尽才会发出 NET_TX,让软中断上。gEf拜客生活常识网

综上两个原因,那么在机器上查看 NET_RX 比 NET_TX 大的多就不难理解了。gEf拜客生活常识网

3.发送网络数据的时候都涉及到哪些内存拷贝操作?gEf拜客生活常识网

这里的内存拷贝,我们只特指待发送数据的内存拷贝。

相关阅读:

  • 量子子系统的新理论
  • 无法检验的科学是科学吗?
  • 伊朗成功发射太空拖船“萨曼轨道传输器”
  • HUAWEI
  • 纳莱迪人儿童遗骸发现谜团重重
  • 并不是所有的物联网平台都适合系统集成
  • 网络销售怎么去聊客户(网络销售出单难吗)
  • 多益网络怎么样(广州多益网络工作感受)
  • 网络短视频内容审核标准细则发布:短视频节目不得未经
  • 移动网络怎么样(移动300兆相当于电信多少兆)
    • 网站地图 |
    • 声明:登载此文出于传递更多信息之目的,并不意味着赞同其观点或证实其描述。文章内容仅供参考,不做权威认证,如若验证其真实性,请咨询相关权威专业人士。