vhost.c 代码逻辑
vhost_devices 初始化
struct virtio_net *vhost_devices[MAX_VHOST_DEVICE];
struct virtio_net {
struct rte_vhost_memory *mem;
uint64_t features;
uint64_t protocol_features;
int vid;
uint32_t flags;
uint16_t vhost_hlen;
int16_t broadcast_rarp;
uint32_t nr_vring;
int async_copy;
int extbuf;
int linearbuf;
struct vhost_virtqueue *virtqueue[VHOST_MAX_QUEUE_PAIRS * 2];
struct inflight_mem_info *inflight_info;
char ifname[IF_NAME_SZ];
uint64_t log_size;
uint64_t log_base;
uint64_t log_addr;
struct rte_ether_addr mac;
uint16_t mtu;
uint8_t status;
struct rte_vhost_device_ops const *notify_ops;
uint32_t nr_guest_pages;
uint32_t max_guest_pages;
struct guest_page *guest_pages;
int slave_req_fd;
rte_spinlock_t slave_req_lock;
int postcopy_ufd;
int postcopy_listening;
struct rte_vdpa_device *vdpa_dev;
void *extern_data;
struct rte_vhost_user_extern_ops extern_ops;
} __rte_cache_aligned;
graph TD; subgraph _alloc_vring_queue [检查并alloc_vring_queue:创建vhost_virtqueue] vhost_user_check_and_alloc_queue_pair --> alloc_vring_queue end subgraph VHOST_USER_SET_VRING_CALL [VHOST_USER_SET_VRING_CALL ] vhost_user_set_vring_call --> VHOST_USER_SET_VRING_CALL_if{vq->ready} end VHOST_USER_SET_VRING_CALL_if -- enable->disable --> vhost_user_notify_queue_state subgraph VHOST_USER_SET_VRING_ADDR vhost_user_set_vring_addr --> translate_ring_addresses end subgraph set_vring_state [ysk2_set_vring_state 队列使能] ysk2_set_vring_state --> ysk2_vq_enable --> vring_vva_to_gpa --> ysk2_rxtx_queue_enable --> ysk2_vdpa_rx_queue_setup ysk2_vdpa_rx_queue_setup -- 创建收发包队列 --> ysk2_create_rxqp --> ysk2_alloc_ring --> rte_vfio_container_dma_map ysk2_vdpa_rx_queue_setup --> ysk2_recover_vring_state end subgraph _ysk2_vdpa_config [ysk2_vdpa_config] ysk2_vdpa_config --> ysk2_setup_config_relay ysk2_vdpa_config --> ysk2_dev_start ysk2_vdpa_config --> ysk2_pmd_relay_start ysk2_vdpa_config --> ysk2_dma_map end subgraph VHOST_USER_SET_FEATURES [VHOST_USER_SET_FEATURES] vhost_user_set_features --> ysk2_set_features --> ysk2_set_features_if{sw_lm} -- yes --> ysk2_set_vring_state end ysk2_set_features_if{sw_lm} -- yes --> _ysk2_vdpa_config subgraph _vhost_user_notify_queue_state [使能队列通知机制并改变队列状态] vhost_user_notify_queue_state --> vhost_enable_guest_notification vhost_user_notify_queue_state --> ysk2_set_vring_state vhost_user_notify_queue_state --> vring_state_changed end subgraph VHOST_USER_SET_MEM_TABLE vhost_user_set_mem_table --> vhost_user_mmap_region end subgraph VHOST_USER_GET_VRING_BASE vhost_user_get_vring_base --> vhost_destroy_device_notify --> ysk2_vdpa_close --> ysk2_dev_close --> ysk2_dev_stop end subgraph start [start_vdpa] main --> start_vdpa --> rte_vhost_driver_start(path='/tmp/vdpa-socket0') --> vhost_user_start_client vhost_user_start_client --> vhost_new_device vhost_user_start_client --> vhost_setup_virtio_net main --> pci_probe end start --> init_hw subgraph init_hw [ysk2_init_hw 设备初始化] pci_probe_all_drivers --> rte_pci_probe_one_driver --> ysk2_pci_probe ysk2_pci_probe --> ysk2_vfio_setup --> rte_pci_map_device ysk2_pci_probe --> ysk2_init_hw ysk2_init_hw --> rte_eth_dev_create subgraph ethdev_init [ysk2_ethdev_init 初始化] direction TB ysk2_mempool_init --hw->tx_mp/rx_mp 在这里初始化--> ysk2_create_mempool end rte_eth_dev_create --> ethdev_init rte_eth_dev_create -- hw->dev_cfg 初始化 --> ysk2_virtio_dev_cfg_init ysk2_init_hw --> ysk2_dev_configure end subgraph pmd_relay_start [ysk2_pmd_relay_start pmd 收发包逻辑] ysk2_pmd_relay_start --> ysk2_relay_thread_main --> ysk2_relay_all_queues --> ysk2_rx_relay ysk2_rx_relay --> ysk2_virtio_rx_split --> fill_vec_buf_split --> rx_desc_to_mbuf ysk2_rx_relay --> ysk2_vdpa_rx_pkt_burst --> ysk2_process_rx_cq ysk2_adapter_note>ysk2_adapter 的数据在`ysk2_tx_relay`这一层更新] style ysk2_adapter_note stroke-dasharray: 5 5 ysk2_adapter_note -.- ysk2_rx_relay end subgraph vhost_user_msg [vhost_user消息处理] vhost_user_read_cb --> vhost_user_msg_handler vhost_user_msg_handler --> virtio_is_ready %%vhost_user_msg_handler end vhost_user_msg_handler ==> vhost_msg subgraph vhost_msg [vhost_user_msg状态机] %%msg_id0(VHOST_USER_NONE) msg_id1(VHOST_USER_GET_FEATURES) msg_id2(VHOST_USER_SET_FEATURES) msg_id3(VHOST_USER_SET_OWNER) %%msg_id4(VHOST_USER_RESET_OWNER) msg_id5(VHOST_USER_SET_MEM_TABLE) %%msg_id6(VHOST_USER_SET_LOG_BASE) %%msg_id7(VHOST_USER_SET_LOG_FD) msg_id8(VHOST_USER_SET_VRING_NUM) msg_id9(VHOST_USER_SET_VRING_ADDR) msg_id10(VHOST_USER_SET_VRING_BASE) msg_id11(VHOST_USER_GET_VRING_BASE) msg_id12(VHOST_USER_SET_VRING_KICK) msg_id13(VHOST_USER_SET_VRING_CALL) %%msg_id14(VHOST_USER_SET_VRING_ERR) msg_id15(VHOST_USER_GET_PROTOCOL_FEATURES) msg_id16(VHOST_USER_SET_PROTOCOL_FEATURES) msg_id17(VHOST_USER_GET_QUEUE_NUM) msg_id18(VHOST_USER_SET_VRING_ENABLE) %%msg_id19(VHOST_USER_SEND_RARP) %%msg_id20(VHOST_USER_NET_SET_MTU) msg_id21(VHOST_USER_SET_SLAVE_REQ_FD) %%msg_id22(VHOST_USER_IOTLB_MSG) %%msg_id23(VHOST_USER_POSTCOPY_ADVISE) %%msg_id24(VHOST_USER_POSTCOPY_LISTEN) %%msg_id30(VHOST_USER_POSTCOPY_END) %%msg_id31(VHOST_USER_GET_INFLIGHT_FD) %%msg_id32(VHOST_USER_SET_INFLIGHT_FD) msg_id39(VHOST_USER_SET_STATUS) msg_id40(VHOST_USER_GET_STATUS) %%msg_id25(VHOST_USER_SET_CONFIG) %%msg_id24(VHOST_USER_GET_CONFIG) msg_id0 ==> msg_id1 == 1 ==> msg_id15 == 2 ==> msg_id16 == 3 ==> msg_id17 == 4 ==> msg_id21 == 5 ==> msg_id3 == 6 ==> msg_id1 == 7 ==> msg_id13 == 8 ==> msg_id18 == 9 ==> msg_id2 == 10 ==> msg_id40 == 11 ==> msg_id39 == 12 ==> msg_id5 == 13 ==> msg_id8 == 14 ==> msg_id10 == 15 ==> msg_id9 == 16 ==> msg_id12 == 17 ==> msg_id13 == 18 ==> msg_id40 == 19 ==> msg_id39 close == 20 ==> msg_id11 end vhost_user_msg_handler --> _alloc_vring_queue init_hw --> vhost_user_msg msg_id2 -.-> VHOST_USER_SET_FEATURES msg_id13 -. 17 .-> VHOST_USER_SET_VRING_CALL msg_id9 -.-> VHOST_USER_SET_VRING_ADDR msg_id5 -.-> VHOST_USER_SET_MEM_TABLE msg_id12 -. post enable.-> _vhost_user_notify_queue_state msg_id13 -. post:17 enable.-> _vhost_user_notify_queue_state msg_id11 -.-> VHOST_USER_GET_VRING_BASE subgraph dev_status %% 0x0(VIRTIO_DEVICE_STATUS_RESET) %% 0x01(VIRTIO_DEVICE_STATUS_ACK) %% 0x02(VIRTIO_DEVICE_STATUS_DRIVER) %% 0x04(VIRTIO_DEVICE_STATUS_DRIVER_OK) %% 0x08(VIRTIO_DEVICE_STATUS_FEATURES_OK) %% 0x40(VIRTIO_DEVICE_STATUS_DEV_NEED_RESET) %% 0x80(VIRTIO_DEVICE_STATUS_FAILED) newstatus_1["`VIRTIO_DEVICE_STATUS_ACK VIRTIO_DEVICE_STATUS_DRIVER VIRTIO_DEVICE_STATUS_DRIVER_OK VIRTIO_DEVICE_STATUS_FEATURES_OK`"] dev_status_0 --> VIRTIO_DEVICE_STATUS_FEATURES_OK --> newstatus_1 --> dev_status_0 end subgraph dev_flag %%#define VIRTIO_DEV_RUNNING ((uint32_t)1 << 0) %%#define VIRTIO_DEV_READY ((uint32_t)1 << 1) %%#define VIRTIO_DEV_BUILTIN_VIRTIO_NET ((uint32_t)1 << 2) %%#define VIRTIO_DEV_VDPA_CONFIGURED ((uint32_t)1 << 3) %%#define VIRTIO_DEV_FEATURES_FAILED ((uint32_t)1 << 4) %%#define VIRTIO_DEV_LEGACY_OL_FLAGS ((uint32_t)1 << 5) newflags_1["`VIRTIO_DEV_BUILTIN_VIRTIO_NET VIRTIO_DEV_LEGACY_OL_FLAGS`"] newflags_2["`VIRTIO_DEV_BUILTIN_VIRTIO_NET VIRTIO_DEV_LEGACY_OL_FLAGS VIRTIO_DEV_READY`"] newflags_3["`VIRTIO_DEV_BUILTIN_VIRTIO_NET VIRTIO_DEV_LEGACY_OL_FLAGS VIRTIO_DEV_READY VIRTIO_DEV_RUNNING`"] newflags_4["`VIRTIO_DEV_BUILTIN_VIRTIO_NET VIRTIO_DEV_LEGACY_OL_FLAGS VIRTIO_DEV_READY VIRTIO_DEV_RUNNING VIRTIO_DEV_VDPA_CONFIGURED`"] dev_flag_0 --> VIRTIO_DEV_BUILTIN_VIRTIO_NET --> newflags_1 --> newflags_2 --> newflags_3 --> newflags_4 --> dev_flag_0 end msg_id39 -. post:19 .-> ysk2_vdpa_config vhost_new_device -. init .-> VIRTIO_DEV_BUILTIN_VIRTIO_NET vhost_setup_virtio_net -. init .-o newflags_1 msg_id39 -.-> virtio_is_ready -. post:19 .-o newflags_2 msg_id39 -. post:19 new_device之后且virtio_is_ready .-o newflags_3 msg_id39 -. post:19 dev_conf之后且virtio_is_ready .-o newflags_4 msg_id39 -.-o dev_status msg_id11 -. post:20 .-> vhost_user_notify_queue_state --> ysk2_set_vring_state