启动
vswitchd/ovs-vswitchd.c
启动main-->netdev_run-->netdev_initialize-->netdev_dpdk_register-->netdev_register_provider
注册dpdk_vhost_user_class
。
添加dpdk端口的时候,会触发创建pmd线程的操作。dpif_netdev_port_add-->do_add_port-->dp_netdev_set_pmds_on_numa-->pmd_thread_main
如果已经添加了dpdk端口,启动的时候也会触发创建pmd的线程的操作。dpif_netdev_pmd_set-->dp_netdev_reset_pmd_threads-->dp_netdev_set_pmds_on_numa-->pmd_thread_main
dp_netdev_process_rxq_port
接口负责接收报文,然后调用接口dp_netdev_input-->dp_netdev_input__
负责查表然后调用packet_batch_execute-->dp_netdev_execute_actions
执行actions操作。
poll mode线程
pmd_thread_main
pmd_thread_setaffinity_cpu
设置线程绑定的lcore。- for无限循环
- for循环各个端口,执行
dp_netdev_process_rxq_port
处理端口。 - 循环中间会根据变动重新加载端口和队列信息。
dp_netdev_process_rxq_port
- 调用
netdev_rxq_recv
接收报文,前后都有计时。 - 调用
dp_netdev_input
将报文传输给flow,并且发送报文,前后都有计时。
netdev_rxq_recv=>netdev_dpdk_vhost_rxq_recv
- 调用dpdk接口
rte_vhost_dequeue_burst
接收报文。 - 调用
netdev_dpdk_vhost_update_rx_counters
更新统计信息。
dp_netdev_input=>dp_netdev_input__
emc_processing
主要是将收到的几个报文解析key值,并且从cache中查找流表,匹配的报文放入流表;返回不匹配的报文个数。- 如果存在不匹配的报文,调用
fast_path_processing
则继续查找全部表项,找到则将流表放入cache,不匹配则上报到controller。 - 调用
packet_batch_execute
根据流表来操作报文。
emc_processing
- 调用
miniflow_extract
将报文解析到key值。 - 调用
emc_lookup
,从hash表中查找,并且进行key值比较。 - 如果匹配,调用
dp_netdev_queue_batches
将报文添加在flow->batches
中。 - 不匹配将不匹配的报文当前排。
- 调用
dp_netdev_count_packet
统计匹配的报文数。
fast_path_processing
dpcls_lookup
通过classifier查找子流表,如果所有的报文都找到了匹配的子流表,将流表插入缓存中,并且将报文加入flow->batches
。- 如果不匹配,则上报到controller,没细看。
- 统计匹配、不匹配和丢失。
packet_batch_per_flow_execute
- 调用
dp_netdev_flow_get_actions
获取flow对应的actions。 dp_netdev_execute_actions
执行对应的actions。
actions操作
dp_netdev_execute_actions=>odp_execute_actions
- 如果是一些基本操作的话,调用接口
dp_execute_cb
。
dp_execute_cb
- 如果是
OVS_ACTION_ATTR_OUTPUT
,调用dp_netdev_lookup_port
查找端口,然后调用netdev_send
进行报文发送。 - 如果是
OVS_ACTION_ATTR_TUNNEL_PUSH
,调用push_tnl_action
进行tunnel封装,然后调用dp_netdev_recirculate-->dp_netdev_input__
重新查表操作。 - 如果是
OVS_ACTION_ATTR_TUNNEL_POP
,调用netdev_pop_header
解封装,然后调用dp_netdev_recirculate-->dp_netdev_input__
重新查表操作。
netdev_send=>netdev_dpdk_vhost_send=>__netdev_dpdk_vhost_send
- 循环调用dpdk接口
rte_vhost_enqueue_burst
发送报文。 - 调用
netdev_dpdk_vhost_update_tx_counters
更新统计信息。
dpdk接收报文的接口
rte_vhost_dequeue_burst
涉及到一次数据拷贝
dpdk发送报文的接口
rte_vhost_enqueue_burst-->virtio_dev_rx
- 预取
vhost_virtqueue
的信息。 - 根据发送报文数count,将报文放入ring当中。此处涉及到一次数据拷贝。
- 内存屏障进行同步。
- 如果对方支持中断,通过
eventfd_write
通知对方有报文了,一般是对方virtio有中断,virtio-user无中断。
1 条评论
netdev_rxq_recv收包使用dpdk_class的netdev_dpdk_rxq_recv, 转发到挂载了vhost的port上才用netdev_dpdk_vhost_rxq_recv收包?