Multiqueue in KVM Virtualization: Boosting I/O Performance

Preface

In the realm of virtualization, optimizing I/O performance is a perpetual pursuit. As host systems become more powerful with increasing core counts and faster storage, traditional single-queue I/O models can quickly become a bottleneck, limiting the overall throughput and responsiveness of virtual machines (VMs). This is where multiqueue comes into play, offering a significant leap in how virtualized I/O is handled. This blog post will delve into what multiqueue is, its advantages, and how it’s implemented within the Kernel-based Virtual Machine (KVM) environment.

Disclaimer: This post is based on information available regarding KVM’s multiqueue implementation. As virtualization technologies evolve rapidly, some details might have been updated or refined since the original documentation. Always refer to the latest KVM documentation for the most current information.

What is Multiqueue?

Traditionally, I/O devices (both physical and virtual) often communicated with the operating system through a single request queue. This meant that all I/O operations, regardless of their nature or origin, were serialized and processed sequentially. While this model worked adequately for simpler systems, it became a bottleneck as multi-core processors and high-speed storage (like NVMe SSDs) became commonplace.

Multiqueue, as the name suggests, introduces the concept of multiple independent request queues for an I/O device. Each queue can be processed concurrently, allowing the device to handle multiple I/O requests in parallel. This parallelism significantly improves the ability of the device to utilize the available CPU cores and storage bandwidth. In the context of virtualization, this translates to virtual devices presenting multiple queues to the guest operating system, which can then distribute its I/O across these queues.

Advantages of Multiqueue

The adoption of multiqueue brings several compelling advantages to virtualized environments:

  • Improved I/O Throughput: By allowing parallel processing of I/O requests, multiqueue drastically increases the total amount of data that can be read from or written to storage within a given time frame.
  • Reduced I/O Latency: With multiple queues, individual I/O requests spend less time waiting for other requests to complete, leading to lower latency and a more responsive guest experience.
  • Better CPU Utilization: Multiqueue allows I/O processing to be distributed across multiple CPU cores on the host, preventing a single core from becoming a bottleneck during intensive I/O operations. This leads to more efficient use of host resources.
  • Enhanced Scalability: As the number of virtual CPUs (vCPUs) in a guest VM increases, multiqueue allows each vCPU to potentially manage its own I/O queue, scaling I/O performance with the guest’s computational power.
  • Optimized for Modern Hardware: Multiqueue is specifically designed to leverage the capabilities of modern multi-core processors and high-performance storage devices like NVMe, which inherently support multiple queues.

KVM Implementation

KVM leverages virtio-blk and virtio-net to implement multiqueue support for block devices and network interfaces, respectively.

For virtio-blk, the guest can expose multiple queues to the host. The guest operating system, if it supports multiqueue, will then distribute its block I/O requests across these queues. On the host side, KVM and the underlying block device driver (e.g., for NVMe or even for traditional SCSI/SATA devices with appropriate queueing mechanisms) can process these requests in parallel. This means that a single virtual disk can effectively utilize the parallel processing capabilities of the host’s storage subsystem.

Similarly, for virtio-net, multiqueue allows for multiple receive and transmit queues for a virtual network interface. This is particularly beneficial for high-bandwidth network traffic and scenarios where a single VM handles a large volume of network I/O. The guest OS can direct network packets to different queues, which are then processed concurrently by the host. This reduces contention and improves overall network throughput.

Enabling multiqueue in KVM typically involves configuring the virtio device in the QEMU command line or libvirt XML with the appropriate num_queues parameter. For example, for a virtio-blk device, you might specify --device virtio-blk-pci,drive=mydisk,num_queues=X where X is the desired number of queues. The guest operating system must also have the necessary virtio drivers that support multiqueue.

Reference