[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]
Subject: [PATCH] virtqueue: flexible layout, size, alignment
Transports can now lay out available/used/descriptor
regions in a flexible way.
This is useful for embedded systems to save memory,
and for large systems to reduce the need for
physically-contigious memory.
This does not add a way to actually program this
in any of the transports, so it's not useful by
itself, a follow-up patch with add a way to
program this for PCI.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
virtio-v1.0-wd01-part1-specification.txt | 52 ++++++++++++++++++++++++++++----
1 file changed, 46 insertions(+), 6 deletions(-)
diff --git a/virtio-v1.0-wd01-part1-specification.txt b/virtio-v1.0-wd01-part1-specification.txt
index fcd9fd7..9a40973 100644
--- a/virtio-v1.0-wd01-part1-specification.txt
+++ b/virtio-v1.0-wd01-part1-specification.txt
@@ -223,6 +223,45 @@ transmit and one for receive. Each queue has a 16-bit queue size
parameter, which sets the number of entries and implies the total size
of the queue.
+Each virtqueue consists of three parts:
+
+ Descriptor Table
+ Available Ring
+ Used Ring
+
+where each part is physically-contiguous in guest memory,
+and has different alignment requirements.
+
+The Queue Size field controls the total number of bytes
+required for each part of the virtqueue.
+
+The memory aligment and size requirements, in bytes, of each part of the
+virtqueue are summarized in the following table (qsz is the Queue Size field):
+
++------------+---------------------------------+
+| Virtqueue Part | Alignment | Size |
++------------+---------------------------------+
++------------+---------------------------------+
+| Descriptor Table | 16 | 16 * qsz |
++------------+---------------------------------+
+| Available Ring | 2 | 6 + 2 * qsz |
++------------+---------------------------------+
+| Used Ring | 4 | 6 + 4 * qsz |
++------------+---------------------------------+
+
+When the driver wants to send a buffer to the device, it fills in
+a slot in the descriptor table (or chains several together), and
+writes the descriptor index into the available ring. It then
+notifies the device. When the device has finished a buffer, it
+writes the descriptor into the used ring, and sends an interrupt.
+
+
+100.100.4.1. Legacy Interfaces: A Note on Virtqueue Layout
+--------------------------------------
+
+For Legacy Interfaces, several additional
+restrictions are placed on the virtqueue layout:
+
Each virtqueue occupies two or more physically-contiguous pages
(usually defined as 4096 bytes, but depending on the transport)
and consists of three parts:
@@ -241,9 +280,8 @@ required for the virtqueue according to the following formula:
+ ALIGN(sizeof(u16)*3 + sizeof(struct vring_used_elem)*qsz);
}
-This currently wastes some space with padding, but also allows future
-extensions such as the VIRTIO_RING_F_EVENT_IDX extension. The
-virtqueue layout structure looks like this:
+This wastes some space with padding.
+The legacy virtqueue layout structure therefore looks like this:
struct vring {
// The actual descriptors (16 bytes each)
@@ -814,9 +852,11 @@ This is done as follows, for each virtqueue a device has:
always a power of 2. This controls how big the virtqueue is
(see "2.1.4. Virtqueues"). If this field is 0, the virtqueue does not exist.
-3. Allocate and zero virtqueue in contiguous physical memory, on
- a 4096 byte alignment. Write the physical address, divided by
- 4096 to the Queue Address field.[6]
+3. Optionally, select a smaller virtqueue size and write it in the Queue Size
+ field.
+
+3. Allocate and zero Descriptor Table, Available and Used rings for the
+ virtqueue in contiguous physical memory.
4. Optionally, if MSI-X capability is present and enabled on the
device, select a vector to use to request interrupts triggered
--
MST
[Date Prev] | [Thread Prev] | [Thread Next] | [Date Next] -- [Date Index] | [Thread Index] | [List Home]