缩写说明:
RTE:Run-Time Environment
EAL:Environment Abstraction Layer
PMD: Poll-Mode Driver
一、dpdk mbuf 和 mtu计算
1、ovs-dpdk内存使用方式
1)默认情况下,OVS DPDK使用共享内存模型。这意味着多个端口可以共享同一个内存池。
添加一个新端口后,它将具有给定的MTU和套接字ID。如果先前已为具有相同MTU和套接字ID的现有端口创建了内存池,
则该内存池将用于两个端口。如果不存在支持这些参数的内存池,则将创建一个新的内存池。
2)非共享内存,按照端口分配独立内存,多个相同配置端口将会有更多内存使用
$ ovs-vsctl set Open_vSwitch . other_config:per-port-memory=true
2、mtu和mbuf关系
MTU大小 MBUFS个数
1500 or greater 262144
Less than 1500 16384
如果内存分配不够,256K不足将会按照一半尝试,直到降低16K
MTU = 1500 Bytes
Number of mbufs = 262144
Mbuf size = 3008 Bytes
Memory required = 262144 * 3008 = 788 MB
MTU = 1800 Bytes
Number of mbufs = 262144
Mbuf size = 3008 Bytes
Memory required = 262144 * 3008 = 788 MB
MTU 1500 和 1800 将会共享内存池
MTU = 6000 Bytes
Number of mbufs = 262144
Mbuf size = 7104 Bytes
Memory required = 262144 * 7104 = 1862 MB
MTU = 9000 Bytes
Number of mbufs = 262144
Mbuf size = 10176 Bytes
Memory required = 262144 * 10176 = 2667 MB
非共享内存分配参照附录地址
3 参数 -m
--socket-mem <amounts of memory per socket>
Preallocate specified amounts of memory per socket.
dpdk启动不再需要指定预分配的内存,当然也是可以这样做
指定后,这块内存不再被释放,不指定在使用时动态分配内存
4 ovs mbuf对齐
#define RTE_ETHER_ADDR_LEN 6 /**< Length of Ethernet address. */
#define RTE_ETHER_TYPE_LEN 2 /**< Length of Ethernet type field. */
#define RTE_ETHER_CRC_LEN 4 /**< Length of Ethernet CRC. */
#define RTE_ETHER_HDR_LEN \
(RTE_ETHER_ADDR_LEN * 2 + \
RTE_ETHER_TYPE_LEN) /**< Length of Ethernet header. */
#define FRAME_LEN_TO_MTU(frame_len) ((frame_len) \
- RTE_ETHER_HDR_LEN - RTE_ETHER_CRC_LEN)
#define NETDEV_DPDK_MBUF_ALIGN 1024
#define NETDEV_DPDK_MAX_PKT_LEN 9728
#define RTE_PKTMBUF_HEADROOM 128
ROUND_UP(MTU_TO_MAX_FRAME_LEN(mtu), NETDEV_DPDK_MBUF_ALIGN)
+ RTE_PKTMBUF_HEADROOM;
mtu根据1024对齐,然后减去 RTE_ETHER_HDR_LEN 14 RTE_ETHER_CRC_LEN 4
9000 = 9 * 1024 + 128 - 18 = 9216 + 128 - 18 = 9326
5999 = 6 * 1024 + 128 - 18 = 6144 + 128 - 18 = 6254
mempool "ovsbd3c994900062540016384"
snprintf(mp_name, RTE_MEMPOOL_NAMESIZE, "ovs%08x%02d%05d%07u", hash, socket_id, mtu, n_mbufs)
mempool "ovsbd 3c994900 06254 00 16384"
二、dpdk ovs多队列
1、qemu需要开启多队列
-chardev socket,id=char2,path=/usr/local/var/run/openvswitch/vhost-user-2
-netdev type=vhost-user,id=mynet2,chardev=char2,vhostforce,queues=$q
-device virtio-net-pci,mac=00:00:00:00:00:02,netdev=mynet2,mq=on,vectors=$v
2、vhost再连接设备后,会根据参数自动配置多队列
不支持手动配置多队列,因为n_rxq只有符合qemu配置的队列才能正常工作
至少设置2个PMD核,不然流量只会入一个队列,其他队列创建了,但是不起作用
$ ovs-vsctl set Open_vSwitch . other_config:vhost-iommu-support=true
在考虑安全性时候需要部署,为兼容老版本,默认是false,在qemu v2.9.1后可以安全开启
3、如果vm的流量会经过dpdk的物理接口
需要在物理接口上配置至少两个队列,这样可以增加使用多个PMD核的概率
三、dpdk vhost 内存使用
vhost实现了用户可以直接操作virtio ring队列,从虚拟网络设备直接接收和发送数据
应该能够满足两点功能:
1、可以访问客户内存:
客户机要添加qemu 参数 -object memory-backend-file,share=on,创建共享内存文件
同时允许其他进程访问内存文件
2、知晓队列详细信息
通过socket传递消息,ring的所有配置
这里着重说明vhost处理消息中的VHOST_SET_MEM_TABLE
qemu在消息中发送自己内存的存储区域和文件描述符,用于vhost映射该区域
后续会有,vswitchd内存异常问题与此强相关
参考:
https://docs.openvswitch.org/en/latest/topics/dpdk/memory/
http://doc.dpdk.org/guides/prog_guide/env_abstraction_layer.html
http://doc.dpdk.org/guides/prog_guide/vhost_lib.html?highlight=vhost