启动
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收包?