veth网卡的多队列及RPS

背景:

3.10内核下容器使用的veth网卡,默认开启的是一个队列,导致在某些单线程多TCP链接的应用场景下,出现某个CPU软中断高的情况。之前处理的方案一直是开启这个veth网卡的RPS,让其在多流场景下可以去分散到其它CPU上,将某个CPU上的软中断降低。

偶然发现veth也支持多队列,那是不是可以直接利用多队列去分流,不需要手动开启RPS了呢?带着这个问题看一下内核的处理流程。如下。

上层协议栈

->__dev_queue_xmit

   - >netdev_pick_tx  – 这里会通过skb_tx_hash获取发送队列的id

   - > dev_hard_start_xmit->xmit_one → netdev_start_xmit →ndo_start_xmit → veth_xmit

在veth_xmit中

→dev_forward_skb

   → netif_rx_internal

       → get_rps_cpu

最终调用get_rps_cpu接口:

 

其中,skb_get_rx_queue可以通过veth的多队列,拿到不同的队列,但是下面的一个流程,是要配合rps去使用的,所以当前3.10.957的内核即使veth使用了多队列,若没有开rps的话,仍然是返回到当前cpu。

附一个stap脚本:

# cat veth_rps.stp 
#!/usr/bin/stap --all-modules
%{
#include <linux/kernel.h>
#include <linux/net.h>
#include <linux/textsearch.h>
#include <net/checksum.h>
#include <linux/dma-mapping.h>
#include <linux/netdev_features.h>
#include <linux/skbuff.h>
#include <uapi/linux/ip.h>
#include <uapi/linux/udp.h>
#include <uapi/linux/tcp.h>
%}

function get_packet_info:string(skb:long)
%{
     int ret=-1;
     unsigned int src_port = 0;
     unsigned int dest_port = 0;
     struct udphdr *udp_header;
     struct tcphdr *tcp_header;
     struct sk_buff *skb= (struct sk_buff *)STAP_ARG_skb;
     struct iphdr *ip_header;
     unsigned int src_ip=0,dest_ip=0;
     if(!skb)
     {
         goto EXIT_F;
     }
     ip_header = (struct iphdr *)skb_network_header(skb);
     if(!ip_header)
     {
       goto EXIT_F;
     }
     src_ip = (unsigned int)ip_header->saddr;
     dest_ip = (unsigned int)ip_header->daddr;
EXIT_F:
     snprintf(STAP_RETVALUE, MAXSTRINGLEN, "%d.%d.%d.%d",(unsigned int)((unsigned char *)&src_ip)[0],(unsigned int)((unsigned char *)&src_ip)[1],(unsigned int)((unsigned char *)&src_ip)[2],(unsigned int)((unsigned char *)&src_ip)[3]);
%}

#probe kernel.trace("set_rps_cpu") {
probe kernel.statement("get_rps_cpu@net/core/dev.c:3651") {
  SrcIp=get_packet_info($skb)
  if(SrcIp==@1)
  {
      printf("=== %s   queid:  %d, cpu:  %d  , rps map:%x ===\n", SrcIp, $skb->queue_mapping, $cpu, $rxqueue->rps_flow_table)
      print_backtrace()
  }

}

可以看见queid是散列的,但是cpu仍然是-1,最终和调用者的cpu保持一致。 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值