Full analysis of QEMU source code - virtio (2)

Continuing from the previous article:

References to this article:

"Interesting TalkLinux Operating System" - Liu Chao,Geek Time

"QEMU/KVM" source code analysis and application - Li Qiang, Machinery Industry Press

Thanks!

The last chapter introduced virtio and explained its basic principles and framework. Let’s review the virtio framework again.

The virtio framework is shown in the figure below:

virtio is a framework that uses paravirtualization technology to provide I/O performance. It is afront-end and back-end architecture, including < /span>. self-defined transmission protocolandBack-End DeviceandFront-End Driver

  • front-end driver

The front-end driver is the driver corresponding to the virtio simulation device inside the virtual machine. Each front-end device requires a corresponding driver to run normally. The main functions of the front-end driver are: 1) Receive user-mode requests; 2) Then encapsulate these requests according to the transmission protocol; 3) Then write the I/O port; 4) Send a notification to the back-end device of QEMU.

  • Backend equipment

The back-end device is in QEMU and is used to receive I/O requests from the front-end driver, and then parse the received data according to the format of the transmission protocol. For requests such as network cards that require interaction with actual physical devices, the back-end driver will operate the physical device to complete the request and notify the front-end driver through the interrupt mechanism.

  • virtioqueue

The data transmission of virtio front-end and back-end drivers is completed through virtio queue (virtio queue, virtqueue). A device will register several virtio queues, and each queue is responsible for processing different data transmission. Some of these queues are control-level queues and some are data-level queues. virtqueue is implemented through vring. vring is a ring buffer shared between the virtual machine and QEMU. When the virtual machine needs to send a request to QEMU, prepare the data, put the data description in vring, and write an I/O port. Then QEMU can read the data information from vring and then read the data from the memory. After QEMU completes the request, it also stores the data structure in vring, and the front-end driver can get the data from vring.

There is also another point of view and perspective here, which divides the virtio architecture into four layers:

  • front-end driver

First of all, the virtio front-end in the virtual machine has different drivers for different types of devices, but the interfaces are unified. For example, the hard disk is virtio_blk and the network is virtio_net.

  • Backend equipment

Secondly, in the host's QEMU, the logic of the virtio backend is implemented, mainly to operate the hardware equipment. For example, writing a file on the hard disk of a physical machine completes the operation of the virtual machine writing to the hard disk. Another example is sending a network packet to the kernel protocol stack to complete the virtual machine's network operation.

  • virtio layer and virtio-ring layer

Between the front-end and back-end of virtio, there is a communication layer, which includes the virtio layer and the virtio-ring layer. The virtio layer implements the virtual queue interface, which is regarded as a bridge for front-end and back-end communication; virtio-ring is the specific implementation of this bridge.

virtio uses virtqueue for high-speed communication between the front end and the back end. The number of queues for different types of devices is different. virtio-net uses two queues, one for receiving and the other for sending; while virtio-blk only uses one queue.

If the client wants to send data to the host, it will add the data buffer to the virtqueue and then notify the host by writing to the register. In this way, the host can receive the data in the buffer from virtqueue (the same meaning as the previous mechanism: when the virtual machine needs to send a request to QEMU, prepare the data, put the data description into vring, and write an I/O Port. Then QEMU can read the data information from vring, and then read the data from the memory. After QEMU completes the request, it also stores the data structure in vring, and the front-end driver can get the data from vring).

If you want to know what happens next, let’s look at the breakdown in the next chapter.

Guess you like

Origin blog.csdn.net/phmatthaus/article/details/134938532