系统相关
首页 > 系统相关> > Linux虚拟化KVM-Qemu分析(八)之virtio初探

Linux虚拟化KVM-Qemu分析(八)之virtio初探

作者:互联网

目录

概述

1. 网卡

1.1 网卡工作原理

1.2 Linux网卡驱动

2. 网卡全虚拟化

2.1 全虚拟化方案

2.2 弊端

3. 网卡半虚拟化

3.1 virtio

3.2 半虚拟化方案

参考


 

Linux虚拟化KVM-Qemu分析(一)

Linux虚拟化KVM-Qemu分析(二)之ARMv8虚拟化

Linux虚拟化KVM-Qemu分析(三)之KVM源码(1)

Linux虚拟化KVM-Qemu分析(四)之CPU虚拟化(2)

Linux虚拟化KVM-Qemu分析(五)之内存虚拟化

Linux虚拟化KVM-Qemu分析(六)之中断虚拟化

Linux虚拟化KVM-Qemu分析(七)之timer虚拟化

Linux虚拟化KVM-Qemu分析(八)之virtio初探

Linux虚拟化KVM-Qemu分析(九)之virtio设备

virtio 网络的演化

在CentOS上进行虚拟化:QEMU、Xen、KVM、LibVirt、oVirt

ARM SMMU原理与IOMMU技术(“VT-d” DMA、I/O虚拟化、内存虚拟化)

OpenVZ,Xen,KVM等:虚拟化解决方案

KVM Virtio: An I/O virtualization framework for Linux(Linux虚拟IO框架)

ARM SMMU原理与IOMMU技术(“VT-d” DMA、I/O虚拟化、内存虚拟化)

用QEMU构建嵌入式LINUX系统

疫情下的远程办公:理解Linux虚拟网络设备之tun/tap

Linux虚拟网络设备之tun/tap

Tun/Tap接口教材-[翻译:Tun/Tap interface tutorial]

Linux的TUN/TAP编程

 

说明:

  1. KVM版本:5.9.1
  2. QEMU版本:5.0.0
  3. 工具:Source Insight 3.5, Visio

概述

1. 网卡

1.1 网卡工作原理

先来看一下网卡的架构图(以Intel的82540为例):

我们主要关心它的数据流,所以,看看它的工作原理吧:

ddr,即双倍速率同步动态随机存储器,是内存的其中一种。

BAR(base address register)

1.2 Linux网卡驱动

在网卡数据流图中,我们也基本看到了网卡驱动的影子,驱动与网卡之间是异步通信:

2. 网卡全虚拟化

2.1 全虚拟化方案

全虚拟化方案,通过软件来模拟网卡,Qemu+KVM的方案如下图:

疫情下的远程办公:理解Linux虚拟网络设备之tun/tap

Linux虚拟网络设备之tun/tap

Tun/Tap接口教材-[翻译:Tun/Tap interface tutorial]

Linux的TUN/TAP编程

一个用户态tap的例子《疫情下的远程办公:理解Linux虚拟网络设备之tun/tap》:

/**
 * TUN/TAP编程示例
 */
#include <net/if.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <linux/if_tun.h>
#include <stdlib.h>
#include <stdio.h>
 
int tun_alloc(int flags)
{
 
    struct ifreq ifr;
    int fd, err;
    char *clonedev = "/dev/net/tun";
 
    //打开tun设备
    if ((fd = open(clonedev, O_RDWR)) < 0) {
        return fd;
    }
 
    memset(&ifr, 0, sizeof(ifr));
    ifr.ifr_flags = flags;
 
    if ((err = ioctl(fd, TUNSETIFF, (void *) &ifr)) < 0) {
        close(fd);
        return err;
    }
 
    printf("Open tun/tap device: %s for reading...\n", ifr.ifr_name);
 
    return fd;
}
 
int main()
{
 
    int tun_fd, nread;
    char buffer[1500];
 
    /* Flags: IFF_TUN   - TUN device (no Ethernet headers)
     *        IFF_TAP   - TAP device
     *        IFF_NO_PI - Do not provide packet information
     */
    tun_fd = tun_alloc(IFF_TUN | IFF_NO_PI);
 
    if (tun_fd < 0) {
        perror("Allocating interface");
        exit(1);
    }
 
    while (1) {
        //从tun设备读取数据
        nread = read(tun_fd, buffer, sizeof(buffer));
        if (nread < 0) {
            perror("Reading from interface");
            close(tun_fd);
            exit(1);
        }
 
        printf("Read %d bytes from tun/tap device\n", nread);
    }
 
    return 0;
}

2.2 弊端

所以,让我们大声喊出本文的主角吧!

 

3. 网卡半虚拟化

在进入主题前,先思考几个问题:

  1. 全虚拟化下Guest可以重用驱动、网络协议栈等,但是在软件全模拟的情况下,我们是否真的需要去访问寄存器吗(比如中断处理),真的需要模拟网卡的自协商机制以及EEPROM等功能吗?
  2. 是否真的需要模拟大量的硬件控制寄存器,而这些寄存器在软件看来毫无意义?
  3. 是否真的需要生产者/消费者模型的通知机制(寄存器访问、中断)?

3.1 virtio

网卡的工作过程是一个生产者消费者模型,但是在前文中可以看出,在全虚拟化状态下存在一些弊端,一个更好的生产者消费者模型应该遵循以下原则:

  1. 寄存器只被生产者使用去通知消费者ring-buffer有数据(消费者可以继续消费),而不再被用作存储状态信息;
  2. 中断被消费者用来通知生产者ring-buffer是非满状态(生产者可以继续生产);
  3. 生产者和消费者的状态信息应该存储在内存中,这样读取状态信息时不需要VM退出,减少overhead;
  4. 生产者和消费者跑在不同的线程中,可以并行运行,并且尽可能多的处理任务;
  5. 非必要情况下,相互之间的通知应该避免使用;
  6. 忙等待(比如轮询)不是一个可以接受的通用解决方案;

基于上述原则,我们来看看从特殊到一般的过程:

所以,在virtio的方案下,网卡的虚拟化看上去就是下边这个样子了:

virtio的数据传递使用scatter-gather list(sg-list)

(番外:传统的block DMA 一次只能传输物理上连续的一个块的数据, 完成传输后发起中断。而scatter-gather DMA允许一次传输多个物理上不连续的块,完成传输后只发起一次中断。 )

 
virtio的核心是virtqueue(VQ)的抽象:

  1. 当Guest的驱动产生一个sg-list时,调用add_buf(SG, Token)入列;
  2. Hypervisor进行出列操作,并消费sg-list,并将sg-list push回去;
  3. Guest通过get_buf()进行清理工作;

上图说的是数据流方向,那么事件的通知机制如下:

大体的数据流和控制流讲完了,细节实现后续再跟进了。

 

3.2 半虚拟化方案

那么,半虚拟化框架下的网卡虚拟化数据流是啥样的呢?

相信你应该对virtio有个大概的了解了,好了,收工。

 

参考

《Virtio networking: A case study of I/O paravirtualization》
《 PCI/PCI-X Family of Gigabit Ethernet Controllers Software Developer's Manual》

欢迎关注个人公众号,不定期更新Linux相关技术文章。

转自公众号

作者:LoyenWang
出处:https://www.cnblogs.com/LoyenWang/
公众号:LoyenWang
版权:本文版权归作者和博客园共有
转载:欢迎转载,但未经作者同意,必须保留此段声明;必须在文章中给出原文连接;否则必究法律责任

标签:virtio,虚拟化,KVM,网卡,Linux,Qemu
来源: https://blog.csdn.net/Rong_Toa/article/details/113819423