在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

淺談vhost的數據路徑硬件化 DPDK中的vDPA實現方案

454398 ? 來源: Chinaunix ? 作者:lvyilong316 ? 2020-09-25 15:32 ? 次閱讀

vDPA就是VHOST DATA PATH ACCELERATION,即將vhost的數據路徑硬件化,如下圖所示。

只把dataplane硬件化對于網卡廠商要相對容易實現,否則如果要求dataplane和controlplane都需要硬件支持,這就要求硬件的dataringlayout需要和virtio一致,還需要controlplane的PCIbar和virtiospec一致,而硬件廠商通常有自己定制的pcibar。不過在智能網卡的裸金屬服務器場景,廠商也在做full emulation,即控制面也相對硬件化的方案,我們這只討論正常的dataplane硬件化。

對于kernel的vDPA方案如下圖所示。

這里面有幾個關鍵組件需要介紹一下。

vhost-mdev

在介紹vhost-mdev前需要先介紹virtio-mdev框架,說起virtio-mdev又不得不先講vfio-mdev。

vfio-mdev

先快速對vfio的概念進行掃盲。這個掃盲的目的不是詳細介紹什么是VFIO,而是給對沒有vfio的讀者一個入門的指引。

vfio是Linux Kernel UIO特性的升級版本。UIO的作用是把一個設備的IO和中斷能力暴露給用戶態,從而實現在用戶態對硬件的直接訪問。它的基本實現方法是,當我們probe一個設備的時候,通過uio_register_device()注冊為一個字符設備/dev/uioN,用戶程序通過對這個設備mmap訪問它的IO空間,通過read/select等接口等待中斷。

UIO的缺點在于,用戶態的虛擬地址無法直接用于做設備的DMA地址(因為在用戶態無法知道DMA內存的物理地址),這樣限制了UIO的使用范圍。我們有人通過UIO設備自己的ioctl來提供求物理地址的機制,從而實現DMA,但這種方案是有風險的。這里提到的UIO的缺點,基本上拒絕了大流量IO設備使用該機制提供用戶空間訪問的能力了。

vfio通過IOMMU的能力來解決這個問題。IOMMU可以為設備直接翻譯虛擬地址,這樣我們在提供虛擬地址給設備前,把地址映射提供給vfio,vfio就可以為這個設備提供頁表映射,從而實現用戶程序的DMA操作。背負提供DMA操作這個使命,VFIO要解決一個更大的問題,就是要把設備隔離掉。在Linux的概念中,內核是可信任的,用戶程序是不可信任的,如果我們允許用戶程序對設備做DMA,那么設備也是不可信任的,我們不能允許設備訪問程序的全部地址空間(這會包括內核),所以,每個設備,針對每個應用,必須有獨立的頁表。這個頁表,通過iommu_group承載(iommu_group.domain),和進程的頁表相互獨立。進程必須主動做DMA映射,才能把對應的地址映射寫進去。

所以vfio的概念空間是container和group,前者代表設備iommu的格式,后者代表一個獨立的iommu_group(vfio中用vfio_group代表),我們先創建container,然后把物理的iommu_group綁定到container上,讓container解釋group,之后我們基于group訪問設備(IO,中斷,DMA等等)即可。

這個邏輯空間其實是有破綻的,iommu_group是基于設備來創建的,一個設備有一個iommu_group(或者如果這個設備和其他設備共享同一個IOMMU硬件,是幾個設備才有一個iommu_group),那如果我兩個進程要一起使用同一個設備呢?基于現在的架構,你只能通過比如VF(Virtual Function,虛擬設備),在物理上先把一個設備拆成多個,然后還是一個進程使用一個設備。這用于虛擬機還可以,但如果用于其他功能,基本上是沒戲了。

再說,VF功能基本都依賴SR-IOV這樣的實現,也不是你想用就能用的。這我們就要引出vfio-mdev(以下簡稱mdev)了。

mdev本質上是在vfio層面實現VF功能。在mdev的模型中,通過mdev_register_device()注冊到mdev中的設備稱為父設備(parent_dev),但你用的時候不使用父設備,而是通過父設備提供的機制(在sysfs中,后面會詳細談這個)創建一個mdev,這個mdev自帶一個iommu_group,這樣,你有多個進程要訪問這個父設備的功能,每個都可以有獨立的設備頁表,而且互相不受影響。

所以,整個mdev框架包括兩個基本概念,一個是pdev(父設備),一個是mdev(注意,我們這里mdev有時指整個vfio-mdev的框架,有時指基于一個pdev的device,請注意區分上下文)。前者提供設備硬件支持,后者支持針對一個獨立地址空間的請求。

兩者都是device(struct device),前者的總線是真實的物理總線,后者屬于虛擬總線mdev,mdev上只有一個驅動vfio_mdev,當你通過pdev創建一個mdev的時候,這個mdev和vfio_mdev驅動匹配,從而給用戶態暴露一個普通vfio設備的接口(比如platform_device或者pci_device)的接口。

換句話說,如果一個設備需要給多個進程提供用戶態驅動的訪問能力,這個設備在probe的時候可以注冊到mdev框架中,成為一個mdev框架的pdev。之后,用戶程序可以通過sysfs創建這個pdev的mdev。

pdev注冊需要提供如下參數

點擊(此處)折疊或打開

struct mdev_parent_ops{

struct module*owner;

conststruct attribute_group**dev_attr_groups;

conststruct attribute_group**mdev_attr_groups;

struct attribute_group**supported_type_groups;

int(*create)(struct kobject*kobj,struct mdev_device*mdev);

int(*remove)(struct mdev_device*mdev);

int(*open)(struct mdev_device*mdev);

void(*release)(struct mdev_device*mdev);

ssize_t(*read)(struct mdev_device*mdev,char __user*buf,

size_t count,loff_t*ppos);

ssize_t(*write)(struct mdev_device*mdev,constchar __user*buf,

size_t count,loff_t*ppos);

long(*ioctl)(struct mdev_device*mdev,unsignedintcmd,

unsigned long arg);

int(*mmap)(struct mdev_device*mdev,struct vm_area_struct*vma);

};

其中三個attribute_group都用于在sysfs中增加一組屬性。device本身根據它的bus_type,就會產生一個sysfs的屬性組(所謂屬性組就是sysfs中的一個目錄,里面每個文件就是一個“屬性”,文件名就是屬性名,內容就是屬性的值),假設你的pdev是/sys/bus/platform/devices/abc.0,那么這三個attribute_group產生的屬性分別在:

dev_attr_groups:/sys/bus/platform/devices/abc.0下

mdev_attr_groups:/sys/bus/platform/devices/abc.0/下,/sys/bus/mdev/devices中有這個設備的鏈接

supported_type_groups:/sys/bus/platform/devices/abc.0/mdev_supported_types/下,里面有什么屬性是框架規定的,包括:

1)name:設備名稱

2)available_instances:還可以創建多少個實例

3)device_api:設備對外的接口API標識

這些參數支持具體用戶態驅動如何訪問這個設備,pdev的驅動當然可以增加更多。mdev框架在這個目錄中還增加如下屬性:

1)devices:這是一個目錄,鏈接向所有被創建的mdev

2)create:向這個文件中寫入一個uuid就可以創建一個新的mdev,實際上產生對mdev_parent_ops.create()的回調;

mdev這個模型建得最不好的地方是,create的時候只能傳進去一個uuid,不能傳進去參數,這樣如果我創建的設備需要參數怎么辦呢?那就只能創建以后再設置了,這增加了“創建以后沒有足夠資源提供”的可能性),不過看起來,大部分情況我們是可以接受這個限制的。

virtio-mdev

說完了vfio-mdev再來看看virtio-mdev。我們為什么要引入vfio-mdev,因為為了屏蔽不同廠商的配置接口差異需要一個中間層,而這個中間層就是基于vfio-mdev的virtio-mdev。virtio-mdev框架的主要目的是提供給不同的vDPA網卡廠家一個標準的API來實現他們自己的控制路徑。mdev提供的框架可以支持vDPA實現數據和控制路徑的分離。數據路徑硬化,控制路徑在軟件實現。

這個驅動可以是用戶態基于VFIO,也可以是內核態基于virtio的。在目前這個系列,主要關注基于vfio的用戶態驅動,但是在未來也會討論基于virtio的內核態驅動,比如支持AF_VIRTIO。

這個驅動的實現也比較簡單,本質上就是一些列的virtio-mdev的API。主要包含:

1)set/get設備的配置空間

2)set/get virtqueue的元數據:vring地址,大小和基地址

3)kick一個特定的virtqueue

4)為一個特定的virtqueue注冊回調中斷

5)協商功能

6)set/get臟頁日志

7)啟動/重置設備

可以看到這就是virtio消息處理的功能,所以virtio-mdev就是一個抽象層,對上提供統一的接口來支持virtio的配置,對下屏蔽不同廠商的差異,每個廠商實現自己的這些接口注冊進來。

vhost-mdev

vhost-mdev是一個kernel的模塊,主要功能是:

(1)轉發用戶空間的virtio命令到virtio mdev的API(這里看出vhost-mdev是在virtio-mdev之上的);

(2)復用VFIO的框架來準備DMA映射和解映射的用戶空間請求。

vhost-mdev相當于一個直接和qemu對接的,類似于vhost-net的角色,不過它只是一個轉換的作用,將qemu發過來的virtio命令轉換為virtio mdev的標準API調用(如set_feature,get_feature)。

vhost-mdev通常的工作流程如下:

(1)把自己注冊成一個新類型的mdev驅動

(2)對外提供和vhost-net兼容的ioctl接口,用戶空間的VFIO驅動可以傳遞virtio的命令

(3)翻譯好的virtio命令以virtio mdev API的形式通過mdev bus傳遞給virtio-mdev設備。

(4)當一個新的mdev設備創建時,kernel總是廠商去加載驅動

(5)在加載過程中,vhost-mdev會把virtio mdev設備連接在VFIO的群組,因此DMA請求就可以通過VFIO的文件描述符。

vhost-mdev是連接用戶空間驅動和virtio-mdev設備的關鍵。它為用戶空間驅動提供兩個文件描述符:

1)vhost-mdev FD:從用戶空間接受vhost的控制命令

2)VFIO container FD:用戶空間驅動用來設置DMA

vhost-vfio

vhost-vfio從QEMU的觀點來看,vhost-vfio就是一個新類型的QEMU網路后端用來支持virtio-net的設備。(注意,vhost-vfio是在qemu側工作的)它的主要作用是:

(1)設置vhost-mdev設備:打開vhost-mdev的設備文件,用來傳遞vhost的命令到設備去,得到vhost-mdev設備的container,用來傳遞DMAsetup的命令到VFIO container。

(2)從virtio-net設備接收數據路徑卸載的命令(set/get virtqueue狀態,set臟頁日志,功能協商等等),并把他們翻譯vhost-mdev的ioctl。

(3)接受vIOMMU map和umap的命令并同VFIO DMA的ioctl執行。

最后我們再以下圖總結一下vDPA實現的關鍵,vDPA只將dataplan硬件化,所以重點要考慮的是control plan。設備的PCI配置空間等還是有qemu模擬,但qemu收到Guest寫寄存器的中斷時的處理不能再像對待vhost-net一樣了,所以qemu引入了vhost-vfio模塊用來和后端協商。

而vhost-mdev則作為kernel處理后端協商的代理,接收來自qemu的控制消息,并將消息轉文化virtio-mdev的標準接口調用。Virtio-mdev是一個抽象層,抽象了virtio的常用處理函數接口,同時又基于vfio-mdev框架對接不同硬件設備,而不同的硬件廠商只需要實現virtio-mdev的標準接口,同時支持vfio-mdev即可。這樣控制通道就從qemu到廠商硬件打通了。

DPDK中的vDPA實現

下面我們看一下在DPDK中是如何實現對vDPA的支持的,我們的分析代碼是基于DPDK release 20.02版本的,因為正是在這個版本增加了基于Mellanox設備的vDPA PMD(回想當初寫第一篇關于DPDK的文章還是release 16.07)。Mellanox支持vDPA的網卡有ConnectX-6,Mellanox ConnectX-6 Dx以及Mellanox BlueField。在DPDK的example中有一個vDPA的使用例子,這個是在18.11版本加入的,其使用方式可以參考https://mp.weixin.qq.com/s/YspEKL5fRmoJJbHlyPz9IA。這里我們就從這個example入手分析下DPDK中關于vDPA的實現。

這個程序的啟動命令是類似如下的方式:

./ vdpa -c 0x2 -n 4 --socket-mem 1024,1024 -w 0000:06:00.3,vdpa=1 -w 0000:06:00.4,vdpa=1

vDPA的設備初始化

所以首先一定是通過-w指定的PCI設備加載對應的驅動,我們以Mellanox的vDPA驅動(mlx5_vdpa_driver)為例分析,注意其相關代碼和Mellanox正常mlx5驅動不在一起,而是在drivers/vdpa的專門路徑中。

下面就看一下mlx5_vdpa_driver的注冊過程。

點擊(此處)折疊或打開

static struct rte_pci_driver mlx5_vdpa_driver={

.driver={

.name="mlx5_vdpa",

},

.id_table=mlx5_vdpa_pci_id_map,

.probe=mlx5_vdpa_pci_probe,

.remove=mlx5_vdpa_pci_remove,

.drv_flags=0,

};

其核心是驅動加載函數:mlx5_vdpa_pci_probe

lmlx5_vdpa_pci_probe

點擊(此處)折疊或打開

/**

*DPDK callbacktoregister a PCI device.

*

*Thisfunctionspawns vdpa device out of a given PCI device.

*

*@param[in]pci_drv

*PCI driver structure(mlx5_vpda_driver).

*@param[in]pci_dev

*PCI device information.

*

*@return

*0onsuccess,1toskip this driver,a negative errno value otherwise

*andrte_errnoisset.

*/

staticint

mlx5_vdpa_pci_probe(struct rte_pci_driver*pci_drv __rte_unused,

struct rte_pci_device*pci_dev __rte_unused)

{

struct ibv_device*ibv;

struct mlx5_vdpa_priv*priv=NULL;

struct ibv_context*ctx=NULL;

struct mlx5_hca_attr attr;

intret;

/*......*/

ctx=mlx5_glue->dv_open_device(ibv);

priv=rte_zmalloc("mlx5 vDPA device private",sizeof(*priv),

RTE_CACHE_LINE_SIZE);

ret=mlx5_devx_cmd_query_hca_attr(ctx,&attr);

if(ret){

DRV_LOG(ERR,"Unable to read HCA capabilities.");

rte_errno=ENOTSUP;

gotoerror;

}else{

if(!attr.vdpa.valid||!attr.vdpa.max_num_virtio_queues){

DRV_LOG(ERR,"Not enough capabilities to support vdpa,"

" maybe old FW/OFED version?");

rte_errno=ENOTSUP;

gotoerror;

}

priv->caps=attr.vdpa;

priv->log_max_rqt_size=attr.log_max_rqt_size;

}

priv->ctx=ctx;

priv->dev_addr.pci_addr=pci_dev->addr;

priv->dev_addr.type=PCI_ADDR;

priv->id=rte_vdpa_register_device(&priv->dev_addr,&mlx5_vdpa_ops);

if(priv->id

DRV_LOG(ERR,"Failed to register vDPA device.");

rte_errno=rte_errno?rte_errno:EINVAL;

gotoerror;

}

SLIST_INIT(&priv->mr_list);

SLIST_INIT(&priv->virtq_list);

pthread_mutex_lock(&priv_list_lock);

TAILQ_INSERT_TAIL(&priv_list,priv,next);

pthread_mutex_unlock(&priv_list_lock);

return 0;

error:

if(priv)

rte_free(priv);

if(ctx)

mlx5_glue->close_device(ctx);

return-rte_errno;

}

這個函數首先分配mlx的vDPA設備私有結構struct mlx5_vdpa_priv,然后通過mlx5_devx_cmd_query_hca_attr函數獲取當前設備的屬性并初始化這個vDPA私有結構。其中關鍵的一步是通過rte_vdpa_register_device函數申請vDPA通用結構struct rte_vdpa_device,并將mlx的vDPA ops函數結合mlx5_vdpa_ops設置為其ops。

lrte_vdpa_register_device

點擊(此處)折疊或打開

int

rte_vdpa_register_device(struct rte_vdpa_dev_addr*addr,

struct rte_vdpa_dev_ops*ops)

{

struct rte_vdpa_device*dev;

char device_name[MAX_VDPA_NAME_LEN];

inti;

if(vdpa_device_num>=MAX_VHOST_DEVICE||addr==NULL||ops==NULL)

return-1;

for(i=0;i

dev=vdpa_devices[i];

if(dev&&is_same_vdpa_device(&dev->addr,addr))

return-1;

}

for(i=0;i

if(vdpa_devices[i]==NULL)

break;

}

if(i==MAX_VHOST_DEVICE)

return-1;

snprintf(device_name,sizeof(device_name),"vdpa-dev-%d",i);

dev=rte_zmalloc(device_name,sizeof(struct rte_vdpa_device),

RTE_CACHE_LINE_SIZE);

if(!dev)

return-1;

memcpy(&dev->addr,addr,sizeof(struct rte_vdpa_dev_addr));

dev->ops=ops;/*設置ops為設備廠商的具體實現*/

vdpa_devices[i]=dev;

vdpa_device_num++;/*全局變量,記錄vDPA設備的個數*/

return i;

}

rte_vdpa_register_device中關鍵工作就是分配一個vDPA通用結構struct rte_vdpa_device,并將mlx vDPA的實現操作mlx5_vdpa_ops關聯上。而rte_vdpa_device結構又是一個全局數組,其數組index就是vDPA的設備id,也就是struct mlx5_vdpa_priv中的id。

另外mlx5_vdpa_ops的具體成員和實現結合如下。可以看到這里的函數和vhost-user的消息處理函數很多是對應的。

點擊(此處)折疊或打開

static struct rte_vdpa_dev_ops mlx5_vdpa_ops={

.get_queue_num=mlx5_vdpa_get_queue_num,

.get_features=mlx5_vdpa_get_vdpa_features,

.get_protocol_features=mlx5_vdpa_get_protocol_features,

.dev_conf=mlx5_vdpa_dev_config,

.dev_close=mlx5_vdpa_dev_close,

.set_vring_state=mlx5_vdpa_set_vring_state,

.set_features=mlx5_vdpa_features_set,

.migration_done=NULL,

.get_vfio_group_fd=NULL,

.get_vfio_device_fd=NULL,

.get_notify_area=NULL,

};

這樣就完成了Mellanox側的vDPA設備初始化,產生的相關數據結構如下圖所示。

vDPA和vhost-uesr關聯

廠商定制化的vDPA部分以及初始化完畢,下面我們看下vhost-user和vDPA是怎么關聯的。參考的是vDPA example中的start_vdpa函數,具體如下

lstart_vdpa

點擊(此處)折疊或打開

staticint

start_vdpa(struct vdpa_port*vport)

{

intret;

char*socket_path=vport->ifname;

intdid=vport->did;/*vDPA設備id*/

if(client_mode)

vport->flags|=RTE_VHOST_USER_CLIENT;

if(access(socket_path,F_OK)!=-1&&!client_mode){

RTE_LOG(ERR,VDPA,

"%s exists, please remove it or specify another file and try again. ",

socket_path);

return-1;

}

ret=rte_vhost_driver_register(socket_path,vport->flags);/*初始化vsocket結構,創建vhost-user后端重連線程*/

if(ret!=0)

rte_exit(EXIT_FAILURE,

"register driver failed: %s ",

socket_path);

ret=rte_vhost_driver_callback_register(socket_path,

&vdpa_sample_devops);/*注冊自定義的vsocket->notify_ops*/

if(ret!=0)

rte_exit(EXIT_FAILURE,

"register driver ops failed: %s ",

socket_path);

ret=rte_vhost_driver_attach_vdpa_device(socket_path,did);/*將vsocket結構和vDPA設備關聯*/

if(ret!=0)

rte_exit(EXIT_FAILURE,

"attach vdpa device failed: %s ",

socket_path);

if(rte_vhost_driver_start(socket_path)

rte_exit(EXIT_FAILURE,

"start vhost driver failed: %s ",

socket_path);

return 0;

}

這個函數關鍵執行了4步操作:

(1)rte_vhost_driver_register:初始化vsocket結構,創建vhost-user后端重連線程;

(2)rte_vhost_driver_callback_register:注冊自定義的vsocket->notify_ops;

(3)rte_vhost_driver_attach_vdpa_device:將vsocket結構和vDPA設備關聯

(4)rte_vhost_driver_start:創建vhost控制面消息處理線程,將vsocket加入重連鏈表;

其中(1)(2)(4)都是vhost-user設備的常規操作,這里不再展開,其中關鍵的是(3)。

lrte_vhost_driver_attach_vdpa_device

點擊(此處)折疊或打開

int

rte_vhost_driver_attach_vdpa_device(constchar*path,intdid)

{

struct vhost_user_socket*vsocket;

if(rte_vdpa_get_device(did)==NULL||path==NULL)

return-1;

pthread_mutex_lock(&vhost_user.mutex);

vsocket=find_vhost_user_socket(path);

if(vsocket)

vsocket->vdpa_dev_id=did;

pthread_mutex_unlock(&vhost_user.mutex);

return vsocket?0:-1;

}

這個函數將vDPA的deviceid記錄在vsocket結構中,這樣就將vhost和vDPA設備關聯起來了。

vhost控制面的vDPA初始化

前面說到通過vhost-user的vsocket結構中的vDPA deviceid將vhost-user和vDPA關聯起來,那么下面就來看一下vhost-user進行初始化時怎么將對應vDPA設備初始化的。

首先,vhost-user前后端建立連接后會調用vhost_user_add_connection,而vhost_user_add_connection中則會調用vhost_new_device()分配struct virtio_net結構,而virtio_net中也有一個vdpa_dev_id,在調用vhost_attach_vdpa_device時將vsocket的vdpa_dev_id賦值給virtio_net的vdpa_dev_id。

點擊(此處)折疊或打開

static void

vhost_user_add_connection(intfd,struct vhost_user_socket*vsocket)

{

intvid;

size_t size;

struct vhost_user_connection*conn;

intret;

/*......*/

vid=vhost_new_device();

if(vid==-1){

gotoerr;

}

/*......*/

vhost_attach_vdpa_device(vid,vsocket->vdpa_dev_id);

/*......*/

}

有了這個關聯以后,后續所有vhost-user的消息處理就可以找到對應的vDPA設備,進而找到廠商關聯的vDPA ops函數。回憶前面設備初始化時將Mellanox的mlx5_vdpa_ops注冊到的vDPA設備上,其實這是一個struct rte_vdpa_dev_ops結構,如下所示:

點擊(此處)折疊或打開

/**

*vdpa device operations

*/

struct rte_vdpa_dev_ops{

/**Getcapabilities of this device*/

int(*get_queue_num)(intdid,uint32_t*queue_num);

/**Getsupported features of this device*/

int(*get_features)(intdid,uint64_t*features);

/**Getsupported protocol features of this device*/

int(*get_protocol_features)(intdid,uint64_t*protocol_features);

/**Driver configure/close the device*/

int(*dev_conf)(intvid);

int(*dev_close)(intvid);

/**Enable/disable this vring*/

int(*set_vring_state)(intvid,intvring,intstate);

/**Setfeatures when changed*/

int(*set_features)(intvid);

/**Destination operations when migration done*/

int(*migration_done)(intvid);

/**Getthe vfio group fd*/

int(*get_vfio_group_fd)(intvid);

/**Getthe vfio device fd*/

int(*get_vfio_device_fd)(intvid);

/**Getthe notify area info of the queue*/

int(*get_notify_area)(intvid,intqid,

uint64_t*offset,uint64_t*size);

/**Reservedforfuture extension*/

void*reserved[5];

};

可以看到他和我們的vhost-user消息處理函數很多都是對應的,這也是前面我們提到過的virtio-mdev在DPDK的表現。所以很自然的相當在vhost-user處理后端消息時會調用對應的vDPA處理函數。以vhost_user_set_features為例,其中調用了rte_vdpa_get_device通過virtio-net的vdpa_dev_id獲取到對應的vDPA設備,并調用對應的vDPA的set_features函數。

點擊(此處)折疊或打開

staticint

vhost_user_set_features(struct virtio_net**pdev,struct VhostUserMsg*msg,

intmain_fd __rte_unused)

{

/*......*/

did=dev->vdpa_dev_id;

vdpa_dev=rte_vdpa_get_device(did);

if(vdpa_dev&&vdpa_dev->ops->set_features)

vdpa_dev->ops->set_features(dev->vid);

return RTE_VHOST_MSG_RESULT_OK;

}

其他函數也是類似的,我們可以搜索一下vdpa_dev_id關鍵字確認。

整個vDPA在DPDK的工作方式可以用下圖來表示。

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 服務器
    +關注

    關注

    12

    文章

    9255

    瀏覽量

    85754
  • dma
    dma
    +關注

    關注

    3

    文章

    566

    瀏覽量

    100752
  • 數據路徑
    +關注

    關注

    0

    文章

    4

    瀏覽量

    6311
  • DPDK
    +關注

    關注

    0

    文章

    13

    瀏覽量

    1728
收藏 人收藏

    評論

    相關推薦

    物聯網數據臺是什么?可以實現什么功能?

    物聯網數據臺是一個集成和管理大量設備產生的數據的平臺,主要功能包括數據采集、數據管理、數據可視
    的頭像 發表于 01-10 11:24 ?90次閱讀

    淺談基于物聯網的智能路燈系統-盾華電子智慧路燈解決方案

    淺談基于物聯網的智能路燈系統-盾華電子智慧路燈解決方案
    的頭像 發表于 10-11 10:08 ?422次閱讀
    <b class='flag-5'>淺談</b>基于物聯網的智能路燈系統-盾華電子智慧路燈解決<b class='flag-5'>方案</b>

    SD-WAN技術在直播網絡如何實現智能路徑選擇?

    SD-WAN技術在直播網絡實現智能路徑選擇主要通過以下幾個步驟: 1、實時網絡監控:SD-WAN系統持續監控所有可用的網絡路徑,包括它們的帶寬、延遲、丟包率和抖動等關鍵性能指標。 2
    的頭像 發表于 09-09 14:39 ?338次閱讀

    淺談國產異構雙核RISC-V+FPGA處理器AG32VF407的優勢和應用場景

    任務優化計算資源,提高整體計算效率。 靈活性與可擴展性 : FPGA的靈活性允許用戶根據需求重新配置硬件邏輯,實現高度定制的解決方案。結合RISC-V的開放架構,用戶可以更容易地根
    發表于 08-31 08:32

    適用于數據中心應用硬件加速器的直流/直流轉換器解決方案

    電子發燒友網站提供《適用于數據中心應用硬件加速器的直流/直流轉換器解決方案.pdf》資料免費下載
    發表于 08-26 09:38 ?0次下載
    適用于<b class='flag-5'>數據</b>中心應用<b class='flag-5'>中</b>的<b class='flag-5'>硬件</b>加速器的直流/直流轉換器解決<b class='flag-5'>方案</b>

    智慧校園如何實現管理智能

    智慧校園 是利用現代科技手段,通過信息、智能的方式對校園管理進行全面優化和升級的綜合解決方案實現校園管理智能需要涵蓋多個方面,以下是
    的頭像 發表于 06-18 15:45 ?698次閱讀

    數據臺:企業數字轉型的驅動力量

    在當今數字快速發展的時代,企業正積極尋求轉型升級的新路徑。在這個過程數據臺以其獨特的功能和價值,逐漸成為了企業數字
    的頭像 發表于 05-08 17:00 ?324次閱讀

    淺談光伏電站數據通訊管理機的設計與應用

    淺談光伏電站數據通訊管理機的設計與應用 張穎姣 江蘇安科瑞電器制造有限公司江蘇江陰214405 摘要 :設計了一種分布式光伏電站數據通訊管理機,包括硬件系統和軟件系統.
    的頭像 發表于 03-14 10:23 ?623次閱讀
    <b class='flag-5'>淺談</b>光伏電站<b class='flag-5'>數據</b>通訊管理機的設計與應用

    淺談建筑電氣設計的火災隱患及其對策方案

    淺談建筑電氣設計的火災隱患及其對策方案 張穎姣 安科瑞電氣股份有限公司?上海嘉定201801 摘要:隨著我國城市發展水平的不斷提升,建筑體系已經逐步成熟,而電氣設計能夠滿足建筑日常用電需求,同時也
    的頭像 發表于 03-12 10:28 ?381次閱讀
    <b class='flag-5'>淺談</b>建筑電氣設計<b class='flag-5'>中</b>的火災隱患及其對策<b class='flag-5'>方案</b>

    數智轉型的新篇章:企業如何在「數據飛輪」理念尋求增長?

    在當今的數字浪潮,企業對數據的渴求與日俱增。數據不再僅是輔助決策的工具,而是成為推動業務增長的核心動力。自從「數據
    的頭像 發表于 03-06 16:01 ?639次閱讀

    關于DPDK的一些常見問題

    對于單核多CPU部署,一個CPU分配給操作系統,另一個分配給基于DPDK的應用程序。對于多核部署,無論是否使用超線程,都可以為每個端口分配多個內核。
    的頭像 發表于 03-05 11:44 ?887次閱讀
    關于<b class='flag-5'>DPDK</b>的一些常見問題

    DPDK在AI驅動的高效數據包處理應用

    傳統的數據包處理方式是數據包先到內核最后再到用戶層進行處理。這種方式會增加額外的延遲和CPU開銷,嚴重影響數據包處理的性能。 DPDK 繞過內核,在用戶空間中
    的頭像 發表于 02-25 11:28 ?988次閱讀
    <b class='flag-5'>DPDK</b>在AI驅動的高效<b class='flag-5'>數據</b>包處理應用

    淺談公網無信號區域遠程抄表問題解決方案及產品選型

    淺談公網無信號區域遠程抄表問題解決方案及產品選型 張穎姣 安科瑞電氣股份有限公司 上海嘉定 201801 摘要:隨著計量自動系統的逐步完善,電網全用戶表碼信息采集成為系統數據得以深化
    的頭像 發表于 02-20 15:34 ?591次閱讀
    <b class='flag-5'>淺談</b>公網無信號區域遠程抄表問題解決<b class='flag-5'>方案</b>及產品選型

    建設工業數據臺可以實現哪些功能

    工業數據臺是一個讓工業數據可持續利用起來的中間層平臺,能夠持續不斷將數據變成重要資產并落地于執行業務
    的頭像 發表于 02-01 17:16 ?394次閱讀

    數據臺助力數據可視智能治理

    隨著數字轉型的不斷推進,數據已經成為企業核心競爭力的重要組成部分。如何將海量數據轉化為有價值的信息,為企業決策提供有力支持,運用高效便捷的方式進行管理,成為每個企業必須面對的挑戰。數據
    的頭像 發表于 02-01 13:41 ?331次閱讀
    <b class='flag-5'>數據</b><b class='flag-5'>中</b>臺助力<b class='flag-5'>數據</b>可視<b class='flag-5'>化</b>智能治理
    主站蜘蛛池模板: 美女一级免费毛片| 午夜啪啪免费视频| 成年人看的毛片| 色福利视频| 色爱综合区| 女人张开腿双腿让男人桶| 亚洲电影在线看| 最近新韩国hd视频| 在线观看免费av网站| 在线99热| 国产在播放一区| 亚洲video| 性xxxxbbbb在线| 一级毛片免费全部播放| 四虎影院免费观看| 啪啪网站视频| 51xx嘿嘿午夜| 一道精品视频一区二区三区男同| 欧美经典三级春潮烂漫海棠红| 在线网站你懂| 三级在线国产| 国产一区二区三区乱码| 午夜视频精品| 天天射天天射天天干| 午夜资源站| 九九热在线视频观看| 国产日日操| 亚洲一二| 婷婷丁香激情| 玖玖国产| 午夜国产精品久久影院| 99精品偷自拍| 九九热免费在线观看| 日韩免费三级电影| 成 人 色综合| 国产免费福利网站| 美女扒开尿口给男人桶视频免费 | www色午夜| 国产小视频在线观看www| 午夜三级理论在线观看视频| 免费一区在线观看|