DPDK vhost庫(二十四)

Vhost庫實現了一個用戶空間virtio網絡服務器,允許用戶直接操作virtio。 換句話說,它允許用戶通過VM virtio網絡設備獲取/發送數據包。 爲了達到這個功能,一個vhost庫需要實現:

訪問guest內存:

  • 對於QEMU,這是通過使用 -object memory-backend-file,share=on,… 選項實現的。這意味着QEMU將創建一個文件作爲guest RAM。 選項 share=on 允許另一個進程映射該文件,這意味着該進程可以訪問這個guest RAM。

知道關於vring所有必要的信息:

  • 諸如可用環形存儲鏈表的存儲空間。Vhost定義了一些消息(通過Unix套接字傳遞)來告訴後端所有需要知道如何操作vring的信息。

1、vhost API 概述

以下是一些關鍵的Vhost API函數概述:

  • rte_vhost_driver_register(path, flags)
    此函數將vhost驅動程序註冊到系統中。path 指定Unix套接字的文件路徑。
    當前支持的flags包括:

    • RTE_VHOST_USER_CLIENT
      當使用該flag時,DPDK vhost-user 作爲客戶端。 請參閱以下說明。

    • RTE_VHOST_USER_NO_RECONNECT
      當 DPDK vhost-user 作爲客戶端時,它將不斷嘗試連接到服務端(QEMU),知道成功。 這在以下兩個情況中是非常有用的:

      • 當 QEMU 還沒啓動時
      • 當 QEMU 重啓時(如guset OS 重啓)
        這個重新連接選項是默認啓用的,但是,可以通過設置這個標誌來關閉它。
    • RTE_VHOST_USER_DEQUEUE_ZERO_COPY
      設置此flag時將啓用出隊了零複製。默認情況下是禁用的。
      在設置此標誌時,需要知道以下原則:

      • 零拷貝對於小數據包(小於512)是不好的。
      • 零拷貝對VM2VM情況比較好。對於兩個虛擬機之間的ipref,提升性能可能高達70%(當TSO使能時).
      • 對於VM2NIC情況,nb_tx_desc 必須足夠小:如果未啓動virtio間接特性則 <=64,否則 <= 128。
        這是因爲,當啓用出隊列零拷貝時,只有當相應的mbuf被釋放時,客戶端TX使用的vring纔會被更新。 因此,nb_tx_desc必須足夠小,以便PMD驅動程序將耗盡可用的TX描述符,並及時釋放mbufs。 否則,guset TX vring將無mbuf使用。
      • Guest的內存應該使用應該使用huge page支持以獲得更好的性能。最好使用1G大小的頁面。
        當啓用出隊零拷貝時,必須建立guest 物理地址和host物理地址之間的映射。 使用non-huge page則意味着更多的頁面細分。 爲了簡單起見,DPDK vhost對這些段進行了線性搜索,因此,段越少,我們得到的映射就越快。 注意:將來我們可能使用樹搜索來提升速度。
  • rte_vhost_driver_set_features(path, features)
    此函數設置vhost-user驅動支持的功能位。 vhost-user驅動可以是vhost-user net,但也可以是其他的,例如vhost-user SCSI。

  • rte_vhost_driver_callback_register(path, vhost_device_ops)
    此函數註冊一組回調函數,以便在發生某些事件時讓DPDK應用程序採取適當的操作。 目前支持以下事件:

    • new_device(int vid)
      這個回調在virtio設備準備就緒時調用,vid 是虛擬設備ID。

    • destroy_device(int vid)
      當virtio設備關閉時(或vhost連接中斷),調用此函數處理。

    • vring_state_changed(int vid, uint16_t queue_id, int enable)
      當特定隊列的狀態發生改變,如啓用或禁用,將調用此回調。

    • features_changed(int vid, uint64_t features)
      這個函數在feature改變時被調用。例如,VHOST_F_LOG_ALL 將分別在實時遷移的開始/結束時設置/清除。

  • rte_vhost_driver_disable/enable_features(path, features))
    該函數禁用或啓用某些功能。例如,可以使用它來禁用可合併的緩衝區和TSO功能,這兩個功能默認都是啓用的。

  • rte_vhost_driver_start(path)
    這個函數觸發vhost-user協商。它應該在初始化一個vhost-user驅動程序結束時被調用。

  • rte_vhost_enqueue_burst(vid, queue_id, pkts, count)
    傳輸(入隊)從host到guest的 count 包。

  • rte_vhost_dequeue_burst(vid, queue_id, mbuf_pool, pkts, count)
    接收(出隊)來自guest的 count 包,並將它們存儲在 pkts。

2、vhost-user 實現

vhost-user 使用Unix套接字來傳遞消息。這意味着DPDK vhost-user的實現具有兩種角色:

  • DPDK vhost-user作爲server: DPDK 將創建一個Unix套接字服務器文件,並監聽來自前端的連接。
    注意,這是默認模式,也是DPDK v16.07之前的唯一模式。
  • DPDK vhost-user最爲client: 與服務器模式不同,此模式不會創建套接字文件;
    它只是試圖連接到服務器(而不是創建文件的響應)。
  • 當DPDK vhost-user應用程序重新啓動時,DPDK vhost-user將嘗試再次連接到服務器。這是“重新連接”功能的工作原理。

注意:“重連” 功能需要 QEMU v2.7 及以上的版本。
vhost支持的功能在重新啓動之前和之後必須完全相同。例如,如果TSO被禁用,但是重啓之後被啓用了,將導致未定義的錯誤。

無論使用哪種模式,建立連接之後,DPDK vhost-user 都將開始接收和處理來自QEMU的vhost消息。

對於帶有文件描述符的消息,文件描述符可以直接在vhost進程中使用,因爲它已經被Unix套接字安裝了。

當前支持的vhost 消息包括:

  • VHOST_SET_MEM_TABLE
  • VHOST_SET_VRING_KICK
  • VHOST_SET_VRING_CALL
  • VHOST_SET_LOG_FD
  • VHOST_SET_VRING_ERR

對於 VHOST_SET_MEM_TABLE 消息,QEMU將在消息的輔助數據中爲每個存儲區域及其文件描述符發送信息。 文件描述符用於映射該區域。

VHOST_SET_VRING_KICK 用作將vhost設備放入數據面的信號, VHOST_GET_VRING_BASE 用作從數據面移除vhost設備的信號。

當套接字連接關閉,vhost將銷燬設備。

3、支持vhost的vSwitch

有關更多vhost詳細信息以及如何在vSwitch中支持vhost,請參閱《DPDK Sample Applications Guide》。

原文鏈接:https://lockless.github.io/2017/11/01/dpdk-pg-27/

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