成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Linux虛擬化KVM-Qemu分析之Vhost-Net

云計算 虛擬化
結構體的核心圍繞著數據和通知機制,其中數據在vhost_virtqueue中體現,而通知主要是通過vhost_poll來實現,具體的細節下文將進一步描述。

 [[397740]]

本文轉載自微信公眾號「LoyenWang」,作者LoyenWang。轉載本文請聯系LoyenWang公眾號。

背景

  • Read the fucking source code! --By 魯迅
  • A picture is worth a thousand words. --By 高爾基

說明:

  • KVM版本:5.9.1
  • QEMU版本:5.0.0
  • 工具:Source Insight 3.5, Visio
  • 文章同步在博客園:https://www.cnblogs.com/LoyenWang/

1. 概述

讓我們先來看看問題的引入,在之前的virtio系列文章中,網絡虛擬化的框架如下圖所示:

  • Qemu中的virtio-net設備數據包收發,通過用戶態訪問tap設備完成的;
  • 收發過程涉及Guest OS,KVM,Qemu中的virtio-net設備,Host中的網絡協議棧等的交互,路徑長并且涉及的切換多,帶來了性能的損耗;
  • vhost-net的引入,就是將vitio-net后端設備的數據處理模塊下沉到Kernel中,從而提高整體的效率;

vhost-net的框架圖如下:

  • 從圖中可以看出,Guest的網絡數據交互直接可以通過vhost-net內核模塊進行處理,而不再需要從內核態切換回用戶態的Qemu進程中進行處理;
  • 之前的文章分析過virtio設備與驅動,針對數據傳遵循virtio協議,因此vhost-net中需要去實現virtqueue的相關機制;

本文將分析vhost-net的原理,只說重點,進入主題。

2. 數據結構

vhost-net內核模塊的層次結構如下圖:

  • struct vhost_net:用于描述Vhost-Net設備。它包含幾個關鍵字段:1)struct vhost_dev,通用的vhost設備,可以類比struct device結構體內嵌在其他特定設備的結構體中;2)struct vhost_net_virtqueue,實際上對struct vhost_virtqueue進行了封裝,用于網絡包的數據傳輸;3)struct vhost_poll,用于socket的poll,以便在數據包接收與發送時進行任務調度;
  • struct vhost_dev:描述通用的vhost設備,可內嵌在基于vhost機制的其他設備結構體中,比如struct vhost_net,struct vhost_scsi等。關鍵字段如下:1)vqs指針,指向已經分配好的struct vhost_virtqueue,對應數據傳輸;2)work_list,任務鏈表,用于放置需要在vhost_worker內核線程上執行的任務;3)worker,用于指向創建的內核線程,執行任務列表中的任務;
  • struct vhost_virtqueue:用于描述設備對應的virtqueue,這部分內容可以參考之前virtqueue機制分析,本質上是將Qemu中virtqueue處理機制下沉到了Kernel中。關鍵字段如下:1)struct vhost_poll,用于poll eventfd對應的文件,當不滿足處理請求時會添加到eventfd對應的等待隊列中,而一旦被喚醒,該結構體中的struct vhost_work(執行函數被初始化為handle_tx_kick,以發送為例)將被放置到內核線程中去執行;

結構體的核心圍繞著數據和通知機制,其中數據在vhost_virtqueue中體現,而通知主要是通過vhost_poll來實現,具體的細節下文將進一步描述。

3. 流程分析

3.1 初始化

vhost-net為內核模塊,注冊為misc設備,Qemu通過系統調用接口與內核交互,Qemu中的初始化如下圖:

  • Qemu中tap設備初始化在net_init_tap中完成,其中net_init_tap_one打開vhost-net設備文件,用于與內核的vhost-net交互;
  • vhost_set_backend_type:設置vhost的后端類型,以及vhost的操作函數集。目前有兩種vhost后端,一種是在內核態實現的virtio后端,一種是在用戶態中實現的virtio后端;
  • kernel_ops:vhost的內核操作函數集,都是一些回調函數的實現,最終會通過vhost_kernel_call-->ioctl-->vhost-net.ko路徑,進行配置;

ioctl系統調用,與驅動交互簡單來說可以分為三大類,下邊分別介紹幾個關鍵的設置:

vhost net設置

  • VHOST_SET_OWNER:底層會為調用者創建一個內核線程,對應到前文中數據結構中的vhost_worker,同時在vhost_dev結構體中還會保存調用者線程的內存空間數據結構;
  • VHOST_NET_SET_BACKEND:設置vhost-net的后端設備,比如Qemu往內核態傳遞的tap設備對應的fd,從而讓vhost-net直接與tap設備進行通信;

vhost dev設置

從Guest OS中的虛擬地址到最終的Host上的物理地址映射關系如上圖所示,如果在Guest OS中要將數據發送出去,實際上只需要將Qemu中關于Guest OS的物理地址布局信息傳遞下去,此外再結合VHOST_SET_OWNER時傳遞的內存空間信息,就可以根據映射關系找到Guest OS中的數據對應到Host之上的物理地址,完成最后搬運即可;

  • VHOST_SET_MEM_TABLE:將Qemu中的虛擬機物理地址布局信息傳遞給內核,為了解釋清楚這個問題,可以回顧一下之前內存虛擬化中的一張圖:

vhost vring設置

  • VHOST_SET_VRING_KICK:設置vhost-net模塊前端virtio驅動發送通知時觸發的eventfd,通知機制,最終觸發handle_kick函數的執行;
  • VHOST_SET_VRING_CALL:設置vhost-net后端到虛擬機virtio前端的中斷通知,參考之前文章中的irqfd機制;
  • 此外關于vring的設備還包括vring的大小,地址信息等;

上述的這些設置的流程路徑如下,只畫出了關鍵路徑:

  • 當Guest OS中的virtio-net驅動完成初始化后,會通過vp_set_status來設置狀態,以通知后端驅動已經ready,此時會觸發VM的退出并進入KVM進行異常處理,最終路由給Qemu;
  • Qemu中的vcpu線程監測異常,當檢測到KVM_EXIT_MMIO時,去回調注冊該IO區域的讀寫函數,比如virtio_pci_common_write函數,在該函數中逐級往下最終調用到vhost_net_start函數;
  • 在vhost_net_start中最終去通過kernel_ops函數集去設置底層并交互;

初始化完成后,接下來讓我們看看數據的發送與接收,為了能將整個流程表達清楚,我會將完整的圖拆分成幾個步驟來講述。

3.2 數據發送

1)

發送前的框圖如下:

  • Guest OS中的virtio-net驅動中維護兩個virtqueue,分別用于發送和接收;
  • 圖中的datagram表示的是需要發送的數據;
  • KVM模塊提供了ioeventfd和irqfd用于通知機制;
  • vhost-net模塊中創建好了vhost_worker內核線程,用于處理任務;

2)

  • 當數據包準備好之后,通過往kick fd上觸發信號,從而喚醒vhost_worker內核線程來調用handle_tx_kick進行數據的發送;
  • 當Tap/Tun不具備發送條件時,vhost_worker會poll在socket上,等待Tap/Tun的喚醒,一旦被喚醒后可以調用handle_tx_net發送;
  • 最終的handle_tx完成具體的發送;

3)

  • vhost_get_vq_desc函數在vritqueue中查找可用的buffer,并將信息存儲到iov中,以便更好的訪問;
  • sock->ops->sendmsg()函數,實際調用的是tun_sendmsg函數,在該函數中分配了skb結構體,并將iov[]中的信息傳遞過來,最終如圖中所示完成數據的拷貝和發送,通過NIC發送出去;

4)

  • 數據發送完畢后,通過irqfd機制通知vcpu;

3.3 數據接收

數據的接收是發送的逆過程,流程一致:

1)

初始化部分與發送過程一致;

Tap/Tun驅動從NIC接收到數據包,準備發送給vhost-net;

2)

  • vhost-net中的vhost_worker線程也poll在兩個fd之上,與發送端類似;
  • kick fd上觸發信號時最終調用handle_rx_kick函數,Tap/Tun對應的socket上觸發信號時,調用handle_rx_net函數;
  • 最終通過handle_rx來完成實際的接收;

3)

  • 接收過程中,vhost_get_vq_desc獲取virtqueue中的可用buffer,并將信息存儲到iov[]中;
  • sock->ops->recvmsg()函數實際指向tun_recvmsg函數,在該函數中最終完成數據的傳遞;

4)

數據接收完成后,通過irqfd機制通過vcpu,從而在Guest OS中進行處理;

vhost-net的整體內容較多,從上到下涉及到的細節很繁瑣,短短的一篇文章難以涵蓋全部,權當給個輪廓了。

暫且告一段落吧。

參考

Introduction to virtio-networking and vhost-net

Deep dive into Virtio-networking and vhost-net

Vhost-net Device IOTLB

 

責任編輯:武曉燕 來源: LoyenWang
相關推薦

2021-03-28 18:23:22

Linux虛擬化Virtqueue

2021-02-14 16:49:22

Linux虛擬化Virtio

2020-11-23 07:19:15

Linux虛擬化KVM

2023-08-17 16:51:00

虛擬化QEMUKVM

2020-06-18 16:39:10

KVM虛擬化虛擬機

2015-09-25 16:18:36

2019-11-12 14:48:00

Linux桌面虛擬化KVM

2024-12-27 15:28:10

HBAFC-SAN存儲

2018-06-05 14:28:25

KVM嵌套虛擬化

2019-06-27 15:38:52

KVM虛擬化開源

2021-04-30 09:46:08

虛擬化Virtio-Net云計算

2013-03-07 10:02:13

IBMKVM

2013-05-23 13:56:12

IBMKVM特點

2019-08-22 16:26:02

LinuxKVM虛擬化

2012-12-28 10:18:03

LinuxXenKVM

2013-04-08 10:08:22

開源虛擬化KVM

2013-05-29 15:33:01

開源虛擬化KVM

2015-09-09 17:25:06

2015-09-18 09:33:03

2013-04-07 09:33:31

開源虛擬化KVM
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品视频在线免费观看 | 国产区在线观看 | 一区二区三区中文字幕 | 毛片毛片毛片毛片 | 一区在线播放 | 免费观看一级毛片 | 美女福利网站 | 国产激情毛片 | 国产综合av | 91婷婷韩国欧美一区二区 | 日韩在线观看网站 | 国产亚洲一区精品 | 黑人巨大精品 | 精品久久久久久亚洲精品 | 亚洲天堂一区 | 91精品国产欧美一区二区成人 | 久久精品一区二 | 日日夜精品视频 | 亚洲精品久久久一区二区三区 | 成人依人| 国产精品一区二区三区久久 | 欧美一区2区三区3区公司 | 国产欧美在线观看 | 久久高清精品 | 国产色在线 | 日本亚洲精品 | 欧美一区二区三区 | 国产精品一区二区av | 黄色一级视频免费 | 中文在线a在线 | 羞羞在线观看视频 | 久久久蜜桃 | 一级毛片,一级毛片 | 久热国产在线 | 中文字幕亚洲欧美日韩在线不卡 | 2022国产精品| 亚洲电影一区二区三区 | 天天色官网 | h视频免费在线观看 | 999www视频免费观看 | 日本不卡一区二区 |