virtio收包整体有三种模式,small、big、mergeable,差异主要体现在描述符链表组成方式上。
三种模式具体描述符特征如下:
receive_mergeable:一次fill一个desc,每个desc的next均是0。每个desc的len为PAGE_SIZE,默认应该是4k
add_recvbuf_big:一次fill 17或19个,最后一个desc的next是0,中间的next均为1。第1个desc的len为hdr的长度12, 第2个为PAGE_SIZE-(12+4),其余len为PAGE_SIZE
receive_small:一次fill两个desc,每2个desc由next连接,第二个desc的next位0。第一个给hdr,第二个给data。第一个desc的len为hdr的长度12,第二个desc的len长度为skb->len
三种模式确定方法:
Mergeable模式在virtio规范中有特定的feature可以开启和关闭,对应feature开关如下为VIRTIO_NET_F_MRG_RXBUF,当device侧开启此feature时,driver默认会协商会工作在Mergeable;而驱动进入small模式,首先需要device侧关闭VIRTIO_NET_F_MRG_RXBUF feature,同时guest没有开启TSO或UFO或ECN功能,而当VIRTIO_NET_F_MRG_RXBUF关闭,同时guest开启了TSO或UFO或ECN功能时,此时会进入big模式。
small模式下MTU默认设置为小于等于1500。
驱动中进入big模式条件如下。big模式下: