KVM中virtio-user工作思路(十二)

主要查看一下virtio-user的工作思路,個人覺得他主要是用來替換KNI或者OVS的TAP設備,更好的用法應該是給container來用,主要是通過操作/dev/vhost-net創建kernel的tap設備用,然後kernel和virtio-user進行內存映射,便於收發報文。

更正一下:目前來說container用virtio-user還不太合適,因爲如果TAP設備加入到namespace的話,重啓virtio-user就因爲在當前的宿主機找不到TAP設備,會生成一個新的TAP設備。這塊目前沒有解決。

官方圖
在這裏插入圖片描述
以上就是virtio-user的結構圖,我們可以看到virtio-user驅動會在內核生成一個tap設備,然後另一端連接DPDK,報文通過內核發送到用戶態。

virtio-user創建tap端口流程

接下來詳細看一下,函數路徑如下,就是初始化的時候,根據參數設置初始化虛擬設備。

rte_eal_init–>rte_bus_probe–>vdev_probe–>vdev_probe_all_drivers–>virtio_user_pmd_probe主要是兩個操作

  • 首先會解析一些參數,用來配置tap口,支持的參數爲queues,cq,mac,path,queue_size,iface,這裏面path是必備的,但是mac和iface我們可能也常用。
  • 如果進程是primary的話,調用virtio_user_dev_init初始化設備
  • 如果進程是secondary的話,調用rte_eth_dev_attach_secondary綁定設備,這裏所做的就是簡單的獲取端口,默認就是由primary進行端口的配置了。
  • eth_virtio_dev_init初始化vhost-user或者vhost-net設備

virtio_user_dev_init–>virtio_user_dev_setup主要是根據支持對端爲vhost-user和vhost-net,並且配置通知和中斷,另外我們接下來主要關心一下vhost-net。

virtio_user_dev_setup

  • 當是vhost-user時,得到vhost-user相關的ops,vhost-net時,得到kernel相關的vhost的ops,接下來就看kernel的vhost-net,不管vhost-user。
  • 首先申請vhostfds和tapfds的內存相關空間。
  • 調用vhost_kernel_setup打開相關的設備,比如我們打開的是dev/vhost-net。
  • 調用virtio_user_dev_init_notify去初始化通知。
  • 調用virtio_user_fill_intr_handle創建中斷。

eth_virtio_dev_init

  • virtio_init_device初始化設備
  • rte_intr_callback_register註冊中斷回調

virtio_init_device

  • vtpci_reset重置設備
  • vtpci_set_status告訴host,注意到設備,並且知道怎麼去驅動它了
  • virtio_alloc_queues爲設備創建隊列 virtio_configure_intr配置中斷
  • vtpci_reinit_complete實際調用vtpci_set_status告訴host,驅動完成。

vtpci_set_status–>virtio_user_set_status

  • 如果驅動完成了,調用virtio_user_start_device驅動設備
  • 如果是重置標誌,調用virtio_user_reset重置設備
  • 如果其他狀態,則將狀態記錄在設備中

virtio_user_start_device

  • virtio_user_queue_setup調用virtio_user_create_queue,最終調用ioctl告知kernel的vhost,創建隊列。
  • dev->ops->send_request調用vhost_kernel_ioctl配置共享內存
  • virtio_user_queue_setup調用virtio_user_kick_queue配置隊列的vring
  • dev->ops->enable_qp調用vhost_kernel_enable_queue_pair創建並且配置tap設備

vhost_kernel_enable_queue_pair

  • vhost_kernel_open_tap創建tap設備,並且進行配置。
  • vhost_kernel_set_backend配置tap設備

數據傳遞流程

Kernel部分

接下來我們看一下數據的傳遞路徑,主要看一個流向,就是pktgen通過tap口進行流量發送,然後最終會傳遞給virtio-user的接收。pktgen發送直接調用的是tap的ndo_start_xmit,即tun_net_xmit。

tun_net_xmit–>vhost_poll_wakeup–>vhost_poll_queue–>vhost_work_queue–>wake_up_process會喚醒vhost_worker。

vhost_worker–>handle_rx_kick–>handle_rx–>tun_recvmsg–>tun_do_read會進行報文的收取,然後發送到用戶態,而virtio-user處會輪詢收取報文,所以我們略過了消息通知機制,其實是我沒有找到。

DPDK部分

rte_eth_rx_burst–>virtio_recv_pkts_vec會從相應的隊列中讀取數據。

目前問題

  • virtio-user創建的tap設備是down的狀態,需要手動up,up之前,virtio-user是不知道設備是down的,如果有別的類型的端口的報文,可能就會向virtio-user端口轉發。最後就是tap設備up或者down的狀態目前還不能通知virtio-user。
  • mvs重啓後tap設備丟失,tap設備重新生成後,是down狀態,並且Mac會變化,創建時並不能指定,tap設備丟失的問題會在DPDK-18.05中加入,但是這個功能穩定性和可用性還需要再驗證。
  • virtio-user創建的tap設備的mac地址不能指定。

原文鏈接:https://zhaozhanxu.com/2017/12/25/DPDK/2017-12-25-virtio-user/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章