• qemu 线程 vhost


    [root@localhost cloud_images]# lsmod | grep vhost_net
    vhost_net             262144  0 
    vhost                 262144  1 vhost_net
    tap                   262144  1 vhost_net
    tun                   262144  2 vhost_net
    [root@localhost cloud_images]#
    
    vhost-net网卡的后端默认使用linux的虚拟网桥tap设备qemu和虚拟机内部使用virtio-net虚拟网卡。
    
    步骤1: 创建linux网桥和tap设备(对于fedora,centos,redhat等默认有创建好的虚拟网卡)
    
    brctl addbr virbr0
    
    brctl stp virbr0 on
    
    ip tuntap add name virbr0-nic mode tap
    
    ip link set dev virbr0-nic up
    
    步骤二:将host网卡添加到virbr0的一个port,并把ip配置给virbr0
    
    brctl addif virbr0 eth0
    
    brctl addif virbr0 virbr0-nic
    
    dhclient virbr0
    
    步骤三:用命令行起一个虚拟机
    
    sudo x86_64-softmmu/qemu-system-x86_64 --enable-kvm -m 5120 -drive file=/home/fang/vm/centos.img,if=virtio -net nic,model=virtio -net tap,ifname=virbr0-nic,script=no -vnc :0

    用vhost_net后端驱动

    前面提到virtio在宿主机中的后端处理程序(backend)一般是由用户空间的QEMU提供的,然而如果对于网络IO请求的后端处理能够在在内核空间来完成,则效率会更高,会提高网络吞吐量和减少网络延迟。在比较新的内核中有一个叫做“vhost-net”的驱动模块,它是作为一个内核级别的后端处理程序,将virtio-net的后端处理任务放到内核空间中执行,从而提高效率

    在第4章介绍“使用网桥模式”的网络配置时,有几个选项和virtio相关的,这里也介绍一下。

    -net tap,[,vnet_hdr=on|off][,vhost=on|off][,vhostfd=h][,vhostforce=on|off]

    vnet_hdr =on|off

    设置是否打开TAP设备的“IFF_VNET_HDR”标识。“vnet_hdr=off”表示关闭这个标识;“vnet_hdr=on”则强制开启这个标识,如果没有这个标识的支持,则会触发错误。IFF_VNET_HDR是tun/tap的一个标识,打开它则允许发送或接受大数据包时仅仅做部分的校验和检查。打开这个标识,可以提高virtio_net驱动的吞吐量。

    vhost=on|off

    设置是否开启vhost-net这个内核空间的后端处理驱动,它只对使用MIS-X[5]中断方式的virtio客户机有效。

    vhostforce=on|off

    设置是否强制使用vhost作为非MSI-X中断方式的Virtio客户机的后端处理程序。

    vhostfs=h

    设置为去连接一个已经打开的vhost网络设备。

    用如下的命令行启动一个客户机,就在客户机中使用virtio-net作为前端驱动程序,而后端处理程序则使用vhost-net(当然需要当前宿主机内核支持vhost-net模块)。

    [root@jay-linux kvm_demo]# qemu-system-x86_64 rhel6u3.img -smp 2 -m 1024 -net nic,model=virtio,macaddr=00:16:3e:22:22:22 -net tap,vnet_hdr=on,vhost=on

    VNC server running on ::1:5900'

    qemu-system-aarch64: network script /usr/local/bin/../etc/qemu-ifup failed with status 256

    [root@localhost cloud_images]# cat qemu-ifup 
    #!/bin/sh
    set -x
    
    switch=virbr0 
    
    if [ -n "$1" ];then
        ip tuntap add $1 mode tap user `whoami`
        ip link set $1 up
        sleep 0.5s
        ip link set $1 master $switch
        exit 0
    else
        echo "Error: no interface specified"
        exit 1
    fi
    
    qemu-system-aarch64  -name vm2 -daemonize \
      -enable-kvm -M virt -cpu host -smp 2 -m 4096 \
      -object memory-backend-file,id=mem,size=4096M,mem-path=/mnt/huge,share=on \
      -numa node,memdev=mem -mem-prealloc \
      -global virtio-blk-device.scsi=off \
      -device virtio-scsi-device,id=scsi \
      -kernel vmlinuz-4.18 --append "console=ttyAMA0  root=UUID=6a09973e-e8fd-4a6d-a8c0-1deb9556f477 iommu=pt intel_iommu=on iommu.passthrough=1" \
      -initrd initramfs-4.18 \
     -drive file=vhuser-test1.qcow2  \
     -serial telnet:localhost:4322,server,nowait \
     -monitor telnet:localhost:4321,server,nowait \
     -net nic,model=virtio,macaddr=00:16:3e:22:22:22 -net tap,id=hostnet1,script=qemu-ifup,vnet_hdr=on,vhost=on \
     -vnc :10

    当给一个Qemu进程传递了参数-netdev tap,vhost=on 的时候,QEMU会通过调用几个ioctl命令对这个文件描述符进行一些初始化的工作,然后进行特性的协商,从而宿主机跟客户机的vhost-net driver建立关系。 QEMU代码调用如下:

    vhost_net_init -> vhost_dev_init -> vhost_net_ack_features

    + switch=virbr0
    + '[' -n tap0 ']'
    ++ whoami
    + ip tuntap add tap0 mode tap user root
    ioctl(TUNSETIFF): Device or resource busy
    + ip link set tap0 up
    + sleep 0.5s
    + ip link set tap0 master virbr0
    + exit 0
    
    [root@localhost cloud_images]# brctl show
    bridge name     bridge id               STP enabled     interfaces
    virbr0          8000.5254000d3f71       yes             enp125s0f1
                                                            tap0
                                                            virbr0-nic

    [root@localhost cloud_images]# ps -elf | grep vhost
    7 S root      49044      1  9  80   0 - 88035 poll_s 21:56 ?        00:00:11 qemu-system-aarch64 -name vm2 -daemonize -enable-kvm -M virt -cpu host -smp 2 -m 4096 -object memory-backend-file,id=mem,size=4096M,mem-path=/mnt/huge,share=on -numa node,memdev=mem -mem-prealloc -global virtio-blk-device.scsi=off -device virtio-scsi-device,id=scsi -kernel vmlinuz-4.18 --append console=ttyAMA0  root=UUID=6a09973e-e8fd-4a6d-a8c0-1deb9556f477 iommu=pt intel_iommu=on iommu.passthrough=1 -initrd initramfs-4.18 -drive file=vhuser-test1.qcow2 -serial telnet:localhost:4322,server,nowait -monitor telnet:localhost:4321,server,nowait -net nic,model=virtio,macaddr=00:16:3e:22:22:22 -net tap,id=hostnet1,script=qemu-ifup,vnet_hdr=on,vhost=on -vnc :10
    1 S root      49065      2  0  80   0 -     0 vhost_ 21:56 ?        00:00:00 [vhost-49044]

    [root@localhost ~]# cat /proc/49065/stack 
    [] __switch_to+0x8c/0xa8
    [] vhost_worker+0x148/0x170 [vhost]
    [] kthread+0x10c/0x138
    [] ret_from_fork+0x10/0x18
    [] 0xffffffffffffffff
    [root@localhost ~]# 

    - To get qemu vcpu thread id
    # ps -eLo 
  • 相关阅读:
    nvm管理(切换)node版本,方便vue2,vue3+ts开发
    CodeSys中编程实现串口通讯【基于树莓派4B】
    索引待整理笔记
    计算机网络 - 网络层 选择填空判断复习题
    <Babel> 前端语言的巴别塔
    如何处理 Flink 作业中的数据倾斜问题?
    数据结构考试要求-第四章 串,数组和广义表
    JVM可视化工具之Java VisualVM
    认识一些网络的基础知识
    JavaWeb实现smbms项目核心功能
  • 原文地址:https://blog.csdn.net/lingshengxiyou/article/details/128008964