1. 程式人生 > >DPDK之(八)——vhost庫

DPDK之(八)——vhost庫

設置 _id lba 系列 要求 是個 物理內存 文件描述符 合並

轉:http://www.cnblogs.com/danxi/p/6652725.html

vhost庫實現了一個用戶空間的virtio net server,允許用戶直接處理virtio ring隊列。換句話說,它讓用戶可以從VM virtio網絡設備讀取或寫入數據包,為了達到這個目的,vhost庫應該可以:

  • 訪問客戶虛擬機內存,對於QEMU,這個是通過設置 -objectmemory-backend-file,share=on,...選項。這意味著QEMU將會在客戶虛擬機的內存裏創建一個文件,share=on 選項允許其他進程訪問這個文件,也就意味著能訪問客戶虛擬機內存。
  • 知道vring所有必需的信息,如可用的ring存儲在哪裏,vhost定義了一些消息,通過Unix domain socket文件來通知後臺所有的信息,這樣就知道如何去處理這個vring了。


vhost API概述


rte_vhost_driver_register(path, flags) 這個函數主要是向系統註冊vhost驅動,path 是指定Unix domain socket文件路徑。
當前支持的flags有:

  • RTE_VHOST_USER_CLIENT DPDK 如果設置了這個值,vhost-user將會作為客戶端,下面會有解釋。
  • RTE_VHOST_USER_NO_RECONNECT 當DPDK vhost-user作為客戶端的話,它會一直嘗試重連服務端QEMU直到成功。這在下面2種情況下非常有用:

    當QEMU還沒有啟動時
    當QEMU重啟時(比如客戶操作重啟了)
    重連選項默認是開啟的。然而,這個flag會讓它關閉。

  • RTE_VHOST_USER_DEQUEUE_ZERO_COPY 如何設置了這個值,出隊零拷貝選項會被開啟。默認是關閉的。這有一些事實(包括限制)你需要知道當你要去設置這個值的時候:

  零拷貝對小數據包是不友好的(典型是報文長度小於512)。
   零拷貝在VM2VM的情況下是非常好的。比如在2個VM之間運行iperf,在開啟了TSO的情況下,提升到70%以上。
  對於VM2NIC的情況,nb_tx_desc必須足夠的小,如果virtio間接特性沒開啟小於等於64,如果開啟了,小於等於128.這是因為當出隊零拷貝如果開啟了的話,客戶TX使用的vring,只有在對應的mbuf釋放了才會更新。

因此,nb_tx_desc必須是足夠小,只有這樣才能使PMD驅動及時的用完可用的Tx描述符和釋放mbuf。否則,客戶Tx vring會被餓死。

客戶內存基於巨頁內存會獲得更好的性能。1G大小是最好的。當出隊零拷貝開啟了,客戶物理內存地址和主機物理地址的映射必須建立好。使用非巨頁內存意味著非常多的頁分段。

為了簡化處理,DPDK vhost使用了線性查找這些段,因此段越小,就能越快的獲取到這個映射關系。溫馨提示:將來會使用樹查找來提速。

rte_vhost_driver_session_start() 這個函數啟動vhost會話來輪詢處理vhost消息。這是個無限循環,因此應該放到一個專用線程裏來調用。
rte_vhost_driver_callback_register(virtio_net_device_ops) 這個函數註冊一系列回調函數,使得DPDK應用程序在事件發生的時候調用合適的函數。當前支持如下事件:

  • new_device(int vid)

    這個回調是在有一個virtio網絡設備處於就緒的時候調用,vid是這個virtio設備ID。

  • destroy_device(int vid)

    這個回調是在有一個virtio網絡設備關閉(或者連接斷開)的時候調用,vid是這個virtio設備ID。

  • vring_state_changed(int vid, uint16_t queue_id, int enable)

    這個回調是當指定的隊列狀態變化的時候(比如開啟或停止)調用。

rte_vhost_enqueue_burst(vid, queue_id, pkts, count) 發送(入隊)count 個數量的數據包從主機到客戶虛擬機。
rte_vhost_dequeue_burst(vid, queue_id, mbuf_pool, pkts, count) 從客戶虛擬機接收(出隊)count個數量的數據包,並存儲在pkts上。
rte_vhost_feature_disable/rte_vhost_feature_enable(feature_mask) 這個函數關閉或開啟一些特性。舉個栗子,它能關閉可合並緩沖區和TSO特性,默認這2個是開啟的。

vhost-user的實現


vhos-user通過Unix domian socket來傳遞消息。這意味著DPDK vhost-user的實現有2個選項:
DPDK vhost-user作為服務端
DPDK 會創建一個Unix domain socket服務文件並在它上面監聽連接。
註意:這是默認模式,在DPDK 16.07之後唯一的模式
DPDK vhost-user作為客戶端
不像服務端模式,這個模式不創建socket文件,它只是嘗試去連接服務端。
當DPDK vhost-user應用程序重啟了,DPDK vhost-user會嘗試重新連接服務端。這就是reconnect特性是怎樣工作的。

註意:
重連特性要求QEMU 2.7版本及以上。
vhost支持的特性必須在重啟前後都完全一致。舉個栗子,TSO關閉了然後開啟,不會有任何作用並可能發生未知問題。

不管哪種模式,一旦連接建立了,DPDK vhost-user將會啟動接收並處理來自QEMU的vhost消息。
對於文件描述符的消息,文件描述符可以直接在vhost進程裏,當它已經通過 Unix domain socket安裝了。
支持如下的vhost消息:

  1. VHOST_SET_MEM_TABLE
  2. VHOST_SET_VRING_KICK
  3. VHOST_SET_VRING_CALL
  4. VHOST_SET_LOG_FD
  5. VHOST_SET_VRING_ERR


對於VHOST_SET_MEM_TABLE消息,QEMU會發送每一個內存區域的信息並且它的文件描述符在這個消息的輔助數據裏。這個文件描述就是用來映射這塊內存區域的。

VHOST_SET_VRING_KICK用來作為信號將vhost設備放入到數據平面,VHOST_GET_VRING_BASE作為信號去數據平面刪除vhost設備。
當socket連接關閉時,vhost會刪除這個設備。

DPDK之(八)——vhost庫