| |

QEMU/KVM Network Mechanisms

Introduction

As we know, network subsystems are important in computer systems since they are I/O systems and need to be optimized with many algorithms and skills. This article will introduce how QEMU/KVM [2] network part works. In order to put everything simple and easy to understand, we will begin with several examples and then understand how it works internally.

Examples

In this example, we will use TAP device [1] as QEMU/KVM host network device driver and VirtIO driver will be used to send/receive network packets/data between Host OS and Guest OS. See following “Start QEMU/KVM virtual machine” commands in details.


sudo x86_64-softmmu/qemu-system-x86_64 /home/hkucs/colo_ubuntu_single.img -machine pc-i440fx-2.3,accel=kvm,usb=off -netdev tap,id=hn0,script=/etc/qemu-ifup,downscript=/etc/qemu-ifdown -device virtio-net-pci,id=net-pci0,netdev=hn0 -vnc :7 -m 2048 -smp 2 -device piix3-usb-uhci -device usb-tablet -monitor stdio

Actually, according to my understanding, TAP device and driver are used in Host OS to send/receive packets/data to/from Gust OS since TAP driver can connect Gust OS with Internet. TAP driver will send the packets to Virtio in Host OS part and Virtio puts these packets into buffers, and at last, it notifies Virtio driver in Guest OS part to receive these packets. It has the same theory for how TAP devices receive packets from Guest OS. See following function stack for this part.


tap_send -----------> HOST TAP device driver
-> qemu_send_packet_async
-> qemu_send_packet_async_with_flags
->qemu_net_queue_send
->qemu_net_queue_deliver
->qemu_deliver_packet
->nc->info->receive
->virtio_net_receive -------------> since we use virtio-net-pci driver
->virtqueue_fill, virtqueue_flush, virtio_notify
->virtio_notify_vector
->k->notify
->virtio_pci_notify
->msix_notify
-> msi_send_message
->address_space_stl_le
->address_space_stl_internal

Actually, I think there is another example in [1]’s “Connecting VLANs To TAP Devices” part, and the function call stack should be like following.


tap_send -----------> HOST TAP device driver
-> qemu_send_packet_async
-> qemu_send_packet_async_with_flags
->qemu_net_queue_send
->qemu_net_queue_deliver
->qemu_deliver_packet
->nc->info->receive
->net_hub_port_receive ---> Start VLAN
->net_hub_receive
->qemu_send_packet
-> qemu_send_packet_async
->qemu_sendv_packet_async
...
->e1000_receive ---->NIC

Mechanisms

We need to look into mechanisms from above examples. So firstly, we will find that, in order to improve system performance, network part in QEMU/KVM will handle these packets in asynchronous way (it is also the way to be used in critical section). This is also due to these packets in memory cannot be operated by two threads simultaneously. On the other hand, these layers (TAP layer, Virtio layer, etc) are decoupled so they system design/implementation will be more flexibility and scalability. At last, Virtio is a para-virtualized technology to improve the performance for I/O systems in virtualization environments.

References

[1] https://people.gnome.org/~markmc/qemu-networking.html
[2] https://lxr.missinglinkelectronics.com/qemu+v2.4.0/

Similar Posts

  • MFC程序使用系统风格界面

    VC6默认编译出来的程序在XP下Luma风格下运行也是Windows的经典界面, 有损界面的美观与统一. VC2008默认设置下如果不是使用的unicode也是如此. 本文给出使VC6和VC2008可以编译出使用系统界面风格的解决方案. 1. 使VC6编译出使用系统风格的程序 步骤如下: 1) 创建一个.manifest文件的资源. 在res/文件夹下创建一个跟以程序名加.manifest的文件, 如果程序为test.exe, 则创建test.exe.manifest 文件可由此下载: https://www.systutorials.com/t/g/programming/resultcollector.manifest/ 注意要使用utf-8编码保存。 2) 将新定义的资源加入到.rc2文件中, 类型设为24. 打开res/文件夹下的.rc2文件, 在其中加入如下定义: 1 24 MOVEABLE PURE “res/test.exe.manifest” 其中的文件地址按1)步中修改的设置即可. 之后编译即可, 为了使程序界面可能充分利用系统的界面特性, 可以将界面字体设置为TrueType类型的, 利用Windows XP等系统的屏幕字体平滑特性. 2. 使VC2008编译出使用系统风格的程序 在VC2008下就比较简单了, 如果程序字符集使用unicode则默认就是使用系统界面风格的, 如果选择其它的类型, 则编辑下stdafx.h即可. 最后面部分找到这么一段: #ifdef _UNICODE #if defined _M_IX86 #pragma comment(linker,”/manifestdependency:”type=’win32′ name=’Microsoft.Windows.Common-Controls’ version=’6.0.0.0′ processorArchitecture=’x86′ publicKeyToken=’6595b64144ccf1df’ language=’*'””) #elif defined _M_IA64 #pragma comment(linker,”/manifestdependency:”type=’win32’…

  • How to import a googlecode git project to github project

    I wanna migrate leveldb (code.google.com/p/leveldb) to my github repository. Create a new repo on github.com with this link https://help.github.com/articles/creating-a-new-repository git clone https://code.google.com/p/ project-name.git Set the remote origin url as follows: git remote set-url origin https://github.com/ username/ repo-name.git git pull to pull the latest. git push origin master after making local changes. This is the original…

  • |

    How to handle missing blocks and blocks with corrupt replicas in HDFS?

    One of HDFS cluster’s hdfs dfsadmin -report reports: Under replicated blocks: 139016 Blocks with corrupt replicas: 9 Missing blocks: 0 The “Under replicated blocks” can be re-replicated automatically after some time. How to handle the missing blocks and blocks with corrupt replicas in HDFS? Understanding these blocks A block is “with corrupt replicas” in HDFS…

Leave a Reply

Your email address will not be published. Required fields are marked *