diff options
author | mstsirkin <mstsirkin@0c8fb4dd-22a2-4bb5-bc14-6c75a5f43652> | 2013-09-30 06:15:08 +0000 |
---|---|---|
committer | mstsirkin <mstsirkin@0c8fb4dd-22a2-4bb5-bc14-6c75a5f43652> | 2013-09-30 06:15:08 +0000 |
commit | 1a0b2c653aed105f8cf9af9b6598f887bff22023 (patch) | |
tree | b26ce364ba87011464626ea902c6ae4ce5dea136 | |
parent | 2c758494de010bf29db35716c13f45263fd07ed1 (diff) |
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.
However, this does not add a way to actually program this
in any of the transports, so it's not useful by
itself, separate follow-up patches will add a way to
program this for transports.
Resolves issue: VIRTIO-23
Approved OASIS meeting 2013-09-24.
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
git-svn-id: https://tools.oasis-open.org/version-control/svn/virtio@49 0c8fb4dd-22a2-4bb5-bc14-6c75a5f43652
-rw-r--r-- | virtio-v1.0-wd01-part1-specification.txt | 54 |
1 files changed, 51 insertions, 3 deletions
diff --git a/virtio-v1.0-wd01-part1-specification.txt b/virtio-v1.0-wd01-part1-specification.txt index 1c2214f..b2d3cd9 100644 --- a/virtio-v1.0-wd01-part1-specification.txt +++ b/virtio-v1.0-wd01-part1-specification.txt @@ -216,6 +216,55 @@ 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 memory aligment and size requirements, in bytes, of each part of the +virtqueue are summarized in the following table: + ++------------+-----------------------------------------+ +| Virtqueue Part | Alignment | Size | ++------------+-----------------------------------------+ ++------------+-----------------------------------------+ +| Descriptor Table | 16 | 16 * (Queue Size) | ++------------+-----------------------------------------+ +| Available Ring | 2 | 6 + 2 * (Queue Size) | ++------------+-----------------------------------------+ +| Used Ring | 4 | 6 + 4 * (Queue Size) | ++------------+-----------------------------------------+ + +The Alignment column gives the miminum alignment: for each part +of the virtqueue, the physical address of the first byte of it +must be a multiple of the specified alignment value. + +The Size column gives the total number of bytes required for each +part of the virtqueue. + +Queue Size corresponds to the maximum number of buffers in the +virtqueue. For example, if Queue Size is 4 then at most 4 buffers +can be queued at any given time. Queue Size value is always a +power of 2. The maximum Queue Size value is 32768. This value +is specified in a bus-specific way. + +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. + + +2.1.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: @@ -234,9 +283,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) |