Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance Linux中的NET_DMA TCP接收卸载_Performance_Linux Kernel_Tcp - Fatal编程技术网

Performance Linux中的NET_DMA TCP接收卸载

Performance Linux中的NET_DMA TCP接收卸载,performance,linux-kernel,tcp,Performance,Linux Kernel,Tcp,Linux内核可以选择启用TCP接收副本卸载功能(CONFIG\u NET\u DMA)。我使用iperf(TCP窗口大小=250 KB,缓冲区长度=2 MB)和oprofile在三种情况下测试性能:启用和不启用NET_DMA、启用NET_DMA和sk_rcvlowat设置为200 KB。结果如下: 禁用NET_DMA时:带宽可达到930 Mbps,\u copy\u tofu\rom\u user占用36.1%的cpu时间 启用NET_DMA时:带宽小于上述情况下的40 Mbps(890

Linux内核可以选择启用TCP接收副本卸载功能(
CONFIG\u NET\u DMA
)。我使用
iperf
(TCP窗口大小=250 KB,缓冲区长度=2 MB)和oprofile在三种情况下测试性能:启用和不启用NET_DMA、启用NET_DMA和
sk_rcvlowat
设置为200 KB。结果如下:

  • 禁用NET_DMA时:带宽可达到930 Mbps,
    \u copy\u tofu\rom\u user
    占用36.1%的cpu时间

  • 启用NET_DMA时:带宽小于上述情况下的40 Mbps(890 Mbps),
    \u copy\u tofrom\u user
    占用33.5%的cpu时间

  • 启用NET_DMA(sk_rcvlowat=200KB):带宽为874 Mbps,
    \u copy\u tofrom\u user
    占用25.1%的cpu时间

我还尝试检查函数tcp_recvmsg()(在/net/ipv4/tcp.c中)(内核版本为2.6.32.2)。这就是我理解NET_DMA工作方式的方式:

//在tcp_revmsg()的开头

#ifdef配置网络DMA

   tp->ucopy.dma_chan = NULL;

   preempt_disable();

   skb = skb_peek_tail(&sk->sk_receive_queue);

   {
           int available = 0;

           if (skb)
                   available = TCP_SKB_CB(skb)->seq + skb->len - (*seq);
           if ((available < target) &&
               (len > sysctl_tcp_dma_copybreak) && !(flags & MSG_PEEK) &&
               !sysctl_tcp_low_latency &&
               dma_find_channel(DMA_MEMCPY)) {
                   preempt_enable_no_resched();
                   tp->ucopy.pinned_list =
                                   dma_pin_iovec_pages(msg->msg_iov, len);
           } else {
                   preempt_enable_no_resched();
           }
   }
}否则

   sk_wait_data(sk, &timeo);
当进程处于休眠状态时,到达的数据包将通过
tcp\u dma\u try\u early\u copy()
中的
tcp\u rcv\u-builded()
(在
/net/ipv4/tcp\u-input.c
中)直接跳转到用户空间缓冲区。也许这是Netu DMA的有效点,进程进入休眠状态,但数据可以通过硬件移动到其缓冲区

//在/net/ipv4/tcp\u input.c:tcp\u dma\u try\u early\u copy()中

如果((tp->ucopy.len==0)||

}

当没有更多缓冲区(
tp->ucopy.len==0
)或分配的
skb
的总大小大于1/2
sk\u rcvbuf
(我发现
sk_rcvbuf
设置为TCP窗口大小
iperf

这是我第一次在Linux中使用TCP/IP堆栈。我不确定我上面得出的结论是否正确,如果我错了,请纠正我。我的问题是:

问题1:为什么启用NET_DMA的情况下的带宽总是低于未启用NET_DMA的情况下的带宽

问题2:是否有一组好的值(TCP窗口大小、缓冲区长度、
sk_rcvlowat
)来提高启用网络DMA的情况下的性能

问题3:每次DMA传输大约只有1448字节。它是否太小而无法进行DMAed


任何建议都将不胜感激。提前谢谢。

我的猜测是,对于小数据包(1448现在被认为是小数据包),激活和等待IOAT中断的延迟开销比简单复制内存的开销要高,特别是在内存和CPU访问速度很快的情况下。现代服务器可以使用
memcpy
推送5GB/秒的速度


对于10Gbit/sec以太网,尽可能使用更高的MTU和更大的缓冲区是值得的。我认为原始的接收卸载测试仅在单个数据包约为PAGE_大小时才开始显示性能提高。

嗨,Dan,谢谢你的回复。你完全正确,我们创建了一个虚拟test来比较memcpy和DMA速度。测试表明,对于大小大于2048字节的数据包,DMA会受益。使用较小的负载(在本例中为1448),memcpy甚至比DMA更快,分配DMA描述符的开销相当高。如果我们使用MTU 9000,DMA可以节省大约10%的CPU使用率
   /* Do not sleep, just process backlog. */

   release_sock(sk);

   lock_sock(sk);
   sk_wait_data(sk, &timeo);
   (tcp_flag_word(tcp_hdr(skb)) & TCP_FLAG_PSH) ||

   (atomic_read(&sk->sk_rmem_alloc) > (sk->sk_rcvbuf >> 1))) {

       tp->ucopy.wakeup = 1;

       sk->sk_data_ready(sk, 0);