当前位置: 首页 > 工具软件 > http-copy > 使用案例 >

Linux内核追踪[4.14] 网络报文send的ZERO-COPY(零拷贝)

裴俊雅
2023-12-01
需求:

       ZERO-COPY对于有性能要求的大数据报文的网络应用来说是一个比较好的优化思路。在之前的内核中,ZERO-COPY只发生在sendfile、splice接口中。send接口无法做到ZERO-COPY。因此通用send 接口进行大报文发送的应用性能仍然有提升空间。

功能:

       4.14内核,Google工程师Willem de Bruijn实现了一个网络报文的通用发送接口(send)的报文ZERO-COPY功能
       经patch作者验证,采用netperf大包发送测试,发送性能提升了39%,实际产品提升了5%~8%。可以看到对于大包发送还是有一定效果的。

接口

       首先,进程需要调用 setsockopt() 接口(传递新的SOCK_ZEROCOPY option)。
       其次,发送接口  send(socket, buffer, length, MSG_ZEROCOPY); 需要传入一个新的MSG_ZEROCOPY flag。
       最后,Userspace App需要hold住上述buffer,不能释放。直到采用  status = recvmsg(socket, &message, MSG_ERRORQUEUE); 接口进行状态判断之后,通过message的内容得知之前的 ZERO-COPY的buffer已经发送完毕了,buffer才能释放。
       之所以需要两步,是因为目前有一些应用会随机的传递一些错误的flag,比如(MSG_ZEROCOPY)。(不过我觉得这个做法有点土,居然需要两步)。

约束
     
       对于需要在内核进行加密或者计算checksum的报文,虽然传递了新参数,内核仍然会有一次拷贝。
       当前只支持发送ZERO-COPY,不支持报文的接收ZERO-COPY。

实现

       在传入的报文length太小时,内核会选择性地拷贝,因为建立ZEROCOPY所需要的页表映射、lock等操作也是需要时间(即使传递了新的ZEROCOPY的flag),小报文拷贝的时间可能还少于这些操作的时间。
       更多的实现待补充......

 类似资料: